// Copyright (C) 2019 Storj Labs, Inc. // See LICENSE for copying information. syntax = "proto3"; option go_package = "pb"; import "gogo.proto"; import "metainfo.proto"; import "orders.proto"; package gracefulexit; // NodeGracefulExit is a private service on storagenodes service NodeGracefulExit { // GetSatellitesList returns a list of satellites that the storagenode has not exited. rpc GetNonExitingSatellites(GetNonExitingSatellitesRequest) returns (GetNonExitingSatellitesResponse); // 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 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; } message GetNonExitingSatellitesResponse { repeated NonExitingSatellite satellites = 1; } message GetExitProgressRequest {} message GetExitProgressResponse { repeated ExitProgress progress = 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 { // Process is called by storage nodes to initiate the graceful exit, get pieces to transfer, and receive exit status. rpc Process(stream StorageNodeMessage) returns (stream SatelliteMessage); } message TransferSucceeded { orders.OrderLimit original_order_limit = 1; orders.PieceHash original_piece_hash = 2; orders.PieceHash replacement_piece_hash = 3; bytes original_piece_id = 4 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; } message TransferFailed { bytes original_piece_id = 1 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; enum Error { NOT_FOUND = 0; STORAGE_NODE_UNAVAILABLE = 1; HASH_VERIFICATION = 2; UNKNOWN = 10; } Error error = 2; } message StorageNodeMessage { oneof Message { TransferSucceeded succeeded = 1; TransferFailed failed = 2; } } message NotReady {} message TransferPiece { bytes original_piece_id = 1 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; bytes private_key = 2 [(gogoproto.customtype) = "PiecePrivateKey", (gogoproto.nullable) = false]; // addressed_order_limit contains the new piece id. metainfo.AddressedOrderLimit addressed_order_limit =3; } message DeletePiece { bytes original_piece_id = 1 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; } message ExitCompleted { // when everything is completed bytes exit_complete_signature = 1; } message ExitFailed { enum Reason { VERIFICATION_FAILED = 0; } // on failure bytes exit_failure_signature = 1; Reason reason = 2; } message SatelliteMessage { oneof Message { NotReady not_ready = 1; TransferPiece transfer_piece = 2; DeletePiece delete_piece = 3; ExitCompleted exit_completed = 4; ExitFailed exit_failed = 5; } }