-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: expose Leadership Transfer API to clients #8153
Conversation
@@ -59,6 +59,7 @@ var ( | |||
ErrGRPCInvalidAuthMgmt = grpc.Errorf(codes.InvalidArgument, "etcdserver: invalid auth management") | |||
|
|||
ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") | |||
ErrGRPCNotLeader = grpc.Errorf(codes.Unavailable, "etcdserver: not a leader") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/not a leader/not leader
etcdserver/errors.go
Outdated
@@ -29,6 +29,7 @@ var ( | |||
ErrTimeoutLeaderTransfer = errors.New("etcdserver: request timed out, leader transfer took too long") | |||
ErrNotEnoughStartedMembers = errors.New("etcdserver: re-configuration failed due to not enough started members") | |||
ErrNoLeader = errors.New("etcdserver: no leader") | |||
ErrNotLeader = errors.New("etcdserver: not a leader") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/not a leader/not leader/
etcdserver/etcdserverpb/rpc.proto
Outdated
@@ -785,6 +793,15 @@ message DefragmentResponse { | |||
ResponseHeader header = 1; | |||
} | |||
|
|||
message TransferLeadershipRequest { | |||
// transferee is the target node ID for leadership transfer. | |||
uint64 transferee = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// target is the node ID for the new leader.
uint64 target = 1;
?
etcdserver/etcdserverpb/rpc.proto
Outdated
@@ -191,6 +191,14 @@ service Maintenance { | |||
body: "*" | |||
}; | |||
} | |||
|
|||
// TransferLeadership requests current leader node to transfer its leadership to transferee. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MoveLeader
? TransferLeadership
is kind of wordy
integration/v3_leadership_test.go
Outdated
} | ||
} | ||
|
||
// TestTransferLeaderServiceNonLeader ensures that request to non-leader fail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensures followers return an error for transferring leadership.
etcdserver/api/v3rpc/maintenance.go
Outdated
@@ -147,6 +153,20 @@ func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) ( | |||
return resp, nil | |||
} | |||
|
|||
func (ms *maintenanceServer) TransferLeadership(ctx context.Context, tr *pb.TransferLeadershipRequest) (*pb.TransferLeadershipResponse, error) { | |||
if ms.rg.ID() != ms.rg.Leader() { | |||
return nil, togRPCError(etcdserver.ErrNotLeader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return nil, ErrGRPCNotLeader
?
etcdserver/api/v3rpc/maintenance.go
Outdated
|
||
plog.Noticef("starting to transfer leadership from %s to %s", ms.rg.ID(), types.ID(tr.Transferee)) | ||
if err := ms.lt.TransferLeader(ctx, uint64(ms.rg.Leader()), tr.Transferee); err != nil { | ||
return nil, togRPCError(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there already a warning or error message if there's a failure to transfer? the 'starting' message should probably be matched with some completion message even if it fails
ExitWithError(ExitError, cerr) | ||
return | ||
} | ||
fmt.Printf("leader transferred to %s\n", types.ID(transferee)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should use the printer/display stuff since it maps directly to an RPC
cancel() | ||
if cerr != nil { | ||
ExitWithError(ExitError, cerr) | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not needed since ExitWithError never returns
if len(args) != 1 { | ||
ExitWithError(ExitBadArgs, fmt.Errorf("transfer-leadership command needs 1 argument")) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this figure out the current leader instead of expecting the user to supply the leader's endpoint?
9a7a9f4
to
27a260c
Compare
9f1a8d4
to
976b49f
Compare
etcdctl/ctlv3/command/printer.go
Outdated
@@ -43,6 +43,7 @@ type printer interface { | |||
MemberList(v3.MemberListResponse) | |||
|
|||
EndpointStatus([]epStatus) | |||
MoveLeader(leader, target uint64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is an RPC, it should probably be MoveLeader(leader, target uint64, v3.MoveLeaderResponse)
and support printerRPC
DialTimeout: 3 * time.Second, | ||
}) | ||
if err != nil { | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra err check?
|
||
if resp.Header.GetMemberId() == resp.Leader { | ||
leaderCli = cli | ||
leaderID = resp.Leader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break
?
} | ||
} | ||
resp, err := cli.Status(ctx, ep) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra err check?
etcdctl/README.md
Outdated
@@ -805,6 +805,29 @@ Prints a line of JSON encoding the database hash, revision, total keys, and size | |||
+----------+----------+------------+------------+ | |||
``` | |||
|
|||
### MOVE-LEADER \<hexadecimal-transferee-id\> | |||
|
|||
MOVE-LEADER manually transfers a leadership to another node in the cluster. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MOVE-LEADER transfers leadership from the leader to another member in the cluster.
etcdserver/etcdserverpb/rpc.proto
Outdated
@@ -787,6 +795,15 @@ message DefragmentResponse { | |||
ResponseHeader header = 1; | |||
} | |||
|
|||
message MoveLeaderRequest { | |||
// target is the node ID for the new leader. | |||
uint64 target = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
judging by the rest of rpc.proto, this probably needs ID
in the name to be consistent with other rpc message naming-- something like targetID, memberID, or ID
// NewMoveLeaderCommand returns the cobra command for "move-leader". | ||
func NewMoveLeaderCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "move-leader <transferee>", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transferee-member-id?
func NewMoveLeaderCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "move-leader <transferee>", | ||
Short: "Transfers leadership.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transfers leadership to another etcd cluster member.
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
976b49f
to
d428958
Compare
Fix #7584.