You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							92 lines
						
					
					
						
							2.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							92 lines
						
					
					
						
							2.8 KiB
						
					
					
				
								package weed_server
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"context"
							 | 
						|
									"fmt"
							 | 
						|
								
							 | 
						|
									"github.com/hashicorp/raft"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/cluster"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								func (ms *MasterServer) RaftListClusterServers(ctx context.Context, req *master_pb.RaftListClusterServersRequest) (*master_pb.RaftListClusterServersResponse, error) {
							 | 
						|
									resp := &master_pb.RaftListClusterServersResponse{}
							 | 
						|
								
							 | 
						|
									ms.Topo.RaftServerAccessLock.RLock()
							 | 
						|
									if ms.Topo.HashicorpRaft == nil {
							 | 
						|
										ms.Topo.RaftServerAccessLock.RUnlock()
							 | 
						|
										return resp, nil
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									servers := ms.Topo.HashicorpRaft.GetConfiguration().Configuration().Servers
							 | 
						|
									_, leaderId := ms.Topo.HashicorpRaft.LeaderWithID()
							 | 
						|
									ms.Topo.RaftServerAccessLock.RUnlock()
							 | 
						|
								
							 | 
						|
									for _, server := range servers {
							 | 
						|
										resp.ClusterServers = append(resp.ClusterServers, &master_pb.RaftListClusterServersResponse_ClusterServers{
							 | 
						|
											Id:       string(server.ID),
							 | 
						|
											Address:  string(server.Address),
							 | 
						|
											Suffrage: server.Suffrage.String(),
							 | 
						|
											IsLeader: server.ID == leaderId,
							 | 
						|
										})
							 | 
						|
									}
							 | 
						|
									return resp, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (ms *MasterServer) RaftAddServer(ctx context.Context, req *master_pb.RaftAddServerRequest) (*master_pb.RaftAddServerResponse, error) {
							 | 
						|
									resp := &master_pb.RaftAddServerResponse{}
							 | 
						|
								
							 | 
						|
									ms.Topo.RaftServerAccessLock.RLock()
							 | 
						|
									defer ms.Topo.RaftServerAccessLock.RUnlock()
							 | 
						|
								
							 | 
						|
									if ms.Topo.HashicorpRaft == nil {
							 | 
						|
										return resp, nil
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if ms.Topo.HashicorpRaft.State() != raft.Leader {
							 | 
						|
										return nil, fmt.Errorf("raft add server %s failed: %s is no current leader", req.Id, ms.Topo.HashicorpRaft.String())
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									var idxFuture raft.IndexFuture
							 | 
						|
									if req.Voter {
							 | 
						|
										idxFuture = ms.Topo.HashicorpRaft.AddVoter(raft.ServerID(req.Id), raft.ServerAddress(req.Address), 0, 0)
							 | 
						|
									} else {
							 | 
						|
										idxFuture = ms.Topo.HashicorpRaft.AddNonvoter(raft.ServerID(req.Id), raft.ServerAddress(req.Address), 0, 0)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if err := idxFuture.Error(); err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
									return resp, nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (ms *MasterServer) RaftRemoveServer(ctx context.Context, req *master_pb.RaftRemoveServerRequest) (*master_pb.RaftRemoveServerResponse, error) {
							 | 
						|
									resp := &master_pb.RaftRemoveServerResponse{}
							 | 
						|
								
							 | 
						|
									ms.Topo.RaftServerAccessLock.RLock()
							 | 
						|
									defer ms.Topo.RaftServerAccessLock.RUnlock()
							 | 
						|
								
							 | 
						|
									if ms.Topo.HashicorpRaft == nil {
							 | 
						|
										return resp, nil
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if ms.Topo.HashicorpRaft.State() != raft.Leader {
							 | 
						|
										return nil, fmt.Errorf("raft remove server %s failed: %s is no current leader", req.Id, ms.Topo.HashicorpRaft.String())
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if !req.Force {
							 | 
						|
										ms.clientChansLock.RLock()
							 | 
						|
										_, ok := ms.clientChans[fmt.Sprintf("%s@%s", cluster.MasterType, req.Id)]
							 | 
						|
										ms.clientChansLock.RUnlock()
							 | 
						|
										if ok {
							 | 
						|
											return resp, fmt.Errorf("raft remove server %s failed: client connection to master exists", req.Id)
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									idxFuture := ms.Topo.HashicorpRaft.RemoveServer(raft.ServerID(req.Id), 0, 0)
							 | 
						|
									if err := idxFuture.Error(); err != nil {
							 | 
						|
										return nil, err
							 | 
						|
									}
							 | 
						|
									return resp, nil
							 | 
						|
								}
							 |