in cmd/operator/main.go [108:207]
func main() {
//parse then parameters from console.
f := conf.ParseFlags()
//parse env
envs := conf.ParseEnvs()
//print version infos.
printVersionInfos(f.PrintVar)
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&f.Opts)))
webhookServer := webhook.NewServer(webhook.Options{
Port: 9443,
})
defaultNamespaces := map[string]cache.Config{}
if f.Namespace != "" {
defaultNamespaces[f.Namespace] = cache.Config{}
}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
BindAddress: f.MetricsAddr,
},
HealthProbeBindAddress: f.ProbeAddr,
Cache: cache.Options{
DefaultNamespaces: defaultNamespaces,
},
WebhookServer: webhookServer,
LeaderElection: f.EnableLeaderElection,
LeaderElectionID: "e1370669.selectdb.com",
//if one reconcile failed, others will not be affected.
Controller: controllerconfig.Controller{
RecoverPanic: pointer.Bool(true),
},
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
// speeds up voluntary leader transitions as the new leader don't have to wait
// LeaseDuration time first.
//
// In the default scaffold provided, the program ends immediately after
// the manager stops, so would be fine to enable this option. However,
// if you are doing or is intended to do any operation such as perform cleanups
// after the manager stops then its usage might be unsafe.
// LeaderElectionReleaseOnCancel: true,
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
options := conf.NewControllerOptions(envs)
//initial all controllers
for _, c := range controller.Controllers {
c.Init(mgr, options)
}
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")
os.Exit(1)
}
// enable webhook, check webhook certificate
if options.EnableWebHook {
//wait for the secret have
interval := time.Second * 1
timeout := time.Second * 30
fctx := context.Background()
err = wait.PollUntilContextTimeout(fctx, interval, timeout, true, func(ctx context.Context) (bool, error) {
srv := webhookServer.(*webhook.DefaultServer)
//when default server start in mgr.start, the option will add default values. so, certDir if not set, default values will be "<temp-dir>/k8s-webhook-server/serving-certs."
certDir := srv.Options.CertDir
keyPath := filepath.Join(certDir, certificate.TLsCertName)
_, err := os.Stat(keyPath)
if os.IsNotExist(err) {
setupLog.Info("webhook certificate have not present waiting kubelet update", "file", keyPath)
return false, nil
} else if err != nil {
setupLog.Info("check webhook certificate ", "path", keyPath, "err=", err.Error())
return false, err
}
setupLog.Info("webhook certificate file exit.")
return true, nil
})
if err != nil {
setupLog.Error(err, "check webhook certificate failed")
os.Exit(1)
}
}
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}