diff --git a/operator/cmd/legacy/deployment.go b/operator/cmd/legacy/deployment.go index 41a060b485..3f1bb23b20 100644 --- a/operator/cmd/legacy/deployment.go +++ b/operator/cmd/legacy/deployment.go @@ -8,7 +8,6 @@ import ( "fmt" "net/http" "net/http/pprof" - "os" "time" "go.uber.org/zap/zapcore" @@ -40,6 +39,7 @@ import ( retinaendpointcontroller "github.com/microsoft/retina/pkg/controllers/operator/retinaendpoint" "github.com/microsoft/retina/pkg/log" "github.com/microsoft/retina/pkg/telemetry" + "github.com/pkg/errors" ) var ( @@ -81,7 +81,7 @@ func NewOperator(metricsAddr, probeAddr, configFile string, enableLeaderElection } } -func (o *Operator) Start() { +func (o *Operator) Start() error { mainLogger = log.Logger().Named("main") mainLogger.Sugar().Infof("Starting legacy operator") @@ -93,8 +93,7 @@ func (o *Operator) Start() { var err error oconfig, err = config.GetConfig(o.configFile) if err != nil { - fmt.Printf("failed to load config with err %s", err.Error()) - os.Exit(1) + return errors.Wrap(err, "failed to load config") } mainLogger.Sugar().Infof("Operator configuration", zap.Any("configuration", oconfig)) @@ -103,15 +102,9 @@ func (o *Operator) Start() { oconfig.CaptureConfig.CaptureImageVersion = buildinfo.Version oconfig.CaptureConfig.CaptureImageVersionSource = captureUtils.VersionSourceOperatorImageVersion - if err != nil { - fmt.Printf("failed to load config with err %s", err.Error()) - os.Exit(1) - } - err = initLogging(oconfig, buildinfo.ApplicationInsightsID) if err != nil { - fmt.Printf("failed to initialize logging with err %s", err.Error()) - os.Exit(1) + return errors.Wrap(err, "failed to initialize logging") } ctrl.SetLogger(crzap.New(crzap.UseFlagOptions(opts), crzap.Encoder(zapcore.NewConsoleEncoder(log.EncoderConfig())))) @@ -138,15 +131,13 @@ func (o *Operator) Start() { // LeaderElectionReleaseOnCancel: true, }) if err != nil { - mainLogger.Error("Unable to start manager", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to start manager") } ctx := context.Background() clientset, err := apiextv1.NewForConfig(mgr.GetConfig()) if err != nil { - mainLogger.Error("Failed to get apiextension clientset", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "failed to get apiextension clientset") } if oconfig.InstallCRDs { @@ -155,8 +146,7 @@ func (o *Operator) Start() { var crds map[string]*v1.CustomResourceDefinition crds, err = deploy.InstallOrUpdateCRDs(ctx, oconfig.EnableRetinaEndpoint, clientset) if err != nil { - mainLogger.Error("unable to register CRDs", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to register CRDs") } for name := range crds { mainLogger.Info("CRD registered", zap.String("name", name)) @@ -165,8 +155,7 @@ func (o *Operator) Start() { apiserverURL, err := telemetry.GetK8SApiserverURLFromKubeConfig() if err != nil { - mainLogger.Error("Apiserver URL is cannot be found", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "apiserver URL is cannot be found") } var tel telemetry.Telemetry @@ -176,10 +165,14 @@ func (o *Operator) Start() { "version": buildinfo.Version, telemetry.PropertyApiserver: apiserverURL, } + + telemetry.InitAppInsights(buildinfo.ApplicationInsightsID, buildinfo.Version) + defer telemetry.ShutdownAppInsights() + defer telemetry.TrackPanic() + tel, err = telemetry.NewAppInsightsTelemetryClient("retina-operator", properties) if err != nil { - mainLogger.Error("failed to create telemetry client", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "failed to create telemetry client") } } else { mainLogger.Info("telemetry disabled", zap.String("apiserver", apiserverURL)) @@ -188,20 +181,17 @@ func (o *Operator) Start() { kubeClient, err := kubernetes.NewForConfig(mgr.GetConfig()) if err != nil { - mainLogger.Error("Failed to get clientset", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "failed to get clientset") } captureReconciler, err := captureController.NewCaptureReconciler( mgr.GetClient(), mgr.GetScheme(), kubeClient, oconfig.CaptureConfig, ) if err != nil { - mainLogger.Error("Unable to create capture reconciler", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to create capture reconciler") } if err = captureReconciler.SetupWithManager(mgr); err != nil { - mainLogger.Error("Unable to setup retina capture controller with manager", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to setup retina capture controller with manager") } ctrlCtx := ctrl.SetupSignalHandler() @@ -225,37 +215,34 @@ func (o *Operator) Start() { pc := podcontroller.New(mgr.GetClient(), mgr.GetScheme(), retinaendpointchannel) if err = (pc).SetupWithManager(mgr); err != nil { - mainLogger.Error("Unable to create controller", zap.String("controller", "podcontroller"), zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to create controller - podcontroller") } } } mc := metricsconfiguration.New(mgr.GetClient(), mgr.GetScheme()) if err = (mc).SetupWithManager(mgr); err != nil { - mainLogger.Error("Unable to create controller", zap.String("controller", "metricsconfiguration"), zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to create controller - metricsconfiguration") } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - mainLogger.Error("Unable to set up health check", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to set up health check") } if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - mainLogger.Error("Unable to set up ready check", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "unable to set up ready check") } mainLogger.Info("Starting manager") if err := mgr.Start(ctrlCtx); err != nil { - mainLogger.Error("Problem running manager", zap.Error(err)) - os.Exit(1) + return errors.Wrap(err, "problem running manager") } // start heartbeat goroutine for application insights go tel.Heartbeat(ctx, HeartbeatFrequency) + + return nil } func EnablePProf() { diff --git a/operator/cmd/root.go b/operator/cmd/root.go index f689f12909..9cbcfb3811 100644 --- a/operator/cmd/root.go +++ b/operator/cmd/root.go @@ -8,6 +8,7 @@ import ( "os" "github.com/microsoft/retina/operator/cmd/legacy" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -25,10 +26,14 @@ var ( Use: "retina-operator", Short: "Retina Operator", Long: "Start Retina Operator", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(_ *cobra.Command, _ []string) error { fmt.Println("Starting Retina Operator") d := legacy.NewOperator(metricsAddr, probeAddr, cfgFile, enableLeaderElection) - d.Start() + + if err := d.Start(); err != nil { + return errors.Wrap(err, "failed to start retina-operator") + } + return nil }, } )