diff --git a/templates/cmd/controller/main.go.tpl b/templates/cmd/controller/main.go.tpl index 74f65b15..149df447 100644 --- a/templates/cmd/controller/main.go.tpl +++ b/templates/cmd/controller/main.go.tpl @@ -69,13 +69,14 @@ func main() { flag.Parse() ackCfg.SetupLogger() + ctx := ctrlrt.SetupSignalHandler() + managerFactories := svcresource.GetManagerFactories() resourceGVKs := make([]schema.GroupVersionKind, 0, len(managerFactories)) for _, mf := range managerFactories { resourceGVKs = append(resourceGVKs, mf.ResourceDescriptor().GroupVersionKind()) } - ctx := context.Background() if err := ackCfg.Validate(ctx, ackcfg.WithGVKs(resourceGVKs)); err != nil { setupLog.Error( err, "Unable to create controller manager", @@ -144,8 +145,6 @@ func main() { os.Exit(1) } - stopChan := ctrlrt.SetupSignalHandler() - setupLog.Info( "initializing service controller", "aws.service", awsServiceAlias, @@ -177,7 +176,7 @@ func main() { } } - if err = sc.BindControllerManager(mgr, ackCfg); err != nil { + if err = sc.BindControllerManager(ctx, mgr, ackCfg); err != nil { setupLog.Error( err, "unable bind to controller manager to service controller", "aws.service", awsServiceAlias, @@ -204,7 +203,7 @@ func main() { "starting manager", "aws.service", awsServiceAlias, ) - if err := mgr.Start(stopChan); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error( err, "unable to start controller manager", "aws.service", awsServiceAlias, diff --git a/templates/config/controller/deployment.yaml.tpl b/templates/config/controller/deployment.yaml.tpl index 08e84cd1..3fe072de 100644 --- a/templates/config/controller/deployment.yaml.tpl +++ b/templates/config/controller/deployment.yaml.tpl @@ -44,6 +44,9 @@ spec: - --feature-gates - "$(FEATURE_GATES)" - --enable-carm=$(ENABLE_CARM) + - --lazy-bind-reconcilers=$(LAZY_BIND_RECONCILERS) + - --lazy-bind-retry-interval + - "$(LAZY_BIND_RETRY_INTERVAL)" image: controller:latest name: controller ports: @@ -83,6 +86,10 @@ spec: value: "" - name: "ENABLE_CARM" value: "true" + - name: "LAZY_BIND_RECONCILERS" + value: "false" + - name: "LAZY_BIND_RETRY_INTERVAL" + value: "10" securityContext: allowPrivilegeEscalation: false privileged: false diff --git a/templates/helm/templates/deployment.yaml.tpl b/templates/helm/templates/deployment.yaml.tpl index a8219bac..2f17affa 100644 --- a/templates/helm/templates/deployment.yaml.tpl +++ b/templates/helm/templates/deployment.yaml.tpl @@ -104,6 +104,11 @@ spec: - "$(FEATURE_GATES)" {{ "{{- end }}" }} - {{ "--enable-carm={{ .Values.enableCARM }}" }} + - {{ "--lazy-bind-reconcilers={{ .Values.lazyBindReconcilers }}" }} +{{ "{{- if .Values.lazyBindReconcilers }}" }} + - --lazy-bind-retry-interval + - {{ "{{ .Values.lazyBindRetryInterval | quote }}" }} +{{ "{{- end }}" }} image: {{ "{{ .Values.image.repository }}:{{ .Values.image.tag }}" }} imagePullPolicy: {{ "{{ .Values.image.pullPolicy }}" }} name: controller diff --git a/templates/helm/values.yaml.tpl b/templates/helm/values.yaml.tpl index 15cf4d09..d70d2cd9 100644 --- a/templates/helm/values.yaml.tpl +++ b/templates/helm/values.yaml.tpl @@ -180,6 +180,15 @@ leaderElection: # Enable Cross Account Resource Management (default = true). Set this to false to disable cross account resource management. enableCARM: true +# Enable Lazy Bind Reconcilers (default = false). When enabled, defers reconciler +# binding for missing CRDs until they become available, allowing the controller to +# start serving installed CRDs immediately instead of crash-looping. +lazyBindReconcilers: false + +# The interval in seconds between retry attempts when polling the discovery API +# for missing CRDs (only used when lazyBindReconcilers is true). +lazyBindRetryInterval: 10 + # Configuration for feature gates. These are optional controller features that # can be individually enabled ("true") or disabled ("false") by adding key/value # pairs below. diff --git a/templates/pkg/resource/descriptor.go.tpl b/templates/pkg/resource/descriptor.go.tpl index a5cb26d4..cba7291a 100644 --- a/templates/pkg/resource/descriptor.go.tpl +++ b/templates/pkg/resource/descriptor.go.tpl @@ -37,6 +37,12 @@ func (d *resourceDescriptor) GroupVersionKind() schema.GroupVersionKind { return svcapitypes.GroupVersion.WithKind(GroupKind.Kind) } +// GroupVersionResource returns a Kubernetes schema.GroupVersionResource struct that +// describes the API Group, Version and Resource of CRs described by the descriptor +func (d *resourceDescriptor) GroupVersionResource() schema.GroupVersionResource { + return GroupVersionResource +} + // EmptyRuntimeObject returns an empty object prototype that may be used in // apimachinery and k8s client operations func (d *resourceDescriptor) EmptyRuntimeObject() rtclient.Object {