package controller import ( "os" "time" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/fields" kruntime "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" ctrlmgr "sigs.k8s.io/controller-runtime/pkg/manager" "k8s.io/apimachinery/pkg/util/wait" "edge-infra.dev/pkg/k8s/runtime/controller" v1ienpatch "edge-infra.dev/pkg/sds/patching/k8s/apis/ienpatch/v1" ) var ( scheme = kruntime.NewScheme() requeueTime = time.Minute ) func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(v1ienpatch.AddToScheme(scheme)) } func Run(logger logr.Logger, opts ...controller.Option) error { ctrl.SetLogger(logger) log := ctrl.Log.WithName("setup") backoff := wait.Backoff{ // Max duration is approx 9.5 minutes Duration: 500 * time.Millisecond, Factor: 2.0, Jitter: 1.0, Steps: 15, Cap: 60 * time.Second, } var mgrPtr *ctrlmgr.Manager if err := wait.ExponentialBackoff(backoff, func() (bool, error) { mgr, err := createManager(opts...) // setup the controller manager if err != nil { log.Error(err, "unable to setup the controller manager") return false, nil // not returning error to continue backoff } mgrPtr = &mgr return true, nil }); err != nil { log.Error(err, "error creating patchctl manager: too many retries") os.Exit(1) } mgr := *mgrPtr // register controllers if err := setupControllersWithManager(mgr, log); err != nil { log.Error(err, "unable to setup controllers") return err } // start controllers registered to the manager if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { log.Error(err, "could not start controllers") return err } return nil } func createManager(o ...controller.Option) (mgr ctrl.Manager, err error) { mgrRestConfig, mgrOpts := getManagerOptions(o...) return ctrl.NewManager(mgrRestConfig, mgrOpts) } func getManagerOptions(opts ...controller.Option) (*rest.Config, ctrlmgr.Options) { mgrConfig, mgrOpts := controller.ProcessOptions(opts...) mgrOpts.Scheme = scheme mgrOpts.Cache = cacheOptions() return mgrConfig, mgrOpts } func cacheOptions() cache.Options { return cache.Options{ ByObject: map[client.Object]cache.ByObject{ &v1ienpatch.IENPatch{}: { Field: fields.Everything(), }, }, } } func setupControllersWithManager(mgr ctrl.Manager, log logr.Logger) error { controller := NewPatchController(mgr, log) return controller.SetUpWithManager(mgr) }