Browse Source

Fix admin GUI list ordering on refresh (#7782)

Sort lists of filers, volume servers, masters, and message brokers
by address to ensure consistent ordering on page refresh.

This fixes the non-deterministic ordering caused by iterating over
Go maps with range.

Fixes #7781
pull/7784/head
Chris Lu 5 days ago
committed by GitHub
parent
commit
93499cd944
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 17
      weed/admin/dash/admin_data.go
  2. 16
      weed/admin/dash/admin_server.go
  3. 5
      weed/admin/dash/volume_management.go

17
weed/admin/dash/admin_data.go

@ -109,13 +109,6 @@ func (s *AdminServer) GetAdminData(username string) (AdminData, error) {
glog.Errorf("Failed to get cluster volume servers: %v", err) glog.Errorf("Failed to get cluster volume servers: %v", err)
return AdminData{}, err return AdminData{}, err
} }
// Sort the servers so they show up in consistent order after each reload
sort.Slice(volumeServersData.VolumeServers, func(i, j int) bool {
s1Name := volumeServersData.VolumeServers[i].GetDisplayAddress()
s2Name := volumeServersData.VolumeServers[j].GetDisplayAddress()
return s1Name < s2Name
})
// Get master nodes status // Get master nodes status
masterNodes := s.getMasterNodesStatus() masterNodes := s.getMasterNodesStatus()
@ -265,6 +258,11 @@ func (s *AdminServer) getFilerNodesStatus() []FilerNode {
return []FilerNode{} return []FilerNode{}
} }
// Sort filer nodes by address for consistent ordering on page refresh
sort.Slice(filerNodes, func(i, j int) bool {
return filerNodes[i].Address < filerNodes[j].Address
})
return filerNodes return filerNodes
} }
@ -301,5 +299,10 @@ func (s *AdminServer) getMessageBrokerNodesStatus() []MessageBrokerNode {
return []MessageBrokerNode{} return []MessageBrokerNode{}
} }
// Sort message broker nodes by address for consistent ordering on page refresh
sort.Slice(messageBrokers, func(i, j int) bool {
return messageBrokers[i].Address < messageBrokers[j].Address
})
return messageBrokers return messageBrokers
} }

16
weed/admin/dash/admin_server.go

@ -5,6 +5,7 @@ import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"sort"
"strconv" "strconv"
"time" "time"
@ -720,6 +721,11 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) {
masters = append(masters, *masterInfo) masters = append(masters, *masterInfo)
} }
// Sort masters by address for consistent ordering on page refresh
sort.Slice(masters, func(i, j int) bool {
return masters[i].Address < masters[j].Address
})
// If no masters found at all, add the current master as fallback // If no masters found at all, add the current master as fallback
if len(masters) == 0 { if len(masters) == 0 {
currentMaster := s.masterClient.GetMaster(context.Background()) currentMaster := s.masterClient.GetMaster(context.Background())
@ -776,6 +782,11 @@ func (s *AdminServer) GetClusterFilers() (*ClusterFilersData, error) {
return nil, fmt.Errorf("failed to get filer nodes from master: %w", err) return nil, fmt.Errorf("failed to get filer nodes from master: %w", err)
} }
// Sort filers by address for consistent ordering on page refresh
sort.Slice(filers, func(i, j int) bool {
return filers[i].Address < filers[j].Address
})
return &ClusterFilersData{ return &ClusterFilersData{
Filers: filers, Filers: filers,
TotalFilers: len(filers), TotalFilers: len(filers),
@ -818,6 +829,11 @@ func (s *AdminServer) GetClusterBrokers() (*ClusterBrokersData, error) {
return nil, fmt.Errorf("failed to get broker nodes from master: %w", err) return nil, fmt.Errorf("failed to get broker nodes from master: %w", err)
} }
// Sort brokers by address for consistent ordering on page refresh
sort.Slice(brokers, func(i, j int) bool {
return brokers[i].Address < brokers[j].Address
})
return &ClusterBrokersData{ return &ClusterBrokersData{
Brokers: brokers, Brokers: brokers,
TotalBrokers: len(brokers), TotalBrokers: len(brokers),

5
weed/admin/dash/volume_management.go

@ -544,6 +544,11 @@ func (s *AdminServer) GetClusterVolumeServers() (*ClusterVolumeServersData, erro
volumeServers = append(volumeServers, *vs) volumeServers = append(volumeServers, *vs)
} }
// Sort volume servers by address for consistent ordering on page refresh
sort.Slice(volumeServers, func(i, j int) bool {
return volumeServers[i].GetDisplayAddress() < volumeServers[j].GetDisplayAddress()
})
var totalCapacity int64 var totalCapacity int64
var totalVolumes int var totalVolumes int
for _, vs := range volumeServers { for _, vs := range volumeServers {

Loading…
Cancel
Save