From 3f557b73c8d29eb28b6897ea894c49128aad011f Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 11 Nov 2026 15:22:29 -0800 Subject: [PATCH] admin: show the right master ports when -port.grpc is not port+10000 (#12570) * admin: take master HTTP ports from raft member names The masters page and dashboard turned each raft member's gRPC address into an HTTP address by subtracting 10000 from the port, so masters with a custom -port.grpc showed wrong or negative ports. Raft members are named after their master address, which carries the HTTP port; use it and keep the old derivation only for names that are not addresses. Co-Authored-By: Claude Opus 5.5 * admin: test raft member address mapping Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 --- weed/admin/dash/admin_data.go | 14 +++++++++++++- weed/admin/dash/admin_data_test.go | 28 ++++++++++++++++++++++++++++ weed/admin/dash/admin_server.go | 3 +-- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 weed/admin/dash/admin_data_test.go diff --git a/weed/admin/dash/admin_data.go b/weed/admin/dash/admin_data.go index 499de6e154..770c58d23d 100644 --- a/weed/admin/dash/admin_data.go +++ b/weed/admin/dash/admin_data.go @@ -12,6 +12,7 @@ import ( "github.com/seaweedfs/seaweedfs/weed/iam" "github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb/master_pb" + "github.com/seaweedfs/seaweedfs/weed/util" ) // Access key status constants @@ -290,6 +291,17 @@ func (s *AdminServer) ShowOverview(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, topology) } +// raftMasterHttpAddress returns a raft member's HTTP address. Members are +// named after their master address, while the raft address only carries the +// gRPC port, which is not always the HTTP port + 10000. +func raftMasterHttpAddress(server *master_pb.RaftListClusterServersResponse_ClusterServers) string { + httpAddress := pb.ServerAddress(server.Id).ToHttpAddress() + if _, port, err := util.ParseHostPort(httpAddress); err == nil && port > 0 && port < 65536 { + return httpAddress + } + return pb.GrpcAddressToServerAddress(server.Address) +} + // getMasterNodesStatus returns the full set of master nodes in the cluster. // It prefers the authoritative raft membership (RaftListClusterServers) and // falls back to the currently-connected master if the raft call fails, so the @@ -313,7 +325,7 @@ func (s *AdminServer) getMasterNodesStatus() []MasterNode { glog.Warningf("skip master with invalid raft address %q: %v", server.Address, splitErr) continue } - httpAddress := pb.GrpcAddressToServerAddress(server.Address) + httpAddress := raftMasterHttpAddress(server) if httpAddress == "" { glog.Warningf("skip master with invalid raft address %q", server.Address) continue diff --git a/weed/admin/dash/admin_data_test.go b/weed/admin/dash/admin_data_test.go new file mode 100644 index 0000000000..53a6bd8939 --- /dev/null +++ b/weed/admin/dash/admin_data_test.go @@ -0,0 +1,28 @@ +package dash + +import ( + "testing" + + "github.com/seaweedfs/seaweedfs/weed/pb/master_pb" +) + +func TestRaftMasterHttpAddress(t *testing.T) { + tests := []struct { + name, id, address, want string + }{ + {"goraft names members by full address", "127.101.0.1:11111.11112", "127.101.0.1:11112", "127.101.0.1:11111"}, + {"hashicorp names members by http address", "127.102.0.1:2222", "127.102.0.1:3333", "127.102.0.1:2222"}, + {"default ports", "10.0.0.1:9333", "10.0.0.1:19333", "10.0.0.1:9333"}, + {"ipv6", "[::1]:2222.3333", "[::1]:3333", "[::1]:2222"}, + {"id that is not an address", "master-a", "10.0.0.2:19333", "10.0.0.2:9333"}, + {"id without a valid port", "10.0.0.3:0", "10.0.0.3:19334", "10.0.0.3:9334"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := raftMasterHttpAddress(&master_pb.RaftListClusterServersResponse_ClusterServers{Id: tt.id, Address: tt.address}) + if got != tt.want { + t.Errorf("raftMasterHttpAddress(%q, %q) = %q, want %q", tt.id, tt.address, got, tt.want) + } + }) + } +} diff --git a/weed/admin/dash/admin_server.go b/weed/admin/dash/admin_server.go index afdb28b39e..c79263ca24 100644 --- a/weed/admin/dash/admin_server.go +++ b/weed/admin/dash/admin_server.go @@ -1371,8 +1371,7 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) { // Process each raft server for _, server := range resp.ClusterServers { - // Raft stores gRPC addresses, convert to HTTP address - httpAddress := pb.GrpcAddressToServerAddress(server.Address) + httpAddress := raftMasterHttpAddress(server) if httpAddress == "" { continue }