diff --git a/staging/src/k8s.io/apiserver/pkg/server/hooks.go b/staging/src/k8s.io/apiserver/pkg/server/hooks.go index 593e5b8a53c..d431eda869b 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/hooks.go +++ b/staging/src/k8s.io/apiserver/pkg/server/hooks.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "net/http" + "runtime/debug" "k8s.io/klog" @@ -58,6 +59,9 @@ type PostStartHookProvider interface { type postStartHookEntry struct { hook PostStartHookFunc + // originatingStack holds the stack that registered postStartHooks. This allows us to show a more helpful message + // for duplicate registration. + originatingStack string // done will be closed when the postHook is finished done chan struct{} @@ -85,8 +89,9 @@ func (s *GenericAPIServer) AddPostStartHook(name string, hook PostStartHookFunc) if s.postStartHooksCalled { return fmt.Errorf("unable to add %q because PostStartHooks have already been called", name) } - if _, exists := s.postStartHooks[name]; exists { - return fmt.Errorf("unable to add %q because it is already registered", name) + if postStartHook, exists := s.postStartHooks[name]; exists { + // this is programmer error, but it can be hard to debug + return fmt.Errorf("unable to add %q because it was already registered by: %s", name, postStartHook.originatingStack) } // done is closed when the poststarthook is finished. This is used by the health check to be able to indicate @@ -95,7 +100,7 @@ func (s *GenericAPIServer) AddPostStartHook(name string, hook PostStartHookFunc) if err := s.AddHealthzChecks(postStartHookHealthz{name: "poststarthook/" + name, done: done}); err != nil { return err } - s.postStartHooks[name] = postStartHookEntry{hook: hook, done: done} + s.postStartHooks[name] = postStartHookEntry{hook: hook, originatingStack: string(debug.Stack()), done: done} return nil }