diff --git a/Protobuild.toml b/Protobuild.toml index 1e34eb92f1..48d04ea350 100644 --- a/Protobuild.toml +++ b/Protobuild.toml @@ -21,5 +21,6 @@ prefixes = [ "github.com/Microsoft/hcsshim/internal/computeagent", "github.com/Microsoft/hcsshim/internal/ncproxyttrpc", "github.com/Microsoft/hcsshim/internal/vmservice", + "github.com/Microsoft/hcsshim/pkg/migration", ] generators = ["go", "go-ttrpc"] diff --git a/pkg/migration/doc.go b/pkg/migration/doc.go new file mode 100644 index 0000000000..28df60e9e9 --- /dev/null +++ b/pkg/migration/doc.go @@ -0,0 +1,4 @@ +// Package migration contains the proto and compiled go files for the live +// migration service, which manages sandbox live migration workflows including +// preparation, memory transfer, and finalization. +package migration diff --git a/pkg/migration/migration.pb.go b/pkg/migration/migration.pb.go new file mode 100644 index 0000000000..feb617c98a --- /dev/null +++ b/pkg/migration/migration.pb.go @@ -0,0 +1,847 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v5.26.0 +// source: github.com/Microsoft/hcsshim/pkg/migration/migration.proto + +package migration + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// FinalizeAction specifies the action to take on the sandbox during +// finalization. The concrete meaning depends on whether the call is made +// on the source or the destination — see the FinalizeSandbox RPC docs. +type FinalizeAction int32 + +const ( + // No action specified. Servers should treat this as an error. + FinalizeAction_FINALIZE_ACTION_UNSPECIFIED FinalizeAction = 0 + // Stop and clean up the sandbox on this side. On the source this is + // used after a successful migration; on the destination this is used + // when the migration was cancelled or failed. + FinalizeAction_FINALIZE_ACTION_STOP FinalizeAction = 1 + // Resume the sandbox on this side. On the destination this completes + // a successful migration by bringing the migrated VM back to a + // running state; on the source this is used to roll back when the + // migration was cancelled or failed. + FinalizeAction_FINALIZE_ACTION_RESUME FinalizeAction = 2 +) + +// Enum value maps for FinalizeAction. +var ( + FinalizeAction_name = map[int32]string{ + 0: "FINALIZE_ACTION_UNSPECIFIED", + 1: "FINALIZE_ACTION_STOP", + 2: "FINALIZE_ACTION_RESUME", + } + FinalizeAction_value = map[string]int32{ + "FINALIZE_ACTION_UNSPECIFIED": 0, + "FINALIZE_ACTION_STOP": 1, + "FINALIZE_ACTION_RESUME": 2, + } +) + +func (x FinalizeAction) Enum() *FinalizeAction { + p := new(FinalizeAction) + *p = x + return p +} + +func (x FinalizeAction) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FinalizeAction) Descriptor() protoreflect.EnumDescriptor { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_enumTypes[0].Descriptor() +} + +func (FinalizeAction) Type() protoreflect.EnumType { + return &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_enumTypes[0] +} + +func (x FinalizeAction) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FinalizeAction.Descriptor instead. +func (FinalizeAction) EnumDescriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{0} +} + +type PrepareAndExportSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the migration session. The same session_id is used on + // both source and destination for the lifetime of this LM and is what + // ties subsequent calls (TransferSandbox, FinalizeSandbox, etc.) back + // to this sandbox. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Source-side options that control how live migration is initialized + // on the compute system. + InitOptions *MigrationInitializeOptions `protobuf:"bytes,2,opt,name=init_options,json=initOptions,proto3" json:"init_options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PrepareAndExportSandboxRequest) Reset() { + *x = PrepareAndExportSandboxRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PrepareAndExportSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareAndExportSandboxRequest) ProtoMessage() {} + +func (x *PrepareAndExportSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareAndExportSandboxRequest.ProtoReflect.Descriptor instead. +func (*PrepareAndExportSandboxRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{0} +} + +func (x *PrepareAndExportSandboxRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *PrepareAndExportSandboxRequest) GetInitOptions() *MigrationInitializeOptions { + if x != nil { + return x.InitOptions + } + return nil +} + +type PrepareAndExportSandboxResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Opaque, serialized snapshot of the source shim's view of the sandbox + // and its containers. The caller must forward this verbatim as the + // `config` field of ImportSandboxRequest on the destination; only the + // destination shim knows how to decode it. + Config *anypb.Any `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PrepareAndExportSandboxResponse) Reset() { + *x = PrepareAndExportSandboxResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PrepareAndExportSandboxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareAndExportSandboxResponse) ProtoMessage() {} + +func (x *PrepareAndExportSandboxResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareAndExportSandboxResponse.ProtoReflect.Descriptor instead. +func (*PrepareAndExportSandboxResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{1} +} + +func (x *PrepareAndExportSandboxResponse) GetConfig() *anypb.Any { + if x != nil { + return x.Config + } + return nil +} + +type ImportSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the migration session. Must match the session_id used + // on the source for this LM. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Opaque config produced by PrepareAndExportSandbox on the source. + // Forwarded verbatim by the caller; the destination shim is responsible + // for decoding and applying it. + Config *anypb.Any `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ImportSandboxRequest) Reset() { + *x = ImportSandboxRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ImportSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportSandboxRequest) ProtoMessage() {} + +func (x *ImportSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportSandboxRequest.ProtoReflect.Descriptor instead. +func (*ImportSandboxRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{2} +} + +func (x *ImportSandboxRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *ImportSandboxRequest) GetConfig() *anypb.Any { + if x != nil { + return x.Config + } + return nil +} + +type ImportSandboxResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ImportSandboxResponse) Reset() { + *x = ImportSandboxResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ImportSandboxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportSandboxResponse) ProtoMessage() {} + +func (x *ImportSandboxResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportSandboxResponse.ProtoReflect.Descriptor instead. +func (*ImportSandboxResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{3} +} + +type PrepareSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the migration session. Must match the session_id used + // by ImportSandbox on this destination. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Destination-side options that control how live migration is + // initialized when the HCS compute system is created. + InitOptions *MigrationInitializeOptions `protobuf:"bytes,2,opt,name=init_options,json=initOptions,proto3" json:"init_options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PrepareSandboxRequest) Reset() { + *x = PrepareSandboxRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PrepareSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareSandboxRequest) ProtoMessage() {} + +func (x *PrepareSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareSandboxRequest.ProtoReflect.Descriptor instead. +func (*PrepareSandboxRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{4} +} + +func (x *PrepareSandboxRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *PrepareSandboxRequest) GetInitOptions() *MigrationInitializeOptions { + if x != nil { + return x.InitOptions + } + return nil +} + +type PrepareSandboxResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PrepareSandboxResponse) Reset() { + *x = PrepareSandboxResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PrepareSandboxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareSandboxResponse) ProtoMessage() {} + +func (x *PrepareSandboxResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareSandboxResponse.ProtoReflect.Descriptor instead. +func (*PrepareSandboxResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{5} +} + +type TransferSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the migration session. Must match the session_id used + // for the rest of this LM on this side. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Maximum time to wait for the migration socket / underlying transport + // to become ready before the server gives up and reports a TIMEOUT + // event on the response stream. If unset, the server applies a sensible + // default (e.g. 10 minutes). + Timeout *durationpb.Duration `protobuf:"bytes,2,opt,name=timeout,proto3" json:"timeout,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TransferSandboxRequest) Reset() { + *x = TransferSandboxRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TransferSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferSandboxRequest) ProtoMessage() {} + +func (x *TransferSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferSandboxRequest.ProtoReflect.Descriptor instead. +func (*TransferSandboxRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{6} +} + +func (x *TransferSandboxRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *TransferSandboxRequest) GetTimeout() *durationpb.Duration { + if x != nil { + return x.Timeout + } + return nil +} + +type TransferSandboxResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Monotonically increasing per-message counter on this stream. Useful + // for de-duplication if the client reconnects mid-transfer. + MessageID uint32 `protobuf:"varint,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + // Event-specific message describing the current migration notification. + Event string `protobuf:"bytes,2,opt,name=event,proto3" json:"event,omitempty"` + // Populated when `event` indicates an error or a timeout; empty + // otherwise. + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + // Server-side timestamp of when the transfer began. + StartTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + // Server-side timestamp of when this particular update was produced. + UpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TransferSandboxResponse) Reset() { + *x = TransferSandboxResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TransferSandboxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferSandboxResponse) ProtoMessage() {} + +func (x *TransferSandboxResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferSandboxResponse.ProtoReflect.Descriptor instead. +func (*TransferSandboxResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{7} +} + +func (x *TransferSandboxResponse) GetMessageID() uint32 { + if x != nil { + return x.MessageID + } + return 0 +} + +func (x *TransferSandboxResponse) GetEvent() string { + if x != nil { + return x.Event + } + return "" +} + +func (x *TransferSandboxResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *TransferSandboxResponse) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *TransferSandboxResponse) GetUpdateTime() *timestamppb.Timestamp { + if x != nil { + return x.UpdateTime + } + return nil +} + +type FinalizeSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the migration session. Must match the session_id used + // for the rest of this LM on this side. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Action the shim should take on the sandbox during finalization. See + // FinalizeAction and the FinalizeSandbox RPC documentation for the + // per-side semantics of STOP vs. RESUME. + Action FinalizeAction `protobuf:"varint,2,opt,name=action,proto3,enum=FinalizeAction" json:"action,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FinalizeSandboxRequest) Reset() { + *x = FinalizeSandboxRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FinalizeSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FinalizeSandboxRequest) ProtoMessage() {} + +func (x *FinalizeSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FinalizeSandboxRequest.ProtoReflect.Descriptor instead. +func (*FinalizeSandboxRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{8} +} + +func (x *FinalizeSandboxRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *FinalizeSandboxRequest) GetAction() FinalizeAction { + if x != nil { + return x.Action + } + return FinalizeAction_FINALIZE_ACTION_UNSPECIFIED +} + +type FinalizeSandboxResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FinalizeSandboxResponse) Reset() { + *x = FinalizeSandboxResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FinalizeSandboxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FinalizeSandboxResponse) ProtoMessage() {} + +func (x *FinalizeSandboxResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FinalizeSandboxResponse.ProtoReflect.Descriptor instead. +func (*FinalizeSandboxResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{9} +} + +type CreateDuplicateSocketRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Identifier for the active LM session. Must match the session_id used + // for the rest of this LM on this side. + SessionID string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Serialized WSAProtocolInfo struct describing the source socket whose + // handle should be duplicated into the shim process. The exact layout + // is opaque to clients; the shim feeds it directly to WSASocket to + // create the duplicate. + ProtocolInfo []byte `protobuf:"bytes,2,opt,name=protocol_info,json=protocolInfo,proto3" json:"protocol_info,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateDuplicateSocketRequest) Reset() { + *x = CreateDuplicateSocketRequest{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateDuplicateSocketRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDuplicateSocketRequest) ProtoMessage() {} + +func (x *CreateDuplicateSocketRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDuplicateSocketRequest.ProtoReflect.Descriptor instead. +func (*CreateDuplicateSocketRequest) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{10} +} + +func (x *CreateDuplicateSocketRequest) GetSessionID() string { + if x != nil { + return x.SessionID + } + return "" +} + +func (x *CreateDuplicateSocketRequest) GetProtocolInfo() []byte { + if x != nil { + return x.ProtocolInfo + } + return nil +} + +type CreateDuplicateSocketResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateDuplicateSocketResponse) Reset() { + *x = CreateDuplicateSocketResponse{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateDuplicateSocketResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDuplicateSocketResponse) ProtoMessage() {} + +func (x *CreateDuplicateSocketResponse) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDuplicateSocketResponse.ProtoReflect.Descriptor instead. +func (*CreateDuplicateSocketResponse) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP(), []int{11} +} + +var File_github_com_Microsoft_hcsshim_pkg_migration_migration_proto protoreflect.FileDescriptor + +const file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDesc = "" + + "\n" + + ":github.com/Microsoft/hcsshim/pkg/migration/migration.proto\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1aBgithub.com/Microsoft/hcsshim/pkg/migration/migration_options.proto\"\x7f\n" + + "\x1ePrepareAndExportSandboxRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12>\n" + + "\finit_options\x18\x02 \x01(\v2\x1b.MigrationInitializeOptionsR\vinitOptions\"O\n" + + "\x1fPrepareAndExportSandboxResponse\x12,\n" + + "\x06config\x18\x01 \x01(\v2\x14.google.protobuf.AnyR\x06config\"c\n" + + "\x14ImportSandboxRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12,\n" + + "\x06config\x18\x02 \x01(\v2\x14.google.protobuf.AnyR\x06config\"\x17\n" + + "\x15ImportSandboxResponse\"v\n" + + "\x15PrepareSandboxRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12>\n" + + "\finit_options\x18\x02 \x01(\v2\x1b.MigrationInitializeOptionsR\vinitOptions\"\x18\n" + + "\x16PrepareSandboxResponse\"l\n" + + "\x16TransferSandboxRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x123\n" + + "\atimeout\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\atimeout\"\xdc\x01\n" + + "\x17TransferSandboxResponse\x12\x1d\n" + + "\n" + + "message_id\x18\x01 \x01(\rR\tmessageId\x12\x14\n" + + "\x05event\x18\x02 \x01(\tR\x05event\x12\x14\n" + + "\x05error\x18\x03 \x01(\tR\x05error\x129\n" + + "\n" + + "start_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tstartTime\x12;\n" + + "\vupdate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\n" + + "updateTime\"`\n" + + "\x16FinalizeSandboxRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12'\n" + + "\x06action\x18\x02 \x01(\x0e2\x0f.FinalizeActionR\x06action\"\x19\n" + + "\x17FinalizeSandboxResponse\"b\n" + + "\x1cCreateDuplicateSocketRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12#\n" + + "\rprotocol_info\x18\x02 \x01(\fR\fprotocolInfo\"\x1f\n" + + "\x1dCreateDuplicateSocketResponse*g\n" + + "\x0eFinalizeAction\x12\x1f\n" + + "\x1bFINALIZE_ACTION_UNSPECIFIED\x10\x00\x12\x18\n" + + "\x14FINALIZE_ACTION_STOP\x10\x01\x12\x1a\n" + + "\x16FINALIZE_ACTION_RESUME\x10\x022\xd2\x03\n" + + "\tMigration\x12\\\n" + + "\x17PrepareAndExportSandbox\x12\x1f.PrepareAndExportSandboxRequest\x1a .PrepareAndExportSandboxResponse\x12>\n" + + "\rImportSandbox\x12\x15.ImportSandboxRequest\x1a\x16.ImportSandboxResponse\x12A\n" + + "\x0ePrepareSandbox\x12\x16.PrepareSandboxRequest\x1a\x17.PrepareSandboxResponse\x12F\n" + + "\x0fTransferSandbox\x12\x17.TransferSandboxRequest\x1a\x18.TransferSandboxResponse0\x01\x12D\n" + + "\x0fFinalizeSandbox\x12\x17.FinalizeSandboxRequest\x1a\x18.FinalizeSandboxResponse\x12V\n" + + "\x15CreateDuplicateSocket\x12\x1d.CreateDuplicateSocketRequest\x1a\x1e.CreateDuplicateSocketResponseB6Z4github.com/Microsoft/hcsshim/pkg/migration;migrationb\x06proto3" + +var ( + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescOnce sync.Once + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescData []byte +) + +func file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescGZIP() []byte { + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescOnce.Do(func() { + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDesc), len(file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDesc))) + }) + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDescData +} + +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_goTypes = []any{ + (FinalizeAction)(0), // 0: FinalizeAction + (*PrepareAndExportSandboxRequest)(nil), // 1: PrepareAndExportSandboxRequest + (*PrepareAndExportSandboxResponse)(nil), // 2: PrepareAndExportSandboxResponse + (*ImportSandboxRequest)(nil), // 3: ImportSandboxRequest + (*ImportSandboxResponse)(nil), // 4: ImportSandboxResponse + (*PrepareSandboxRequest)(nil), // 5: PrepareSandboxRequest + (*PrepareSandboxResponse)(nil), // 6: PrepareSandboxResponse + (*TransferSandboxRequest)(nil), // 7: TransferSandboxRequest + (*TransferSandboxResponse)(nil), // 8: TransferSandboxResponse + (*FinalizeSandboxRequest)(nil), // 9: FinalizeSandboxRequest + (*FinalizeSandboxResponse)(nil), // 10: FinalizeSandboxResponse + (*CreateDuplicateSocketRequest)(nil), // 11: CreateDuplicateSocketRequest + (*CreateDuplicateSocketResponse)(nil), // 12: CreateDuplicateSocketResponse + (*MigrationInitializeOptions)(nil), // 13: MigrationInitializeOptions + (*anypb.Any)(nil), // 14: google.protobuf.Any + (*durationpb.Duration)(nil), // 15: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp +} +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_depIdxs = []int32{ + 13, // 0: PrepareAndExportSandboxRequest.init_options:type_name -> MigrationInitializeOptions + 14, // 1: PrepareAndExportSandboxResponse.config:type_name -> google.protobuf.Any + 14, // 2: ImportSandboxRequest.config:type_name -> google.protobuf.Any + 13, // 3: PrepareSandboxRequest.init_options:type_name -> MigrationInitializeOptions + 15, // 4: TransferSandboxRequest.timeout:type_name -> google.protobuf.Duration + 16, // 5: TransferSandboxResponse.start_time:type_name -> google.protobuf.Timestamp + 16, // 6: TransferSandboxResponse.update_time:type_name -> google.protobuf.Timestamp + 0, // 7: FinalizeSandboxRequest.action:type_name -> FinalizeAction + 1, // 8: Migration.PrepareAndExportSandbox:input_type -> PrepareAndExportSandboxRequest + 3, // 9: Migration.ImportSandbox:input_type -> ImportSandboxRequest + 5, // 10: Migration.PrepareSandbox:input_type -> PrepareSandboxRequest + 7, // 11: Migration.TransferSandbox:input_type -> TransferSandboxRequest + 9, // 12: Migration.FinalizeSandbox:input_type -> FinalizeSandboxRequest + 11, // 13: Migration.CreateDuplicateSocket:input_type -> CreateDuplicateSocketRequest + 2, // 14: Migration.PrepareAndExportSandbox:output_type -> PrepareAndExportSandboxResponse + 4, // 15: Migration.ImportSandbox:output_type -> ImportSandboxResponse + 6, // 16: Migration.PrepareSandbox:output_type -> PrepareSandboxResponse + 8, // 17: Migration.TransferSandbox:output_type -> TransferSandboxResponse + 10, // 18: Migration.FinalizeSandbox:output_type -> FinalizeSandboxResponse + 12, // 19: Migration.CreateDuplicateSocket:output_type -> CreateDuplicateSocketResponse + 14, // [14:20] is the sub-list for method output_type + 8, // [8:14] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_init() } +func file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_init() { + if File_github_com_Microsoft_hcsshim_pkg_migration_migration_proto != nil { + return + } + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDesc), len(file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_rawDesc)), + NumEnums: 1, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_goTypes, + DependencyIndexes: file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_depIdxs, + EnumInfos: file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_enumTypes, + MessageInfos: file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_msgTypes, + }.Build() + File_github_com_Microsoft_hcsshim_pkg_migration_migration_proto = out.File + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_goTypes = nil + file_github_com_Microsoft_hcsshim_pkg_migration_migration_proto_depIdxs = nil +} diff --git a/pkg/migration/migration.proto b/pkg/migration/migration.proto new file mode 100644 index 0000000000..2296580b88 --- /dev/null +++ b/pkg/migration/migration.proto @@ -0,0 +1,224 @@ +syntax = "proto3"; + +option go_package = "github.com/Microsoft/hcsshim/pkg/migration;migration"; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "github.com/Microsoft/hcsshim/pkg/migration/migration_options.proto"; + +// Migration is the ttrpc service exposed by the shim that orchestrates a live +// migration (LM) of a sandbox (utility VM and its containers) from a SOURCE +// host to a DESTINATION host. +// +// High-level flow (in order): +// +// SOURCE DESTINATION +// ------ ----------- +// 1. PrepareAndExportSandbox ─────────► 2. ImportSandbox +// 3. NewTask (per container, repeated) +// 4. PrepareSandbox +// 5. CreateDuplicateSocket 5. CreateDuplicateSocket +// 6. TransferSandbox ◄────────► 6. TransferSandbox +// 7. FinalizeSandbox 7. FinalizeSandbox +// +// NewTask is part of the existing task service (not this service) and is what +// the destination uses to attach updated resource paths to the rehydrated +// shim state produced by ImportSandbox. +service Migration { + // PrepareAndExportSandbox is the FIRST call of a live migration and is + // invoked on the SOURCE shim. + // + // It performs two things: + // 1. Calls into HCS to initialize live migration on the underlying + // compute system. After this returns successfully, the utility VM + // is in the "migrating" state and is no longer mutable. + // 2. Collects the full in-memory state of the source shim (sandbox + // and container bookkeeping) and returns it as an opaque blob to + // the caller. + // + // The caller is expected to forward the returned opaque config verbatim + // to ImportSandbox on the destination. + rpc PrepareAndExportSandbox(PrepareAndExportSandboxRequest) returns (PrepareAndExportSandboxResponse); + + // ImportSandbox is the FIRST call made on the DESTINATION shim. + // + // It consumes the opaque config produced by PrepareAndExportSandbox on + // the source and rehydrates the destination shim with that state so that + // it mirrors the source's view of the sandbox and its containers. + // + // ImportSandbox does NOT create any HCS compute system, and + // the resource paths embedded in the rehydrated state still refer to + // source-host paths. Those paths must be fixed up by issuing a NewTask + // call (on the existing task service) for each container. Each NewTask + // identifies the corresponding container imported here and supplies the + // updated, destination-local resource paths, which the shim then patches + // into the rehydrated state. + rpc ImportSandbox(ImportSandboxRequest) returns (ImportSandboxResponse); + + // PrepareSandbox is the SECOND call made on the DESTINATION shim, after + // ImportSandbox and after a NewTask has been issued for every container + // in the sandbox. + // + // At this point the shim has a complete, destination-correct view of the + // sandbox. PrepareSandbox uses that view to create the HCS compute + // system on the destination with the updated resources. The compute + // system is created but NOT started; starting happens later, as part of + // TransferSandbox. + rpc PrepareSandbox(PrepareSandboxRequest) returns (PrepareSandboxResponse); + + // TransferSandbox drives the actual memory transfer between source and + // destination. It is called on BOTH sides and returns a stream of + // progress / status updates so the caller can observe the transfer. + // + // The stream remains open for the duration of the transfer and emits + // TransferSandboxResponse messages as state changes (progress, error, + // timeout, completion). + rpc TransferSandbox(TransferSandboxRequest) returns (stream TransferSandboxResponse); + + // FinalizeSandbox terminates a live migration session. It is called on + // BOTH the source and the destination, and the meaning of the action + // depends on which side it is being invoked on: + // + // SOURCE: + // - STOP : Migration completed successfully; tear down the source + // compute system and release its resources. + // - RESUME : Migration was cancelled or failed; roll back and + // resume running the VM on the source. + // + // DESTINATION: + // - STOP : Migration was cancelled or failed; discard the + // destination compute system and clean up. + // - RESUME : Migration completed successfully; bring the migrated + // VM back to a running state on the destination. + rpc FinalizeSandbox(FinalizeSandboxRequest) returns (FinalizeSandboxResponse); + + // CreateDuplicateSocket is called on BOTH the source and destination + // shims, after the caller has created the underlying + // migration transport sockets on each host. The caller hands the shim + // an opaque, serialized WSAProtocolInfo describing one of those sockets, + // and the shim uses it to materialize a duplicate handle to that same + // socket inside the shim process. + // + // This must be invoked prior to TransferSandbox on each side, because + // TransferSandbox uses the duplicated socket as the migration channel + // owned by the shim. + // + // Duplicating the sockets into the shim decouples the migration + // transport from the containerd process lifetime: once the duplicates + // exist, the shim alone can drive the migration to completion. This + // also provides resiliency — if containerd is interrupted mid-migration, + // the duplicated sockets in the shim continue to work and the shim can + // finish the live migration on its own. + rpc CreateDuplicateSocket(CreateDuplicateSocketRequest) returns (CreateDuplicateSocketResponse); +} + +message PrepareAndExportSandboxRequest { + // Identifier for the migration session. The same session_id is used on + // both source and destination for the lifetime of this LM and is what + // ties subsequent calls (TransferSandbox, FinalizeSandbox, etc.) back + // to this sandbox. + string session_id = 1; + // Source-side options that control how live migration is initialized + // on the compute system. + MigrationInitializeOptions init_options = 2; +} + +message PrepareAndExportSandboxResponse { + // Opaque, serialized snapshot of the source shim's view of the sandbox + // and its containers. The caller must forward this verbatim as the + // `config` field of ImportSandboxRequest on the destination; only the + // destination shim knows how to decode it. + google.protobuf.Any config = 1; +} + +message ImportSandboxRequest { + // Identifier for the migration session. Must match the session_id used + // on the source for this LM. + string session_id = 1; + // Opaque config produced by PrepareAndExportSandbox on the source. + // Forwarded verbatim by the caller; the destination shim is responsible + // for decoding and applying it. + google.protobuf.Any config = 2; +} + +message ImportSandboxResponse {} + +message PrepareSandboxRequest { + // Identifier for the migration session. Must match the session_id used + // by ImportSandbox on this destination. + string session_id = 1; + // Destination-side options that control how live migration is + // initialized when the HCS compute system is created. + MigrationInitializeOptions init_options = 2; +} + +message PrepareSandboxResponse {} + +message TransferSandboxRequest { + // Identifier for the migration session. Must match the session_id used + // for the rest of this LM on this side. + string session_id = 1; + // Maximum time to wait for the migration socket / underlying transport + // to become ready before the server gives up and reports a TIMEOUT + // event on the response stream. If unset, the server applies a sensible + // default (e.g. 10 minutes). + google.protobuf.Duration timeout = 2; +} + +message TransferSandboxResponse { + // Monotonically increasing per-message counter on this stream. Useful + // for de-duplication if the client reconnects mid-transfer. + uint32 message_id = 1; + // Event-specific message describing the current migration notification. + string event = 2; + // Populated when `event` indicates an error or a timeout; empty + // otherwise. + string error = 3; + // Server-side timestamp of when the transfer began. + google.protobuf.Timestamp start_time = 4; + // Server-side timestamp of when this particular update was produced. + google.protobuf.Timestamp update_time = 5; +} + +message FinalizeSandboxRequest { + // Identifier for the migration session. Must match the session_id used + // for the rest of this LM on this side. + string session_id = 1; + // Action the shim should take on the sandbox during finalization. See + // FinalizeAction and the FinalizeSandbox RPC documentation for the + // per-side semantics of STOP vs. RESUME. + FinalizeAction action = 2; +} + +// FinalizeAction specifies the action to take on the sandbox during +// finalization. The concrete meaning depends on whether the call is made +// on the source or the destination — see the FinalizeSandbox RPC docs. +enum FinalizeAction { + // No action specified. Servers should treat this as an error. + FINALIZE_ACTION_UNSPECIFIED = 0; + // Stop and clean up the sandbox on this side. On the source this is + // used after a successful migration; on the destination this is used + // when the migration was cancelled or failed. + FINALIZE_ACTION_STOP = 1; + // Resume the sandbox on this side. On the destination this completes + // a successful migration by bringing the migrated VM back to a + // running state; on the source this is used to roll back when the + // migration was cancelled or failed. + FINALIZE_ACTION_RESUME = 2; +} + +message FinalizeSandboxResponse {} + +message CreateDuplicateSocketRequest { + // Identifier for the active LM session. Must match the session_id used + // for the rest of this LM on this side. + string session_id = 1; + // Serialized WSAProtocolInfo struct describing the source socket whose + // handle should be duplicated into the shim process. The exact layout + // is opaque to clients; the shim feeds it directly to WSASocket to + // create the duplicate. + bytes protocol_info = 2; +} + +message CreateDuplicateSocketResponse {} diff --git a/pkg/migration/migration_options.pb.go b/pkg/migration/migration_options.pb.go new file mode 100644 index 0000000000..5f2116ff9a --- /dev/null +++ b/pkg/migration/migration_options.pb.go @@ -0,0 +1,482 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v5.26.0 +// source: github.com/Microsoft/hcsshim/pkg/migration/migration_options.proto + +package migration + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// MigrationMemoryTransport is the transport protocol used for memory transfer during migration. +type MigrationMemoryTransport int32 + +const ( + MigrationMemoryTransport_MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED MigrationMemoryTransport = 0 + // VM memory is copied over a TCP/IP connection. + MigrationMemoryTransport_MIGRATION_MEMORY_TRANSPORT_TCP MigrationMemoryTransport = 1 +) + +// Enum value maps for MigrationMemoryTransport. +var ( + MigrationMemoryTransport_name = map[int32]string{ + 0: "MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED", + 1: "MIGRATION_MEMORY_TRANSPORT_TCP", + } + MigrationMemoryTransport_value = map[string]int32{ + "MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED": 0, + "MIGRATION_MEMORY_TRANSPORT_TCP": 1, + } +) + +func (x MigrationMemoryTransport) Enum() *MigrationMemoryTransport { + p := new(MigrationMemoryTransport) + *p = x + return p +} + +func (x MigrationMemoryTransport) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MigrationMemoryTransport) Descriptor() protoreflect.EnumDescriptor { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_enumTypes[0].Descriptor() +} + +func (MigrationMemoryTransport) Type() protoreflect.EnumType { + return &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_enumTypes[0] +} + +func (x MigrationMemoryTransport) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MigrationMemoryTransport.Descriptor instead. +func (MigrationMemoryTransport) EnumDescriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP(), []int{0} +} + +type MigrationInitializeOptions struct { + state protoimpl.MessageState `protogen:"open.v1"` + // MemoryTransport specifies the transport protocol for memory transfer during migration. + MemoryTransport MigrationMemoryTransport `protobuf:"varint,1,opt,name=memory_transport,json=memoryTransport,proto3,enum=MigrationMemoryTransport" json:"memory_transport,omitempty"` + // MemoryTransferThrottleParams specifies settings for throttling during memory transfer. + MemoryTransferThrottleParams *MemoryMigrationTransferThrottleParams `protobuf:"bytes,2,opt,name=memory_transfer_throttle_params,json=memoryTransferThrottleParams,proto3,oneof" json:"memory_transfer_throttle_params,omitempty"` + // CompressionSettings specifies additional settings when compression is enabled. + CompressionSettings *MigrationCompressionSettings `protobuf:"bytes,3,opt,name=compression_settings,json=compressionSettings,proto3,oneof" json:"compression_settings,omitempty"` + // ChecksumVerification enables memory checksum verification. + ChecksumVerification bool `protobuf:"varint,4,opt,name=checksum_verification,json=checksumVerification,proto3" json:"checksum_verification,omitempty"` + // PerfTracingEnabled enables performance tracing during migration. + PerfTracingEnabled bool `protobuf:"varint,5,opt,name=perf_tracing_enabled,json=perfTracingEnabled,proto3" json:"perf_tracing_enabled,omitempty"` + // CancelIfBlackoutThresholdExceeds cancels the operation if the blackout threshold is exceeded. + CancelIfBlackoutThresholdExceeds bool `protobuf:"varint,6,opt,name=cancel_if_blackout_threshold_exceeds,json=cancelIfBlackoutThresholdExceeds,proto3" json:"cancel_if_blackout_threshold_exceeds,omitempty"` + // PrepareMemoryTransferMode extends timeout for cross-version live migration. + PrepareMemoryTransferMode bool `protobuf:"varint,7,opt,name=prepare_memory_transfer_mode,json=prepareMemoryTransferMode,proto3" json:"prepare_memory_transfer_mode,omitempty"` + // CompatibilityData is the compatibility information required for the destination VM. + CompatibilityData *CompatibilityInfo `protobuf:"bytes,8,opt,name=compatibility_data,json=compatibilityData,proto3,oneof" json:"compatibility_data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MigrationInitializeOptions) Reset() { + *x = MigrationInitializeOptions{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MigrationInitializeOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrationInitializeOptions) ProtoMessage() {} + +func (x *MigrationInitializeOptions) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MigrationInitializeOptions.ProtoReflect.Descriptor instead. +func (*MigrationInitializeOptions) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP(), []int{0} +} + +func (x *MigrationInitializeOptions) GetMemoryTransport() MigrationMemoryTransport { + if x != nil { + return x.MemoryTransport + } + return MigrationMemoryTransport_MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED +} + +func (x *MigrationInitializeOptions) GetMemoryTransferThrottleParams() *MemoryMigrationTransferThrottleParams { + if x != nil { + return x.MemoryTransferThrottleParams + } + return nil +} + +func (x *MigrationInitializeOptions) GetCompressionSettings() *MigrationCompressionSettings { + if x != nil { + return x.CompressionSettings + } + return nil +} + +func (x *MigrationInitializeOptions) GetChecksumVerification() bool { + if x != nil { + return x.ChecksumVerification + } + return false +} + +func (x *MigrationInitializeOptions) GetPerfTracingEnabled() bool { + if x != nil { + return x.PerfTracingEnabled + } + return false +} + +func (x *MigrationInitializeOptions) GetCancelIfBlackoutThresholdExceeds() bool { + if x != nil { + return x.CancelIfBlackoutThresholdExceeds + } + return false +} + +func (x *MigrationInitializeOptions) GetPrepareMemoryTransferMode() bool { + if x != nil { + return x.PrepareMemoryTransferMode + } + return false +} + +func (x *MigrationInitializeOptions) GetCompatibilityData() *CompatibilityInfo { + if x != nil { + return x.CompatibilityData + } + return nil +} + +// CompatibilityInfo is opaque VM compatibility data, primarily used in migration. +type CompatibilityInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Raw compatibility information. + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompatibilityInfo) Reset() { + *x = CompatibilityInfo{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompatibilityInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompatibilityInfo) ProtoMessage() {} + +func (x *CompatibilityInfo) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompatibilityInfo.ProtoReflect.Descriptor instead. +func (*CompatibilityInfo) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP(), []int{1} +} + +func (x *CompatibilityInfo) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type MemoryMigrationTransferThrottleParams struct { + state protoimpl.MessageState `protogen:"open.v1"` + // A flag indicating if throttling should be skipped. + SkipThrottling *bool `protobuf:"varint,1,opt,name=skip_throttling,json=skipThrottling,proto3,oneof" json:"skip_throttling,omitempty"` + // The scale of the throttling. The value is in percentage (1-100). + ThrottlingScale *float64 `protobuf:"fixed64,2,opt,name=throttling_scale,json=throttlingScale,proto3,oneof" json:"throttling_scale,omitempty"` + // Minimum percentage value to which memory transfer can be throttled. + MinimumThrottlePercentage *uint32 `protobuf:"varint,3,opt,name=minimum_throttle_percentage,json=minimumThrottlePercentage,proto3,oneof" json:"minimum_throttle_percentage,omitempty"` + // Number of memory transfer passes targeted before the VM enters blackout. + TargetNumberOfBrownoutTransferPasses *uint32 `protobuf:"varint,4,opt,name=target_number_of_brownout_transfer_passes,json=targetNumberOfBrownoutTransferPasses,proto3,oneof" json:"target_number_of_brownout_transfer_passes,omitempty"` + // The starting transfer pass where throttling is starting. + StartingBrownoutPassNumberForThrottling *uint32 `protobuf:"varint,5,opt,name=starting_brownout_pass_number_for_throttling,json=startingBrownoutPassNumberForThrottling,proto3,oneof" json:"starting_brownout_pass_number_for_throttling,omitempty"` + // Maximum number of memory transfer passes before forcing the VM to enter blackout. + MaximumNumberOfBrownoutTransferPasses *uint32 `protobuf:"varint,6,opt,name=maximum_number_of_brownout_transfer_passes,json=maximumNumberOfBrownoutTransferPasses,proto3,oneof" json:"maximum_number_of_brownout_transfer_passes,omitempty"` + // Expected duration for blackout transfer time. + TargetBlackoutTransferTime *uint32 `protobuf:"varint,7,opt,name=target_blackout_transfer_time,json=targetBlackoutTransferTime,proto3,oneof" json:"target_blackout_transfer_time,omitempty"` + // Threshold for blackout duration prior to cancelling migration. + BlackoutTimeThresholdForCancellingMigration *uint32 `protobuf:"varint,8,opt,name=blackout_time_threshold_for_cancelling_migration,json=blackoutTimeThresholdForCancellingMigration,proto3,oneof" json:"blackout_time_threshold_for_cancelling_migration,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MemoryMigrationTransferThrottleParams) Reset() { + *x = MemoryMigrationTransferThrottleParams{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MemoryMigrationTransferThrottleParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MemoryMigrationTransferThrottleParams) ProtoMessage() {} + +func (x *MemoryMigrationTransferThrottleParams) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MemoryMigrationTransferThrottleParams.ProtoReflect.Descriptor instead. +func (*MemoryMigrationTransferThrottleParams) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP(), []int{2} +} + +func (x *MemoryMigrationTransferThrottleParams) GetSkipThrottling() bool { + if x != nil && x.SkipThrottling != nil { + return *x.SkipThrottling + } + return false +} + +func (x *MemoryMigrationTransferThrottleParams) GetThrottlingScale() float64 { + if x != nil && x.ThrottlingScale != nil { + return *x.ThrottlingScale + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetMinimumThrottlePercentage() uint32 { + if x != nil && x.MinimumThrottlePercentage != nil { + return *x.MinimumThrottlePercentage + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetTargetNumberOfBrownoutTransferPasses() uint32 { + if x != nil && x.TargetNumberOfBrownoutTransferPasses != nil { + return *x.TargetNumberOfBrownoutTransferPasses + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetStartingBrownoutPassNumberForThrottling() uint32 { + if x != nil && x.StartingBrownoutPassNumberForThrottling != nil { + return *x.StartingBrownoutPassNumberForThrottling + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetMaximumNumberOfBrownoutTransferPasses() uint32 { + if x != nil && x.MaximumNumberOfBrownoutTransferPasses != nil { + return *x.MaximumNumberOfBrownoutTransferPasses + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetTargetBlackoutTransferTime() uint32 { + if x != nil && x.TargetBlackoutTransferTime != nil { + return *x.TargetBlackoutTransferTime + } + return 0 +} + +func (x *MemoryMigrationTransferThrottleParams) GetBlackoutTimeThresholdForCancellingMigration() uint32 { + if x != nil && x.BlackoutTimeThresholdForCancellingMigration != nil { + return *x.BlackoutTimeThresholdForCancellingMigration + } + return 0 +} + +type MigrationCompressionSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Number of worker threads used for [de]compression. Values higher than what the host + // and VM configuration can support will be adjusted. The value should be non-zero. + ThrottleWorkerCount *uint32 `protobuf:"varint,1,opt,name=throttle_worker_count,json=throttleWorkerCount,proto3,oneof" json:"throttle_worker_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MigrationCompressionSettings) Reset() { + *x = MigrationCompressionSettings{} + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MigrationCompressionSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrationCompressionSettings) ProtoMessage() {} + +func (x *MigrationCompressionSettings) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MigrationCompressionSettings.ProtoReflect.Descriptor instead. +func (*MigrationCompressionSettings) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP(), []int{3} +} + +func (x *MigrationCompressionSettings) GetThrottleWorkerCount() uint32 { + if x != nil && x.ThrottleWorkerCount != nil { + return *x.ThrottleWorkerCount + } + return 0 +} + +var File_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto protoreflect.FileDescriptor + +const file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDesc = "" + + "\n" + + "Bgithub.com/Microsoft/hcsshim/pkg/migration/migration_options.proto\"\xc1\x05\n" + + "\x1aMigrationInitializeOptions\x12D\n" + + "\x10memory_transport\x18\x01 \x01(\x0e2\x19.MigrationMemoryTransportR\x0fmemoryTransport\x12r\n" + + "\x1fmemory_transfer_throttle_params\x18\x02 \x01(\v2&.MemoryMigrationTransferThrottleParamsH\x00R\x1cmemoryTransferThrottleParams\x88\x01\x01\x12U\n" + + "\x14compression_settings\x18\x03 \x01(\v2\x1d.MigrationCompressionSettingsH\x01R\x13compressionSettings\x88\x01\x01\x123\n" + + "\x15checksum_verification\x18\x04 \x01(\bR\x14checksumVerification\x120\n" + + "\x14perf_tracing_enabled\x18\x05 \x01(\bR\x12perfTracingEnabled\x12N\n" + + "$cancel_if_blackout_threshold_exceeds\x18\x06 \x01(\bR cancelIfBlackoutThresholdExceeds\x12?\n" + + "\x1cprepare_memory_transfer_mode\x18\a \x01(\bR\x19prepareMemoryTransferMode\x12F\n" + + "\x12compatibility_data\x18\b \x01(\v2\x12.CompatibilityInfoH\x02R\x11compatibilityData\x88\x01\x01B\"\n" + + " _memory_transfer_throttle_paramsB\x17\n" + + "\x15_compression_settingsB\x15\n" + + "\x13_compatibility_data\"'\n" + + "\x11CompatibilityInfo\x12\x12\n" + + "\x04data\x18\x01 \x01(\fR\x04data\"\xce\a\n" + + "%MemoryMigrationTransferThrottleParams\x12,\n" + + "\x0fskip_throttling\x18\x01 \x01(\bH\x00R\x0eskipThrottling\x88\x01\x01\x12.\n" + + "\x10throttling_scale\x18\x02 \x01(\x01H\x01R\x0fthrottlingScale\x88\x01\x01\x12C\n" + + "\x1bminimum_throttle_percentage\x18\x03 \x01(\rH\x02R\x19minimumThrottlePercentage\x88\x01\x01\x12\\\n" + + ")target_number_of_brownout_transfer_passes\x18\x04 \x01(\rH\x03R$targetNumberOfBrownoutTransferPasses\x88\x01\x01\x12b\n" + + ",starting_brownout_pass_number_for_throttling\x18\x05 \x01(\rH\x04R'startingBrownoutPassNumberForThrottling\x88\x01\x01\x12^\n" + + "*maximum_number_of_brownout_transfer_passes\x18\x06 \x01(\rH\x05R%maximumNumberOfBrownoutTransferPasses\x88\x01\x01\x12F\n" + + "\x1dtarget_blackout_transfer_time\x18\a \x01(\rH\x06R\x1atargetBlackoutTransferTime\x88\x01\x01\x12j\n" + + "0blackout_time_threshold_for_cancelling_migration\x18\b \x01(\rH\aR+blackoutTimeThresholdForCancellingMigration\x88\x01\x01B\x12\n" + + "\x10_skip_throttlingB\x13\n" + + "\x11_throttling_scaleB\x1e\n" + + "\x1c_minimum_throttle_percentageB,\n" + + "*_target_number_of_brownout_transfer_passesB/\n" + + "-_starting_brownout_pass_number_for_throttlingB-\n" + + "+_maximum_number_of_brownout_transfer_passesB \n" + + "\x1e_target_blackout_transfer_timeB3\n" + + "1_blackout_time_threshold_for_cancelling_migration\"q\n" + + "\x1cMigrationCompressionSettings\x127\n" + + "\x15throttle_worker_count\x18\x01 \x01(\rH\x00R\x13throttleWorkerCount\x88\x01\x01B\x18\n" + + "\x16_throttle_worker_count*j\n" + + "\x18MigrationMemoryTransport\x12*\n" + + "&MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED\x10\x00\x12\"\n" + + "\x1eMIGRATION_MEMORY_TRANSPORT_TCP\x10\x01B6Z4github.com/Microsoft/hcsshim/pkg/migration;migrationb\x06proto3" + +var ( + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescOnce sync.Once + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescData []byte +) + +func file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescGZIP() []byte { + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescOnce.Do(func() { + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDesc), len(file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDesc))) + }) + return file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDescData +} + +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_goTypes = []any{ + (MigrationMemoryTransport)(0), // 0: MigrationMemoryTransport + (*MigrationInitializeOptions)(nil), // 1: MigrationInitializeOptions + (*CompatibilityInfo)(nil), // 2: CompatibilityInfo + (*MemoryMigrationTransferThrottleParams)(nil), // 3: MemoryMigrationTransferThrottleParams + (*MigrationCompressionSettings)(nil), // 4: MigrationCompressionSettings +} +var file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_depIdxs = []int32{ + 0, // 0: MigrationInitializeOptions.memory_transport:type_name -> MigrationMemoryTransport + 3, // 1: MigrationInitializeOptions.memory_transfer_throttle_params:type_name -> MemoryMigrationTransferThrottleParams + 4, // 2: MigrationInitializeOptions.compression_settings:type_name -> MigrationCompressionSettings + 2, // 3: MigrationInitializeOptions.compatibility_data:type_name -> CompatibilityInfo + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_init() } +func file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_init() { + if File_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto != nil { + return + } + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[0].OneofWrappers = []any{} + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[2].OneofWrappers = []any{} + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes[3].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDesc), len(file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_rawDesc)), + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_goTypes, + DependencyIndexes: file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_depIdxs, + EnumInfos: file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_enumTypes, + MessageInfos: file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_msgTypes, + }.Build() + File_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto = out.File + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_goTypes = nil + file_github_com_Microsoft_hcsshim_pkg_migration_migration_options_proto_depIdxs = nil +} diff --git a/pkg/migration/migration_options.proto b/pkg/migration/migration_options.proto new file mode 100644 index 0000000000..e7ad0b75ad --- /dev/null +++ b/pkg/migration/migration_options.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; + +option go_package = "github.com/Microsoft/hcsshim/pkg/migration;migration"; + +// MigrationMemoryTransport is the transport protocol used for memory transfer during migration. +enum MigrationMemoryTransport { + MIGRATION_MEMORY_TRANSPORT_UNSPECIFIED = 0; + // VM memory is copied over a TCP/IP connection. + MIGRATION_MEMORY_TRANSPORT_TCP = 1; +} + +message MigrationInitializeOptions { + // MemoryTransport specifies the transport protocol for memory transfer during migration. + MigrationMemoryTransport memory_transport = 1; + // MemoryTransferThrottleParams specifies settings for throttling during memory transfer. + optional MemoryMigrationTransferThrottleParams memory_transfer_throttle_params = 2; + // CompressionSettings specifies additional settings when compression is enabled. + optional MigrationCompressionSettings compression_settings = 3; + // ChecksumVerification enables memory checksum verification. + bool checksum_verification = 4; + // PerfTracingEnabled enables performance tracing during migration. + bool perf_tracing_enabled = 5; + // CancelIfBlackoutThresholdExceeds cancels the operation if the blackout threshold is exceeded. + bool cancel_if_blackout_threshold_exceeds = 6; + // PrepareMemoryTransferMode extends timeout for cross-version live migration. + bool prepare_memory_transfer_mode = 7; + // CompatibilityData is the compatibility information required for the destination VM. + optional CompatibilityInfo compatibility_data = 8; +} + +// CompatibilityInfo is opaque VM compatibility data, primarily used in migration. +message CompatibilityInfo { + // Raw compatibility information. + bytes data = 1; +} + +message MemoryMigrationTransferThrottleParams { + // A flag indicating if throttling should be skipped. + optional bool skip_throttling = 1; + // The scale of the throttling. The value is in percentage (1-100). + optional double throttling_scale = 2; + // Minimum percentage value to which memory transfer can be throttled. + optional uint32 minimum_throttle_percentage = 3; + // Number of memory transfer passes targeted before the VM enters blackout. + optional uint32 target_number_of_brownout_transfer_passes = 4; + // The starting transfer pass where throttling is starting. + optional uint32 starting_brownout_pass_number_for_throttling = 5; + // Maximum number of memory transfer passes before forcing the VM to enter blackout. + optional uint32 maximum_number_of_brownout_transfer_passes = 6; + // Expected duration for blackout transfer time. + optional uint32 target_blackout_transfer_time = 7; + // Threshold for blackout duration prior to cancelling migration. + optional uint32 blackout_time_threshold_for_cancelling_migration = 8; +} + +message MigrationCompressionSettings { + // Number of worker threads used for [de]compression. Values higher than what the host + // and VM configuration can support will be adjusted. The value should be non-zero. + optional uint32 throttle_worker_count = 1; +} diff --git a/pkg/migration/migration_ttrpc.pb.go b/pkg/migration/migration_ttrpc.pb.go new file mode 100644 index 0000000000..63f6404b31 --- /dev/null +++ b/pkg/migration/migration_ttrpc.pb.go @@ -0,0 +1,173 @@ +// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT. +// source: github.com/Microsoft/hcsshim/pkg/migration/migration.proto +package migration + +import ( + context "context" + ttrpc "github.com/containerd/ttrpc" +) + +type MigrationService interface { + PrepareAndExportSandbox(context.Context, *PrepareAndExportSandboxRequest) (*PrepareAndExportSandboxResponse, error) + ImportSandbox(context.Context, *ImportSandboxRequest) (*ImportSandboxResponse, error) + PrepareSandbox(context.Context, *PrepareSandboxRequest) (*PrepareSandboxResponse, error) + TransferSandbox(context.Context, *TransferSandboxRequest, Migration_TransferSandboxServer) error + FinalizeSandbox(context.Context, *FinalizeSandboxRequest) (*FinalizeSandboxResponse, error) + CreateDuplicateSocket(context.Context, *CreateDuplicateSocketRequest) (*CreateDuplicateSocketResponse, error) +} + +type Migration_TransferSandboxServer interface { + Send(*TransferSandboxResponse) error + ttrpc.StreamServer +} + +type migrationTransferSandboxServer struct { + ttrpc.StreamServer +} + +func (x *migrationTransferSandboxServer) Send(m *TransferSandboxResponse) error { + return x.StreamServer.SendMsg(m) +} + +func RegisterMigrationService(srv *ttrpc.Server, svc MigrationService) { + srv.RegisterService("Migration", &ttrpc.ServiceDesc{ + Methods: map[string]ttrpc.Method{ + "PrepareAndExportSandbox": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req PrepareAndExportSandboxRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.PrepareAndExportSandbox(ctx, &req) + }, + "ImportSandbox": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req ImportSandboxRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.ImportSandbox(ctx, &req) + }, + "PrepareSandbox": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req PrepareSandboxRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.PrepareSandbox(ctx, &req) + }, + "FinalizeSandbox": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req FinalizeSandboxRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.FinalizeSandbox(ctx, &req) + }, + "CreateDuplicateSocket": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req CreateDuplicateSocketRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.CreateDuplicateSocket(ctx, &req) + }, + }, + Streams: map[string]ttrpc.Stream{ + "TransferSandbox": { + Handler: func(ctx context.Context, stream ttrpc.StreamServer) (interface{}, error) { + m := new(TransferSandboxRequest) + if err := stream.RecvMsg(m); err != nil { + return nil, err + } + return nil, svc.TransferSandbox(ctx, m, &migrationTransferSandboxServer{stream}) + }, + StreamingClient: false, + StreamingServer: true, + }, + }, + }) +} + +type MigrationClient interface { + PrepareAndExportSandbox(context.Context, *PrepareAndExportSandboxRequest) (*PrepareAndExportSandboxResponse, error) + ImportSandbox(context.Context, *ImportSandboxRequest) (*ImportSandboxResponse, error) + PrepareSandbox(context.Context, *PrepareSandboxRequest) (*PrepareSandboxResponse, error) + TransferSandbox(context.Context, *TransferSandboxRequest) (Migration_TransferSandboxClient, error) + FinalizeSandbox(context.Context, *FinalizeSandboxRequest) (*FinalizeSandboxResponse, error) + CreateDuplicateSocket(context.Context, *CreateDuplicateSocketRequest) (*CreateDuplicateSocketResponse, error) +} + +type migrationClient struct { + client *ttrpc.Client +} + +func NewMigrationClient(client *ttrpc.Client) MigrationClient { + return &migrationClient{ + client: client, + } +} + +func (c *migrationClient) PrepareAndExportSandbox(ctx context.Context, req *PrepareAndExportSandboxRequest) (*PrepareAndExportSandboxResponse, error) { + var resp PrepareAndExportSandboxResponse + if err := c.client.Call(ctx, "Migration", "PrepareAndExportSandbox", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *migrationClient) ImportSandbox(ctx context.Context, req *ImportSandboxRequest) (*ImportSandboxResponse, error) { + var resp ImportSandboxResponse + if err := c.client.Call(ctx, "Migration", "ImportSandbox", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *migrationClient) PrepareSandbox(ctx context.Context, req *PrepareSandboxRequest) (*PrepareSandboxResponse, error) { + var resp PrepareSandboxResponse + if err := c.client.Call(ctx, "Migration", "PrepareSandbox", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *migrationClient) TransferSandbox(ctx context.Context, req *TransferSandboxRequest) (Migration_TransferSandboxClient, error) { + stream, err := c.client.NewStream(ctx, &ttrpc.StreamDesc{ + StreamingClient: false, + StreamingServer: true, + }, "Migration", "TransferSandbox", req) + if err != nil { + return nil, err + } + x := &migrationTransferSandboxClient{stream} + return x, nil +} + +type Migration_TransferSandboxClient interface { + Recv() (*TransferSandboxResponse, error) + ttrpc.ClientStream +} + +type migrationTransferSandboxClient struct { + ttrpc.ClientStream +} + +func (x *migrationTransferSandboxClient) Recv() (*TransferSandboxResponse, error) { + m := new(TransferSandboxResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *migrationClient) FinalizeSandbox(ctx context.Context, req *FinalizeSandboxRequest) (*FinalizeSandboxResponse, error) { + var resp FinalizeSandboxResponse + if err := c.client.Call(ctx, "Migration", "FinalizeSandbox", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +func (c *migrationClient) CreateDuplicateSocket(ctx context.Context, req *CreateDuplicateSocketRequest) (*CreateDuplicateSocketResponse, error) { + var resp CreateDuplicateSocketResponse + if err := c.client.Call(ctx, "Migration", "CreateDuplicateSocket", req, &resp); err != nil { + return nil, err + } + return &resp, nil +}