package app import ( "context" "fmt" "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/cmd/controller/app/options" "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/cmd/util" "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/controller" logf "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/logs" "golang.org/x/sync/errgroup" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/utils/clock" ) func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) error { rootCtx, cancelContext := context.WithCancel(util.ContextWithStopCh(context.Background(), stopCh)) defer cancelContext() rootCtx = logf.NewContext(rootCtx, logf.Log, "controller") log := logf.FromContext(rootCtx) g, rootCtx := errgroup.WithContext(rootCtx) ctxFactory, err := buildControllerContextFactory(rootCtx, opts) if err != nil { return err } // Build the base controller context for the cert-manager controller manager // used here. ctx, err := ctxFactory.Build() if err != nil { return err } enabledControllers := opts.EnabledControllers() logf.Log.V(logf.DebugLevel).Info(fmt.Sprintf("enabled controllers: %s", enabledControllers)) //TODO: Start metrics server //TODO: Start profiler //TODO: Start leader elect for n, fn := range controller.Known() { log := log.WithValues("controller", n) // only run a controller if it is been enabled if !enabledControllers.Has(n) { log.V(logf.InfoLevel).Info("not starting controller as it's disabled") continue } iface, err := fn(ctxFactory) if err != nil { if err != nil { err = fmt.Errorf("error starting controller: %v", err) cancelContext() if err1 := g.Wait(); err1 != nil { return utilerrors.NewAggregate([]error{err, err1}) } return err } } g.Go(func() error { log.V(logf.InfoLevel).Info("starting controller") // TODO: make this either a constant or a command line flag workers := 5 return iface.Run(workers, rootCtx.Done()) }) } log.V(logf.DebugLevel).Info("starting shared informer factories") ctx.SharedInformerFactory.Start(rootCtx.Done()) ctx.KubeSharedInformerFactory.Start(rootCtx.Done()) err = g.Wait() if err != nil { return fmt.Errorf("error starting controller: %v", err) } log.V(logf.InfoLevel).Info("control loops exited") return nil } func buildControllerContextFactory(ctx context.Context, opts *options.ControllerOptions) (*controller.ContextFactory, error) { // log := logf.FromContext(ctx) ctxFactory, err := controller.NewContextFactory(ctx, controller.ContextOptions{ Clock: clock.RealClock{}, }) if err != nil { return nil, err } return ctxFactory, nil }