aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-12-05 12:19:06 -0800
committerGitHub <noreply@github.com>2025-12-05 12:19:06 -0800
commit4cc6a2a4e58ac03ae79816b636bc8bbf5797b707 (patch)
tree67e118c3e34f2d257a78dcc48f4e1210bdfb0e81
parent5c1de633cb10fe87450c9a38e090c4d69b1242da (diff)
downloadseaweedfs-4cc6a2a4e58ac03ae79816b636bc8bbf5797b707.tar.xz
seaweedfs-4cc6a2a4e58ac03ae79816b636bc8bbf5797b707.zip
fix: Admin UI user creation fails before filer discovery (#7624) (#7625)
* fix: Admin UI user creation fails before filer discovery (#7624) The credential manager's filer address function was not configured quickly enough after admin server startup, causing 'filer address function not configured' errors when users tried to create users immediately. Changes: - Use exponential backoff (200ms -> 5s) instead of fixed 5s polling for faster filer discovery on startup - Improve error messages to be more user-friendly and actionable Fixes #7624 * Add more debug logging to help diagnose filer discovery issues * fix: Use dynamic filer address function to eliminate race condition Instead of using a goroutine to wait for filer discovery before setting the filer address function, we now set a dynamic function immediately that returns the current filer address whenever it's called. This eliminates the race condition where users could create users before the goroutine completed, and provides clearer error messages when no filer is available. The dynamic function is HA-aware - it automatically returns whatever filer is currently available, adapting to filer failovers.
-rw-r--r--weed/admin/dash/admin_server.go28
-rw-r--r--weed/credential/filer_etc/filer_etc_store.go4
2 files changed, 13 insertions, 19 deletions
diff --git a/weed/admin/dash/admin_server.go b/weed/admin/dash/admin_server.go
index 4ce357502..c499ca8fe 100644
--- a/weed/admin/dash/admin_server.go
+++ b/weed/admin/dash/admin_server.go
@@ -99,28 +99,22 @@ func NewAdminServer(masters string, templateFS http.FileSystem, dataDir string)
// Continue without credential manager - will fall back to legacy approach
} else {
server.credentialManager = credentialManager
+ glog.V(0).Infof("Credential manager initialized with store type: %s", credentialManager.GetStore().GetName())
- // For stores that need filer address function, set them
+ // For stores that need filer address function, configure them
if store := credentialManager.GetStore(); store != nil {
if filerFuncSetter, ok := store.(interface {
SetFilerAddressFunc(func() pb.ServerAddress, grpc.DialOption)
}); ok {
- // Set up a goroutine to configure filer address function once we discover filers
- go func() {
- for {
- filerAddr := server.GetFilerAddress()
- if filerAddr != "" {
- // Configure the function to dynamically return the current active filer (HA-aware)
- filerFuncSetter.SetFilerAddressFunc(func() pb.ServerAddress {
- return pb.ServerAddress(server.GetFilerAddress())
- }, server.grpcDialOption)
- glog.V(1).Infof("Set filer address function for credential manager: %s", filerAddr)
- break
- }
- glog.V(1).Infof("Waiting for filer discovery for credential manager...")
- time.Sleep(5 * time.Second)
- }
- }()
+ // Configure the filer address function to dynamically return the current active filer
+ // This function will be called each time credentials need to be loaded/saved,
+ // so it will automatically use whatever filer is currently available (HA-aware)
+ filerFuncSetter.SetFilerAddressFunc(func() pb.ServerAddress {
+ return pb.ServerAddress(server.GetFilerAddress())
+ }, server.grpcDialOption)
+ glog.V(0).Infof("Credential store configured with dynamic filer address function")
+ } else {
+ glog.V(0).Infof("Credential store %s does not support filer address function", store.GetName())
}
}
}
diff --git a/weed/credential/filer_etc/filer_etc_store.go b/weed/credential/filer_etc/filer_etc_store.go
index b181a55f0..e174b5ef4 100644
--- a/weed/credential/filer_etc/filer_etc_store.go
+++ b/weed/credential/filer_etc/filer_etc_store.go
@@ -58,7 +58,7 @@ func (store *FilerEtcStore) withFilerClient(fn func(client filer_pb.SeaweedFiler
store.mu.RLock()
if store.filerAddressFunc == nil {
store.mu.RUnlock()
- return fmt.Errorf("filer_etc: filer address function not configured")
+ return fmt.Errorf("filer_etc: filer not yet available - please wait for filer discovery to complete and try again")
}
filerAddress := store.filerAddressFunc()
@@ -66,7 +66,7 @@ func (store *FilerEtcStore) withFilerClient(fn func(client filer_pb.SeaweedFiler
store.mu.RUnlock()
if filerAddress == "" {
- return fmt.Errorf("filer_etc: filer address is empty")
+ return fmt.Errorf("filer_etc: no filer discovered yet - please ensure a filer is running and accessible")
}
// Use the pb.WithGrpcFilerClient helper similar to existing code