From 13dea92311f0e102deb456353bf1bfd6c5b24890 Mon Sep 17 00:00:00 2001 From: Pavel Sviderski Date: Tue, 8 Apr 2025 16:33:35 +1000 Subject: [PATCH] chore(volumes): gRPC methods for managing Docker volumes --- internal/machine/api/pb/docker.pb.go | 752 +++++++++++++++++----- internal/machine/api/pb/docker.proto | 36 ++ internal/machine/api/pb/docker_grpc.pb.go | 114 ++++ internal/machine/docker/client.go | 70 ++ internal/machine/docker/server.go | 124 ++++ 5 files changed, 932 insertions(+), 164 deletions(-) diff --git a/internal/machine/api/pb/docker.pb.go b/internal/machine/api/pb/docker.pb.go index eddfdfdc..a1e421e6 100644 --- a/internal/machine/api/pb/docker.pb.go +++ b/internal/machine/api/pb/docker.pb.go @@ -982,6 +982,309 @@ func (x *RemoteImage) GetManifest() []byte { return nil } +type CreateVolumeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // JSON serialised volume.CreateOptions. + Options []byte `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *CreateVolumeRequest) Reset() { + *x = CreateVolumeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVolumeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVolumeRequest) ProtoMessage() {} + +func (x *CreateVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVolumeRequest.ProtoReflect.Descriptor instead. +func (*CreateVolumeRequest) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{18} +} + +func (x *CreateVolumeRequest) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +type CreateVolumeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // JSON serialised volume.Volume. + Volume []byte `protobuf:"bytes,1,opt,name=volume,proto3" json:"volume,omitempty"` +} + +func (x *CreateVolumeResponse) Reset() { + *x = CreateVolumeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVolumeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVolumeResponse) ProtoMessage() {} + +func (x *CreateVolumeResponse) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVolumeResponse.ProtoReflect.Descriptor instead. +func (*CreateVolumeResponse) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{19} +} + +func (x *CreateVolumeResponse) GetVolume() []byte { + if x != nil { + return x.Volume + } + return nil +} + +type ListVolumesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // JSON serialised volume.ListOptions. + Options []byte `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *ListVolumesRequest) Reset() { + *x = ListVolumesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVolumesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVolumesRequest) ProtoMessage() {} + +func (x *ListVolumesRequest) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVolumesRequest.ProtoReflect.Descriptor instead. +func (*ListVolumesRequest) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{20} +} + +func (x *ListVolumesRequest) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +type ListVolumesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Must contain only one repeated messages field to allow broadcasting ListVolumes requests to multiple machines. + Messages []*MachineVolumes `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (x *ListVolumesResponse) Reset() { + *x = ListVolumesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVolumesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVolumesResponse) ProtoMessage() {} + +func (x *ListVolumesResponse) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVolumesResponse.ProtoReflect.Descriptor instead. +func (*ListVolumesResponse) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{21} +} + +func (x *ListVolumesResponse) GetMessages() []*MachineVolumes { + if x != nil { + return x.Messages + } + return nil +} + +type MachineVolumes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // JSON serialised volume.ListResponse. + Response []byte `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"` +} + +func (x *MachineVolumes) Reset() { + *x = MachineVolumes{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MachineVolumes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MachineVolumes) ProtoMessage() {} + +func (x *MachineVolumes) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MachineVolumes.ProtoReflect.Descriptor instead. +func (*MachineVolumes) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{22} +} + +func (x *MachineVolumes) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *MachineVolumes) GetResponse() []byte { + if x != nil { + return x.Response + } + return nil +} + +type RemoveVolumeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` +} + +func (x *RemoveVolumeRequest) Reset() { + *x = RemoveVolumeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveVolumeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveVolumeRequest) ProtoMessage() {} + +func (x *RemoveVolumeRequest) ProtoReflect() protoreflect.Message { + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveVolumeRequest.ProtoReflect.Descriptor instead. +func (*RemoveVolumeRequest) Descriptor() ([]byte, []int) { + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{23} +} + +func (x *RemoveVolumeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *RemoveVolumeRequest) GetForce() bool { + if x != nil { + return x.Force + } + return false +} + type CreateServiceContainerRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -996,7 +1299,7 @@ type CreateServiceContainerRequest struct { func (x *CreateServiceContainerRequest) Reset() { *x = CreateServiceContainerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[18] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1009,7 +1312,7 @@ func (x *CreateServiceContainerRequest) String() string { func (*CreateServiceContainerRequest) ProtoMessage() {} func (x *CreateServiceContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[18] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1022,7 +1325,7 @@ func (x *CreateServiceContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateServiceContainerRequest.ProtoReflect.Descriptor instead. func (*CreateServiceContainerRequest) Descriptor() ([]byte, []int) { - return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{18} + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{24} } func (x *CreateServiceContainerRequest) GetServiceId() string { @@ -1060,7 +1363,7 @@ type ServiceContainer struct { func (x *ServiceContainer) Reset() { *x = ServiceContainer{} if protoimpl.UnsafeEnabled { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[19] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1073,7 +1376,7 @@ func (x *ServiceContainer) String() string { func (*ServiceContainer) ProtoMessage() {} func (x *ServiceContainer) ProtoReflect() protoreflect.Message { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[19] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1086,7 +1389,7 @@ func (x *ServiceContainer) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceContainer.ProtoReflect.Descriptor instead. func (*ServiceContainer) Descriptor() ([]byte, []int) { - return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{19} + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{25} } func (x *ServiceContainer) GetContainer() []byte { @@ -1116,7 +1419,7 @@ type ListServiceContainersRequest struct { func (x *ListServiceContainersRequest) Reset() { *x = ListServiceContainersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[20] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1129,7 +1432,7 @@ func (x *ListServiceContainersRequest) String() string { func (*ListServiceContainersRequest) ProtoMessage() {} func (x *ListServiceContainersRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[20] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1142,7 +1445,7 @@ func (x *ListServiceContainersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServiceContainersRequest.ProtoReflect.Descriptor instead. func (*ListServiceContainersRequest) Descriptor() ([]byte, []int) { - return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{20} + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{26} } func (x *ListServiceContainersRequest) GetServiceId() string { @@ -1172,7 +1475,7 @@ type ListServiceContainersResponse struct { func (x *ListServiceContainersResponse) Reset() { *x = ListServiceContainersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[21] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1185,7 +1488,7 @@ func (x *ListServiceContainersResponse) String() string { func (*ListServiceContainersResponse) ProtoMessage() {} func (x *ListServiceContainersResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[21] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1198,7 +1501,7 @@ func (x *ListServiceContainersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServiceContainersResponse.ProtoReflect.Descriptor instead. func (*ListServiceContainersResponse) Descriptor() ([]byte, []int) { - return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{21} + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{27} } func (x *ListServiceContainersResponse) GetMessages() []*MachineServiceContainers { @@ -1220,7 +1523,7 @@ type MachineServiceContainers struct { func (x *MachineServiceContainers) Reset() { *x = MachineServiceContainers{} if protoimpl.UnsafeEnabled { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[22] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1233,7 +1536,7 @@ func (x *MachineServiceContainers) String() string { func (*MachineServiceContainers) ProtoMessage() {} func (x *MachineServiceContainers) ProtoReflect() protoreflect.Message { - mi := &file_internal_machine_api_pb_docker_proto_msgTypes[22] + mi := &file_internal_machine_api_pb_docker_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1246,7 +1549,7 @@ func (x *MachineServiceContainers) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineServiceContainers.ProtoReflect.Descriptor instead. func (*MachineServiceContainers) Descriptor() ([]byte, []int) { - return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{22} + return file_internal_machine_api_pb_docker_proto_rawDescGZIP(), []int{28} } func (x *MachineServiceContainers) GetMetadata() *Metadata { @@ -1352,108 +1655,143 @@ var file_internal_machine_api_pb_docker_proto_rawDesc = []byte{ 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x88, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x22, 0x53, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x22, 0x57, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0x5a, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x73, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x7c, 0x0a, - 0x18, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x35, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x32, 0xf3, 0x07, 0x0a, 0x06, - 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, - 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0d, 0x53, - 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x49, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0f, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x36, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4a, 0x53, 0x4f, - 0x4e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0c, 0x49, 0x6e, - 0x73, 0x70, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, - 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x55, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x17, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x12, 0x5e, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2e, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x46, 0x0a, 0x13, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2f, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x22, 0x57, 0x0a, 0x0e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x13, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0x53, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x22, 0x57, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x5a, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x73, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x7c, 0x0a, 0x18, + 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x35, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x32, 0xbc, 0x09, 0x0a, 0x06, 0x44, + 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0d, 0x53, 0x74, + 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, + 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0f, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x73, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x6b, 0x69, 0x2f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x79, 0x12, 0x36, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x15, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0c, 0x49, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, + 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, 0x6c, + 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x18, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x5a, + 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x17, 0x49, 0x6e, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x5e, 0x0a, 0x15, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x16, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x73, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, + 0x6b, 0x69, 0x2f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1468,7 +1806,7 @@ func file_internal_machine_api_pb_docker_proto_rawDescGZIP() []byte { return file_internal_machine_api_pb_docker_proto_rawDescData } -var file_internal_machine_api_pb_docker_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_internal_machine_api_pb_docker_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_internal_machine_api_pb_docker_proto_goTypes = []any{ (*CreateContainerRequest)(nil), // 0: api.CreateContainerRequest (*CreateContainerResponse)(nil), // 1: api.CreateContainerResponse @@ -1488,55 +1826,69 @@ var file_internal_machine_api_pb_docker_proto_goTypes = []any{ (*InspectRemoteImageRequest)(nil), // 15: api.InspectRemoteImageRequest (*InspectRemoteImageResponse)(nil), // 16: api.InspectRemoteImageResponse (*RemoteImage)(nil), // 17: api.RemoteImage - (*CreateServiceContainerRequest)(nil), // 18: api.CreateServiceContainerRequest - (*ServiceContainer)(nil), // 19: api.ServiceContainer - (*ListServiceContainersRequest)(nil), // 20: api.ListServiceContainersRequest - (*ListServiceContainersResponse)(nil), // 21: api.ListServiceContainersResponse - (*MachineServiceContainers)(nil), // 22: api.MachineServiceContainers - (*Metadata)(nil), // 23: api.Metadata - (*emptypb.Empty)(nil), // 24: google.protobuf.Empty + (*CreateVolumeRequest)(nil), // 18: api.CreateVolumeRequest + (*CreateVolumeResponse)(nil), // 19: api.CreateVolumeResponse + (*ListVolumesRequest)(nil), // 20: api.ListVolumesRequest + (*ListVolumesResponse)(nil), // 21: api.ListVolumesResponse + (*MachineVolumes)(nil), // 22: api.MachineVolumes + (*RemoveVolumeRequest)(nil), // 23: api.RemoveVolumeRequest + (*CreateServiceContainerRequest)(nil), // 24: api.CreateServiceContainerRequest + (*ServiceContainer)(nil), // 25: api.ServiceContainer + (*ListServiceContainersRequest)(nil), // 26: api.ListServiceContainersRequest + (*ListServiceContainersResponse)(nil), // 27: api.ListServiceContainersResponse + (*MachineServiceContainers)(nil), // 28: api.MachineServiceContainers + (*Metadata)(nil), // 29: api.Metadata + (*emptypb.Empty)(nil), // 30: google.protobuf.Empty } var file_internal_machine_api_pb_docker_proto_depIdxs = []int32{ 8, // 0: api.ListContainersResponse.messages:type_name -> api.MachineContainers - 23, // 1: api.MachineContainers.metadata:type_name -> api.Metadata + 29, // 1: api.MachineContainers.metadata:type_name -> api.Metadata 14, // 2: api.InspectImageResponse.messages:type_name -> api.Image - 23, // 3: api.Image.metadata:type_name -> api.Metadata + 29, // 3: api.Image.metadata:type_name -> api.Metadata 17, // 4: api.InspectRemoteImageResponse.messages:type_name -> api.RemoteImage - 23, // 5: api.RemoteImage.metadata:type_name -> api.Metadata - 22, // 6: api.ListServiceContainersResponse.messages:type_name -> api.MachineServiceContainers - 23, // 7: api.MachineServiceContainers.metadata:type_name -> api.Metadata - 19, // 8: api.MachineServiceContainers.containers:type_name -> api.ServiceContainer - 0, // 9: api.Docker.CreateContainer:input_type -> api.CreateContainerRequest - 2, // 10: api.Docker.InspectContainer:input_type -> api.InspectContainerRequest - 4, // 11: api.Docker.StartContainer:input_type -> api.StartContainerRequest - 5, // 12: api.Docker.StopContainer:input_type -> api.StopContainerRequest - 6, // 13: api.Docker.ListContainers:input_type -> api.ListContainersRequest - 9, // 14: api.Docker.RemoveContainer:input_type -> api.RemoveContainerRequest - 10, // 15: api.Docker.PullImage:input_type -> api.PullImageRequest - 12, // 16: api.Docker.InspectImage:input_type -> api.InspectImageRequest - 15, // 17: api.Docker.InspectRemoteImage:input_type -> api.InspectRemoteImageRequest - 18, // 18: api.Docker.CreateServiceContainer:input_type -> api.CreateServiceContainerRequest - 2, // 19: api.Docker.InspectServiceContainer:input_type -> api.InspectContainerRequest - 20, // 20: api.Docker.ListServiceContainers:input_type -> api.ListServiceContainersRequest - 9, // 21: api.Docker.RemoveServiceContainer:input_type -> api.RemoveContainerRequest - 1, // 22: api.Docker.CreateContainer:output_type -> api.CreateContainerResponse - 3, // 23: api.Docker.InspectContainer:output_type -> api.InspectContainerResponse - 24, // 24: api.Docker.StartContainer:output_type -> google.protobuf.Empty - 24, // 25: api.Docker.StopContainer:output_type -> google.protobuf.Empty - 7, // 26: api.Docker.ListContainers:output_type -> api.ListContainersResponse - 24, // 27: api.Docker.RemoveContainer:output_type -> google.protobuf.Empty - 11, // 28: api.Docker.PullImage:output_type -> api.JSONMessage - 13, // 29: api.Docker.InspectImage:output_type -> api.InspectImageResponse - 16, // 30: api.Docker.InspectRemoteImage:output_type -> api.InspectRemoteImageResponse - 1, // 31: api.Docker.CreateServiceContainer:output_type -> api.CreateContainerResponse - 19, // 32: api.Docker.InspectServiceContainer:output_type -> api.ServiceContainer - 21, // 33: api.Docker.ListServiceContainers:output_type -> api.ListServiceContainersResponse - 24, // 34: api.Docker.RemoveServiceContainer:output_type -> google.protobuf.Empty - 22, // [22:35] is the sub-list for method output_type - 9, // [9:22] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 29, // 5: api.RemoteImage.metadata:type_name -> api.Metadata + 22, // 6: api.ListVolumesResponse.messages:type_name -> api.MachineVolumes + 29, // 7: api.MachineVolumes.metadata:type_name -> api.Metadata + 28, // 8: api.ListServiceContainersResponse.messages:type_name -> api.MachineServiceContainers + 29, // 9: api.MachineServiceContainers.metadata:type_name -> api.Metadata + 25, // 10: api.MachineServiceContainers.containers:type_name -> api.ServiceContainer + 0, // 11: api.Docker.CreateContainer:input_type -> api.CreateContainerRequest + 2, // 12: api.Docker.InspectContainer:input_type -> api.InspectContainerRequest + 4, // 13: api.Docker.StartContainer:input_type -> api.StartContainerRequest + 5, // 14: api.Docker.StopContainer:input_type -> api.StopContainerRequest + 6, // 15: api.Docker.ListContainers:input_type -> api.ListContainersRequest + 9, // 16: api.Docker.RemoveContainer:input_type -> api.RemoveContainerRequest + 10, // 17: api.Docker.PullImage:input_type -> api.PullImageRequest + 12, // 18: api.Docker.InspectImage:input_type -> api.InspectImageRequest + 15, // 19: api.Docker.InspectRemoteImage:input_type -> api.InspectRemoteImageRequest + 18, // 20: api.Docker.CreateVolume:input_type -> api.CreateVolumeRequest + 20, // 21: api.Docker.ListVolumes:input_type -> api.ListVolumesRequest + 23, // 22: api.Docker.RemoveVolume:input_type -> api.RemoveVolumeRequest + 24, // 23: api.Docker.CreateServiceContainer:input_type -> api.CreateServiceContainerRequest + 2, // 24: api.Docker.InspectServiceContainer:input_type -> api.InspectContainerRequest + 26, // 25: api.Docker.ListServiceContainers:input_type -> api.ListServiceContainersRequest + 9, // 26: api.Docker.RemoveServiceContainer:input_type -> api.RemoveContainerRequest + 1, // 27: api.Docker.CreateContainer:output_type -> api.CreateContainerResponse + 3, // 28: api.Docker.InspectContainer:output_type -> api.InspectContainerResponse + 30, // 29: api.Docker.StartContainer:output_type -> google.protobuf.Empty + 30, // 30: api.Docker.StopContainer:output_type -> google.protobuf.Empty + 7, // 31: api.Docker.ListContainers:output_type -> api.ListContainersResponse + 30, // 32: api.Docker.RemoveContainer:output_type -> google.protobuf.Empty + 11, // 33: api.Docker.PullImage:output_type -> api.JSONMessage + 13, // 34: api.Docker.InspectImage:output_type -> api.InspectImageResponse + 16, // 35: api.Docker.InspectRemoteImage:output_type -> api.InspectRemoteImageResponse + 19, // 36: api.Docker.CreateVolume:output_type -> api.CreateVolumeResponse + 21, // 37: api.Docker.ListVolumes:output_type -> api.ListVolumesResponse + 30, // 38: api.Docker.RemoveVolume:output_type -> google.protobuf.Empty + 1, // 39: api.Docker.CreateServiceContainer:output_type -> api.CreateContainerResponse + 25, // 40: api.Docker.InspectServiceContainer:output_type -> api.ServiceContainer + 27, // 41: api.Docker.ListServiceContainers:output_type -> api.ListServiceContainersResponse + 30, // 42: api.Docker.RemoveServiceContainer:output_type -> google.protobuf.Empty + 27, // [27:43] is the sub-list for method output_type + 11, // [11:27] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_internal_machine_api_pb_docker_proto_init() } @@ -1763,7 +2115,7 @@ func file_internal_machine_api_pb_docker_proto_init() { } } file_internal_machine_api_pb_docker_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*CreateServiceContainerRequest); i { + switch v := v.(*CreateVolumeRequest); i { case 0: return &v.state case 1: @@ -1775,7 +2127,7 @@ func file_internal_machine_api_pb_docker_proto_init() { } } file_internal_machine_api_pb_docker_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*ServiceContainer); i { + switch v := v.(*CreateVolumeResponse); i { case 0: return &v.state case 1: @@ -1787,7 +2139,7 @@ func file_internal_machine_api_pb_docker_proto_init() { } } file_internal_machine_api_pb_docker_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*ListServiceContainersRequest); i { + switch v := v.(*ListVolumesRequest); i { case 0: return &v.state case 1: @@ -1799,7 +2151,7 @@ func file_internal_machine_api_pb_docker_proto_init() { } } file_internal_machine_api_pb_docker_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*ListServiceContainersResponse); i { + switch v := v.(*ListVolumesResponse); i { case 0: return &v.state case 1: @@ -1811,6 +2163,78 @@ func file_internal_machine_api_pb_docker_proto_init() { } } file_internal_machine_api_pb_docker_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*MachineVolumes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*RemoveVolumeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*CreateServiceContainerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*ServiceContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*ListServiceContainersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*ListServiceContainersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_machine_api_pb_docker_proto_msgTypes[28].Exporter = func(v any, i int) any { switch v := v.(*MachineServiceContainers); i { case 0: return &v.state @@ -1829,7 +2253,7 @@ func file_internal_machine_api_pb_docker_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_internal_machine_api_pb_docker_proto_rawDesc, NumEnums: 0, - NumMessages: 23, + NumMessages: 29, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/machine/api/pb/docker.proto b/internal/machine/api/pb/docker.proto index a423fc5a..1472e376 100644 --- a/internal/machine/api/pb/docker.proto +++ b/internal/machine/api/pb/docker.proto @@ -14,12 +14,17 @@ service Docker { rpc StopContainer(StopContainerRequest) returns (google.protobuf.Empty); rpc ListContainers(ListContainersRequest) returns (ListContainersResponse); rpc RemoveContainer(RemoveContainerRequest) returns (google.protobuf.Empty); + rpc PullImage(PullImageRequest) returns (stream JSONMessage); rpc InspectImage(InspectImageRequest) returns (InspectImageResponse); // InspectRemoteImage returns the image metadata for an image in a remote registry using the machine's // Docker auth credentials if necessary. rpc InspectRemoteImage(InspectRemoteImageRequest) returns (InspectRemoteImageResponse); + rpc CreateVolume(CreateVolumeRequest) returns (CreateVolumeResponse); + rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse); + rpc RemoveVolume(RemoveVolumeRequest) returns (google.protobuf.Empty); + rpc CreateServiceContainer(CreateServiceContainerRequest) returns (CreateContainerResponse); rpc InspectServiceContainer(InspectContainerRequest) returns (ServiceContainer); rpc ListServiceContainers(ListServiceContainersRequest) returns (ListServiceContainersResponse); @@ -129,6 +134,37 @@ message RemoteImage { bytes manifest = 3; } +message CreateVolumeRequest { + // JSON serialised volume.CreateOptions. + bytes options = 1; +} + +message CreateVolumeResponse { + // JSON serialised volume.Volume. + bytes volume = 1; +} + +message ListVolumesRequest { + // JSON serialised volume.ListOptions. + bytes options = 1; +} + +message ListVolumesResponse { + // Must contain only one repeated messages field to allow broadcasting ListVolumes requests to multiple machines. + repeated MachineVolumes messages = 1; +} + +message MachineVolumes { + Metadata metadata = 1; + // JSON serialised volume.ListResponse. + bytes response = 2; +} + +message RemoveVolumeRequest { + string id = 1; + bool force = 2; +} + message CreateServiceContainerRequest { string service_id = 1; // JSON serialised api.ServiceSpec. diff --git a/internal/machine/api/pb/docker_grpc.pb.go b/internal/machine/api/pb/docker_grpc.pb.go index 4435ae90..2718fa17 100644 --- a/internal/machine/api/pb/docker_grpc.pb.go +++ b/internal/machine/api/pb/docker_grpc.pb.go @@ -29,6 +29,9 @@ const ( Docker_PullImage_FullMethodName = "/api.Docker/PullImage" Docker_InspectImage_FullMethodName = "/api.Docker/InspectImage" Docker_InspectRemoteImage_FullMethodName = "/api.Docker/InspectRemoteImage" + Docker_CreateVolume_FullMethodName = "/api.Docker/CreateVolume" + Docker_ListVolumes_FullMethodName = "/api.Docker/ListVolumes" + Docker_RemoveVolume_FullMethodName = "/api.Docker/RemoveVolume" Docker_CreateServiceContainer_FullMethodName = "/api.Docker/CreateServiceContainer" Docker_InspectServiceContainer_FullMethodName = "/api.Docker/InspectServiceContainer" Docker_ListServiceContainers_FullMethodName = "/api.Docker/ListServiceContainers" @@ -50,6 +53,9 @@ type DockerClient interface { // InspectRemoteImage returns the image metadata for an image in a remote registry using the machine's // Docker auth credentials if necessary. InspectRemoteImage(ctx context.Context, in *InspectRemoteImageRequest, opts ...grpc.CallOption) (*InspectRemoteImageResponse, error) + CreateVolume(ctx context.Context, in *CreateVolumeRequest, opts ...grpc.CallOption) (*CreateVolumeResponse, error) + ListVolumes(ctx context.Context, in *ListVolumesRequest, opts ...grpc.CallOption) (*ListVolumesResponse, error) + RemoveVolume(ctx context.Context, in *RemoveVolumeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) CreateServiceContainer(ctx context.Context, in *CreateServiceContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) InspectServiceContainer(ctx context.Context, in *InspectContainerRequest, opts ...grpc.CallOption) (*ServiceContainer, error) ListServiceContainers(ctx context.Context, in *ListServiceContainersRequest, opts ...grpc.CallOption) (*ListServiceContainersResponse, error) @@ -163,6 +169,36 @@ func (c *dockerClient) InspectRemoteImage(ctx context.Context, in *InspectRemote return out, nil } +func (c *dockerClient) CreateVolume(ctx context.Context, in *CreateVolumeRequest, opts ...grpc.CallOption) (*CreateVolumeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateVolumeResponse) + err := c.cc.Invoke(ctx, Docker_CreateVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dockerClient) ListVolumes(ctx context.Context, in *ListVolumesRequest, opts ...grpc.CallOption) (*ListVolumesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListVolumesResponse) + err := c.cc.Invoke(ctx, Docker_ListVolumes_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dockerClient) RemoveVolume(ctx context.Context, in *RemoveVolumeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, Docker_RemoveVolume_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dockerClient) CreateServiceContainer(ctx context.Context, in *CreateServiceContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateContainerResponse) @@ -218,6 +254,9 @@ type DockerServer interface { // InspectRemoteImage returns the image metadata for an image in a remote registry using the machine's // Docker auth credentials if necessary. InspectRemoteImage(context.Context, *InspectRemoteImageRequest) (*InspectRemoteImageResponse, error) + CreateVolume(context.Context, *CreateVolumeRequest) (*CreateVolumeResponse, error) + ListVolumes(context.Context, *ListVolumesRequest) (*ListVolumesResponse, error) + RemoveVolume(context.Context, *RemoveVolumeRequest) (*emptypb.Empty, error) CreateServiceContainer(context.Context, *CreateServiceContainerRequest) (*CreateContainerResponse, error) InspectServiceContainer(context.Context, *InspectContainerRequest) (*ServiceContainer, error) ListServiceContainers(context.Context, *ListServiceContainersRequest) (*ListServiceContainersResponse, error) @@ -259,6 +298,15 @@ func (UnimplementedDockerServer) InspectImage(context.Context, *InspectImageRequ func (UnimplementedDockerServer) InspectRemoteImage(context.Context, *InspectRemoteImageRequest) (*InspectRemoteImageResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method InspectRemoteImage not implemented") } +func (UnimplementedDockerServer) CreateVolume(context.Context, *CreateVolumeRequest) (*CreateVolumeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVolume not implemented") +} +func (UnimplementedDockerServer) ListVolumes(context.Context, *ListVolumesRequest) (*ListVolumesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVolumes not implemented") +} +func (UnimplementedDockerServer) RemoveVolume(context.Context, *RemoveVolumeRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveVolume not implemented") +} func (UnimplementedDockerServer) CreateServiceContainer(context.Context, *CreateServiceContainerRequest) (*CreateContainerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateServiceContainer not implemented") } @@ -447,6 +495,60 @@ func _Docker_InspectRemoteImage_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _Docker_CreateVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DockerServer).CreateVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Docker_CreateVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DockerServer).CreateVolume(ctx, req.(*CreateVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Docker_ListVolumes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListVolumesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DockerServer).ListVolumes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Docker_ListVolumes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DockerServer).ListVolumes(ctx, req.(*ListVolumesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Docker_RemoveVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveVolumeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DockerServer).RemoveVolume(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Docker_RemoveVolume_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DockerServer).RemoveVolume(ctx, req.(*RemoveVolumeRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Docker_CreateServiceContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateServiceContainerRequest) if err := dec(in); err != nil { @@ -558,6 +660,18 @@ var Docker_ServiceDesc = grpc.ServiceDesc{ MethodName: "InspectRemoteImage", Handler: _Docker_InspectRemoteImage_Handler, }, + { + MethodName: "CreateVolume", + Handler: _Docker_CreateVolume_Handler, + }, + { + MethodName: "ListVolumes", + Handler: _Docker_ListVolumes_Handler, + }, + { + MethodName: "RemoveVolume", + Handler: _Docker_RemoveVolume_Handler, + }, { MethodName: "CreateServiceContainer", Handler: _Docker_CreateServiceContainer_Handler, diff --git a/internal/machine/docker/client.go b/internal/machine/docker/client.go index 25939e06..b400705c 100644 --- a/internal/machine/docker/client.go +++ b/internal/machine/docker/client.go @@ -11,6 +11,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" + "github.com/docker/docker/api/types/volume" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/jsonmessage" regtypes "github.com/google/go-containerregistry/pkg/v1/types" @@ -341,6 +342,75 @@ func parseRemoteImageMessage(msg *pb.RemoteImage) (api.MachineRemoteImage, error return mri, nil } +// CreateVolume creates a new volume with the given options. +func (c *Client) CreateVolume(ctx context.Context, opts volume.CreateOptions) (volume.Volume, error) { + var vol volume.Volume + + optsBytes, err := json.Marshal(opts) + if err != nil { + return vol, fmt.Errorf("marshal options: %w", err) + } + + resp, err := c.grpcClient.CreateVolume(ctx, &pb.CreateVolumeRequest{Options: optsBytes}) + if err != nil { + return vol, err + } + + if err = json.Unmarshal(resp.Volume, &vol); err != nil { + return vol, fmt.Errorf("unmarshal volume: %w", err) + } + + return vol, nil +} + +// MachineVolumes represents a volume list response from a machine. +type MachineVolumes struct { + Metadata *pb.Metadata + Response volume.ListResponse +} + +// ListVolumes returns a list of all volumes matching the filter. +func (c *Client) ListVolumes(ctx context.Context, opts volume.ListOptions) ([]MachineVolumes, error) { + optsBytes, err := json.Marshal(opts) + if err != nil { + return nil, fmt.Errorf("marshal options: %w", err) + } + + resp, err := c.grpcClient.ListVolumes(ctx, &pb.ListVolumesRequest{Options: optsBytes}) + if err != nil { + return nil, err + } + + machineVolumes := make([]MachineVolumes, len(resp.Messages)) + for i, msg := range resp.Messages { + machineVolumes[i].Metadata = msg.Metadata + if msg.Metadata != nil && msg.Metadata.Error != "" { + continue + } + + if err = json.Unmarshal(msg.Response, &machineVolumes[i].Response); err != nil { + return nil, fmt.Errorf("unmarshal response: %w", err) + } + } + + return machineVolumes, nil +} + +// RemoveVolume removes a volume with the given ID. +func (c *Client) RemoveVolume(ctx context.Context, id string, force bool) error { + _, err := c.grpcClient.RemoveVolume(ctx, &pb.RemoveVolumeRequest{ + Id: id, + Force: force, + }) + if err != nil { + if status.Convert(err).Code() == codes.NotFound { + return errdefs.NotFound(err) + } + } + + return err +} + // CreateServiceContainer creates a new container for the service with the given specifications. func (c *Client) CreateServiceContainer( ctx context.Context, serviceID string, spec api.ServiceSpec, containerName string, diff --git a/internal/machine/docker/server.go b/internal/machine/docker/server.go index 20b77a37..d36f3a37 100644 --- a/internal/machine/docker/server.go +++ b/internal/machine/docker/server.go @@ -18,6 +18,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" + "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" "github.com/docker/go-connections/nat" "github.com/google/go-containerregistry/pkg/authn" @@ -329,6 +330,80 @@ func (s *Server) InspectRemoteImage( }, nil } +// CreateVolume creates a new volume with the given options. +func (s *Server) CreateVolume(ctx context.Context, req *pb.CreateVolumeRequest) (*pb.CreateVolumeResponse, error) { + var opts volume.CreateOptions + if err := json.Unmarshal(req.Options, &opts); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "unmarshal options: %v", err) + } + + vol, err := s.client.VolumeCreate(ctx, opts) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + volBytes, err := json.Marshal(vol) + if err != nil { + return nil, status.Errorf(codes.Internal, "marshal volume: %v", err) + } + + return &pb.CreateVolumeResponse{Volume: volBytes}, nil +} + +// ListVolumes returns a list of all volumes matching the filter. +func (s *Server) ListVolumes(ctx context.Context, req *pb.ListVolumesRequest) (*pb.ListVolumesResponse, error) { + var opts volume.ListOptions + if len(req.Options) > 0 { + if err := json.Unmarshal(req.Options, &opts); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "unmarshal options: %v", err) + } + + // Handle filters separately because they implement custom JSON unmarshalling. + var raw map[string]json.RawMessage + if err := json.Unmarshal(req.Options, &raw); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "unmarshal options to raw map: %v", err) + } + + if filtersBytes, ok := raw["Filters"]; ok { + args, err := filters.FromJSON(string(filtersBytes)) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "unmarshal filters: %v", err) + } + opts.Filters = args + } + } + + resp, err := s.client.VolumeList(ctx, opts) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + respBytes, err := json.Marshal(resp) + if err != nil { + return nil, status.Errorf(codes.Internal, "marshal response: %v", err) + } + + return &pb.ListVolumesResponse{ + Messages: []*pb.MachineVolumes{ + { + Response: respBytes, + }, + }, + }, nil +} + +// RemoveVolume removes a volume with the given ID. +func (s *Server) RemoveVolume(ctx context.Context, req *pb.RemoveVolumeRequest) (*emptypb.Empty, error) { + if err := s.client.VolumeRemove(ctx, req.Id, req.Force); err != nil { + if client.IsErrNotFound(err) { + return nil, status.Error(codes.NotFound, err.Error()) + } + return nil, status.Error(codes.Internal, err.Error()) + } + + return &emptypb.Empty{}, nil +} + // CreateServiceContainer creates a new container for the service with the given specifications. func (s *Server) CreateServiceContainer( ctx context.Context, req *pb.CreateServiceContainerRequest, @@ -451,6 +526,55 @@ func (s *Server) CreateServiceContainer( return &pb.CreateContainerResponse{Response: respBytes}, nil } +//func toMounts(volumes []api.VolumeSpec) ([]mount.Mount, error) { +// mounts := make([]mount.Mount, 0, len(volumes)) +// for _, vol := range volumes { +// m := mount.Mount{ +// Type: mount.Type(vol.Type), +// Source: vol.Source, +// Target: vol.Target, +// ReadOnly: vol.ReadOnly, +// } +// +// // Set type-specific options. +// switch vol.Type { +// case api.VolumeTypeBind: +// if vol.BindOptions != nil { +// m.BindOptions = &mount.BindOptions{ +// Propagation: vol.BindOptions.Propagation, +// NonRecursive: false, +// } +// if vol.BindOptions.CreateHostPath { +// m.BindOptions.CreateMountpoint = true +// } +// // Handle SELinux options if specified +// if vol.BindOptions.SELinux == api.SELinuxShared { +// m.BindOptions.Propagation = mount.PropagationShared +// } else if vol.BindOptions.SELinux == api.SELinuxUnshared { +// m.BindOptions.Propagation = mount.PropagationPrivate +// } +// } +// case api.VolumeTypeVolume: +// if vol.VolumeOptions != nil { +// m.VolumeOptions = &mount.VolumeOptions{ +// NoCopy: vol.VolumeOptions.NoCopy, +// Labels: vol.VolumeOptions.Labels, +// DriverConfig: vol.VolumeOptions.Driver, +// Subpath: vol.VolumeOptions.Subpath, +// } +// } +// case api.VolumeTypeTmpfs: +// m.TmpfsOptions = vol.TmpfsOptions +// default: +// return nil, fmt.Errorf("invalid volume type: '%s' (must be one of %s, %s, %s)", +// vol.Type, api.VolumeTypeBind, api.VolumeTypeVolume, api.VolumeTypeTmpfs) +// } +// +// mounts = append(mounts, m) +// } +// return mounts +//} + // InspectServiceContainer returns the container information and service specification that was used to create the // container with the given ID. func (s *Server) InspectServiceContainer(