diff --git a/cmd/kube-httpcache/internal/flags.go b/cmd/kube-httpcache/internal/flags.go index d6e2f18..05aa56e 100644 --- a/cmd/kube-httpcache/internal/flags.go +++ b/cmd/kube-httpcache/internal/flags.go @@ -55,6 +55,8 @@ type KubeHTTPProxyFlags struct { VCLTemplate string VCLTemplatePoll bool WorkingDir string + FrontendInitTimeout time.Duration + BackendInitTimeout time.Duration } Readiness struct { Enable bool @@ -107,6 +109,10 @@ func (f *KubeHTTPProxyFlags) Parse() error { flag.StringVar(&f.Varnish.AdditionalParameters, "varnish-additional-parameters", "", "Additional Varnish start parameters (-p, seperated by comma), like 'ban_dups=on,cli_timeout=30'") flag.BoolVar(&f.Varnish.VCLTemplatePoll, "varnish-vcl-template-poll", false, "poll for file changes instead of using inotify (useful on some network filesystems)") flag.StringVar(&f.Varnish.WorkingDir, "varnish-working-dir", "", "varnish working directory (-n)") + flag.DurationVar(&f.Varnish.FrontendInitTimeout, "varnish-frontend-init-timeout", time.Duration(0), + "timeout for initial frontend configuration to be discovered. The default 0s means wait indefinitely. When timeout is reached, the controller will continue with an empty list of front-ends") + flag.DurationVar(&f.Varnish.BackendInitTimeout, "varnish-backend-init-timeout", time.Duration(0), + "timeout for initial backend configuration to be discovered. The default 0s means wait indefinitely. When timeout is reached, the controller will continue with an empty list of back-ends") // present for BC only; no effect until #36 [1] has resolved // [1]: https://github.com/mittwald/kube-httpcache/issues/36 diff --git a/cmd/kube-httpcache/main.go b/cmd/kube-httpcache/main.go index a9e1262..42f453d 100644 --- a/cmd/kube-httpcache/main.go +++ b/cmd/kube-httpcache/main.go @@ -133,6 +133,8 @@ func main() { templateUpdates, varnishSignaller, opts.Varnish.VCLTemplate, + opts.Varnish.FrontendInitTimeout, + opts.Varnish.BackendInitTimeout, ) if err != nil { panic(err) diff --git a/pkg/controller/run.go b/pkg/controller/run.go index 8d01dd2..9df310d 100644 --- a/pkg/controller/run.go +++ b/pkg/controller/run.go @@ -6,17 +6,41 @@ import ( "os" "os/exec" "strings" + "time" "github.com/golang/glog" "github.com/mittwald/kube-httpcache/pkg/watcher" ) +func (v *VarnishController) waitForUpdate(updatesChan chan *watcher.EndpointConfig, timeout time.Duration) (*watcher.EndpointConfig, error) { + var cancel context.CancelFunc + var ctx context.Context + + ctx = context.Background() + + if timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, timeout) + defer cancel() + } + + select { + case u := <-updatesChan: + return u, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + func (v *VarnishController) Run(ctx context.Context) error { glog.Infof("waiting for initial configuration before starting Varnish") v.frontend = watcher.NewEndpointConfig() if v.frontendUpdates != nil { - v.frontend = <-v.frontendUpdates + if frontend, err := v.waitForUpdate(v.frontendUpdates, v.frontendInitTimeout); err == nil { + v.frontend = frontend + } else { + glog.Info("timeout while waiting for initial frontend configuration: %s", err.Error()) + } if v.varnishSignaller != nil { v.varnishSignaller.SetEndpoints(v.frontend) } @@ -24,7 +48,11 @@ func (v *VarnishController) Run(ctx context.Context) error { v.backend = watcher.NewEndpointConfig() if v.backendUpdates != nil { - v.backend = <-v.backendUpdates + if backend, err := v.waitForUpdate(v.backendUpdates, v.backendInitTimeout); err == nil { + v.backend = backend + } else { + glog.Info("timeout while waiting for initial backend configuration: %s", err.Error()) + } } target, err := os.Create(v.configFile) diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 2297394..c988730 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -1,11 +1,13 @@ package controller import ( - "github.com/golang/glog" "io" "os" "strings" "text/template" + "time" + + "github.com/golang/glog" "github.com/mittwald/kube-httpcache/pkg/signaller" "github.com/mittwald/kube-httpcache/pkg/watcher" @@ -32,16 +34,17 @@ type VarnishController struct { vclTemplate *template.Template // md5 hash of unparsed template - vclTemplateHash string - vclTemplateUpdates chan []byte - frontendUpdates chan *watcher.EndpointConfig - frontend *watcher.EndpointConfig - backendUpdates chan *watcher.EndpointConfig - backend *watcher.EndpointConfig - varnishSignaller *signaller.Signaller - configFile string - localAdminAddr string - currentVCLName string + vclTemplateHash string + vclTemplateUpdates chan []byte + frontendUpdates chan *watcher.EndpointConfig + frontendInitTimeout time.Duration + backendInitTimeout time.Duration + frontend *watcher.EndpointConfig + backendUpdates chan *watcher.EndpointConfig + backend *watcher.EndpointConfig + varnishSignaller *signaller.Signaller + configFile string + currentVCLName string } func NewVarnishController( @@ -59,6 +62,8 @@ func NewVarnishController( templateUpdates chan []byte, varnishSignaller *signaller.Signaller, vclTemplateFile string, + frontendInitTimeout time.Duration, + backendInitTimeout time.Duration, ) (*VarnishController, error) { contents, err := os.ReadFile(vclTemplateFile) if err != nil { @@ -80,6 +85,8 @@ func NewVarnishController( backendUpdates: backendUpdates, varnishSignaller: varnishSignaller, configFile: "/tmp/vcl", + frontendInitTimeout: frontendInitTimeout, + backendInitTimeout: backendInitTimeout, } err = v.setTemplate(contents) if err != nil {