From 150e8aba6dbc7c0520bb9495d52f320f83127101 Mon Sep 17 00:00:00 2001 From: Yohei Ueda Date: Thu, 17 Feb 2022 10:45:40 +0900 Subject: [PATCH 1/5] runtime: Add hypervisor proto to support peer pod VMs This patch adds a protobuf definiton of the remote hypervisor type. Signed-off-by: Yohei Ueda --- .../hack/update-generated-hypervisor-proto.sh | 11 + .../protocols/hypervisor/hypervisor.pb.go | 1848 +++++++++++++++++ .../protocols/hypervisor/hypervisor.proto | 43 + 3 files changed, 1902 insertions(+) create mode 100755 src/runtime/hack/update-generated-hypervisor-proto.sh create mode 100644 src/runtime/protocols/hypervisor/hypervisor.pb.go create mode 100644 src/runtime/protocols/hypervisor/hypervisor.proto diff --git a/src/runtime/hack/update-generated-hypervisor-proto.sh b/src/runtime/hack/update-generated-hypervisor-proto.sh new file mode 100755 index 0000000000..16c873d98e --- /dev/null +++ b/src/runtime/hack/update-generated-hypervisor-proto.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -o errexit -o pipefail -o nounset + +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +protoc --gogottrpc_out=protocols/hypervisor \ + --gogottrpc_opt=plugins=ttrpc+fieldpath,paths=source_relative \ + -Iprotocols/hypervisor \ + -I../agent/protocols/protos/gogo/protobuf \ + protocols/hypervisor/hypervisor.proto diff --git a/src/runtime/protocols/hypervisor/hypervisor.pb.go b/src/runtime/protocols/hypervisor/hypervisor.pb.go new file mode 100644 index 0000000000..ba3b7d7786 --- /dev/null +++ b/src/runtime/protocols/hypervisor/hypervisor.pb.go @@ -0,0 +1,1848 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: hypervisor.proto + +package hypervisor + +import ( + context "context" + fmt "fmt" + github_com_containerd_ttrpc "github.com/containerd/ttrpc" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + io "io" + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type VersionRequest struct { + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionRequest) Reset() { *m = VersionRequest{} } +func (*VersionRequest) ProtoMessage() {} +func (*VersionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{0} +} +func (m *VersionRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VersionRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *VersionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionRequest.Merge(m, src) +} +func (m *VersionRequest) XXX_Size() int { + return m.Size() +} +func (m *VersionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VersionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionRequest proto.InternalMessageInfo + +type VersionResponse struct { + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionResponse) Reset() { *m = VersionResponse{} } +func (*VersionResponse) ProtoMessage() {} +func (*VersionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{1} +} +func (m *VersionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VersionResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *VersionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionResponse.Merge(m, src) +} +func (m *VersionResponse) XXX_Size() int { + return m.Size() +} +func (m *VersionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VersionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionResponse proto.InternalMessageInfo + +type CreateVMRequest struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Annotations map[string]string `protobuf:"bytes,2,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + NetworkNamespacePath string `protobuf:"bytes,3,opt,name=networkNamespacePath,proto3" json:"networkNamespacePath,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateVMRequest) Reset() { *m = CreateVMRequest{} } +func (*CreateVMRequest) ProtoMessage() {} +func (*CreateVMRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{2} +} +func (m *CreateVMRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CreateVMRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CreateVMRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CreateVMRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateVMRequest.Merge(m, src) +} +func (m *CreateVMRequest) XXX_Size() int { + return m.Size() +} +func (m *CreateVMRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateVMRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateVMRequest proto.InternalMessageInfo + +type CreateVMResponse struct { + AgentSocketPath string `protobuf:"bytes,1,opt,name=agentSocketPath,proto3" json:"agentSocketPath,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateVMResponse) Reset() { *m = CreateVMResponse{} } +func (*CreateVMResponse) ProtoMessage() {} +func (*CreateVMResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{3} +} +func (m *CreateVMResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CreateVMResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CreateVMResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CreateVMResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateVMResponse.Merge(m, src) +} +func (m *CreateVMResponse) XXX_Size() int { + return m.Size() +} +func (m *CreateVMResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateVMResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateVMResponse proto.InternalMessageInfo + +type StartVMRequest struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartVMRequest) Reset() { *m = StartVMRequest{} } +func (*StartVMRequest) ProtoMessage() {} +func (*StartVMRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{4} +} +func (m *StartVMRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StartVMRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StartVMRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StartVMRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartVMRequest.Merge(m, src) +} +func (m *StartVMRequest) XXX_Size() int { + return m.Size() +} +func (m *StartVMRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StartVMRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StartVMRequest proto.InternalMessageInfo + +type StartVMResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartVMResponse) Reset() { *m = StartVMResponse{} } +func (*StartVMResponse) ProtoMessage() {} +func (*StartVMResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{5} +} +func (m *StartVMResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StartVMResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StartVMResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StartVMResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartVMResponse.Merge(m, src) +} +func (m *StartVMResponse) XXX_Size() int { + return m.Size() +} +func (m *StartVMResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StartVMResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StartVMResponse proto.InternalMessageInfo + +type StopVMRequest struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StopVMRequest) Reset() { *m = StopVMRequest{} } +func (*StopVMRequest) ProtoMessage() {} +func (*StopVMRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{6} +} +func (m *StopVMRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StopVMRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StopVMRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StopVMRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopVMRequest.Merge(m, src) +} +func (m *StopVMRequest) XXX_Size() int { + return m.Size() +} +func (m *StopVMRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StopVMRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StopVMRequest proto.InternalMessageInfo + +type StopVMResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StopVMResponse) Reset() { *m = StopVMResponse{} } +func (*StopVMResponse) ProtoMessage() {} +func (*StopVMResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7b34fdb27c05edf8, []int{7} +} +func (m *StopVMResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StopVMResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StopVMResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StopVMResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopVMResponse.Merge(m, src) +} +func (m *StopVMResponse) XXX_Size() int { + return m.Size() +} +func (m *StopVMResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StopVMResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StopVMResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*VersionRequest)(nil), "hypervisor.VersionRequest") + proto.RegisterType((*VersionResponse)(nil), "hypervisor.VersionResponse") + proto.RegisterType((*CreateVMRequest)(nil), "hypervisor.CreateVMRequest") + proto.RegisterMapType((map[string]string)(nil), "hypervisor.CreateVMRequest.AnnotationsEntry") + proto.RegisterType((*CreateVMResponse)(nil), "hypervisor.CreateVMResponse") + proto.RegisterType((*StartVMRequest)(nil), "hypervisor.StartVMRequest") + proto.RegisterType((*StartVMResponse)(nil), "hypervisor.StartVMResponse") + proto.RegisterType((*StopVMRequest)(nil), "hypervisor.StopVMRequest") + proto.RegisterType((*StopVMResponse)(nil), "hypervisor.StopVMResponse") +} + +func init() { proto.RegisterFile("hypervisor.proto", fileDescriptor_7b34fdb27c05edf8) } + +var fileDescriptor_7b34fdb27c05edf8 = []byte{ + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x93, 0xcf, 0x4e, 0xf2, 0x40, + 0x14, 0xc5, 0x3b, 0x25, 0x1f, 0x7c, 0x5e, 0x22, 0xad, 0x13, 0x16, 0xb5, 0x98, 0x4a, 0xba, 0x22, + 0x6a, 0x58, 0xe0, 0xc6, 0x18, 0x63, 0x82, 0x7f, 0xa2, 0x1b, 0x89, 0x81, 0x84, 0xfd, 0x08, 0x13, + 0x69, 0xd0, 0x99, 0x3a, 0x1d, 0x30, 0xec, 0x7c, 0x18, 0x1f, 0x86, 0xa5, 0x4b, 0x97, 0xd2, 0xc4, + 0xf7, 0x30, 0xb4, 0xa5, 0xb4, 0x4d, 0x61, 0xd7, 0xb9, 0xf7, 0xcc, 0xe9, 0xef, 0x9e, 0xdc, 0x01, + 0x7d, 0x34, 0x73, 0xa9, 0x98, 0x3a, 0x1e, 0x17, 0x4d, 0x57, 0x70, 0xc9, 0x31, 0xac, 0x2b, 0xf6, + 0x11, 0x54, 0xfa, 0x54, 0x78, 0x0e, 0x67, 0x5d, 0xfa, 0x36, 0xa1, 0x9e, 0xc4, 0x06, 0x94, 0xa6, + 0x61, 0xc5, 0x40, 0x75, 0xd4, 0xd8, 0xe9, 0xae, 0x8e, 0xf6, 0x31, 0x68, 0xb1, 0xd6, 0x73, 0x39, + 0xf3, 0xe8, 0x16, 0xf1, 0x2f, 0x02, 0xed, 0x5a, 0x50, 0x22, 0x69, 0xff, 0x61, 0x65, 0x5d, 0x01, + 0xd5, 0x19, 0x46, 0x42, 0xd5, 0x19, 0xe2, 0x0e, 0x94, 0x09, 0x63, 0x5c, 0x12, 0xe9, 0x70, 0xe6, + 0x19, 0x6a, 0xbd, 0xd0, 0x28, 0xb7, 0x4e, 0x9a, 0x09, 0xe0, 0x8c, 0x43, 0xb3, 0xbd, 0x96, 0xdf, + 0x32, 0x29, 0x66, 0xdd, 0xa4, 0x01, 0x6e, 0x41, 0x95, 0x51, 0xf9, 0xce, 0xc5, 0xb8, 0x43, 0x5e, + 0xa9, 0xe7, 0x92, 0x01, 0x7d, 0x24, 0x72, 0x64, 0x14, 0x82, 0x3f, 0xe6, 0xf6, 0xcc, 0x4b, 0xd0, + 0xb3, 0xa6, 0x58, 0x87, 0xc2, 0x98, 0xce, 0x22, 0xd0, 0xe5, 0x27, 0xae, 0xc2, 0xbf, 0x29, 0x79, + 0x99, 0x50, 0x43, 0x0d, 0x6a, 0xe1, 0xe1, 0x5c, 0x3d, 0x43, 0xf6, 0x05, 0xe8, 0x6b, 0xc8, 0x28, + 0x95, 0x06, 0x68, 0xe4, 0x99, 0x32, 0xd9, 0xe3, 0x83, 0x31, 0x95, 0x01, 0x42, 0xe8, 0x95, 0x2d, + 0xdb, 0x75, 0xa8, 0xf4, 0x24, 0x11, 0x72, 0x63, 0x46, 0xf6, 0x1e, 0x68, 0xb1, 0x22, 0xb4, 0xb7, + 0x0f, 0x61, 0xb7, 0x27, 0xb9, 0xbb, 0xf9, 0x8e, 0xbe, 0x74, 0x0d, 0x05, 0xe1, 0x95, 0xd6, 0xa7, + 0x0a, 0x70, 0x1f, 0xc7, 0x8a, 0xef, 0xe0, 0xff, 0x0a, 0x1a, 0xd7, 0xb6, 0xe4, 0x6d, 0x1e, 0xe4, + 0x37, 0x23, 0x10, 0x05, 0xdf, 0x40, 0x29, 0xa2, 0xc3, 0x66, 0x52, 0x9a, 0x1e, 0xca, 0xac, 0xe5, + 0xf6, 0x62, 0x97, 0x36, 0x14, 0x43, 0x5e, 0xbc, 0x9f, 0x16, 0x26, 0x86, 0x34, 0xcd, 0xbc, 0x56, + 0x12, 0x24, 0xda, 0xcd, 0x34, 0x48, 0x7a, 0xb9, 0xd3, 0x20, 0x99, 0x65, 0xb6, 0x95, 0x2b, 0x63, + 0xbe, 0xb0, 0x94, 0xef, 0x85, 0xa5, 0x7c, 0xf8, 0x16, 0x9a, 0xfb, 0x16, 0xfa, 0xf2, 0x2d, 0xf4, + 0xe3, 0x5b, 0xe8, 0xa9, 0x18, 0x3c, 0x9d, 0xd3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xc0, + 0xa3, 0xa4, 0x4e, 0x03, 0x00, 0x00, +} + +func (m *VersionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VersionRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VersionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *VersionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VersionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VersionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CreateVMRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CreateVMRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CreateVMRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.NetworkNamespacePath) > 0 { + i -= len(m.NetworkNamespacePath) + copy(dAtA[i:], m.NetworkNamespacePath) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.NetworkNamespacePath))) + i-- + dAtA[i] = 0x1a + } + if len(m.Annotations) > 0 { + for k := range m.Annotations { + v := m.Annotations[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintHypervisor(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintHypervisor(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintHypervisor(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CreateVMResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CreateVMResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CreateVMResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.AgentSocketPath) > 0 { + i -= len(m.AgentSocketPath) + copy(dAtA[i:], m.AgentSocketPath) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.AgentSocketPath))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *StartVMRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StartVMRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StartVMRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *StartVMResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StartVMResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StartVMResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + return len(dAtA) - i, nil +} + +func (m *StopVMRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StopVMRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StopVMRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintHypervisor(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *StopVMResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StopVMResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StopVMResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + return len(dAtA) - i, nil +} + +func encodeVarintHypervisor(dAtA []byte, offset int, v uint64) int { + offset -= sovHypervisor(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *VersionRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *VersionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CreateVMRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if len(m.Annotations) > 0 { + for k, v := range m.Annotations { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovHypervisor(uint64(len(k))) + 1 + len(v) + sovHypervisor(uint64(len(v))) + n += mapEntrySize + 1 + sovHypervisor(uint64(mapEntrySize)) + } + } + l = len(m.NetworkNamespacePath) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CreateVMResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AgentSocketPath) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *StartVMRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *StartVMResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *StopVMRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovHypervisor(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *StopVMResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovHypervisor(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozHypervisor(x uint64) (n int) { + return sovHypervisor(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *VersionRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&VersionRequest{`, + `Version:` + fmt.Sprintf("%v", this.Version) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *VersionResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&VersionResponse{`, + `Version:` + fmt.Sprintf("%v", this.Version) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CreateVMRequest) String() string { + if this == nil { + return "nil" + } + keysForAnnotations := make([]string, 0, len(this.Annotations)) + for k, _ := range this.Annotations { + keysForAnnotations = append(keysForAnnotations, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAnnotations) + mapStringForAnnotations := "map[string]string{" + for _, k := range keysForAnnotations { + mapStringForAnnotations += fmt.Sprintf("%v: %v,", k, this.Annotations[k]) + } + mapStringForAnnotations += "}" + s := strings.Join([]string{`&CreateVMRequest{`, + `Id:` + fmt.Sprintf("%v", this.Id) + `,`, + `Annotations:` + mapStringForAnnotations + `,`, + `NetworkNamespacePath:` + fmt.Sprintf("%v", this.NetworkNamespacePath) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CreateVMResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CreateVMResponse{`, + `AgentSocketPath:` + fmt.Sprintf("%v", this.AgentSocketPath) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *StartVMRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StartVMRequest{`, + `Id:` + fmt.Sprintf("%v", this.Id) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *StartVMResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StartVMResponse{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *StopVMRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StopVMRequest{`, + `Id:` + fmt.Sprintf("%v", this.Id) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *StopVMResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StopVMResponse{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringHypervisor(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} + +type HypervisorService interface { + CreateVM(ctx context.Context, req *CreateVMRequest) (*CreateVMResponse, error) + StartVM(ctx context.Context, req *StartVMRequest) (*StartVMResponse, error) + StopVM(ctx context.Context, req *StopVMRequest) (*StopVMResponse, error) + Version(ctx context.Context, req *VersionRequest) (*VersionResponse, error) +} + +func RegisterHypervisorService(srv *github_com_containerd_ttrpc.Server, svc HypervisorService) { + srv.Register("hypervisor.Hypervisor", map[string]github_com_containerd_ttrpc.Method{ + "CreateVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req CreateVMRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.CreateVM(ctx, &req) + }, + "StartVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req StartVMRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.StartVM(ctx, &req) + }, + "StopVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req StopVMRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.StopVM(ctx, &req) + }, + "Version": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req VersionRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.Version(ctx, &req) + }, + }) +} + +type hypervisorClient struct { + client *github_com_containerd_ttrpc.Client +} + +func NewHypervisorClient(client *github_com_containerd_ttrpc.Client) HypervisorService { + return &hypervisorClient{ + client: client, + } +} + +func (c *hypervisorClient) CreateVM(ctx context.Context, req *CreateVMRequest) (*CreateVMResponse, error) { + var resp CreateVMResponse + if err := c.client.Call(ctx, "hypervisor.Hypervisor", "CreateVM", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *hypervisorClient) StartVM(ctx context.Context, req *StartVMRequest) (*StartVMResponse, error) { + var resp StartVMResponse + if err := c.client.Call(ctx, "hypervisor.Hypervisor", "StartVM", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *hypervisorClient) StopVM(ctx context.Context, req *StopVMRequest) (*StopVMResponse, error) { + var resp StopVMResponse + if err := c.client.Call(ctx, "hypervisor.Hypervisor", "StopVM", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *hypervisorClient) Version(ctx context.Context, req *VersionRequest) (*VersionResponse, error) { + var resp VersionResponse + if err := c.client.Call(ctx, "hypervisor.Hypervisor", "Version", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (m *VersionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VersionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VersionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VersionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VersionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VersionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreateVMRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreateVMRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreateVMRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Annotations == nil { + m.Annotations = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthHypervisor + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthHypervisor + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthHypervisor + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthHypervisor + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Annotations[mapkey] = mapvalue + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetworkNamespacePath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NetworkNamespacePath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreateVMResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreateVMResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreateVMResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgentSocketPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AgentSocketPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StartVMRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StartVMRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StartVMRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StartVMResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StartVMResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StartVMResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StopVMRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StopVMRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StopVMRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHypervisor + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHypervisor + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StopVMResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHypervisor + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StopVMResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StopVMResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipHypervisor(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHypervisor + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipHypervisor(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHypervisor + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHypervisor + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHypervisor + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthHypervisor + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupHypervisor + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthHypervisor + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthHypervisor = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowHypervisor = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupHypervisor = fmt.Errorf("proto: unexpected end of group") +) diff --git a/src/runtime/protocols/hypervisor/hypervisor.proto b/src/runtime/protocols/hypervisor/hypervisor.proto new file mode 100644 index 0000000000..11aeb2910f --- /dev/null +++ b/src/runtime/protocols/hypervisor/hypervisor.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package hypervisor; + +service Hypervisor { + rpc CreateVM(CreateVMRequest) returns (CreateVMResponse) {} + rpc StartVM(StartVMRequest) returns (StartVMResponse) {} + rpc StopVM(StopVMRequest) returns (StopVMResponse) {} + rpc Version(VersionRequest) returns (VersionResponse) {} +} + + +message VersionRequest { + string version = 1; +} + +message VersionResponse { + string version = 1; +} + +message CreateVMRequest { + string id = 1; + map annotations = 2; + string networkNamespacePath = 3; +} + +message CreateVMResponse { + string agentSocketPath = 1; +} + +message StartVMRequest { + string id = 1; +} + +message StartVMResponse { +} + +message StopVMRequest { + string id = 1; +} + +message StopVMResponse { +} From f9278f22c353e2ac253fa2eb2f129685af544bd0 Mon Sep 17 00:00:00 2001 From: Yohei Ueda Date: Thu, 17 Feb 2022 11:04:38 +0900 Subject: [PATCH 2/5] runtime: Support the remote hypervisor type This patch adds the support of the remote hypervisor type. Shim opens a Unix domain socket specified in the config file, and sends TTPRC requests to a external process to control sandbox VMs. Fixes #4482 Co-authored-by: Pradipta Banerjee Signed-off-by: Yohei Ueda --- .../cmd/kata-runtime/kata-check_amd64.go | 2 + .../cmd/kata-runtime/kata-check_arm64.go | 3 + .../cmd/kata-runtime/kata-check_ppc64le.go | 3 + .../cmd/kata-runtime/kata-check_s390x.go | 3 + .../hack/update-generated-hypervisor-proto.sh | 4 +- src/runtime/pkg/katautils/config.go | 19 ++ .../protocols/hypervisor/hypervisor.proto | 3 + src/runtime/virtcontainers/hypervisor.go | 12 + .../hypervisor_config_darwin.go | 4 + .../virtcontainers/hypervisor_config_linux.go | 4 + .../virtcontainers/hypervisor_linux.go | 2 + src/runtime/virtcontainers/kata_agent.go | 60 ++-- .../pkg/agent/protocols/client/client.go | 33 ++ src/runtime/virtcontainers/remote.go | 296 ++++++++++++++++++ src/runtime/virtcontainers/sandbox.go | 17 + src/runtime/virtcontainers/types/sandbox.go | 12 + 16 files changed, 456 insertions(+), 21 deletions(-) create mode 100644 src/runtime/virtcontainers/remote.go diff --git a/src/runtime/cmd/kata-runtime/kata-check_amd64.go b/src/runtime/cmd/kata-runtime/kata-check_amd64.go index 09f5bfe179..77d6b6ce78 100644 --- a/src/runtime/cmd/kata-runtime/kata-check_amd64.go +++ b/src/runtime/cmd/kata-runtime/kata-check_amd64.go @@ -304,6 +304,8 @@ func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error { return kvmIsUsable() case "acrn": return acrnIsUsable() + case "remote": + return nil case "mock": return nil default: diff --git a/src/runtime/cmd/kata-runtime/kata-check_arm64.go b/src/runtime/cmd/kata-runtime/kata-check_arm64.go index 66d81c71c3..933c977609 100644 --- a/src/runtime/cmd/kata-runtime/kata-check_arm64.go +++ b/src/runtime/cmd/kata-runtime/kata-check_arm64.go @@ -86,6 +86,9 @@ func checkKVMExtensions() error { } func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error { + if hypervisorType == "remote" { + return nil + } if err := kvmIsUsable(); err != nil { return err } diff --git a/src/runtime/cmd/kata-runtime/kata-check_ppc64le.go b/src/runtime/cmd/kata-runtime/kata-check_ppc64le.go index 7c5e7453ac..de34f9614f 100644 --- a/src/runtime/cmd/kata-runtime/kata-check_ppc64le.go +++ b/src/runtime/cmd/kata-runtime/kata-check_ppc64le.go @@ -61,6 +61,9 @@ func setCPUtype(hypervisorType vc.HypervisorType) error { } func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error { + if hypervisorType == "remote" { + return nil + } return kvmIsUsable() } diff --git a/src/runtime/cmd/kata-runtime/kata-check_s390x.go b/src/runtime/cmd/kata-runtime/kata-check_s390x.go index c9b1578b43..8ee51b7e5c 100644 --- a/src/runtime/cmd/kata-runtime/kata-check_s390x.go +++ b/src/runtime/cmd/kata-runtime/kata-check_s390x.go @@ -55,6 +55,9 @@ func kvmIsUsable() error { } func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error { + if hypervisorType == "remote" { + return nil + } return kvmIsUsable() } diff --git a/src/runtime/hack/update-generated-hypervisor-proto.sh b/src/runtime/hack/update-generated-hypervisor-proto.sh index 16c873d98e..df32974044 100755 --- a/src/runtime/hack/update-generated-hypervisor-proto.sh +++ b/src/runtime/hack/update-generated-hypervisor-proto.sh @@ -1,4 +1,6 @@ #!/bin/bash +# (C) Copyright IBM Corp. 2022. +# SPDX-License-Identifier: Apache-2.0 set -o errexit -o pipefail -o nounset @@ -7,5 +9,5 @@ cd "$(dirname "${BASH_SOURCE[0]}")/.." protoc --gogottrpc_out=protocols/hypervisor \ --gogottrpc_opt=plugins=ttrpc+fieldpath,paths=source_relative \ -Iprotocols/hypervisor \ - -I../agent/protocols/protos/gogo/protobuf \ + -I../libs/protocols/protos/gogo/protobuf \ protocols/hypervisor/hypervisor.proto diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index 1ec4993754..77d59a20aa 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -52,6 +52,7 @@ const ( qemuHypervisorTableType = "qemu" acrnHypervisorTableType = "acrn" dragonballHypervisorTableType = "dragonball" + remoteHypervisorTableType = "remote" // the maximum amount of PCI bridges that can be cold plugged in a VM maxPCIBridges uint32 = 5 @@ -106,6 +107,7 @@ type hypervisor struct { GuestPreAttestationSecretType string `toml:"guest_pre_attestation_secret_type"` SEVCertChainPath string `toml:"sev_cert_chain"` BlockDeviceAIO string `toml:"block_device_aio"` + RemoteHypervisorSocket string `toml:"remote_hypervisor_socket"` HypervisorPathList []string `toml:"valid_hypervisor_paths"` JailerPathList []string `toml:"valid_jailer_paths"` CtlPathList []string `toml:"valid_ctlpaths"` @@ -137,6 +139,7 @@ type hypervisor struct { PCIeRootPort uint32 `toml:"pcie_root_port"` GuestPreAttestationGRPCTimeout uint32 `toml:"guest_pre_attestation_grpc_timeout"` SEVGuestPolicy uint32 `toml:"sev_guest_policy"` + RemoteHypervisorTimeout uint32 `toml:"remote_hypervisor_timeout"` NumVCPUs int32 `toml:"default_vcpus"` BlockDeviceCacheSet bool `toml:"block_device_cache_set"` BlockDeviceCacheDirect bool `toml:"block_device_cache_direct"` @@ -1052,6 +1055,14 @@ func newDragonballHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { }, nil } +func newRemoteHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { + + return vc.HypervisorConfig{ + RemoteHypervisorSocket: h.RemoteHypervisorSocket, + RemoteHypervisorTimeout: h.RemoteHypervisorTimeout, + }, nil +} + func newFactoryConfig(f factory) (oci.FactoryConfig, error) { if f.TemplatePath == "" { f.TemplatePath = defaultTemplatePath @@ -1088,6 +1099,9 @@ func updateRuntimeConfigHypervisor(configPath string, tomlConf tomlConfig, confi case dragonballHypervisorTableType: config.HypervisorType = vc.DragonballHypervisor hConfig, err = newDragonballHypervisorConfig(hypervisor) + case remoteHypervisorTableType: + config.HypervisorType = vc.RemoteHypervisor + hConfig, err = newRemoteHypervisorConfig(hypervisor) } if err != nil { @@ -1638,6 +1652,11 @@ func checkFactoryConfig(config oci.RuntimeConfig) error { // checkHypervisorConfig performs basic "sanity checks" on the hypervisor // config. func checkHypervisorConfig(config vc.HypervisorConfig) error { + + if config.RemoteHypervisorSocket != "" { + return nil + } + type image struct { path string initrd bool diff --git a/src/runtime/protocols/hypervisor/hypervisor.proto b/src/runtime/protocols/hypervisor/hypervisor.proto index 11aeb2910f..0342e8ba4f 100644 --- a/src/runtime/protocols/hypervisor/hypervisor.proto +++ b/src/runtime/protocols/hypervisor/hypervisor.proto @@ -1,3 +1,6 @@ +// (C) Copyright IBM Corp. 2022. +// SPDX-License-Identifier: Apache-2.0 + syntax = "proto3"; package hypervisor; diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 0fb1a49278..d6f3b5086b 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -49,6 +49,9 @@ const ( // DragonballHypervisor is the Dragonball hypervisor. DragonballHypervisor HypervisorType = "dragonball" + // RemoteHypervisor is the Remote hypervisor. + RemoteHypervisor HypervisorType = "remote" + // MockHypervisor is a mock hypervisor for testing purposes MockHypervisor HypervisorType = "mock" @@ -175,6 +178,9 @@ func (hType *HypervisorType) Set(value string) error { case "dragonball": *hType = DragonballHypervisor return nil + case "remote": + *hType = RemoteHypervisor + return nil case "mock": *hType = MockHypervisor return nil @@ -194,6 +200,8 @@ func (hType *HypervisorType) String() string { return string(AcrnHypervisor) case ClhHypervisor: return string(ClhHypervisor) + case RemoteHypervisor: + return string(RemoteHypervisor) case MockHypervisor: return string(MockHypervisor) default: @@ -279,6 +287,9 @@ type HypervisorConfig struct { GuestPreAttestationSecretType string SEVCertChainPath string BlockDeviceAIO string + RemoteHypervisorSocket string + SandboxName string + SandboxNamespace string JailerPathList []string EntropySourceList []string VirtioFSDaemonList []string @@ -316,6 +327,7 @@ type HypervisorConfig struct { SEVGuestPolicy uint32 PCIeRootPort uint32 NumVCPUs uint32 + RemoteHypervisorTimeout uint32 IOMMUPlatform bool EnableIOThreads bool Debug bool diff --git a/src/runtime/virtcontainers/hypervisor_config_darwin.go b/src/runtime/virtcontainers/hypervisor_config_darwin.go index e074d59ea6..e0dafb912a 100644 --- a/src/runtime/virtcontainers/hypervisor_config_darwin.go +++ b/src/runtime/virtcontainers/hypervisor_config_darwin.go @@ -11,6 +11,10 @@ import ( func validateHypervisorConfig(conf *HypervisorConfig) error { + if conf.RemoteHypervisorSocket != "" { + return nil + } + if conf.KernelPath == "" { return fmt.Errorf("Missing kernel path") } diff --git a/src/runtime/virtcontainers/hypervisor_config_linux.go b/src/runtime/virtcontainers/hypervisor_config_linux.go index f1f20d3151..4a2d33e202 100644 --- a/src/runtime/virtcontainers/hypervisor_config_linux.go +++ b/src/runtime/virtcontainers/hypervisor_config_linux.go @@ -13,6 +13,10 @@ import ( func validateHypervisorConfig(conf *HypervisorConfig) error { + if conf.RemoteHypervisorSocket != "" { + return nil + } + if conf.KernelPath == "" { return fmt.Errorf("Missing kernel path") } diff --git a/src/runtime/virtcontainers/hypervisor_linux.go b/src/runtime/virtcontainers/hypervisor_linux.go index 3d81c1ada0..bff4d96df1 100644 --- a/src/runtime/virtcontainers/hypervisor_linux.go +++ b/src/runtime/virtcontainers/hypervisor_linux.go @@ -39,6 +39,8 @@ func NewHypervisor(hType HypervisorType) (Hypervisor, error) { return &cloudHypervisor{}, nil case DragonballHypervisor: return &mockHypervisor{}, nil + case RemoteHypervisor: + return &remoteHypervisor{}, nil case MockHypervisor: return &mockHypervisor{}, nil default: diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index f649e63b60..13179aa646 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -73,9 +73,13 @@ const ( kernelParamDebugConsoleVPortValue = "1026" ) +type customRequestTimeoutKeyType struct{} + var ( checkRequestTimeout = 30 * time.Second defaultRequestTimeout = 60 * time.Second + remoteRequestTimeout = 300 * time.Second + customRequestTimeoutKey = customRequestTimeoutKeyType(struct{}{}) errorMissingOCISpec = errors.New("Missing OCI specification") defaultKataHostSharedDir = "/run/kata-containers/shared/sandboxes/" defaultKataGuestSharedDir = "/run/kata-containers/shared/containers/" @@ -362,6 +366,8 @@ func (k *kataAgent) agentURL() (string, error) { return s.String(), nil case types.HybridVSock: return s.String(), nil + case types.RemoteSock: + return s.String(), nil case types.MockHybridVSock: return s.String(), nil default: @@ -412,6 +418,7 @@ func (k *kataAgent) configure(ctx context.Context, h Hypervisor, id, sharePath s if err != nil { return err } + case types.RemoteSock: case types.MockHybridVSock: default: return types.ErrInvalidConfigType @@ -716,30 +723,38 @@ func (k *kataAgent) startSandbox(ctx context.Context, sandbox *Sandbox) error { return err } - // Check grpc server is serving - if err = k.check(ctx); err != nil { - return err - } + var kmodules []*grpc.KernelModule - // Setup network interfaces and routes - interfaces, routes, neighs, err := generateVCNetworkStructures(ctx, sandbox.network) - if err != nil { - return err - } - if err = k.updateInterfaces(ctx, interfaces); err != nil { - return err - } - if _, err = k.updateRoutes(ctx, routes); err != nil { - return err - } - if err = k.addARPNeighbors(ctx, neighs); err != nil { - return err + if sandbox.config.HypervisorType == RemoteHypervisor { + ctx = context.WithValue(ctx, customRequestTimeoutKey, remoteRequestTimeout) + } else { + // TODO: Enable the following features for remote hypervisor if necessary + + // Check grpc server is serving + if err = k.check(ctx); err != nil { + return err + } + + // Setup network interfaces and routes + interfaces, routes, neighs, err := generateVCNetworkStructures(ctx, sandbox.network) + if err != nil { + return err + } + if err = k.updateInterfaces(ctx, interfaces); err != nil { + return err + } + if _, err = k.updateRoutes(ctx, routes); err != nil { + return err + } + if err = k.addARPNeighbors(ctx, neighs); err != nil { + return err + } + + kmodules = setupKernelModules(k.kmodules) } storages := setupStorages(ctx, sandbox) - kmodules := setupKernelModules(k.kmodules) - req := &grpc.CreateSandboxRequest{ Hostname: hostname, Dns: dns, @@ -1993,7 +2008,12 @@ func (k *kataAgent) getReqContext(ctx context.Context, reqName string) (newCtx c case grpcCheckRequest: newCtx, cancel = context.WithTimeout(ctx, checkRequestTimeout) default: - newCtx, cancel = context.WithTimeout(ctx, defaultRequestTimeout) + var requestTimeout = defaultRequestTimeout + + if timeout, ok := ctx.Value(customRequestTimeoutKey).(time.Duration); ok { + requestTimeout = timeout + } + newCtx, cancel = context.WithTimeout(ctx, requestTimeout) } return newCtx, cancel diff --git a/src/runtime/virtcontainers/pkg/agent/protocols/client/client.go b/src/runtime/virtcontainers/pkg/agent/protocols/client/client.go index 5728c89331..5aee043ab1 100644 --- a/src/runtime/virtcontainers/pkg/agent/protocols/client/client.go +++ b/src/runtime/virtcontainers/pkg/agent/protocols/client/client.go @@ -34,6 +34,7 @@ import ( const ( VSockSocketScheme = "vsock" HybridVSockScheme = "hvsock" + RemoteSockScheme = "remote" MockHybridVSockScheme = "mock" ) @@ -237,6 +238,11 @@ func parse(sock string) (string, *url.URL, error) { } hybridVSockPort = uint32(port) grpcAddr = HybridVSockScheme + ":" + hvsocket[0] + case RemoteSockScheme: + if addr.Host != "" { + return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid remote sock scheme: host address must be empty: %s", sock) + } + grpcAddr = RemoteSockScheme + ":" + addr.Path // just for tests use. case MockHybridVSockScheme: if addr.Path == "" { @@ -257,6 +263,8 @@ func agentDialer(addr *url.URL) dialer { return VsockDialer case HybridVSockScheme: return HybridVSockDialer + case RemoteSockScheme: + return RemoteSockDialer case MockHybridVSockScheme: return MockHybridVSockDialer default: @@ -437,6 +445,31 @@ func HybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) { return commonDialer(timeout, dialFunc, timeoutErr) } +// RemoteSockDialer dials to an agent in a remote hypervisor sandbox +func RemoteSockDialer(sock string, timeout time.Duration) (net.Conn, error) { + + s := strings.Split(sock, ":") + if !(len(s) == 2 && s[0] == RemoteSockScheme) { + return nil, fmt.Errorf("failed to parse remote sock: %q", sock) + } + socketPath := s[1] + + logrus.Printf("Dialing remote sock: %q %q", socketPath, sock) + + dialFunc := func() (net.Conn, error) { + conn, err := net.Dial("unix", socketPath) + if err != nil { + logrus.Errorf("failed to dial remote sock %q: %v", socketPath, err) + return nil, err + } + return conn, nil + } + + timeoutErr := grpcStatus.Errorf(codes.DeadlineExceeded, "timed out connecting to remote sock: %s", socketPath) + + return commonDialer(timeout, dialFunc, timeoutErr) +} + // just for tests use. func MockHybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) { sock = strings.TrimPrefix(sock, "mock:") diff --git a/src/runtime/virtcontainers/remote.go b/src/runtime/virtcontainers/remote.go new file mode 100644 index 0000000000..543fb72ba0 --- /dev/null +++ b/src/runtime/virtcontainers/remote.go @@ -0,0 +1,296 @@ +// (C) Copyright IBM Corp. 2022. +// SPDX-License-Identifier: Apache-2.0 + +package virtcontainers + +import ( + "context" + "fmt" + "net" + "os" + "time" + + cri "github.com/containerd/containerd/pkg/cri/annotations" + "github.com/containerd/ttrpc" + persistapi "github.com/kata-containers/kata-containers/src/runtime/pkg/hypervisors" + pb "github.com/kata-containers/kata-containers/src/runtime/protocols/hypervisor" + "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +const defaultMinTimeout = 60 + +type remoteHypervisor struct { + sandboxID remoteHypervisorSandboxID + agentSocketPath string + config HypervisorConfig +} + +type remoteHypervisorSandboxID string + +type remoteService struct { + conn net.Conn + client pb.HypervisorService +} + +func openRemoteService(socketPath string) (*remoteService, error) { + + conn, err := net.Dial("unix", socketPath) + if err != nil { + return nil, fmt.Errorf("failed to connect to remote hypervisor socket: %w", err) + } + + ttrpcClient := ttrpc.NewClient(conn) + + client := pb.NewHypervisorClient(ttrpcClient) + + s := &remoteService{ + conn: conn, + client: client, + } + + return s, nil +} + +func (s *remoteService) Close() error { + return s.conn.Close() +} + +func (rh *remoteHypervisor) CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error { + + rh.sandboxID = remoteHypervisorSandboxID(id) + + if err := rh.setConfig(hypervisorConfig); err != nil { + return err + } + + s, err := openRemoteService(hypervisorConfig.RemoteHypervisorSocket) + if err != nil { + return err + } + defer s.Close() + + annotations := map[string]string{} + annotations[cri.SandboxName] = hypervisorConfig.SandboxName + annotations[cri.SandboxNamespace] = hypervisorConfig.SandboxNamespace + + req := &pb.CreateVMRequest{ + Id: id, + Annotations: annotations, + NetworkNamespacePath: network.NetworkID(), + } + + res, err := s.client.CreateVM(context.Background(), req) + if err != nil { + return fmt.Errorf("remote hypervisor call failed: %w", err) + } + + if res.AgentSocketPath == "" { + return errors.New("remote hypervisor does not return tunnel socket path") + } + + rh.agentSocketPath = res.AgentSocketPath + + return nil +} + +func (rh *remoteHypervisor) StartVM(ctx context.Context, timeout int) error { + + minTimeout := defaultMinTimeout + if rh.config.RemoteHypervisorTimeout > 0 { + minTimeout = int(rh.config.RemoteHypervisorTimeout) + } + + if timeout < minTimeout { + timeout = minTimeout + } + + s, err := openRemoteService(rh.config.RemoteHypervisorSocket) + if err != nil { + return err + } + defer s.Close() + + req := &pb.StartVMRequest{ + Id: string(rh.sandboxID), + } + + ctx2, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + logrus.Printf("calling remote hypervisor StartVM (timeout: %d)", timeout) + + if _, err := s.client.StartVM(ctx2, req); err != nil { + return fmt.Errorf("remote hypervisor call failed: %w", err) + } + + return nil +} + +func (rh *remoteHypervisor) AttestVM(ctx context.Context) error { + return nil +} + +func (rh *remoteHypervisor) StopVM(ctx context.Context, waitOnly bool) error { + + s, err := openRemoteService(rh.config.RemoteHypervisorSocket) + if err != nil { + return err + } + defer s.Close() + + req := &pb.StopVMRequest{ + Id: string(rh.sandboxID), + } + + if _, err := s.client.StopVM(context.Background(), req); err != nil { + return fmt.Errorf("remote hypervisor call failed: %w", err) + } + + return nil +} + +func (rh *remoteHypervisor) GenerateSocket(id string) (interface{}, error) { + + socketPath := rh.agentSocketPath + if len(socketPath) == 0 { + return nil, errors.New("failed to generate remote sock: TunnelSocketPath is not set") + } + + remoteSock := types.RemoteSock{ + SandboxID: id, + TunnelSocketPath: socketPath, + } + + return remoteSock, nil +} + +func notImplemented(name string) error { + + err := errors.Errorf("%s: not implemented", name) + + logrus.Errorf(err.Error()) + + if tracer, ok := err.(interface{ StackTrace() errors.StackTrace }); ok { + for _, f := range tracer.StackTrace() { + logrus.Errorf("%+s:%d\n", f, f) + } + } + + return err +} + +func (rh *remoteHypervisor) PauseVM(ctx context.Context) error { + panic(notImplemented("PauseVM")) +} + +func (rh *remoteHypervisor) SaveVM() error { + panic(notImplemented("SaveVM")) +} + +func (rh *remoteHypervisor) ResumeVM(ctx context.Context) error { + panic(notImplemented("ResumeVM")) +} + +func (rh *remoteHypervisor) AddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error { + // TODO + logrus.Printf("addDevice: deviceType=%v devInfo=%#v", devType, devInfo) + return nil +} + +func (rh *remoteHypervisor) HotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { + panic(notImplemented("HotplugAddDevice")) +} + +func (rh *remoteHypervisor) HotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { + panic(notImplemented("HotplugRemoveDevice")) +} + +func (rh *remoteHypervisor) ResizeMemory(ctx context.Context, memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) { + // TODO + return memMB, MemoryDevice{}, nil +} + +func (rh *remoteHypervisor) GetTotalMemoryMB(ctx context.Context) uint32 { + return rh.config.MemorySize +} + +func (rh *remoteHypervisor) ResizeVCPUs(ctx context.Context, vcpus uint32) (uint32, uint32, error) { + // TODO + return vcpus, vcpus, nil +} + +func (rh *remoteHypervisor) GetVMConsole(ctx context.Context, sandboxID string) (string, string, error) { + panic(notImplemented("GetVMConsole")) +} + +func (rh *remoteHypervisor) Disconnect(ctx context.Context) { + // TODO + panic(notImplemented("Disconnect")) +} + +func (rh *remoteHypervisor) Capabilities(ctx context.Context) types.Capabilities { + var caps types.Capabilities + caps.SetBlockDeviceHotplugSupport() + return caps +} + +func (rh *remoteHypervisor) HypervisorConfig() HypervisorConfig { + return rh.config +} + +func (rh *remoteHypervisor) GetThreadIDs(ctx context.Context) (VcpuThreadIDs, error) { + // TODO + return VcpuThreadIDs{vcpus: make(map[int]int)}, nil +} + +func (rh *remoteHypervisor) Cleanup(ctx context.Context) error { + // TODO + return nil +} + +func (rh *remoteHypervisor) setConfig(config *HypervisorConfig) error { + // Create a Validator specific for remote hypervisor + rh.config = *config + + return nil +} + +func (rh *remoteHypervisor) GetPids() []int { + // TODO: meanwhile let's use shim pid as it used by crio to fetch start time + return []int{os.Getpid()} +} + +func (rh *remoteHypervisor) GetVirtioFsPid() *int { + panic(notImplemented("GetVirtioFsPid")) +} + +func (rh *remoteHypervisor) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error { + panic(notImplemented("fromGrpc")) +} + +func (rh *remoteHypervisor) toGrpc(ctx context.Context) ([]byte, error) { + panic(notImplemented("toGrpc")) +} + +func (rh *remoteHypervisor) Check() error { + //TODO + return nil +} + +func (rh *remoteHypervisor) Save() persistapi.HypervisorState { + // TODO + // called from Sandbox.dumpHypervisor + return persistapi.HypervisorState{} +} + +func (rh *remoteHypervisor) Load(persistapi.HypervisorState) { + // TODO + // called from Sandbox.loadHypervisor +} + +func (rh *remoteHypervisor) IsRateLimiterBuiltin() bool { + // TODO + return true +} diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go index cb0d57d632..8122fff5e6 100644 --- a/src/runtime/virtcontainers/sandbox.go +++ b/src/runtime/virtcontainers/sandbox.go @@ -27,6 +27,8 @@ import ( "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" + cri "github.com/containerd/containerd/pkg/cri/annotations" + crio "github.com/containers/podman/v4/pkg/annotations" "github.com/kata-containers/kata-containers/src/runtime/pkg/device/api" "github.com/kata-containers/kata-containers/src/runtime/pkg/device/config" "github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers" @@ -592,6 +594,21 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor return nil, err } + if len(sandboxConfig.Containers) > 0 { + // These values are required by remove hypervisor + for _, a := range []string{cri.SandboxName, crio.SandboxName} { + if value, ok := sandboxConfig.Containers[0].Annotations[a]; ok { + sandboxConfig.HypervisorConfig.SandboxName = value + } + } + + for _, a := range []string{cri.SandboxNamespace, crio.Namespace} { + if value, ok := sandboxConfig.Containers[0].Annotations[a]; ok { + sandboxConfig.HypervisorConfig.SandboxNamespace = value + } + } + } + // store doesn't require hypervisor to be stored immediately if err = s.hypervisor.CreateVM(ctx, s.id, s.network, &sandboxConfig.HypervisorConfig); err != nil { return nil, err diff --git a/src/runtime/virtcontainers/types/sandbox.go b/src/runtime/virtcontainers/types/sandbox.go index 5149b04232..29c909c977 100644 --- a/src/runtime/virtcontainers/types/sandbox.go +++ b/src/runtime/virtcontainers/types/sandbox.go @@ -7,6 +7,7 @@ package types import ( "fmt" + "net" "os" "strings" @@ -37,6 +38,7 @@ const ( HybridVSockScheme = "hvsock" MockHybridVSockScheme = "mock" VSockScheme = "vsock" + RemoteSockScheme = "remote" ) // SandboxState is a sandbox state structure @@ -210,6 +212,16 @@ func (s *HybridVSock) String() string { return fmt.Sprintf("%s://%s:%d", HybridVSockScheme, s.UdsPath, s.Port) } +type RemoteSock struct { + Conn net.Conn + SandboxID string + TunnelSocketPath string +} + +func (s *RemoteSock) String() string { + return fmt.Sprintf("%s://%s", RemoteSockScheme, s.TunnelSocketPath) +} + // MockHybridVSock defines a mock hybrid vsocket for tests only. type MockHybridVSock struct { UdsPath string From c3e6b660515046fef704e60d36efb05c10b5060b Mon Sep 17 00:00:00 2001 From: Lei Li Date: Thu, 21 Jul 2022 08:50:14 +0000 Subject: [PATCH 3/5] runtime: Support privileged containers in peer pod VM This patch fixes the issue of running containers with privileged as true. See the discussion at this URL for the details. https://github.com/confidential-containers/cloud-api-adaptor/issues/111 Author: Lei Li Signed-off-by: Yohei Ueda --- src/runtime/pkg/katautils/config.go | 3 +++ src/runtime/virtcontainers/kata_agent.go | 2 +- src/runtime/virtcontainers/remote.go | 6 ++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index 77d59a20aa..77582f2c34 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -1060,6 +1060,9 @@ func newRemoteHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { return vc.HypervisorConfig{ RemoteHypervisorSocket: h.RemoteHypervisorSocket, RemoteHypervisorTimeout: h.RemoteHypervisorTimeout, + + // No valid value so avoid to append block device to list in kata_agent.appendDevices + BlockDeviceDriver: "dummy", }, nil } diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 13179aa646..c8221b1602 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -1133,7 +1133,7 @@ func (k *kataAgent) appendDevices(deviceList []*grpc.Device, c *Container) []*gr kataDevice = k.appendVfioDevice(dev, device, c) } - if kataDevice == nil { + if kataDevice == nil || kataDevice.Type == "" { continue } diff --git a/src/runtime/virtcontainers/remote.go b/src/runtime/virtcontainers/remote.go index 543fb72ba0..9f1f92bfea 100644 --- a/src/runtime/virtcontainers/remote.go +++ b/src/runtime/virtcontainers/remote.go @@ -200,11 +200,13 @@ func (rh *remoteHypervisor) AddDevice(ctx context.Context, devInfo interface{}, } func (rh *remoteHypervisor) HotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { - panic(notImplemented("HotplugAddDevice")) + logrus.Printf("HotplugAddDevice: devInfo=%#v", devInfo) + return "HotplugAddDevice is not implemented", nil } func (rh *remoteHypervisor) HotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { - panic(notImplemented("HotplugRemoveDevice")) + logrus.Printf("HotplugRemoveDevice: devInfo=%#v", devInfo) + return "HotplugRemoveDevice is not implemented", nil } func (rh *remoteHypervisor) ResizeMemory(ctx context.Context, memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) { From de232b8030eba9908557ac6546b97e8044685bfc Mon Sep 17 00:00:00 2001 From: Yohei Ueda Date: Fri, 17 Jun 2022 23:37:13 +0900 Subject: [PATCH 4/5] agent: support copying of directories and symlinks This patch allows copying of directories and symlinks when static file copying is used between host and guest. This change is necessary to support recursive file copying between shim and agent. Signed-off-by: Yohei Ueda --- src/agent/src/rpc.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs index 4af13be90a..cab703b439 100644 --- a/src/agent/src/rpc.rs +++ b/src/agent/src/rpc.rs @@ -1989,6 +1989,38 @@ fn do_copy_file(req: &CopyFileRequest) -> Result<()> { std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(req.dir_mode))?; + let sflag = stat::SFlag::from_bits_truncate(req.file_mode); + + if sflag.contains(stat::SFlag::S_IFDIR) { + fs::create_dir(path.clone()).or_else(|e| { + if e.kind() != std::io::ErrorKind::AlreadyExists { + return Err(e); + } + Ok(()) + })?; + + std::fs::set_permissions(path.clone(), std::fs::Permissions::from_mode(req.file_mode))?; + + unistd::chown( + &path, + Some(Uid::from_raw(req.uid as u32)), + Some(Gid::from_raw(req.gid as u32)), + )?; + + return Ok(()); + } + + if sflag.contains(stat::SFlag::S_IFLNK) { + let src = PathBuf::from(String::from_utf8(req.data.clone()).unwrap()); + + unistd::symlinkat(&src, None, &path)?; + let path_str = CString::new(path.to_str().unwrap())?; + let ret = unsafe { libc::lchown(path_str.as_ptr(), req.uid as u32, req.gid as u32) }; + Errno::result(ret).map(drop)?; + + return Ok(()); + } + let mut tmpfile = path.clone(); tmpfile.set_extension("tmp"); From 5422a056f2a7e0e796faed9739656f1a6aebe334 Mon Sep 17 00:00:00 2001 From: Yohei Ueda Date: Fri, 17 Jun 2022 23:40:19 +0900 Subject: [PATCH 5/5] runtime: Copy shared files recursively This patch enables recursive file copying when filesystem sharing is not used. Signed-off-by: Yohei Ueda --- src/runtime/virtcontainers/fs_share_linux.go | 47 +++++++++++++----- src/runtime/virtcontainers/kata_agent.go | 52 +++++++++++++------- 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/runtime/virtcontainers/fs_share_linux.go b/src/runtime/virtcontainers/fs_share_linux.go index 2e80bfcc96..e7296bf4e7 100644 --- a/src/runtime/virtcontainers/fs_share_linux.go +++ b/src/runtime/virtcontainers/fs_share_linux.go @@ -11,6 +11,7 @@ import ( "context" "encoding/hex" "fmt" + "io/fs" "os" "path/filepath" "sync" @@ -239,23 +240,43 @@ func (f *FilesystemShare) ShareFile(ctx context.Context, c *Container, m *Mount) if !caps.IsFsSharingSupported() { f.Logger().Debug("filesystem sharing is not supported, files will be copied") - fileInfo, err := os.Stat(m.Source) - if err != nil { - return nil, err + var ignored bool + srcRoot := filepath.Clean(m.Source) + + walk := func(srcPath string, d fs.DirEntry, err error) error { + + if err != nil { + return err + } + + info, err := d.Info() + if err != nil { + return err + } + + if !(info.Mode().IsRegular() || info.Mode().IsDir() || (info.Mode()&os.ModeSymlink) == os.ModeSymlink) { + f.Logger().WithField("ignored-file", srcPath).Debug("Ignoring non-regular file as FS sharing not supported") + if srcPath == srcRoot { + // Ignore the mount if this is not a regular file (excludes socket, device, ...) as it cannot be handled by + // a simple copy. But this should not be treated as an error, only as a limitation. + ignored = true + return filepath.SkipDir + } + return nil + } + + dstPath := filepath.Join(guestPath, srcPath[len(srcRoot):]) + + return f.sandbox.agent.copyFile(ctx, srcPath, dstPath) } - // Ignore the mount if this is not a regular file (excludes - // directory, socket, device, ...) as it cannot be handled by - // a simple copy. But this should not be treated as an error, - // only as a limitation. - if !fileInfo.Mode().IsRegular() { - f.Logger().WithField("ignored-file", m.Source).Debug("Ignoring non-regular file as FS sharing not supported") + if err := filepath.WalkDir(srcRoot, walk); err != nil { + c.Logger().WithField("failed-file", m.Source).Debugf("failed to copy file to sandbox: %v", err) + return nil, err + } + if ignored { return nil, nil } - - if err := f.sandbox.agent.copyFile(ctx, m.Source, guestPath); err != nil { - return nil, err - } } else { // These mounts are created in the shared dir mountDest := filepath.Join(getMountPath(f.sandbox.ID()), filename) diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index c8221b1602..275433f62f 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -10,6 +10,7 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "os" "path/filepath" "strconv" @@ -2119,40 +2120,57 @@ func (k *kataAgent) setGuestDateTime(ctx context.Context, tv time.Time) error { func (k *kataAgent) copyFile(ctx context.Context, src, dst string) error { var st unix.Stat_t - err := unix.Stat(src, &st) + err := unix.Lstat(src, &st) if err != nil { return fmt.Errorf("Could not get file %s information: %v", src, err) } - b, err := os.ReadFile(src) - if err != nil { - return fmt.Errorf("Could not read file %s: %v", src, err) + cpReq := &grpc.CopyFileRequest{ + Path: dst, + DirMode: uint32(DirMode), + FileMode: st.Mode, + Uid: int32(st.Uid), + Gid: int32(st.Gid), } - fileSize := int64(len(b)) + var b []byte + + switch sflag := st.Mode & unix.S_IFMT; sflag { + case unix.S_IFREG: + var err error + // TODO: Support incrementail file copying instead of loading whole file into memory + b, err = ioutil.ReadFile(src) + if err != nil { + return fmt.Errorf("Could not read file %s: %v", src, err) + } + cpReq.FileSize = int64(len(b)) + + case unix.S_IFDIR: + + case unix.S_IFLNK: + symlink, err := os.Readlink(src) + if err != nil { + return fmt.Errorf("Could not read symlink %s: %v", src, err) + } + cpReq.Data = []byte(symlink) + + default: + return fmt.Errorf("Unsupported file type: %o", sflag) + } k.Logger().WithFields(logrus.Fields{ "source": src, "dest": dst, }).Debugf("Copying file from host to guest") - cpReq := &grpc.CopyFileRequest{ - Path: dst, - DirMode: uint32(DirMode), - FileMode: uint32(st.Mode), - FileSize: fileSize, - Uid: int32(st.Uid), - Gid: int32(st.Gid), - } - // Handle the special case where the file is empty - if fileSize == 0 { - _, err = k.sendReq(ctx, cpReq) + if cpReq.FileSize == 0 { + _, err := k.sendReq(ctx, cpReq) return err } // Copy file by parts if it's needed - remainingBytes := fileSize + remainingBytes := cpReq.FileSize offset := int64(0) for remainingBytes > 0 { bytesToCopy := int64(len(b))