@@ -28,10 +28,12 @@ import (
2828 "path/filepath"
2929 "strconv"
3030 "sync"
31+ "time"
3132
3233 "k8s.io/apimachinery/pkg/runtime"
3334 kscheme "k8s.io/client-go/kubernetes/scheme"
3435 "sigs.k8s.io/controller-runtime/pkg/certwatcher"
36+ "sigs.k8s.io/controller-runtime/pkg/healthz"
3537 "sigs.k8s.io/controller-runtime/pkg/runtime/inject"
3638 "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
3739)
@@ -87,6 +89,10 @@ type Server struct {
8789 // defaultingOnce ensures that the default fields are only ever set once.
8890 defaultingOnce sync.Once
8991
92+ // started is set to true immediately before the server is started
93+ // and thus can be used to check if the server has been started
94+ started bool
95+
9096 // mu protects access to the webhook map & setFields for Start, Register, etc
9197 mu sync.Mutex
9298}
@@ -272,6 +278,9 @@ func (s *Server) Start(ctx context.Context) error {
272278 close (idleConnsClosed )
273279 }()
274280
281+ s .mu .Lock ()
282+ s .started = true
283+ s .mu .Unlock ()
275284 if err := srv .Serve (listener ); err != nil && err != http .ErrServerClosed {
276285 return err
277286 }
@@ -280,6 +289,27 @@ func (s *Server) Start(ctx context.Context) error {
280289 return nil
281290}
282291
292+ // StartedChecker returns an healthz.Checker which is healthy after the
293+ // server has been started.
294+ func (s * Server ) StartedChecker () healthz.Checker {
295+ return func (req * http.Request ) error {
296+ s .mu .Lock ()
297+ defer s .mu .Unlock ()
298+
299+ if ! s .started {
300+ return fmt .Errorf ("webhook server has not been started yet" )
301+ }
302+
303+ conn , err := net .DialTimeout ("tcp" , net .JoinHostPort (s .Host , strconv .Itoa (s .Port )), 10 * time .Second )
304+ if err != nil {
305+ return fmt .Errorf ("webhook server is not reachable: %v" , err )
306+ }
307+ conn .Close ()
308+
309+ return nil
310+ }
311+ }
312+
283313// InjectFunc injects the field setter into the server.
284314func (s * Server ) InjectFunc (f inject.Func ) error {
285315 s .setFields = f
0 commit comments