kubeadm: fix a bug where the RemoveMember function did not return the correct member list when the member to be removed did not exist

This commit is contained in:
SataQiu 2024-09-26 14:29:30 +08:00
parent f1ca46fbc8
commit 5ff073516e

View File

@ -347,18 +347,19 @@ func (c *Client) ListMembers() ([]Member, error) {
// RemoveMember notifies an etcd cluster to remove an existing member // RemoveMember notifies an etcd cluster to remove an existing member
func (c *Client) RemoveMember(id uint64) ([]Member, error) { func (c *Client) RemoveMember(id uint64) ([]Member, error) {
// Remove an existing member from the cluster cli, err := c.newEtcdClient(c.Endpoints)
var lastError error if err != nil {
var resp *clientv3.MemberRemoveResponse return nil, err
err := wait.PollUntilContextTimeout(context.Background(), constants.EtcdAPICallRetryInterval, constants.EtcdAPICallTimeout, }
true, func(_ context.Context) (bool, error) { defer func() { _ = cli.Close() }()
cli, err := c.newEtcdClient(c.Endpoints)
if err != nil {
lastError = err
return false, nil
}
defer func() { _ = cli.Close() }()
// Remove an existing member from the cluster
var (
lastError error
respMembers []*etcdserverpb.Member
)
err = wait.PollUntilContextTimeout(context.Background(), constants.EtcdAPICallRetryInterval, constants.EtcdAPICallTimeout,
true, func(_ context.Context) (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout) ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
defer cancel() defer cancel()
@ -378,16 +379,22 @@ func (c *Client) RemoveMember(id uint64) ([]Member, error) {
} }
if !found { if !found {
klog.V(5).Infof("Member %s was not found; assuming it was already removed", strconv.FormatUint(id, 16)) klog.V(5).Infof("Member %s was not found; assuming it was already removed", strconv.FormatUint(id, 16))
respMembers = listResp.Members
return true, nil return true, nil
} }
resp, err = cli.MemberRemove(ctx, id) resp, err := cli.MemberRemove(ctx, id)
if err == nil { if err == nil {
respMembers = resp.Members
return true, nil return true, nil
} }
if errors.Is(rpctypes.ErrMemberNotFound, err) { if errors.Is(rpctypes.ErrMemberNotFound, err) {
klog.V(5).Infof("Member was already removed, because member %s was not found", strconv.FormatUint(id, 16)) klog.V(5).Infof("Member was already removed, because member %s was not found", strconv.FormatUint(id, 16))
return true, nil listResp, err = cli.MemberList(ctx)
if err == nil {
respMembers = listResp.Members
return true, nil
}
} }
klog.V(5).Infof("Failed to remove etcd member: %v", err) klog.V(5).Infof("Failed to remove etcd member: %v", err)
lastError = err lastError = err
@ -399,11 +406,8 @@ func (c *Client) RemoveMember(id uint64) ([]Member, error) {
// Returns the updated list of etcd members // Returns the updated list of etcd members
ret := []Member{} ret := []Member{}
if resp != nil { for _, m := range respMembers {
for _, m := range resp.Members { ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]})
ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]})
}
} }
return ret, nil return ret, nil
@ -484,7 +488,6 @@ func (c *Client) addMember(name string, peerAddrs string, isLearner bool) ([]Mem
// call out to MemberList to fetch all the members before returning. // call out to MemberList to fetch all the members before returning.
if errors.Is(err, rpctypes.ErrPeerURLExist) { if errors.Is(err, rpctypes.ErrPeerURLExist) {
klog.V(5).Info("The peer URL for the added etcd member already exists. Fetching the existing etcd members") klog.V(5).Info("The peer URL for the added etcd member already exists. Fetching the existing etcd members")
var listResp *clientv3.MemberListResponse
listResp, err = cli.MemberList(ctx) listResp, err = cli.MemberList(ctx)
if err == nil { if err == nil {
respMembers = listResp.Members respMembers = listResp.Members