diff --git a/cmd/storagenode/gracefulexit.go b/cmd/storagenode/gracefulexit.go index 03fc47620..9f1a1f141 100644 --- a/cmd/storagenode/gracefulexit.go +++ b/cmd/storagenode/gracefulexit.go @@ -7,6 +7,7 @@ import ( "bufio" "context" "fmt" + "io" "os" "strings" "text/tabwriter" @@ -39,8 +40,12 @@ func (client *gracefulExitClient) getNonExitingSatellites(ctx context.Context) ( return client.conn.NodeGracefulExitClient().GetNonExitingSatellites(ctx, &pb.GetNonExitingSatellitesRequest{}) } -func (client *gracefulExitClient) initGracefulExit(ctx context.Context, req *pb.StartExitRequest) (*pb.StartExitResponse, error) { - return client.conn.NodeGracefulExitClient().StartExit(ctx, req) +func (client *gracefulExitClient) initGracefulExit(ctx context.Context, req *pb.InitiateGracefulExitRequest) (*pb.ExitProgress, error) { + return client.conn.NodeGracefulExitClient().InitiateGracefulExit(ctx, req) +} + +func (client *gracefulExitClient) getExitProgress(ctx context.Context) (*pb.GetExitProgressResponse, error) { + return client.conn.NodeGracefulExitClient().GetExitProgress(ctx, &pb.GetExitProgressRequest{}) } func (client *gracefulExitClient) close() error { @@ -58,7 +63,7 @@ func cmdGracefulExitInit(cmd *cobra.Command, args []string) error { } // display warning message - if !prompt.Confirm("Please be aware that by starting a graceful exit on a satellite, you will no longer be allowed to participate in repairs or uploads from that satellite. This action can not be undone. Are you sure you want to continue? y/n\n") { + if !prompt.Confirm("Please be aware that by starting a graceful exit from a satellite, you will no longer be allowed to participate in repairs or uploads from that satellite. This action can not be undone. Are you sure you want to continue? y/n\n") { return nil } @@ -75,26 +80,26 @@ func cmdGracefulExitInit(cmd *cobra.Command, args []string) error { // get list of satellites satelliteList, err := client.getNonExitingSatellites(ctx) if err != nil { - fmt.Println("Can't find any non-existing satellites.") + fmt.Println("Can't find any non-exiting satellites.") return errs.Wrap(err) } + if len(satelliteList.GetSatellites()) < 1 { + fmt.Println("Can't find any non-exiting satellites.") + return nil + } + // display satellite options w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "Domain Name\tNode ID\tSpace Used\t") for _, satellite := range satelliteList.GetSatellites() { - fmt.Fprintln(w, satellite.GetDomainName()+"\t"+satellite.NodeId.String()+"\t"+memory.Size(satellite.GetSpaceUsed()).Base10String()+"\t\n") - } - fmt.Fprintln(w, "Please enter the domain name for each satellite you would like to start graceful exit on with a space in between each domain name and hit enter once you are done:") - err = w.Flush() - if err != nil { - return errs.Wrap(err) + fmt.Fprintf(w, "%s\t%s\t%s\t\n", satellite.GetDomainName(), satellite.NodeId.String(), memory.Size(satellite.GetSpaceUsed()).Base10String()) } + fmt.Fprintln(w, "Please enter a space delimited list of satellite domain names you would like to gracefully exit. Press enter to continue:") var selectedSatellite []string - scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input := scanner.Text() @@ -123,19 +128,90 @@ func cmdGracefulExitInit(cmd *cobra.Command, args []string) error { } // save satellites for graceful exit into the db - req := &pb.StartExitRequest{ - NodeIds: satelliteIDs, + progresses := make([]*pb.ExitProgress, 0, len(satelliteIDs)) + var errgroup errs.Group + for _, id := range satelliteIDs { + req := &pb.InitiateGracefulExitRequest{ + NodeId: id, + } + resp, err := client.initGracefulExit(ctx, req) + if err != nil { + zap.S().Debug("initializing graceful exit failed", zap.String("Satellite ID", id.String()), zap.Error(err)) + errgroup.Add(err) + continue + } + progresses = append(progresses, resp) } - resp, err := client.initGracefulExit(ctx, req) + + if len(progresses) < 1 { + fmt.Println("Failed to initialize graceful exit. Please try again later.") + return errgroup.Err() + } + + displayExitProgress(w, progresses) + + err = w.Flush() if err != nil { return errs.Wrap(err) } - for _, status := range resp.Statuses { - if !status.GetSuccess() { - fmt.Printf("Failed to start graceful exit on satellite: %s\n", status.GetDomainName()) - continue - } - fmt.Printf("Started graceful exit on satellite: %s\n", status.GetDomainName()) - } + return nil } + +func cmdGracefulExitStatus(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + ident, err := runCfg.Identity.Load() + if err != nil { + zap.S().Fatal(err) + } else { + zap.S().Info("Node ID: ", ident.ID) + } + + client, err := dialGracefulExitClient(ctx, diagCfg.Server.PrivateAddress) + if err != nil { + return errs.Wrap(err) + } + defer func() { + if err := client.close(); err != nil { + zap.S().Debug("closing graceful exit client failed", err) + } + }() + + // call get status to get status for all satellites' that are in exiting + progresses, err := client.getExitProgress(ctx) + if err != nil { + return errs.Wrap(err) + } + + if len(progresses.GetProgress()) < 1 { + fmt.Println("No graceful exit in progress.") + return nil + } + + // display exit progress + w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) + defer func() { + + err = w.Flush() + if err != nil { + err = errs.Wrap(err) + } + + }() + + displayExitProgress(w, progresses.GetProgress()) + return nil +} + +func displayExitProgress(w io.Writer, progresses []*pb.ExitProgress) { + fmt.Fprintln(w, "\nDomain Name\tNode ID\tPercent Complete\tSuccessful") + + for _, progress := range progresses { + isSuccessful := "N" + if progress.Successful { + isSuccessful = "Y" + } + fmt.Fprintf(w, "%s\t%s\t%.2f%%\t%s\t\n", progress.GetDomainName(), progress.NodeId.String(), progress.GetPercentComplete(), isSuccessful) + } +} diff --git a/cmd/storagenode/main.go b/cmd/storagenode/main.go index a96975bb1..ce0970ab0 100644 --- a/cmd/storagenode/main.go +++ b/cmd/storagenode/main.go @@ -75,6 +75,12 @@ var ( RunE: cmdGracefulExitInit, Annotations: map[string]string{"type": "helper"}, } + gracefulExitStatusCmd = &cobra.Command{ + Use: "exit-status", + Short: "Display graceful exit status", + RunE: cmdGracefulExitStatus, + Annotations: map[string]string{"type": "helper"}, + } runCfg StorageNodeFlags setupCfg StorageNodeFlags @@ -107,12 +113,14 @@ func init() { rootCmd.AddCommand(diagCmd) rootCmd.AddCommand(dashboardCmd) rootCmd.AddCommand(gracefulExitInitCmd) + rootCmd.AddCommand(gracefulExitStatusCmd) process.Bind(runCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(setupCmd, &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir), cfgstruct.SetupMode()) process.Bind(configCmd, &setupCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir), cfgstruct.SetupMode()) process.Bind(diagCmd, &diagCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(dashboardCmd, &dashboardCfg, defaults, cfgstruct.ConfDir(defaultDiagDir)) process.Bind(gracefulExitInitCmd, &diagCfg, defaults, cfgstruct.ConfDir(defaultDiagDir)) + process.Bind(gracefulExitStatusCmd, &diagCfg, defaults, cfgstruct.ConfDir(defaultDiagDir)) } func databaseConfig(config storagenode.Config) storagenodedb.Config { diff --git a/pkg/pb/gracefulexit.pb.go b/pkg/pb/gracefulexit.pb.go index a30b4d1e5..6d4d2b5a5 100644 --- a/pkg/pb/gracefulexit.pb.go +++ b/pkg/pb/gracefulexit.pb.go @@ -49,7 +49,7 @@ func (x TransferFailed_Error) String() string { } func (TransferFailed_Error) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{7, 0} + return fileDescriptor_8f0acbf2ce5fa631, []int{8, 0} } type ExitFailed_Reason int32 @@ -71,7 +71,7 @@ func (x ExitFailed_Reason) String() string { } func (ExitFailed_Reason) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{13, 0} + return fileDescriptor_8f0acbf2ce5fa631, []int{14, 0} } type GetNonExitingSatellitesRequest struct { @@ -104,36 +104,36 @@ func (m *GetNonExitingSatellitesRequest) XXX_DiscardUnknown() { var xxx_messageInfo_GetNonExitingSatellitesRequest proto.InternalMessageInfo -type StartExitRequest struct { - NodeIds []NodeID `protobuf:"bytes,1,rep,name=node_ids,json=nodeIds,proto3,customtype=NodeID" json:"node_ids"` +type InitiateGracefulExitRequest struct { + NodeId NodeID `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3,customtype=NodeID" json:"node_id"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *StartExitRequest) Reset() { *m = StartExitRequest{} } -func (m *StartExitRequest) String() string { return proto.CompactTextString(m) } -func (*StartExitRequest) ProtoMessage() {} -func (*StartExitRequest) Descriptor() ([]byte, []int) { +func (m *InitiateGracefulExitRequest) Reset() { *m = InitiateGracefulExitRequest{} } +func (m *InitiateGracefulExitRequest) String() string { return proto.CompactTextString(m) } +func (*InitiateGracefulExitRequest) ProtoMessage() {} +func (*InitiateGracefulExitRequest) Descriptor() ([]byte, []int) { return fileDescriptor_8f0acbf2ce5fa631, []int{1} } -func (m *StartExitRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StartExitRequest.Unmarshal(m, b) +func (m *InitiateGracefulExitRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InitiateGracefulExitRequest.Unmarshal(m, b) } -func (m *StartExitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StartExitRequest.Marshal(b, m, deterministic) +func (m *InitiateGracefulExitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InitiateGracefulExitRequest.Marshal(b, m, deterministic) } -func (m *StartExitRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartExitRequest.Merge(m, src) +func (m *InitiateGracefulExitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitiateGracefulExitRequest.Merge(m, src) } -func (m *StartExitRequest) XXX_Size() int { - return xxx_messageInfo_StartExitRequest.Size(m) +func (m *InitiateGracefulExitRequest) XXX_Size() int { + return xxx_messageInfo_InitiateGracefulExitRequest.Size(m) } -func (m *StartExitRequest) XXX_DiscardUnknown() { - xxx_messageInfo_StartExitRequest.DiscardUnknown(m) +func (m *InitiateGracefulExitRequest) XXX_DiscardUnknown() { + xxx_messageInfo_InitiateGracefulExitRequest.DiscardUnknown(m) } -var xxx_messageInfo_StartExitRequest proto.InternalMessageInfo +var xxx_messageInfo_InitiateGracefulExitRequest proto.InternalMessageInfo // NonExitingSatellite contains information that's needed for a storagenode to start graceful exit type NonExitingSatellite struct { @@ -221,91 +221,129 @@ func (m *GetNonExitingSatellitesResponse) GetSatellites() []*NonExitingSatellite return nil } -// StartExitStatus indicates the result of graceful exit initialization from a storagenode -type StartExitStatus struct { - DomainName string `protobuf:"bytes,1,opt,name=domain_name,json=domainName,proto3" json:"domain_name,omitempty"` - Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` +type GetExitProgressRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *StartExitStatus) Reset() { *m = StartExitStatus{} } -func (m *StartExitStatus) String() string { return proto.CompactTextString(m) } -func (*StartExitStatus) ProtoMessage() {} -func (*StartExitStatus) Descriptor() ([]byte, []int) { +func (m *GetExitProgressRequest) Reset() { *m = GetExitProgressRequest{} } +func (m *GetExitProgressRequest) String() string { return proto.CompactTextString(m) } +func (*GetExitProgressRequest) ProtoMessage() {} +func (*GetExitProgressRequest) Descriptor() ([]byte, []int) { return fileDescriptor_8f0acbf2ce5fa631, []int{4} } -func (m *StartExitStatus) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StartExitStatus.Unmarshal(m, b) +func (m *GetExitProgressRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetExitProgressRequest.Unmarshal(m, b) } -func (m *StartExitStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StartExitStatus.Marshal(b, m, deterministic) +func (m *GetExitProgressRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetExitProgressRequest.Marshal(b, m, deterministic) } -func (m *StartExitStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartExitStatus.Merge(m, src) +func (m *GetExitProgressRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetExitProgressRequest.Merge(m, src) } -func (m *StartExitStatus) XXX_Size() int { - return xxx_messageInfo_StartExitStatus.Size(m) +func (m *GetExitProgressRequest) XXX_Size() int { + return xxx_messageInfo_GetExitProgressRequest.Size(m) } -func (m *StartExitStatus) XXX_DiscardUnknown() { - xxx_messageInfo_StartExitStatus.DiscardUnknown(m) +func (m *GetExitProgressRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetExitProgressRequest.DiscardUnknown(m) } -var xxx_messageInfo_StartExitStatus proto.InternalMessageInfo +var xxx_messageInfo_GetExitProgressRequest proto.InternalMessageInfo -func (m *StartExitStatus) GetDomainName() string { +type GetExitProgressResponse struct { + Progress []*ExitProgress `protobuf:"bytes,1,rep,name=progress,proto3" json:"progress,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetExitProgressResponse) Reset() { *m = GetExitProgressResponse{} } +func (m *GetExitProgressResponse) String() string { return proto.CompactTextString(m) } +func (*GetExitProgressResponse) ProtoMessage() {} +func (*GetExitProgressResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8f0acbf2ce5fa631, []int{5} +} +func (m *GetExitProgressResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetExitProgressResponse.Unmarshal(m, b) +} +func (m *GetExitProgressResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetExitProgressResponse.Marshal(b, m, deterministic) +} +func (m *GetExitProgressResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetExitProgressResponse.Merge(m, src) +} +func (m *GetExitProgressResponse) XXX_Size() int { + return xxx_messageInfo_GetExitProgressResponse.Size(m) +} +func (m *GetExitProgressResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetExitProgressResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetExitProgressResponse proto.InternalMessageInfo + +func (m *GetExitProgressResponse) GetProgress() []*ExitProgress { + if m != nil { + return m.Progress + } + return nil +} + +type ExitProgress struct { + DomainName string `protobuf:"bytes,1,opt,name=domain_name,json=domainName,proto3" json:"domain_name,omitempty"` + NodeId NodeID `protobuf:"bytes,2,opt,name=node_id,json=nodeId,proto3,customtype=NodeID" json:"node_id"` + PercentComplete float32 `protobuf:"fixed32,3,opt,name=percent_complete,json=percentComplete,proto3" json:"percent_complete,omitempty"` + Successful bool `protobuf:"varint,4,opt,name=successful,proto3" json:"successful,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExitProgress) Reset() { *m = ExitProgress{} } +func (m *ExitProgress) String() string { return proto.CompactTextString(m) } +func (*ExitProgress) ProtoMessage() {} +func (*ExitProgress) Descriptor() ([]byte, []int) { + return fileDescriptor_8f0acbf2ce5fa631, []int{6} +} +func (m *ExitProgress) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExitProgress.Unmarshal(m, b) +} +func (m *ExitProgress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExitProgress.Marshal(b, m, deterministic) +} +func (m *ExitProgress) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExitProgress.Merge(m, src) +} +func (m *ExitProgress) XXX_Size() int { + return xxx_messageInfo_ExitProgress.Size(m) +} +func (m *ExitProgress) XXX_DiscardUnknown() { + xxx_messageInfo_ExitProgress.DiscardUnknown(m) +} + +var xxx_messageInfo_ExitProgress proto.InternalMessageInfo + +func (m *ExitProgress) GetDomainName() string { if m != nil { return m.DomainName } return "" } -func (m *StartExitStatus) GetSuccess() bool { +func (m *ExitProgress) GetPercentComplete() float32 { if m != nil { - return m.Success + return m.PercentComplete + } + return 0 +} + +func (m *ExitProgress) GetSuccessful() bool { + if m != nil { + return m.Successful } return false } -type StartExitResponse struct { - Statuses []*StartExitStatus `protobuf:"bytes,1,rep,name=statuses,proto3" json:"statuses,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *StartExitResponse) Reset() { *m = StartExitResponse{} } -func (m *StartExitResponse) String() string { return proto.CompactTextString(m) } -func (*StartExitResponse) ProtoMessage() {} -func (*StartExitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{5} -} -func (m *StartExitResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StartExitResponse.Unmarshal(m, b) -} -func (m *StartExitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StartExitResponse.Marshal(b, m, deterministic) -} -func (m *StartExitResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartExitResponse.Merge(m, src) -} -func (m *StartExitResponse) XXX_Size() int { - return xxx_messageInfo_StartExitResponse.Size(m) -} -func (m *StartExitResponse) XXX_DiscardUnknown() { - xxx_messageInfo_StartExitResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_StartExitResponse proto.InternalMessageInfo - -func (m *StartExitResponse) GetStatuses() []*StartExitStatus { - if m != nil { - return m.Statuses - } - return nil -} - type TransferSucceeded struct { AddressedOrderLimit *AddressedOrderLimit `protobuf:"bytes,1,opt,name=addressed_order_limit,json=addressedOrderLimit,proto3" json:"addressed_order_limit,omitempty"` OriginalPieceHash *PieceHash `protobuf:"bytes,2,opt,name=original_piece_hash,json=originalPieceHash,proto3" json:"original_piece_hash,omitempty"` @@ -320,7 +358,7 @@ func (m *TransferSucceeded) Reset() { *m = TransferSucceeded{} } func (m *TransferSucceeded) String() string { return proto.CompactTextString(m) } func (*TransferSucceeded) ProtoMessage() {} func (*TransferSucceeded) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{6} + return fileDescriptor_8f0acbf2ce5fa631, []int{7} } func (m *TransferSucceeded) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferSucceeded.Unmarshal(m, b) @@ -373,7 +411,7 @@ func (m *TransferFailed) Reset() { *m = TransferFailed{} } func (m *TransferFailed) String() string { return proto.CompactTextString(m) } func (*TransferFailed) ProtoMessage() {} func (*TransferFailed) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{7} + return fileDescriptor_8f0acbf2ce5fa631, []int{8} } func (m *TransferFailed) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferFailed.Unmarshal(m, b) @@ -414,7 +452,7 @@ func (m *StorageNodeMessage) Reset() { *m = StorageNodeMessage{} } func (m *StorageNodeMessage) String() string { return proto.CompactTextString(m) } func (*StorageNodeMessage) ProtoMessage() {} func (*StorageNodeMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{8} + return fileDescriptor_8f0acbf2ce5fa631, []int{9} } func (m *StorageNodeMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StorageNodeMessage.Unmarshal(m, b) @@ -553,7 +591,7 @@ func (m *NotReady) Reset() { *m = NotReady{} } func (m *NotReady) String() string { return proto.CompactTextString(m) } func (*NotReady) ProtoMessage() {} func (*NotReady) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{9} + return fileDescriptor_8f0acbf2ce5fa631, []int{10} } func (m *NotReady) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_NotReady.Unmarshal(m, b) @@ -587,7 +625,7 @@ func (m *TransferPiece) Reset() { *m = TransferPiece{} } func (m *TransferPiece) String() string { return proto.CompactTextString(m) } func (*TransferPiece) ProtoMessage() {} func (*TransferPiece) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{10} + return fileDescriptor_8f0acbf2ce5fa631, []int{11} } func (m *TransferPiece) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferPiece.Unmarshal(m, b) @@ -625,7 +663,7 @@ func (m *DeletePiece) Reset() { *m = DeletePiece{} } func (m *DeletePiece) String() string { return proto.CompactTextString(m) } func (*DeletePiece) ProtoMessage() {} func (*DeletePiece) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{11} + return fileDescriptor_8f0acbf2ce5fa631, []int{12} } func (m *DeletePiece) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeletePiece.Unmarshal(m, b) @@ -657,7 +695,7 @@ func (m *ExitCompleted) Reset() { *m = ExitCompleted{} } func (m *ExitCompleted) String() string { return proto.CompactTextString(m) } func (*ExitCompleted) ProtoMessage() {} func (*ExitCompleted) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{12} + return fileDescriptor_8f0acbf2ce5fa631, []int{13} } func (m *ExitCompleted) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExitCompleted.Unmarshal(m, b) @@ -697,7 +735,7 @@ func (m *ExitFailed) Reset() { *m = ExitFailed{} } func (m *ExitFailed) String() string { return proto.CompactTextString(m) } func (*ExitFailed) ProtoMessage() {} func (*ExitFailed) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{13} + return fileDescriptor_8f0acbf2ce5fa631, []int{14} } func (m *ExitFailed) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExitFailed.Unmarshal(m, b) @@ -748,7 +786,7 @@ func (m *SatelliteMessage) Reset() { *m = SatelliteMessage{} } func (m *SatelliteMessage) String() string { return proto.CompactTextString(m) } func (*SatelliteMessage) ProtoMessage() {} func (*SatelliteMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_8f0acbf2ce5fa631, []int{14} + return fileDescriptor_8f0acbf2ce5fa631, []int{15} } func (m *SatelliteMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SatelliteMessage.Unmarshal(m, b) @@ -971,11 +1009,12 @@ func init() { proto.RegisterEnum("gracefulexit.TransferFailed_Error", TransferFailed_Error_name, TransferFailed_Error_value) proto.RegisterEnum("gracefulexit.ExitFailed_Reason", ExitFailed_Reason_name, ExitFailed_Reason_value) proto.RegisterType((*GetNonExitingSatellitesRequest)(nil), "gracefulexit.GetNonExitingSatellitesRequest") - proto.RegisterType((*StartExitRequest)(nil), "gracefulexit.StartExitRequest") + proto.RegisterType((*InitiateGracefulExitRequest)(nil), "gracefulexit.InitiateGracefulExitRequest") proto.RegisterType((*NonExitingSatellite)(nil), "gracefulexit.NonExitingSatellite") proto.RegisterType((*GetNonExitingSatellitesResponse)(nil), "gracefulexit.GetNonExitingSatellitesResponse") - proto.RegisterType((*StartExitStatus)(nil), "gracefulexit.StartExitStatus") - proto.RegisterType((*StartExitResponse)(nil), "gracefulexit.StartExitResponse") + proto.RegisterType((*GetExitProgressRequest)(nil), "gracefulexit.GetExitProgressRequest") + proto.RegisterType((*GetExitProgressResponse)(nil), "gracefulexit.GetExitProgressResponse") + proto.RegisterType((*ExitProgress)(nil), "gracefulexit.ExitProgress") proto.RegisterType((*TransferSucceeded)(nil), "gracefulexit.TransferSucceeded") proto.RegisterType((*TransferFailed)(nil), "gracefulexit.TransferFailed") proto.RegisterType((*StorageNodeMessage)(nil), "gracefulexit.StorageNodeMessage") @@ -990,79 +1029,84 @@ func init() { func init() { proto.RegisterFile("gracefulexit.proto", fileDescriptor_8f0acbf2ce5fa631) } var fileDescriptor_8f0acbf2ce5fa631 = []byte{ - // 995 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x6e, 0x1a, 0x47, - 0x14, 0x66, 0xed, 0x04, 0xcc, 0x01, 0x63, 0x3c, 0x8e, 0x6d, 0xea, 0x26, 0x81, 0xec, 0x4d, 0x5d, - 0xa9, 0xb5, 0x2a, 0xf7, 0x5f, 0x51, 0x5b, 0xe1, 0x80, 0x81, 0x86, 0x2e, 0xee, 0x60, 0xa7, 0x52, - 0x6f, 0x56, 0x13, 0xe6, 0x18, 0xaf, 0x0a, 0xbb, 0x74, 0x66, 0x88, 0xe2, 0x9b, 0x3e, 0x47, 0xaf, - 0xfa, 0x0a, 0x7d, 0x8d, 0xaa, 0x4f, 0xd0, 0x56, 0x6a, 0x9e, 0xa5, 0x9a, 0xd9, 0x61, 0xcd, 0x62, - 0x88, 0xa2, 0xe6, 0x6e, 0xe7, 0xcc, 0x77, 0xbe, 0xf9, 0xe6, 0x9c, 0x6f, 0x66, 0x16, 0xc8, 0x50, - 0xb0, 0x01, 0x5e, 0x4e, 0x47, 0xf8, 0x32, 0x50, 0x47, 0x13, 0x11, 0xa9, 0x88, 0x14, 0xe7, 0x63, - 0x07, 0x30, 0x8c, 0x86, 0x51, 0x3c, 0x73, 0x50, 0x1a, 0xa3, 0x62, 0x41, 0x78, 0x39, 0x1b, 0x17, - 0x23, 0xc1, 0x51, 0xc8, 0x78, 0xe4, 0xd6, 0xe0, 0x61, 0x0b, 0x95, 0x17, 0x85, 0xcd, 0x97, 0x81, - 0x0a, 0xc2, 0x61, 0x9f, 0x29, 0x1c, 0x8d, 0x02, 0x85, 0x92, 0xe2, 0xcf, 0x53, 0x94, 0xca, 0xfd, - 0x0a, 0xca, 0x7d, 0xc5, 0x84, 0xd2, 0x00, 0x1b, 0x23, 0xef, 0xc3, 0x46, 0x18, 0x71, 0xf4, 0x03, - 0x2e, 0x2b, 0x4e, 0x6d, 0xfd, 0xb0, 0x78, 0x52, 0xfa, 0xe3, 0x55, 0x35, 0xf3, 0xcf, 0xab, 0x6a, - 0xd6, 0x8b, 0x38, 0x76, 0x1a, 0x34, 0xa7, 0xe7, 0x3b, 0x5c, 0xba, 0xbf, 0xc0, 0xce, 0x12, 0x76, - 0xf2, 0x1e, 0xe4, 0x2c, 0x43, 0xc5, 0xa9, 0x39, 0x4b, 0x08, 0xb2, 0x31, 0x01, 0xa9, 0x42, 0x81, - 0x47, 0x63, 0x16, 0x84, 0x7e, 0xc8, 0xc6, 0x58, 0x59, 0xab, 0x39, 0x87, 0x79, 0x0a, 0x71, 0xc8, - 0x63, 0x63, 0x24, 0x0f, 0x00, 0xe4, 0x84, 0x0d, 0xd0, 0x9f, 0x4a, 0xe4, 0x95, 0xf5, 0x9a, 0x73, - 0xe8, 0xd0, 0xbc, 0x89, 0x5c, 0x48, 0xe4, 0x2e, 0x87, 0xea, 0xca, 0x0d, 0xca, 0x49, 0x14, 0x4a, - 0x24, 0x75, 0x00, 0x99, 0x44, 0xcd, 0x7e, 0x0a, 0xc7, 0x8f, 0x8e, 0x52, 0x45, 0x5e, 0x92, 0x4f, - 0xe7, 0x92, 0xdc, 0x2e, 0x6c, 0x25, 0x45, 0xea, 0x2b, 0xa6, 0xa6, 0x72, 0x51, 0xb8, 0x73, 0x4b, - 0x78, 0x05, 0x72, 0x72, 0x3a, 0x18, 0xa0, 0x94, 0x66, 0x57, 0x1b, 0x74, 0x36, 0x74, 0x3d, 0xd8, - 0x9e, 0x2b, 0xb9, 0x55, 0xf9, 0x25, 0x6c, 0x48, 0xc3, 0x9c, 0x68, 0x7c, 0x90, 0xd6, 0xb8, 0x20, - 0x80, 0x26, 0x70, 0xf7, 0xf7, 0x35, 0xd8, 0x3e, 0x17, 0x2c, 0x94, 0x97, 0x28, 0xfa, 0x7a, 0x0d, - 0xe4, 0xc8, 0xc9, 0xf7, 0xb0, 0xcb, 0x38, 0x17, 0x28, 0x25, 0x72, 0xdf, 0x98, 0xc2, 0x1f, 0x05, - 0xe3, 0x40, 0x19, 0xa9, 0x9a, 0x3d, 0x31, 0x4e, 0x7d, 0x06, 0xeb, 0x69, 0x54, 0x57, 0x83, 0xe8, - 0x0e, 0xbb, 0x1d, 0x24, 0x75, 0xd8, 0x89, 0x44, 0x30, 0x0c, 0x42, 0x36, 0xf2, 0x27, 0x01, 0x0e, - 0xd0, 0xbf, 0x62, 0xf2, 0xca, 0x6c, 0xaf, 0x70, 0xbc, 0x7d, 0x64, 0x9d, 0x77, 0xa6, 0x67, 0xda, - 0x4c, 0x5e, 0xd1, 0xed, 0x19, 0x3a, 0x09, 0x91, 0x16, 0xec, 0x09, 0x9c, 0x8c, 0xd8, 0x00, 0xc7, - 0x18, 0xaa, 0x79, 0x96, 0xf5, 0x55, 0x2c, 0xf7, 0xe6, 0x12, 0x6e, 0x88, 0x1e, 0xc3, 0xf6, 0x82, - 0x96, 0x80, 0x57, 0xee, 0x18, 0xaf, 0x6d, 0x59, 0xaf, 0xe5, 0x0c, 0xba, 0xd3, 0xa0, 0x5b, 0x29, - 0x1d, 0x1d, 0xee, 0xfe, 0xe9, 0x40, 0x69, 0x56, 0xb1, 0x53, 0x16, 0x8c, 0x90, 0x2f, 0xe7, 0x73, - 0xde, 0x8c, 0x8f, 0x7c, 0x01, 0x77, 0x51, 0x88, 0x48, 0x98, 0x52, 0x94, 0x8e, 0xdd, 0x74, 0xe7, - 0xd2, 0x2b, 0x1d, 0x35, 0x35, 0x92, 0xc6, 0x09, 0x6e, 0x1d, 0xee, 0x9a, 0x31, 0xd9, 0x84, 0xbc, - 0xd7, 0x3b, 0xf7, 0x4f, 0x7b, 0x17, 0x5e, 0xa3, 0x9c, 0x21, 0xf7, 0xa1, 0xd2, 0x3f, 0xef, 0xd1, - 0x7a, 0xab, 0xe9, 0x7b, 0xbd, 0x46, 0xd3, 0xbf, 0xf0, 0xea, 0xcf, 0xea, 0x9d, 0x6e, 0xfd, 0xa4, - 0xdb, 0x2c, 0x3b, 0xa4, 0x00, 0xb9, 0x0b, 0xef, 0xa9, 0xd7, 0xfb, 0xc1, 0x2b, 0xaf, 0xb9, 0xbf, - 0x3a, 0x40, 0xfa, 0x2a, 0x12, 0x6c, 0x88, 0xfa, 0x70, 0x7d, 0x87, 0x52, 0xb2, 0x21, 0x92, 0x6f, - 0x20, 0x2f, 0x67, 0x66, 0xb0, 0x3d, 0xaf, 0x2e, 0xd7, 0x95, 0x78, 0xa6, 0x9d, 0xa1, 0x37, 0x39, - 0xe4, 0x33, 0xc8, 0x5e, 0x1a, 0xc5, 0xb6, 0xc1, 0xf7, 0x5f, 0xb7, 0xab, 0x76, 0x86, 0x5a, 0xf4, - 0x49, 0x1e, 0x72, 0x56, 0x83, 0x0b, 0xb0, 0xe1, 0x45, 0x8a, 0x22, 0xe3, 0xd7, 0xee, 0xdf, 0x0e, - 0x6c, 0xce, 0x72, 0x4c, 0xdd, 0xde, 0xb6, 0xe4, 0x85, 0x89, 0x08, 0x5e, 0x30, 0x85, 0xfe, 0x4f, - 0x78, 0x6d, 0x24, 0x16, 0x4f, 0xf6, 0x6d, 0xda, 0x96, 0x41, 0x9d, 0xc5, 0xf3, 0x4f, 0xf1, 0x9a, - 0xc2, 0x24, 0xf9, 0x5e, 0x7d, 0x30, 0xd6, 0xff, 0xef, 0xc1, 0x70, 0xbf, 0x85, 0x42, 0x03, 0x47, - 0xa8, 0xf0, 0xed, 0x37, 0xe6, 0xb6, 0x60, 0x53, 0x9f, 0xf2, 0x27, 0xd1, 0x78, 0xa2, 0x19, 0x75, - 0x1f, 0xf6, 0x75, 0xc1, 0xfd, 0x81, 0x8d, 0xf8, 0x32, 0x18, 0x86, 0x4c, 0x4d, 0x45, 0x7c, 0xeb, - 0x14, 0xe9, 0x2e, 0xce, 0xe1, 0xfb, 0xb3, 0x49, 0xf7, 0x37, 0x07, 0x40, 0x33, 0x59, 0x83, 0x7f, - 0x02, 0x7b, 0x86, 0x46, 0x77, 0x69, 0x2a, 0x6e, 0xb3, 0xdc, 0x43, 0x8b, 0x9d, 0x8a, 0x1b, 0x12, - 0xf2, 0x39, 0x64, 0x05, 0x32, 0x19, 0x85, 0xd6, 0xda, 0x0b, 0x16, 0xba, 0xe1, 0x3f, 0xa2, 0x06, - 0x46, 0x2d, 0xdc, 0x7d, 0x04, 0xd9, 0x38, 0x42, 0xf6, 0x61, 0xe7, 0x59, 0x93, 0x76, 0x4e, 0x3b, - 0x4f, 0xea, 0xe7, 0x9d, 0x9e, 0xe7, 0x9f, 0xd6, 0x3b, 0xdd, 0x66, 0xa3, 0x9c, 0x71, 0xff, 0x5d, - 0x83, 0x72, 0x72, 0xdf, 0xce, 0x6c, 0xfb, 0x29, 0xe4, 0xc3, 0x48, 0xf9, 0x42, 0x7b, 0xc6, 0xda, - 0x76, 0x6f, 0xf1, 0xb2, 0x8e, 0x1d, 0xd5, 0xce, 0xd0, 0x8d, 0xd0, 0x7e, 0x93, 0x06, 0x94, 0x94, - 0x35, 0x57, 0x5c, 0x72, 0x6b, 0xda, 0x77, 0x97, 0x9b, 0x36, 0xbe, 0x47, 0x32, 0x74, 0x53, 0xa5, - 0x1c, 0xf9, 0x35, 0x14, 0xb9, 0xe9, 0xa3, 0xe5, 0x88, 0x1d, 0xf1, 0x4e, 0x9a, 0x63, 0xae, 0xd3, - 0xed, 0x0c, 0x2d, 0xf0, 0xb9, 0xc6, 0x37, 0xa0, 0x94, 0x6a, 0x55, 0x7c, 0x23, 0xdd, 0x52, 0x91, - 0xea, 0xaf, 0x56, 0x81, 0xa9, 0x86, 0x3f, 0x86, 0x42, 0xd2, 0x29, 0xe4, 0x95, 0xbb, 0x86, 0xa2, - 0xb2, 0xaa, 0xf0, 0xed, 0x0c, 0x05, 0x4c, 0x46, 0x73, 0xa7, 0xef, 0xf8, 0x2f, 0x07, 0xca, 0xfa, - 0x46, 0x68, 0xd9, 0x44, 0x9d, 0x43, 0x5e, 0xc0, 0xfe, 0x8a, 0x07, 0x93, 0x7c, 0x90, 0x5e, 0xe2, - 0xf5, 0x3f, 0x0e, 0x07, 0x1f, 0xbe, 0x21, 0xda, 0xbe, 0x6f, 0x5d, 0xc8, 0x27, 0x2f, 0x18, 0x79, - 0xb8, 0xe2, 0x69, 0x9b, 0x71, 0x57, 0x57, 0xce, 0xc7, 0x6c, 0xc7, 0x57, 0xb0, 0x9b, 0xac, 0x91, - 0xda, 0x5e, 0x0f, 0x72, 0x67, 0x22, 0xd2, 0xcf, 0x2c, 0xa9, 0x2d, 0x92, 0x2c, 0x5e, 0x91, 0x07, - 0x8b, 0x32, 0x16, 0xbc, 0x78, 0xe8, 0x7c, 0xe4, 0x9c, 0xdc, 0xf9, 0x71, 0x6d, 0xf2, 0xfc, 0x79, - 0xd6, 0xfc, 0x4e, 0x7d, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3d, 0x50, 0xc8, 0xa3, 0x9c, - 0x09, 0x00, 0x00, + // 1053 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xe1, 0x6e, 0x1b, 0x45, + 0x10, 0xf6, 0x39, 0xad, 0x13, 0x8f, 0x1d, 0xc7, 0xd9, 0xb4, 0x89, 0x71, 0xdb, 0xd8, 0x3d, 0x81, + 0x70, 0x25, 0x88, 0x90, 0x81, 0x82, 0x54, 0x09, 0xe4, 0xd4, 0x8e, 0x6d, 0x1a, 0xce, 0xe9, 0x26, + 0x29, 0x12, 0x12, 0x9c, 0xb6, 0xbe, 0x89, 0x73, 0xc2, 0xbe, 0x3b, 0x76, 0xd7, 0x55, 0xf3, 0x87, + 0xe7, 0xe0, 0x17, 0x7f, 0x78, 0x00, 0x5e, 0x03, 0x78, 0x03, 0x90, 0xe8, 0xb3, 0xa0, 0xbd, 0x5b, + 0x5f, 0xee, 0x6c, 0x27, 0x44, 0xf4, 0xdf, 0xdd, 0xcc, 0x37, 0xb3, 0xb3, 0xdf, 0x7c, 0x3b, 0xbb, + 0x40, 0x46, 0x9c, 0x0d, 0xf1, 0x6c, 0x3a, 0xc6, 0xd7, 0xae, 0xdc, 0x0b, 0xb8, 0x2f, 0x7d, 0x52, + 0x4c, 0xda, 0xaa, 0x30, 0xf2, 0x47, 0x7e, 0xe4, 0xa9, 0x96, 0x26, 0x28, 0x99, 0xeb, 0x9d, 0xcd, + 0xfe, 0x8b, 0x3e, 0x77, 0x90, 0x8b, 0xe8, 0xcf, 0xac, 0xc3, 0x6e, 0x17, 0xa5, 0xe5, 0x7b, 0x9d, + 0xd7, 0xae, 0x74, 0xbd, 0xd1, 0x31, 0x93, 0x38, 0x1e, 0xbb, 0x12, 0x05, 0xc5, 0x1f, 0xa7, 0x28, + 0xa4, 0x79, 0x00, 0xf7, 0xfa, 0x9e, 0x2b, 0x5d, 0x26, 0xb1, 0xab, 0xd7, 0x50, 0x58, 0xed, 0x26, + 0xef, 0xc3, 0xaa, 0xe7, 0x3b, 0x68, 0xbb, 0x4e, 0xc5, 0xa8, 0x1b, 0x8d, 0xe2, 0x7e, 0xe9, 0xf7, + 0x37, 0xb5, 0xcc, 0xdf, 0x6f, 0x6a, 0x39, 0xcb, 0x77, 0xb0, 0xdf, 0xa6, 0x39, 0xe5, 0xee, 0x3b, + 0xe6, 0x4f, 0xb0, 0xb5, 0x64, 0x99, 0x1b, 0xc7, 0x93, 0x1a, 0x14, 0x1c, 0x7f, 0xc2, 0x5c, 0xcf, + 0xf6, 0xd8, 0x04, 0x2b, 0xd9, 0xba, 0xd1, 0xc8, 0x53, 0x88, 0x4c, 0x16, 0x9b, 0x20, 0x79, 0x00, + 0x20, 0x02, 0x36, 0x44, 0x7b, 0x2a, 0xd0, 0xa9, 0xac, 0xd4, 0x8d, 0x86, 0x41, 0xf3, 0xa1, 0xe5, + 0x54, 0xa0, 0x63, 0x3a, 0x50, 0xbb, 0x72, 0xa7, 0x22, 0xf0, 0x3d, 0x81, 0xa4, 0x05, 0x20, 0x62, + 0x6b, 0xc5, 0xa8, 0xaf, 0x34, 0x0a, 0xcd, 0x87, 0x7b, 0x29, 0xb6, 0x97, 0xc4, 0xd3, 0x44, 0x90, + 0x59, 0x81, 0xed, 0x2e, 0x4a, 0x05, 0x39, 0xe2, 0xfe, 0x88, 0xa3, 0x88, 0x79, 0x7c, 0x0e, 0x3b, + 0x0b, 0x1e, 0xbd, 0xee, 0x63, 0x58, 0x0b, 0xb4, 0x4d, 0xaf, 0x5a, 0x4d, 0xaf, 0x9a, 0x8a, 0x8a, + 0xb1, 0xe6, 0xaf, 0x06, 0x14, 0x93, 0xae, 0x79, 0x8e, 0x8c, 0x05, 0x8e, 0x12, 0x6c, 0x67, 0xaf, + 0x65, 0xfb, 0x11, 0x94, 0x03, 0xe4, 0x43, 0xf4, 0xa4, 0x3d, 0xf4, 0x27, 0xc1, 0x18, 0x25, 0x86, + 0x94, 0x66, 0xe9, 0x86, 0xb6, 0x3f, 0xd5, 0x66, 0xb2, 0x0b, 0x20, 0xa6, 0xc3, 0x21, 0x0a, 0x71, + 0x36, 0x1d, 0x57, 0x6e, 0xd5, 0x8d, 0xc6, 0x1a, 0x4d, 0x58, 0xcc, 0xdf, 0xb2, 0xb0, 0x79, 0xc2, + 0x99, 0x27, 0xce, 0x90, 0x1f, 0x2b, 0x33, 0x3a, 0xe8, 0x90, 0xe7, 0x70, 0x97, 0x39, 0x8e, 0xaa, + 0x1a, 0x1d, 0x3b, 0x94, 0xa4, 0x3d, 0x76, 0x27, 0xae, 0x0c, 0x8b, 0x2e, 0x34, 0x1f, 0xec, 0xc5, + 0xb2, 0x6d, 0xcd, 0x60, 0x03, 0x85, 0x3a, 0x54, 0x20, 0xba, 0xc5, 0x16, 0x8d, 0xa4, 0x05, 0x5b, + 0x3e, 0x77, 0x47, 0xae, 0xc7, 0xc6, 0x76, 0xe0, 0xe2, 0x10, 0xed, 0x73, 0x26, 0xce, 0xc3, 0x8d, + 0x16, 0x9a, 0x9b, 0x7b, 0x5a, 0xf7, 0x47, 0xca, 0xd3, 0x63, 0xe2, 0x9c, 0x6e, 0xce, 0xd0, 0xb1, + 0x89, 0x74, 0x61, 0x9b, 0x63, 0x30, 0x66, 0x43, 0x9c, 0xa8, 0xad, 0x27, 0xb2, 0xac, 0x5c, 0x95, + 0xe5, 0x4e, 0x22, 0xe0, 0x32, 0xd1, 0x13, 0xd8, 0x9c, 0xab, 0xc5, 0x75, 0x42, 0x6e, 0x8a, 0xfb, + 0x1b, 0x9a, 0xf2, 0xd5, 0x10, 0xdd, 0x6f, 0xd3, 0x8d, 0x54, 0x1d, 0x7d, 0xc7, 0xfc, 0xd3, 0x80, + 0xd2, 0x8c, 0xb1, 0x03, 0xe6, 0x8e, 0xd1, 0x59, 0x9e, 0xcf, 0xb8, 0x59, 0x3e, 0xf2, 0x39, 0xdc, + 0x46, 0xce, 0x7d, 0x1e, 0x52, 0x51, 0x6a, 0x9a, 0x69, 0x71, 0xa5, 0x57, 0xda, 0xeb, 0x28, 0x24, + 0x8d, 0x02, 0xcc, 0x16, 0xdc, 0x0e, 0xff, 0xc9, 0x3a, 0xe4, 0xad, 0xc1, 0x89, 0x7d, 0x30, 0x38, + 0xb5, 0xda, 0xe5, 0x0c, 0xb9, 0x0f, 0x95, 0xe3, 0x93, 0x01, 0x6d, 0x75, 0x3b, 0xb6, 0x35, 0x68, + 0x77, 0xec, 0x53, 0xab, 0xf5, 0xa2, 0xd5, 0x3f, 0x6c, 0xed, 0x1f, 0x76, 0xca, 0x06, 0x29, 0xc0, + 0xea, 0xa9, 0xf5, 0xcc, 0x1a, 0x7c, 0x63, 0x95, 0xb3, 0xe6, 0xcf, 0x06, 0x90, 0x63, 0xe9, 0x73, + 0x36, 0x42, 0xa5, 0xb1, 0xaf, 0x51, 0x08, 0x36, 0x42, 0xf2, 0x25, 0xe4, 0xc5, 0x4c, 0x0c, 0xba, + 0xe7, 0xb5, 0xe5, 0x75, 0xc5, 0x9a, 0xe9, 0x65, 0xe8, 0x65, 0x0c, 0x79, 0x0c, 0xb9, 0xb3, 0xb0, + 0x62, 0xdd, 0xe0, 0xfb, 0xd7, 0xed, 0xaa, 0x97, 0xa1, 0x1a, 0xbd, 0x9f, 0x87, 0x55, 0x5d, 0x83, + 0x09, 0xb0, 0x66, 0xf9, 0x92, 0x22, 0x73, 0x2e, 0xcc, 0xbf, 0x0c, 0x58, 0x9f, 0xc5, 0x84, 0xbc, + 0xbd, 0x2d, 0xe5, 0x85, 0x80, 0xbb, 0xaf, 0x98, 0x44, 0xfb, 0x07, 0xbc, 0xd0, 0x87, 0x6d, 0x47, + 0x87, 0x6d, 0x84, 0xa8, 0xa3, 0xc8, 0xff, 0x0c, 0x2f, 0x28, 0x04, 0xf1, 0xf7, 0xd5, 0x07, 0x63, + 0xe5, 0xff, 0x1e, 0x0c, 0xf3, 0x2b, 0x28, 0xb4, 0x51, 0x9d, 0xd5, 0xb7, 0xdf, 0x98, 0xd9, 0x85, + 0x75, 0x35, 0x72, 0x66, 0xa7, 0x5f, 0xf5, 0x61, 0x47, 0x11, 0x1e, 0x8f, 0x09, 0x5b, 0xb8, 0x23, + 0x8f, 0xc9, 0x29, 0x8f, 0xe6, 0x4f, 0x91, 0xde, 0xc5, 0x04, 0xfe, 0x78, 0xe6, 0x34, 0x7f, 0x31, + 0x00, 0x54, 0x26, 0x2d, 0xf0, 0x4f, 0x60, 0x3b, 0x4c, 0xa3, 0xba, 0x34, 0xe5, 0x8b, 0x59, 0xee, + 0xa0, 0xc6, 0x4e, 0xf9, 0x65, 0x12, 0xf2, 0x19, 0xe4, 0x38, 0x32, 0xe1, 0x7b, 0x5a, 0xda, 0xb5, + 0xc5, 0xb9, 0xa9, 0x65, 0x4d, 0x43, 0x18, 0xd5, 0x70, 0xf3, 0x21, 0xe4, 0x22, 0x0b, 0xd9, 0x81, + 0xad, 0x17, 0x1d, 0xda, 0x3f, 0xe8, 0x3f, 0x6d, 0x9d, 0xf4, 0x07, 0x96, 0x7d, 0xd0, 0xea, 0x1f, + 0x76, 0xda, 0xe5, 0x8c, 0xf9, 0x4f, 0x16, 0xca, 0xf1, 0x90, 0x9f, 0xc9, 0xf6, 0x53, 0xc8, 0x7b, + 0xbe, 0xb4, 0xb9, 0xd2, 0x8c, 0x96, 0xed, 0xf6, 0xfc, 0x0d, 0x11, 0x29, 0xaa, 0x97, 0xa1, 0x6b, + 0x9e, 0xfe, 0x26, 0x6d, 0x28, 0x49, 0x2d, 0xae, 0x88, 0x72, 0x2d, 0xda, 0x7b, 0xcb, 0x45, 0x1b, + 0xcd, 0x91, 0x0c, 0x5d, 0x97, 0x29, 0x45, 0x7e, 0x01, 0x45, 0x27, 0xec, 0xa3, 0xce, 0x11, 0x29, + 0xe2, 0x9d, 0x74, 0x8e, 0x44, 0xa7, 0x7b, 0x19, 0x5a, 0x70, 0x12, 0x8d, 0x6f, 0x43, 0x29, 0xd5, + 0xaa, 0x68, 0x22, 0x2d, 0x54, 0x91, 0xea, 0xaf, 0xaa, 0x02, 0x53, 0x0d, 0x7f, 0x02, 0x85, 0xb8, + 0x53, 0xe8, 0x54, 0x6e, 0x87, 0x29, 0x2a, 0x57, 0x11, 0xdf, 0xcb, 0x50, 0xc0, 0xf8, 0x2f, 0x71, + 0xfa, 0x9a, 0x7f, 0x64, 0xa1, 0xac, 0x26, 0x42, 0xf2, 0x55, 0x41, 0x5e, 0x85, 0xb7, 0xe4, 0xb2, + 0x5b, 0x9a, 0x7c, 0x90, 0x5e, 0xe2, 0xfa, 0x67, 0x4b, 0xf5, 0xc3, 0x1b, 0xa2, 0xf5, 0x15, 0xfc, + 0x1d, 0xdc, 0x59, 0xf6, 0xca, 0x21, 0x8f, 0xd2, 0x69, 0xae, 0x79, 0x09, 0x55, 0xaf, 0xb9, 0xb3, + 0xc9, 0xf7, 0xb0, 0x31, 0x77, 0xf9, 0x93, 0x77, 0x17, 0x0a, 0x5c, 0xf2, 0x6a, 0xa8, 0xbe, 0xf7, + 0x1f, 0xa8, 0xa8, 0xfc, 0xe6, 0x39, 0xdc, 0x8d, 0x37, 0x95, 0xaa, 0x7f, 0x00, 0xab, 0x47, 0xdc, + 0x57, 0x57, 0x31, 0xa9, 0xa7, 0x53, 0x2d, 0xce, 0xe4, 0xea, 0xee, 0x1c, 0x62, 0x4e, 0xfc, 0x0d, + 0xe3, 0x23, 0x63, 0xff, 0xd6, 0xb7, 0xd9, 0xe0, 0xe5, 0xcb, 0x5c, 0xf8, 0x7a, 0xfc, 0xf8, 0xdf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xb3, 0xe2, 0xc3, 0xb2, 0x8b, 0x0a, 0x00, 0x00, } type DRPCNodeGracefulExitClient interface { DRPCConn() drpc.Conn - // GetSatellitesList returns a list of satellites that the storagenode has not begun a graceful exit for. + // GetSatellitesList returns a list of satellites that the storagenode has not exited. GetNonExitingSatellites(ctx context.Context, in *GetNonExitingSatellitesRequest) (*GetNonExitingSatellitesResponse, error) - // StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. - StartExit(ctx context.Context, in *StartExitRequest) (*StartExitResponse, error) + // InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. + InitiateGracefulExit(ctx context.Context, in *InitiateGracefulExitRequest) (*ExitProgress, error) + // GetExitProgress returns graceful exit status on each satellite for a given storagenode. + GetExitProgress(ctx context.Context, in *GetExitProgressRequest) (*GetExitProgressResponse, error) } type drpcNodeGracefulExitClient struct { @@ -1084,9 +1128,18 @@ func (c *drpcNodeGracefulExitClient) GetNonExitingSatellites(ctx context.Context return out, nil } -func (c *drpcNodeGracefulExitClient) StartExit(ctx context.Context, in *StartExitRequest) (*StartExitResponse, error) { - out := new(StartExitResponse) - err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/StartExit", in, out) +func (c *drpcNodeGracefulExitClient) InitiateGracefulExit(ctx context.Context, in *InitiateGracefulExitRequest) (*ExitProgress, error) { + out := new(ExitProgress) + err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/InitiateGracefulExit", in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcNodeGracefulExitClient) GetExitProgress(ctx context.Context, in *GetExitProgressRequest) (*GetExitProgressResponse, error) { + out := new(GetExitProgressResponse) + err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/GetExitProgress", in, out) if err != nil { return nil, err } @@ -1094,15 +1147,17 @@ func (c *drpcNodeGracefulExitClient) StartExit(ctx context.Context, in *StartExi } type DRPCNodeGracefulExitServer interface { - // GetSatellitesList returns a list of satellites that the storagenode has not begun a graceful exit for. + // GetSatellitesList returns a list of satellites that the storagenode has not exited. GetNonExitingSatellites(context.Context, *GetNonExitingSatellitesRequest) (*GetNonExitingSatellitesResponse, error) - // StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. - StartExit(context.Context, *StartExitRequest) (*StartExitResponse, error) + // InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. + InitiateGracefulExit(context.Context, *InitiateGracefulExitRequest) (*ExitProgress, error) + // GetExitProgress returns graceful exit status on each satellite for a given storagenode. + GetExitProgress(context.Context, *GetExitProgressRequest) (*GetExitProgressResponse, error) } type DRPCNodeGracefulExitDescription struct{} -func (DRPCNodeGracefulExitDescription) NumMethods() int { return 2 } +func (DRPCNodeGracefulExitDescription) NumMethods() int { return 3 } func (DRPCNodeGracefulExitDescription) Method(n int) (string, drpc.Handler, interface{}, bool) { switch n { @@ -1116,14 +1171,23 @@ func (DRPCNodeGracefulExitDescription) Method(n int) (string, drpc.Handler, inte ) }, DRPCNodeGracefulExitServer.GetNonExitingSatellites, true case 1: - return "/gracefulexit.NodeGracefulExit/StartExit", + return "/gracefulexit.NodeGracefulExit/InitiateGracefulExit", func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCNodeGracefulExitServer). - StartExit( + InitiateGracefulExit( ctx, - in1.(*StartExitRequest), + in1.(*InitiateGracefulExitRequest), ) - }, DRPCNodeGracefulExitServer.StartExit, true + }, DRPCNodeGracefulExitServer.InitiateGracefulExit, true + case 2: + return "/gracefulexit.NodeGracefulExit/GetExitProgress", + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCNodeGracefulExitServer). + GetExitProgress( + ctx, + in1.(*GetExitProgressRequest), + ) + }, DRPCNodeGracefulExitServer.GetExitProgress, true default: return "", nil, nil, false } @@ -1149,16 +1213,32 @@ func (x *drpcNodeGracefulExitGetNonExitingSatellitesStream) SendAndClose(m *GetN return x.CloseSend() } -type DRPCNodeGracefulExit_StartExitStream interface { +type DRPCNodeGracefulExit_InitiateGracefulExitStream interface { drpc.Stream - SendAndClose(*StartExitResponse) error + SendAndClose(*ExitProgress) error } -type drpcNodeGracefulExitStartExitStream struct { +type drpcNodeGracefulExitInitiateGracefulExitStream struct { drpc.Stream } -func (x *drpcNodeGracefulExitStartExitStream) SendAndClose(m *StartExitResponse) error { +func (x *drpcNodeGracefulExitInitiateGracefulExitStream) SendAndClose(m *ExitProgress) error { + if err := x.MsgSend(m); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCNodeGracefulExit_GetExitProgressStream interface { + drpc.Stream + SendAndClose(*GetExitProgressResponse) error +} + +type drpcNodeGracefulExitGetExitProgressStream struct { + drpc.Stream +} + +func (x *drpcNodeGracefulExitGetExitProgressStream) SendAndClose(m *GetExitProgressResponse) error { if err := x.MsgSend(m); err != nil { return err } @@ -1275,10 +1355,12 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type NodeGracefulExitClient interface { - // GetSatellitesList returns a list of satellites that the storagenode has not begun a graceful exit for. + // GetSatellitesList returns a list of satellites that the storagenode has not exited. GetNonExitingSatellites(ctx context.Context, in *GetNonExitingSatellitesRequest, opts ...grpc.CallOption) (*GetNonExitingSatellitesResponse, error) - // StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. - StartExit(ctx context.Context, in *StartExitRequest, opts ...grpc.CallOption) (*StartExitResponse, error) + // InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. + InitiateGracefulExit(ctx context.Context, in *InitiateGracefulExitRequest, opts ...grpc.CallOption) (*ExitProgress, error) + // GetExitProgress returns graceful exit status on each satellite for a given storagenode. + GetExitProgress(ctx context.Context, in *GetExitProgressRequest, opts ...grpc.CallOption) (*GetExitProgressResponse, error) } type nodeGracefulExitClient struct { @@ -1298,9 +1380,18 @@ func (c *nodeGracefulExitClient) GetNonExitingSatellites(ctx context.Context, in return out, nil } -func (c *nodeGracefulExitClient) StartExit(ctx context.Context, in *StartExitRequest, opts ...grpc.CallOption) (*StartExitResponse, error) { - out := new(StartExitResponse) - err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/StartExit", in, out, opts...) +func (c *nodeGracefulExitClient) InitiateGracefulExit(ctx context.Context, in *InitiateGracefulExitRequest, opts ...grpc.CallOption) (*ExitProgress, error) { + out := new(ExitProgress) + err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/InitiateGracefulExit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeGracefulExitClient) GetExitProgress(ctx context.Context, in *GetExitProgressRequest, opts ...grpc.CallOption) (*GetExitProgressResponse, error) { + out := new(GetExitProgressResponse) + err := c.cc.Invoke(ctx, "/gracefulexit.NodeGracefulExit/GetExitProgress", in, out, opts...) if err != nil { return nil, err } @@ -1309,10 +1400,12 @@ func (c *nodeGracefulExitClient) StartExit(ctx context.Context, in *StartExitReq // NodeGracefulExitServer is the server API for NodeGracefulExit service. type NodeGracefulExitServer interface { - // GetSatellitesList returns a list of satellites that the storagenode has not begun a graceful exit for. + // GetSatellitesList returns a list of satellites that the storagenode has not exited. GetNonExitingSatellites(context.Context, *GetNonExitingSatellitesRequest) (*GetNonExitingSatellitesResponse, error) - // StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. - StartExit(context.Context, *StartExitRequest) (*StartExitResponse, error) + // InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. + InitiateGracefulExit(context.Context, *InitiateGracefulExitRequest) (*ExitProgress, error) + // GetExitProgress returns graceful exit status on each satellite for a given storagenode. + GetExitProgress(context.Context, *GetExitProgressRequest) (*GetExitProgressResponse, error) } func RegisterNodeGracefulExitServer(s *grpc.Server, srv NodeGracefulExitServer) { @@ -1337,20 +1430,38 @@ func _NodeGracefulExit_GetNonExitingSatellites_Handler(srv interface{}, ctx cont return interceptor(ctx, in, info, handler) } -func _NodeGracefulExit_StartExit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(StartExitRequest) +func _NodeGracefulExit_InitiateGracefulExit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitiateGracefulExitRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(NodeGracefulExitServer).StartExit(ctx, in) + return srv.(NodeGracefulExitServer).InitiateGracefulExit(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gracefulexit.NodeGracefulExit/StartExit", + FullMethod: "/gracefulexit.NodeGracefulExit/InitiateGracefulExit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(NodeGracefulExitServer).StartExit(ctx, req.(*StartExitRequest)) + return srv.(NodeGracefulExitServer).InitiateGracefulExit(ctx, req.(*InitiateGracefulExitRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeGracefulExit_GetExitProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExitProgressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeGracefulExitServer).GetExitProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gracefulexit.NodeGracefulExit/GetExitProgress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeGracefulExitServer).GetExitProgress(ctx, req.(*GetExitProgressRequest)) } return interceptor(ctx, in, info, handler) } @@ -1364,8 +1475,12 @@ var _NodeGracefulExit_serviceDesc = grpc.ServiceDesc{ Handler: _NodeGracefulExit_GetNonExitingSatellites_Handler, }, { - MethodName: "StartExit", - Handler: _NodeGracefulExit_StartExit_Handler, + MethodName: "InitiateGracefulExit", + Handler: _NodeGracefulExit_InitiateGracefulExit_Handler, + }, + { + MethodName: "GetExitProgress", + Handler: _NodeGracefulExit_GetExitProgress_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/pkg/pb/gracefulexit.proto b/pkg/pb/gracefulexit.proto index cf866aca5..b51b42456 100644 --- a/pkg/pb/gracefulexit.proto +++ b/pkg/pb/gracefulexit.proto @@ -12,37 +12,42 @@ package gracefulexit; // NodeGracefulExit is a private service on storagenodes service NodeGracefulExit { - // GetSatellitesList returns a list of satellites that the storagenode has not begun a graceful exit for. + // GetSatellitesList returns a list of satellites that the storagenode has not exited. rpc GetNonExitingSatellites(GetNonExitingSatellitesRequest) returns (GetNonExitingSatellitesResponse); - // StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. - rpc StartExit(StartExitRequest) returns (StartExitResponse); - + // InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. + rpc InitiateGracefulExit(InitiateGracefulExitRequest) returns (ExitProgress); + // GetExitProgress returns graceful exit status on each satellite for a given storagenode. + rpc GetExitProgress(GetExitProgressRequest) returns (GetExitProgressResponse); } message GetNonExitingSatellitesRequest{} -message StartExitRequest { - repeated bytes node_ids = 1 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; +message InitiateGracefulExitRequest { + bytes node_id = 1 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; } // NonExitingSatellite contains information that's needed for a storagenode to start graceful exit message NonExitingSatellite { - bytes node_id = 1 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; - string domain_name = 2; - double space_used = 3; + bytes node_id = 1 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; + string domain_name = 2; + double space_used = 3; } message GetNonExitingSatellitesResponse { - repeated NonExitingSatellite satellites = 1; + repeated NonExitingSatellite satellites = 1; } -// StartExitStatus indicates the result of graceful exit initialization from a storagenode -message StartExitStatus { - string domain_name = 1; - bool success = 2; +message GetExitProgressRequest {} + +message GetExitProgressResponse { + repeated ExitProgress progress = 1; } -message StartExitResponse { - repeated StartExitStatus statuses = 1; + +message ExitProgress { + string domain_name = 1; + bytes node_id = 2 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; + float percent_complete = 3; + bool successful = 4; } service SatelliteGracefulExit { @@ -81,7 +86,7 @@ message TransferPiece { bytes private_key = 2 [(gogoproto.customtype) = "PiecePrivateKey", (gogoproto.nullable) = false]; // addressed_order_limit contains the new piece id. - metainfo.AddressedOrderLimit addressed_order_limit =3; + metainfo.AddressedOrderLimit addressed_order_limit =3; } message DeletePiece { diff --git a/proto.lock b/proto.lock index 793f5461b..72120812c 100644 --- a/proto.lock +++ b/proto.lock @@ -881,13 +881,12 @@ "name": "GetNonExitingSatellitesRequest" }, { - "name": "StartExitRequest", + "name": "InitiateGracefulExitRequest", "fields": [ { "id": 1, - "name": "node_ids", + "name": "node_id", "type": "bytes", - "is_repeated": true, "options": [ { "name": "(gogoproto.customtype)", @@ -943,7 +942,21 @@ ] }, { - "name": "StartExitStatus", + "name": "GetExitProgressRequest" + }, + { + "name": "GetExitProgressResponse", + "fields": [ + { + "id": 1, + "name": "progress", + "type": "ExitProgress", + "is_repeated": true + } + ] + }, + { + "name": "ExitProgress", "fields": [ { "id": 1, @@ -952,19 +965,28 @@ }, { "id": 2, - "name": "success", - "type": "bool" - } - ] - }, - { - "name": "StartExitResponse", - "fields": [ + "name": "node_id", + "type": "bytes", + "options": [ + { + "name": "(gogoproto.customtype)", + "value": "NodeID" + }, + { + "name": "(gogoproto.nullable)", + "value": "false" + } + ] + }, { - "id": 1, - "name": "statuses", - "type": "StartExitStatus", - "is_repeated": true + "id": 3, + "name": "percent_complete", + "type": "float" + }, + { + "id": 4, + "name": "successful", + "type": "bool" } ] }, @@ -1172,9 +1194,14 @@ "out_type": "GetNonExitingSatellitesResponse" }, { - "name": "StartExit", - "in_type": "StartExitRequest", - "out_type": "StartExitResponse" + "name": "InitiateGracefulExit", + "in_type": "InitiateGracefulExitRequest", + "out_type": "ExitProgress" + }, + { + "name": "GetExitProgress", + "in_type": "GetExitProgressRequest", + "out_type": "GetExitProgressResponse" } ] }, diff --git a/storagenode/gracefulexit/endpoint.go b/storagenode/gracefulexit/endpoint.go index 6a4ce936a..cdfb0e09b 100644 --- a/storagenode/gracefulexit/endpoint.go +++ b/storagenode/gracefulexit/endpoint.go @@ -88,41 +88,71 @@ func (e *Endpoint) GetNonExitingSatellites(ctx context.Context, req *pb.GetNonEx }, nil } -// StartExit updates one or more satellites in the storagenode's database to be gracefully exiting. -func (e *Endpoint) StartExit(ctx context.Context, req *pb.StartExitRequest) (*pb.StartExitResponse, error) { - e.log.Debug("initialize graceful exit: StartExit", zap.Int("satellite count", len(req.NodeIds))) - // save satellites info into db - resp := &pb.StartExitResponse{} - for _, satelliteID := range req.NodeIds { - e.log.Debug("initialize graceful exit: StartExit", zap.String("satellite ID", satelliteID.String())) +// InitiateGracefulExit updates one or more satellites in the storagenode's database to be gracefully exiting. +func (e *Endpoint) InitiateGracefulExit(ctx context.Context, req *pb.InitiateGracefulExitRequest) (*pb.ExitProgress, error) { + e.log.Debug("initialize graceful exit: start", zap.String("satellite ID", req.NodeId.String())) - status := &pb.StartExitStatus{ - Success: false, - } - domain, err := e.trust.GetAddress(ctx, satelliteID) - if err != nil { - e.log.Debug("initialize graceful exit: StartExit", zap.Error(err)) - resp.Statuses = append(resp.Statuses, status) - continue - } - status.DomainName = domain - - // get space usage by satellites - spaceUsed, err := e.usageCache.SpaceUsedBySatellite(ctx, satelliteID) - if err != nil { - e.log.Debug("initialize graceful exit: StartExit", zap.Error(err)) - resp.Statuses = append(resp.Statuses, status) - continue - } - err = e.satellites.InitiateGracefulExit(ctx, satelliteID, time.Now().UTC(), spaceUsed) - if err != nil { - e.log.Debug("initialize graceful exit: StartExit", zap.Error(err)) - resp.Statuses = append(resp.Statuses, status) - continue - } - status.Success = true - resp.Statuses = append(resp.Statuses, status) + domain, err := e.trust.GetAddress(ctx, req.NodeId) + if err != nil { + e.log.Debug("initialize graceful exit: retrieve satellite address", zap.Error(err)) + return nil, errs.Wrap(err) } + // get space usage by satellites + spaceUsed, err := e.usageCache.SpaceUsedBySatellite(ctx, req.NodeId) + if err != nil { + e.log.Debug("initialize graceful exit: retrieve space used", zap.String("Satellite ID", req.NodeId.String()), zap.Error(err)) + return nil, errs.Wrap(err) + } + + err = e.satellites.InitiateGracefulExit(ctx, req.NodeId, time.Now().UTC(), spaceUsed) + if err != nil { + e.log.Debug("initialize graceful exit: save info into satellites table", zap.String("Satellite ID", req.NodeId.String()), zap.Error(err)) + return nil, errs.Wrap(err) + } + + return &pb.ExitProgress{ + DomainName: domain, + NodeId: req.NodeId, + PercentComplete: float32(0), + }, nil +} + +// GetExitProgress returns graceful exit progress on each satellite that a storagde node has started exiting. +func (e *Endpoint) GetExitProgress(ctx context.Context, req *pb.GetExitProgressRequest) (*pb.GetExitProgressResponse, error) { + exitProgress, err := e.satellites.ListGracefulExits(ctx) + if err != nil { + return nil, errs.Wrap(err) + } + + resp := &pb.GetExitProgressResponse{ + Progress: make([]*pb.ExitProgress, 0, len(exitProgress)), + } + for _, progress := range exitProgress { + domain, err := e.trust.GetAddress(ctx, progress.SatelliteID) + if err != nil { + e.log.Debug("graceful exit: get satellite domain name", zap.String("satelliteID", progress.SatelliteID.String()), zap.Error(err)) + continue + } + + var percentCompleted float32 + var hasCompleted bool + + if progress.StartingDiskUsage != 0 { + percentCompleted = (float32(progress.BytesDeleted) / float32(progress.StartingDiskUsage)) * 100 + } + if progress.CompletionReceipt != nil { + hasCompleted = true + } + + resp.Progress = append(resp.Progress, + &pb.ExitProgress{ + DomainName: domain, + NodeId: progress.SatelliteID, + PercentComplete: percentCompleted, + Successful: hasCompleted, + }, + ) + } return resp, nil } diff --git a/storagenode/gracefulexit/endpoint_test.go b/storagenode/gracefulexit/endpoint_test.go index 5057c5cfa..345572eed 100644 --- a/storagenode/gracefulexit/endpoint_test.go +++ b/storagenode/gracefulexit/endpoint_test.go @@ -12,7 +12,6 @@ import ( "storj.io/storj/internal/testcontext" "storj.io/storj/internal/testplanet" "storj.io/storj/pkg/pb" - "storj.io/storj/pkg/storj" ) func TestGetNonExitingSatellites(t *testing.T) { @@ -42,12 +41,11 @@ func TestGetNonExitingSatellites(t *testing.T) { } } -func TestStartExiting(t *testing.T) { +func TestInitiateGracefulExit(t *testing.T) { ctx := testcontext.New(t) defer ctx.Cleanup() totalSatelliteCount := 3 - const exitingSatelliteCount = 2 planet, err := testplanet.New(t, totalSatelliteCount, 1, 1) require.NoError(t, err) defer ctx.Check(planet.Shutdown) @@ -55,24 +53,48 @@ func TestStartExiting(t *testing.T) { planet.Start(ctx) storagenode := planet.StorageNodes[0] - exitingSatelliteIDs := []storj.NodeID{ - planet.Satellites[0].ID(), - planet.Satellites[1].ID(), - } - req := &pb.StartExitRequest{ - NodeIds: exitingSatelliteIDs, + exitingSatelliteID := planet.Satellites[0].ID() + + req := &pb.InitiateGracefulExitRequest{ + NodeId: exitingSatelliteID, } - resp, err := storagenode.GracefulExit.Endpoint.StartExit(ctx, req) + resp, err := storagenode.GracefulExit.Endpoint.InitiateGracefulExit(ctx, req) require.NoError(t, err) - for _, status := range resp.GetStatuses() { - require.True(t, status.GetSuccess()) - } + // check progress is 0 + require.EqualValues(t, 0, resp.GetPercentComplete()) + require.False(t, resp.GetSuccessful()) exitStatuses, err := storagenode.DB.Satellites().ListGracefulExits(ctx) require.NoError(t, err) - require.Len(t, exitStatuses, exitingSatelliteCount) - for _, status := range exitStatuses { - require.Contains(t, exitingSatelliteIDs, status.SatelliteID) - } + require.Len(t, exitStatuses, 1) + require.Equal(t, exitingSatelliteID, exitStatuses[0].SatelliteID) +} + +func TestGetExitProgress(t *testing.T) { + ctx := testcontext.New(t) + + totalSatelliteCount := 3 + planet, err := testplanet.New(t, totalSatelliteCount, 1, 1) + require.NoError(t, err) + defer ctx.Check(planet.Shutdown) + + planet.Start(ctx) + exitingSatellite := planet.Satellites[0] + storagenode := planet.StorageNodes[0] + + // start graceful exit + err = storagenode.DB.Satellites().InitiateGracefulExit(ctx, exitingSatellite.ID(), time.Now().UTC(), 100) + require.NoError(t, err) + err = storagenode.DB.Satellites().UpdateGracefulExit(ctx, exitingSatellite.ID(), 20) + require.NoError(t, err) + + // check graceful exit progress + resp, err := storagenode.GracefulExit.Endpoint.GetExitProgress(ctx, &pb.GetExitProgressRequest{}) + require.NoError(t, err) + require.Len(t, resp.GetProgress(), 1) + progress := resp.GetProgress()[0] + require.Equal(t, progress.GetDomainName(), exitingSatellite.Addr()) + require.Equal(t, progress.NodeId, exitingSatellite.ID()) + require.EqualValues(t, 20, progress.GetPercentComplete()) }