diff --git a/cmd/frostfs-cli/modules/control/ir.go b/cmd/frostfs-cli/modules/control/ir.go new file mode 100644 index 0000000000..05e712275e --- /dev/null +++ b/cmd/frostfs-cli/modules/control/ir.go @@ -0,0 +1,15 @@ +package control + +import "github.com/spf13/cobra" + +var irCmd = &cobra.Command{ + Use: "ir", + Short: "Operations with inner ring nodes", + Long: "Operations with inner ring nodes", +} + +func initControlIRCmd() { + irCmd.AddCommand(removeContainerCmd) + + initControlIRRemoveContainerCmd() +} diff --git a/cmd/frostfs-cli/modules/control/ir_remove_container.go b/cmd/frostfs-cli/modules/control/ir_remove_container.go new file mode 100644 index 0000000000..43173bcaa1 --- /dev/null +++ b/cmd/frostfs-cli/modules/control/ir_remove_container.go @@ -0,0 +1,94 @@ +package control + +import ( + "errors" + + "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" + rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client" + "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" + "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" + commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" + ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" + ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" + cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" + "github.com/spf13/cobra" +) + +const ( + ownerFlag = "owner" +) + +var removeContainerCmd = &cobra.Command{ + Use: "remove-container", + Short: "Schedules a container removal", + Long: `Schedules a container removal via a notary request. +Container data will be deleted asynchronously by policer. +To check removal status "frostfs-cli container list" command can be used.`, + Run: removeContainer, +} + +func initControlIRRemoveContainerCmd() { + initControlFlags(removeContainerCmd) + + flags := removeContainerCmd.Flags() + flags.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage) + flags.String(ownerFlag, "", "Container owner's wallet address.") + removeContainerCmd.MarkFlagsMutuallyExclusive(commonflags.CIDFlag, ownerFlag) +} + +func removeContainer(cmd *cobra.Command, _ []string) { + req := prepareRemoveContainerRequest(cmd) + + pk := key.Get(cmd) + c := getClient(cmd, pk) + + commonCmd.ExitOnErr(cmd, "could not sign request: %w", ircontrolsrv.SignMessage(pk, req)) + + var resp *ircontrol.RemoveContainerResponse + err := c.ExecRaw(func(client *rawclient.Client) error { + var err error + resp, err = ircontrol.RemoveContainer(client, req) + return err + }) + commonCmd.ExitOnErr(cmd, "failed to execute request: %w", err) + + verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) + + if len(req.GetBody().GetContainerId()) > 0 { + cmd.Println("Container scheduled to removal") + } else { + cmd.Println("User containers sheduled to removal") + } +} + +func prepareRemoveContainerRequest(cmd *cobra.Command) *ircontrol.RemoveContainerRequest { + req := &ircontrol.RemoveContainerRequest{ + Body: &ircontrol.RemoveContainerRequest_Body{}, + } + + cidStr, err := cmd.Flags().GetString(commonflags.CIDFlag) + commonCmd.ExitOnErr(cmd, "failed to get cid: ", err) + + ownerStr, err := cmd.Flags().GetString(ownerFlag) + commonCmd.ExitOnErr(cmd, "failed to get owner: ", err) + + if len(ownerStr) == 0 && len(cidStr) == 0 { + commonCmd.ExitOnErr(cmd, "invalid usage: %w", errors.New("neither owner's wallet address nor container ID are specified")) + } + + if len(ownerStr) > 0 { + var owner user.ID + commonCmd.ExitOnErr(cmd, "invalid owner ID: %w", owner.DecodeString(ownerStr)) + var ownerID refs.OwnerID + owner.WriteToV2(&ownerID) + req.Body.Owner = ownerID.StableMarshal(nil) + } + + if len(cidStr) > 0 { + var containerID cid.ID + commonCmd.ExitOnErr(cmd, "invalid container ID: %w", containerID.DecodeString(cidStr)) + req.Body.ContainerId = containerID[:] + } + return req +} diff --git a/cmd/frostfs-cli/modules/control/root.go b/cmd/frostfs-cli/modules/control/root.go index d3b6563929..015676185d 100644 --- a/cmd/frostfs-cli/modules/control/root.go +++ b/cmd/frostfs-cli/modules/control/root.go @@ -33,6 +33,7 @@ func init() { dropObjectsCmd, shardsCmd, synchronizeTreeCmd, + irCmd, ) initControlHealthCheckCmd() @@ -40,4 +41,5 @@ func init() { initControlDropObjectsCmd() initControlShardsCmd() initControlSynchronizeTreeCmd() + initControlIRCmd() } diff --git a/pkg/innerring/initialization.go b/pkg/innerring/initialization.go index 8db6328a2c..b4f6f206bc 100644 --- a/pkg/innerring/initialization.go +++ b/pkg/innerring/initialization.go @@ -520,7 +520,7 @@ func (s *Server) initGRPCServer(cfg *viper.Viper) error { p.SetPrivateKey(*s.key) p.SetHealthChecker(s) - controlSvc := controlsrv.New(p, + controlSvc := controlsrv.New(p, s.containerClient, controlsrv.WithAllowedKeys(authKeys), ) @@ -581,6 +581,7 @@ func (s *Server) initClientsFromMorph() (*serverMorphClients, error) { if err != nil { return nil, err } + s.containerClient = result.CnrClient s.netmapClient, err = nmClient.NewFromMorph(s.morphClient, s.contracts.netmap, fee, nmClient.TryNotary(), nmClient.AsAlphabet()) if err != nil { diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index a91d2fd0da..fbee056fbf 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -14,6 +14,7 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" auditClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/audit" balanceClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container" nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/subscriber" @@ -45,17 +46,18 @@ type ( epochTimer *timer.BlockTimer // global state - morphClient *client.Client - mainnetClient *client.Client - epochCounter atomic.Uint64 - epochDuration atomic.Uint64 - statusIndex *innerRingIndexer - precision precision.Fixed8Converter - auditClient *auditClient.Client - healthStatus atomic.Value - balanceClient *balanceClient.Client - netmapClient *nmClient.Client - persistate *state.PersistentStorage + morphClient *client.Client + mainnetClient *client.Client + epochCounter atomic.Uint64 + epochDuration atomic.Uint64 + statusIndex *innerRingIndexer + precision precision.Fixed8Converter + auditClient *auditClient.Client + healthStatus atomic.Value + balanceClient *balanceClient.Client + netmapClient *nmClient.Client + persistate *state.PersistentStorage + containerClient *container.Client // metrics metrics *metrics.InnerRingServiceMetrics diff --git a/pkg/morph/client/container/delete.go b/pkg/morph/client/container/delete.go index c9105a3ca1..f04d86bde0 100644 --- a/pkg/morph/client/container/delete.go +++ b/pkg/morph/client/container/delete.go @@ -60,7 +60,7 @@ func (d *DeletePrm) SetToken(token []byte) { // // If TryNotary is provided, calls notary contract. func (c *Client) Delete(p DeletePrm) error { - if len(p.signature) == 0 { + if len(p.signature) == 0 && !p.IsControl() { return errNilArgument } diff --git a/pkg/morph/client/static.go b/pkg/morph/client/static.go index afaf49f3d4..b237a485b1 100644 --- a/pkg/morph/client/static.go +++ b/pkg/morph/client/static.go @@ -94,6 +94,12 @@ type InvokePrmOptional struct { // `validUntilBlock` values by all notification // receivers. hash *util.Uint256 + // controlTX controls whether the invoke method will use a rounded + // block height value, which is useful for control transactions which + // are required to be produced by all nodes with very high probability. + // It's only used by notary transactions and it affects only the + // computation of `validUntilBlock` values. + controlTX bool } // SetHash sets optional hash of the transaction. @@ -104,6 +110,16 @@ func (i *InvokePrmOptional) SetHash(hash util.Uint256) { i.hash = &hash } +// SetControlTX sets whether a control transaction will be used. +func (i *InvokePrmOptional) SetControlTX(b bool) { + i.controlTX = b +} + +// IsControl gets whether a control transaction will be used. +func (i *InvokePrmOptional) IsControl() bool { + return i.controlTX +} + // Invoke calls Invoke method of Client with static internal script hash and fee. // Supported args types are the same as in Client. // diff --git a/pkg/services/control/ir/convert.go b/pkg/services/control/ir/convert.go index 01bc487241..4bf68fdbc4 100644 --- a/pkg/services/control/ir/convert.go +++ b/pkg/services/control/ir/convert.go @@ -32,3 +32,22 @@ func (w *healthCheckResponseWrapper) FromGRPCMessage(m grpc.Message) error { return nil } + +type removeContainerResponseWrapper struct { + m *RemoveContainerResponse +} + +func (w *removeContainerResponseWrapper) ToGRPCMessage() grpc.Message { + return w.m +} + +func (w *removeContainerResponseWrapper) FromGRPCMessage(m grpc.Message) error { + var ok bool + + w.m, ok = m.(*RemoveContainerResponse) + if !ok { + return message.NewUnexpectedMessageType(m, w.m) + } + + return nil +} diff --git a/pkg/services/control/ir/rpc.go b/pkg/services/control/ir/rpc.go index a8b16b6079..b4296dc366 100644 --- a/pkg/services/control/ir/rpc.go +++ b/pkg/services/control/ir/rpc.go @@ -8,7 +8,8 @@ import ( const serviceName = "ircontrol.ControlService" const ( - rpcHealthCheck = "HealthCheck" + rpcHealthCheck = "HealthCheck" + rpcRemoveContainer = "RemoveContainer" ) // HealthCheck executes ControlService.HealthCheck RPC. @@ -32,3 +33,24 @@ func HealthCheck( return wResp.m, nil } + +func RemoveContainer( + cli *client.Client, + req *RemoveContainerRequest, + opts ...client.CallOption, +) (*RemoveContainerResponse, error) { + wResp := &removeContainerResponseWrapper{ + m: new(RemoveContainerResponse), + } + + wReq := &requestWrapper{ + m: req, + } + + err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcRemoveContainer), wReq, wResp, opts...) + if err != nil { + return nil, err + } + + return wResp.m, nil +} diff --git a/pkg/services/control/ir/server/calls.go b/pkg/services/control/ir/server/calls.go index 986da90f1b..3030436e64 100644 --- a/pkg/services/control/ir/server/calls.go +++ b/pkg/services/control/ir/server/calls.go @@ -2,8 +2,13 @@ package control import ( "context" + "fmt" + "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container" control "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" + cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -32,3 +37,63 @@ func (s *Server) HealthCheck(_ context.Context, req *control.HealthCheckRequest) return resp, nil } + +// RemoveContainer forces a container removal. +func (s *Server) RemoveContainer(_ context.Context, req *control.RemoveContainerRequest) (*control.RemoveContainerResponse, error) { + if err := s.isValidRequest(req); err != nil { + return nil, status.Error(codes.PermissionDenied, err.Error()) + } + + if len(req.Body.GetContainerId()) > 0 && len(req.Body.GetOwner()) > 0 { + return nil, status.Error(codes.InvalidArgument, "specify the owner and container at the same time is not allowed") + } + + if len(req.Body.GetContainerId()) > 0 { + var containerID cid.ID + if err := containerID.Decode(req.Body.GetContainerId()); err != nil { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to parse container ID: %s", err.Error())) + } + if err := s.removeContainer(containerID); err != nil { + return nil, err + } + } else { + var ownerID refs.OwnerID + if err := ownerID.Unmarshal(req.GetBody().GetOwner()); err != nil { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to parse ownerID: %s", err.Error())) + } + var owner user.ID + if err := owner.ReadFromV2(ownerID); err != nil { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to read owner: %s", err.Error())) + } + + cids, err := s.containerClient.ContainersOf(&owner) + if err != nil { + return nil, fmt.Errorf("failed to get owner's containers: %w", err) + } + + for _, containerID := range cids { + if err := s.removeContainer(containerID); err != nil { + return nil, err + } + } + } + + resp := &control.RemoveContainerResponse{ + Body: &control.RemoveContainerResponse_Body{}, + } + if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return resp, nil +} + +func (s *Server) removeContainer(containerID cid.ID) error { + var prm container.DeletePrm + prm.SetCID(containerID[:]) + prm.SetControlTX(true) + + if err := s.containerClient.Delete(prm); err != nil { + return fmt.Errorf("forcing container removal: %w", err) + } + return nil +} diff --git a/pkg/services/control/ir/server/server.go b/pkg/services/control/ir/server/server.go index c75c1504e1..edd30303b9 100644 --- a/pkg/services/control/ir/server/server.go +++ b/pkg/services/control/ir/server/server.go @@ -2,6 +2,8 @@ package control import ( "fmt" + + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container" ) // Server is an entity that serves @@ -13,6 +15,8 @@ type Server struct { prm Prm allowedKeys [][]byte + + containerClient *container.Client } func panicOnPrmValue(n string, v any) { @@ -29,7 +33,7 @@ func panicOnPrmValue(n string, v any) { // Forms white list from all keys specified via // WithAllowedKeys option and a public key of // the parameterized private key. -func New(prm Prm, opts ...Option) *Server { +func New(prm Prm, containerClient *container.Client, opts ...Option) *Server { // verify required parameters switch { case prm.healthChecker == nil: @@ -46,6 +50,7 @@ func New(prm Prm, opts ...Option) *Server { return &Server{ prm: prm, - allowedKeys: append(o.allowedKeys, prm.key.PublicKey().Bytes()), + allowedKeys: append(o.allowedKeys, prm.key.PublicKey().Bytes()), + containerClient: containerClient, } } diff --git a/pkg/services/control/ir/service.pb.go b/pkg/services/control/ir/service.pb.go index 9f28347065..f01ba3e27a 100644 --- a/pkg/services/control/ir/service.pb.go +++ b/pkg/services/control/ir/service.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.21.12 +// protoc v4.24.4 // source: pkg/services/control/ir/service.proto package control @@ -138,6 +138,116 @@ func (x *HealthCheckResponse) GetSignature() *Signature { return nil } +type RemoveContainerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveContainerRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveContainerRequest) Reset() { + *x = RemoveContainerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveContainerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveContainerRequest) ProtoMessage() {} + +func (x *RemoveContainerRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[2] + 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 RemoveContainerRequest.ProtoReflect.Descriptor instead. +func (*RemoveContainerRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{2} +} + +func (x *RemoveContainerRequest) GetBody() *RemoveContainerRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveContainerRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type RemoveContainerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveContainerResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveContainerResponse) Reset() { + *x = RemoveContainerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveContainerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveContainerResponse) ProtoMessage() {} + +func (x *RemoveContainerResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[3] + 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 RemoveContainerResponse.ProtoReflect.Descriptor instead. +func (*RemoveContainerResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{3} +} + +func (x *RemoveContainerResponse) GetBody() *RemoveContainerResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveContainerResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + // Health check request body. type HealthCheckRequest_Body struct { state protoimpl.MessageState @@ -148,7 +258,7 @@ type HealthCheckRequest_Body struct { func (x *HealthCheckRequest_Body) Reset() { *x = HealthCheckRequest_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[2] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -161,7 +271,7 @@ func (x *HealthCheckRequest_Body) String() string { func (*HealthCheckRequest_Body) ProtoMessage() {} func (x *HealthCheckRequest_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[2] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -190,7 +300,7 @@ type HealthCheckResponse_Body struct { func (x *HealthCheckResponse_Body) Reset() { *x = HealthCheckResponse_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[3] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -203,7 +313,7 @@ func (x *HealthCheckResponse_Body) String() string { func (*HealthCheckResponse_Body) ProtoMessage() {} func (x *HealthCheckResponse_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[3] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -226,6 +336,99 @@ func (x *HealthCheckResponse_Body) GetHealthStatus() HealthStatus { return HealthStatus_HEALTH_STATUS_UNDEFINED } +type RemoveContainerRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + Owner []byte `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` +} + +func (x *RemoveContainerRequest_Body) Reset() { + *x = RemoveContainerRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveContainerRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveContainerRequest_Body) ProtoMessage() {} + +func (x *RemoveContainerRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] + 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 RemoveContainerRequest_Body.ProtoReflect.Descriptor instead. +func (*RemoveContainerRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *RemoveContainerRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *RemoveContainerRequest_Body) GetOwner() []byte { + if x != nil { + return x.Owner + } + return nil +} + +type RemoveContainerResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveContainerResponse_Body) Reset() { + *x = RemoveContainerResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveContainerResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveContainerResponse_Body) ProtoMessage() {} + +func (x *RemoveContainerResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] + 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 RemoveContainerResponse_Body.ProtoReflect.Descriptor instead. +func (*RemoveContainerResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{3, 0} +} + var File_pkg_services_control_ir_service_proto protoreflect.FileDescriptor var file_pkg_services_control_ir_service_proto_rawDesc = []byte{ @@ -255,18 +458,46 @@ var file_pkg_services_control_ir_service_proto_rawDesc = []byte{ 0x3c, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0x5e, 0x0a, - 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1d, - 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a, - 0x42, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, - 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, - 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xc9, 0x01, + 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x3f, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x92, 0x01, 0x0a, 0x17, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x32, 0xb8, + 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x58, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x12, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, + 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, + 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, + 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -281,28 +512,38 @@ func file_pkg_services_control_ir_service_proto_rawDescGZIP() []byte { return file_pkg_services_control_ir_service_proto_rawDescData } -var file_pkg_services_control_ir_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_pkg_services_control_ir_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_pkg_services_control_ir_service_proto_goTypes = []interface{}{ - (*HealthCheckRequest)(nil), // 0: ircontrol.HealthCheckRequest - (*HealthCheckResponse)(nil), // 1: ircontrol.HealthCheckResponse - (*HealthCheckRequest_Body)(nil), // 2: ircontrol.HealthCheckRequest.Body - (*HealthCheckResponse_Body)(nil), // 3: ircontrol.HealthCheckResponse.Body - (*Signature)(nil), // 4: ircontrol.Signature - (HealthStatus)(0), // 5: ircontrol.HealthStatus + (*HealthCheckRequest)(nil), // 0: ircontrol.HealthCheckRequest + (*HealthCheckResponse)(nil), // 1: ircontrol.HealthCheckResponse + (*RemoveContainerRequest)(nil), // 2: ircontrol.RemoveContainerRequest + (*RemoveContainerResponse)(nil), // 3: ircontrol.RemoveContainerResponse + (*HealthCheckRequest_Body)(nil), // 4: ircontrol.HealthCheckRequest.Body + (*HealthCheckResponse_Body)(nil), // 5: ircontrol.HealthCheckResponse.Body + (*RemoveContainerRequest_Body)(nil), // 6: ircontrol.RemoveContainerRequest.Body + (*RemoveContainerResponse_Body)(nil), // 7: ircontrol.RemoveContainerResponse.Body + (*Signature)(nil), // 8: ircontrol.Signature + (HealthStatus)(0), // 9: ircontrol.HealthStatus } var file_pkg_services_control_ir_service_proto_depIdxs = []int32{ - 2, // 0: ircontrol.HealthCheckRequest.body:type_name -> ircontrol.HealthCheckRequest.Body - 4, // 1: ircontrol.HealthCheckRequest.signature:type_name -> ircontrol.Signature - 3, // 2: ircontrol.HealthCheckResponse.body:type_name -> ircontrol.HealthCheckResponse.Body - 4, // 3: ircontrol.HealthCheckResponse.signature:type_name -> ircontrol.Signature - 5, // 4: ircontrol.HealthCheckResponse.Body.health_status:type_name -> ircontrol.HealthStatus - 0, // 5: ircontrol.ControlService.HealthCheck:input_type -> ircontrol.HealthCheckRequest - 1, // 6: ircontrol.ControlService.HealthCheck:output_type -> ircontrol.HealthCheckResponse - 6, // [6:7] is the sub-list for method output_type - 5, // [5:6] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 4, // 0: ircontrol.HealthCheckRequest.body:type_name -> ircontrol.HealthCheckRequest.Body + 8, // 1: ircontrol.HealthCheckRequest.signature:type_name -> ircontrol.Signature + 5, // 2: ircontrol.HealthCheckResponse.body:type_name -> ircontrol.HealthCheckResponse.Body + 8, // 3: ircontrol.HealthCheckResponse.signature:type_name -> ircontrol.Signature + 6, // 4: ircontrol.RemoveContainerRequest.body:type_name -> ircontrol.RemoveContainerRequest.Body + 8, // 5: ircontrol.RemoveContainerRequest.signature:type_name -> ircontrol.Signature + 7, // 6: ircontrol.RemoveContainerResponse.body:type_name -> ircontrol.RemoveContainerResponse.Body + 8, // 7: ircontrol.RemoveContainerResponse.signature:type_name -> ircontrol.Signature + 9, // 8: ircontrol.HealthCheckResponse.Body.health_status:type_name -> ircontrol.HealthStatus + 0, // 9: ircontrol.ControlService.HealthCheck:input_type -> ircontrol.HealthCheckRequest + 2, // 10: ircontrol.ControlService.RemoveContainer:input_type -> ircontrol.RemoveContainerRequest + 1, // 11: ircontrol.ControlService.HealthCheck:output_type -> ircontrol.HealthCheckResponse + 3, // 12: ircontrol.ControlService.RemoveContainer:output_type -> ircontrol.RemoveContainerResponse + 11, // [11:13] is the sub-list for method output_type + 9, // [9:11] 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 } func init() { file_pkg_services_control_ir_service_proto_init() } @@ -337,7 +578,7 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HealthCheckRequest_Body); i { + switch v := v.(*RemoveContainerRequest); i { case 0: return &v.state case 1: @@ -349,6 +590,30 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveContainerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HealthCheckResponse_Body); i { case 0: return &v.state @@ -360,6 +625,30 @@ func file_pkg_services_control_ir_service_proto_init() { return nil } } + file_pkg_services_control_ir_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveContainerRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveContainerResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -367,7 +656,7 @@ func file_pkg_services_control_ir_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_services_control_ir_service_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/services/control/ir/service.proto b/pkg/services/control/ir/service.proto index 5f99be16b7..c6c4d69a3a 100644 --- a/pkg/services/control/ir/service.proto +++ b/pkg/services/control/ir/service.proto @@ -10,6 +10,8 @@ option go_package = "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/ir/ service ControlService { // Performs health check of the IR node. rpc HealthCheck (HealthCheckRequest) returns (HealthCheckResponse); + // Forces a container removal to be signaled by the IR node with high probability. + rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse); } // Health check request. @@ -41,3 +43,21 @@ message HealthCheckResponse { // Body signature. Signature signature = 2; } + + +message RemoveContainerRequest { + message Body{ + bytes container_id = 1; + bytes owner = 2; + } + + Body body = 1; + Signature signature = 2; +} + +message RemoveContainerResponse { + message Body{} + + Body body = 1; + Signature signature = 2; +} \ No newline at end of file diff --git a/pkg/services/control/ir/service_frostfs.pb.go b/pkg/services/control/ir/service_frostfs.pb.go index f6dd94b3a0..438c3a8c5a 100644 --- a/pkg/services/control/ir/service_frostfs.pb.go +++ b/pkg/services/control/ir/service_frostfs.pb.go @@ -154,3 +154,156 @@ func (x *HealthCheckResponse) ReadSignedData(buf []byte) ([]byte, error) { func (x *HealthCheckResponse) SetSignature(sig *Signature) { x.Signature = sig } + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveContainerRequest_Body) StableSize() (size int) { + size += proto.BytesSize(1, x.ContainerId) + size += proto.BytesSize(2, x.Owner) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveContainerRequest_Body) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.BytesMarshal(1, buf[offset:], x.ContainerId) + offset += proto.BytesMarshal(2, buf[offset:], x.Owner) + return buf +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveContainerRequest) StableSize() (size int) { + size += proto.NestedStructureSize(1, x.Body) + size += proto.NestedStructureSize(2, x.Signature) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveContainerRequest) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.NestedStructureMarshal(1, buf[offset:], x.Body) + offset += proto.NestedStructureMarshal(2, buf[offset:], x.Signature) + return buf +} + +// ReadSignedData fills buf with signed data of x. +// If buffer length is less than x.SignedDataSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same signed data. +func (x *RemoveContainerRequest) SignedDataSize() int { + return x.GetBody().StableSize() +} + +// SignedDataSize returns size of the request signed data in bytes. +// +// Structures with the same field values have the same signed data size. +func (x *RemoveContainerRequest) ReadSignedData(buf []byte) ([]byte, error) { + return x.GetBody().StableMarshal(buf), nil +} + +func (x *RemoveContainerRequest) SetSignature(sig *Signature) { + x.Signature = sig +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveContainerResponse_Body) StableSize() (size int) { + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveContainerResponse_Body) StableMarshal(buf []byte) []byte { + return buf +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveContainerResponse) StableSize() (size int) { + size += proto.NestedStructureSize(1, x.Body) + size += proto.NestedStructureSize(2, x.Signature) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveContainerResponse) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.NestedStructureMarshal(1, buf[offset:], x.Body) + offset += proto.NestedStructureMarshal(2, buf[offset:], x.Signature) + return buf +} + +// ReadSignedData fills buf with signed data of x. +// If buffer length is less than x.SignedDataSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same signed data. +func (x *RemoveContainerResponse) SignedDataSize() int { + return x.GetBody().StableSize() +} + +// SignedDataSize returns size of the request signed data in bytes. +// +// Structures with the same field values have the same signed data size. +func (x *RemoveContainerResponse) ReadSignedData(buf []byte) ([]byte, error) { + return x.GetBody().StableMarshal(buf), nil +} + +func (x *RemoveContainerResponse) SetSignature(sig *Signature) { + x.Signature = sig +} diff --git a/pkg/services/control/ir/service_grpc.pb.go b/pkg/services/control/ir/service_grpc.pb.go index b6bc6fdbab..b4e475a14e 100644 --- a/pkg/services/control/ir/service_grpc.pb.go +++ b/pkg/services/control/ir/service_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.12 +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.4 // source: pkg/services/control/ir/service.proto package control @@ -18,12 +18,19 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + ControlService_HealthCheck_FullMethodName = "/ircontrol.ControlService/HealthCheck" + ControlService_RemoveContainer_FullMethodName = "/ircontrol.ControlService/RemoveContainer" +) + // ControlServiceClient is the client API for ControlService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ControlServiceClient interface { // Performs health check of the IR node. HealthCheck(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) + // Forces a container removal to be signaled by the IR node with high probability. + RemoveContainer(ctx context.Context, in *RemoveContainerRequest, opts ...grpc.CallOption) (*RemoveContainerResponse, error) } type controlServiceClient struct { @@ -36,7 +43,16 @@ func NewControlServiceClient(cc grpc.ClientConnInterface) ControlServiceClient { func (c *controlServiceClient) HealthCheck(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { out := new(HealthCheckResponse) - err := c.cc.Invoke(ctx, "/ircontrol.ControlService/HealthCheck", in, out, opts...) + err := c.cc.Invoke(ctx, ControlService_HealthCheck_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlServiceClient) RemoveContainer(ctx context.Context, in *RemoveContainerRequest, opts ...grpc.CallOption) (*RemoveContainerResponse, error) { + out := new(RemoveContainerResponse) + err := c.cc.Invoke(ctx, ControlService_RemoveContainer_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -49,6 +65,8 @@ func (c *controlServiceClient) HealthCheck(ctx context.Context, in *HealthCheckR type ControlServiceServer interface { // Performs health check of the IR node. HealthCheck(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) + // Forces a container removal to be signaled by the IR node with high probability. + RemoveContainer(context.Context, *RemoveContainerRequest) (*RemoveContainerResponse, error) } // UnimplementedControlServiceServer should be embedded to have forward compatible implementations. @@ -58,6 +76,9 @@ type UnimplementedControlServiceServer struct { func (UnimplementedControlServiceServer) HealthCheck(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method HealthCheck not implemented") } +func (UnimplementedControlServiceServer) RemoveContainer(context.Context, *RemoveContainerRequest) (*RemoveContainerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveContainer not implemented") +} // UnsafeControlServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ControlServiceServer will @@ -80,7 +101,7 @@ func _ControlService_HealthCheck_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/ircontrol.ControlService/HealthCheck", + FullMethod: ControlService_HealthCheck_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ControlServiceServer).HealthCheck(ctx, req.(*HealthCheckRequest)) @@ -88,6 +109,24 @@ func _ControlService_HealthCheck_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _ControlService_RemoveContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveContainerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServiceServer).RemoveContainer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ControlService_RemoveContainer_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServiceServer).RemoveContainer(ctx, req.(*RemoveContainerRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ControlService_ServiceDesc is the grpc.ServiceDesc for ControlService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -99,6 +138,10 @@ var ControlService_ServiceDesc = grpc.ServiceDesc{ MethodName: "HealthCheck", Handler: _ControlService_HealthCheck_Handler, }, + { + MethodName: "RemoveContainer", + Handler: _ControlService_RemoveContainer_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pkg/services/control/ir/service.proto",