From a7aa3921a520876ca7db18313c7f60ebed8b35f7 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Mon, 8 Jun 2026 11:13:06 -0400 Subject: [PATCH 1/9] bugfix: mount /etc/containers so image controllers respect cluster-wide image registry configurations Signed-off-by: Bryce Palmer --- bindata/assets/openshift-controller-manager/deploy.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bindata/assets/openshift-controller-manager/deploy.yaml b/bindata/assets/openshift-controller-manager/deploy.yaml index 743027e1d..cdeff1157 100644 --- a/bindata/assets/openshift-controller-manager/deploy.yaml +++ b/bindata/assets/openshift-controller-manager/deploy.yaml @@ -33,7 +33,7 @@ spec: name: openshift-controller-manager annotations: target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' - openshift.io/required-scc: restricted-v3 + openshift.io/required-scc: hostaccess labels: app: openshift-controller-manager-a controller-manager: "true" @@ -92,6 +92,9 @@ spec: name: proxy-ca-bundles - mountPath: /tmp name: tmp + - mountPath: /etc/containers + name: etc-containers + readOnly: true volumes: - name: config configMap: @@ -110,6 +113,10 @@ spec: path: tls-ca-bundle.pem - emptyDir: {} name: tmp + - hostPath: + path: /etc/containers + type: Directory + name: etc-containers nodeSelector: node-role.kubernetes.io/master: "" tolerations: From ff619cec233615d37d13194232201d734235413d Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Mon, 8 Jun 2026 13:44:48 -0400 Subject: [PATCH 2/9] bugfix: configure registry authentication by syncing the global pull-secret to the openshift-controller-manager namespace mounted as a volume on the openshift-controller-manager pods and setting the REGISTRY_AUTH_FILE environment variable to the mounted file. Signed-off-by: Bryce Palmer --- .../assets/openshift-controller-manager/deploy.yaml | 10 ++++++++++ pkg/operator/starter.go | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/bindata/assets/openshift-controller-manager/deploy.yaml b/bindata/assets/openshift-controller-manager/deploy.yaml index cdeff1157..bdea21be7 100644 --- a/bindata/assets/openshift-controller-manager/deploy.yaml +++ b/bindata/assets/openshift-controller-manager/deploy.yaml @@ -69,6 +69,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + - name: REGISTRY_AUTH_FILE + value: /var/run/secrets/image-auth/auth.json livenessProbe: initialDelaySeconds: 30 httpGet: @@ -95,6 +97,8 @@ spec: - mountPath: /etc/containers name: etc-containers readOnly: true + - mountPath: /var/run/secrets/image-auth + name: image-auth volumes: - name: config configMap: @@ -117,6 +121,12 @@ spec: path: /etc/containers type: Directory name: etc-containers + - name: image-auth + secret: + secretName: pull-secret + items: + - key: .dockercfgjson + path: auth.json nodeSelector: node-role.kubernetes.io/master: "" tolerations: diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index db26e71d3..83773c210 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -131,6 +131,14 @@ func RunOperator(ctx context.Context, controllerConfig *controllercmd.Controller controllerConfig.EventRecorder, ) + err = resourceSyncer.SyncSecret( + resourcesynccontroller.ResourceLocation{Namespace: "openshift-config", Name: "pull-secret"}, + resourcesynccontroller.ResourceLocation{Namespace: util.TargetNamespace, Name: "pull-secret"}, + ) + if err != nil { + return fmt.Errorf("configuring global pull-secret syncing: %w", err) + } + if !cache.WaitForCacheSync(ctx.Done(), configInformers.Config().V1().ClusterVersions().Informer().HasSynced) { klog.Errorf("timed out waiting for configInformers ClusterVersions") return fmt.Errorf("timed out waiting for configInformers ClusterVersions") From b41e22c2fbcaf12455c46ea1aadc9807ab8abb20 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Mon, 8 Jun 2026 13:59:16 -0400 Subject: [PATCH 3/9] assets: add hostaccess use permissions Signed-off-by: Bryce Palmer --- .../openshift-controller-manager/scc-role.yaml | 15 +++++++++++++++ .../scc-rolebinding.yaml | 13 +++++++++++++ pkg/operator/starter.go | 3 +++ 3 files changed, 31 insertions(+) create mode 100644 bindata/assets/openshift-controller-manager/scc-role.yaml create mode 100644 bindata/assets/openshift-controller-manager/scc-rolebinding.yaml diff --git a/bindata/assets/openshift-controller-manager/scc-role.yaml b/bindata/assets/openshift-controller-manager/scc-role.yaml new file mode 100644 index 000000000..18bad4808 --- /dev/null +++ b/bindata/assets/openshift-controller-manager/scc-role.yaml @@ -0,0 +1,15 @@ +# needed to support host-mounted image registry configurations. +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:openshift-controller-manager:hostaccess-role + namespace: openshift-controller-manager +rules: + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - hostaccess + verbs: + - use diff --git a/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml b/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml new file mode 100644 index 000000000..5ed5a9822 --- /dev/null +++ b/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml @@ -0,0 +1,13 @@ +# needed to support host-mounted image registry configurations. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + namespace: openshift-controller-manager + name: system:openshift-controller-manager:hostaccess-rolebinding +roleRef: + kind: Role + name: system:openshift-controller-manager:hostaccess-role +subjects: +- kind: ServiceAccount + namespace: openshift-controller-manager + name: openshift-controller-manager-sa diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index 83773c210..0918d9f74 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -251,6 +251,9 @@ func RunOperator(ctx context.Context, controllerConfig *controllercmd.Controller "assets/openshift-controller-manager/networkpolicy-default-deny.yaml", "assets/openshift-controller-manager/route-controller-manager-networkpolicy-allow.yaml", "assets/openshift-controller-manager/route-controller-manager-networkpolicy-default-deny.yaml", + + "assets/openshift-controller-manager/scc-role.yaml", + "assets/openshift-controller-manager/scc-rolebinding.yaml", }, resourceapply.NewKubeClientHolder(kubeClient), opClient, From 78b69b8695ed920ad11f1404d5f01cfb3de2d46d Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Mon, 8 Jun 2026 14:17:45 -0400 Subject: [PATCH 4/9] testing: update tests with deployment changes Signed-off-by: Bryce Palmer --- ...openshiftcontrollermanager_v311_00_test.go | 55 +++++++++++++------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/pkg/operator/sync_openshiftcontrollermanager_v311_00_test.go b/pkg/operator/sync_openshiftcontrollermanager_v311_00_test.go index 2818ae613..ef8b2ddcb 100644 --- a/pkg/operator/sync_openshiftcontrollermanager_v311_00_test.go +++ b/pkg/operator/sync_openshiftcontrollermanager_v311_00_test.go @@ -44,7 +44,6 @@ import ( ) func TestExpectedConfigMap(t *testing.T) { - objects := []runtime.Object{ &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "serving-cert", Namespace: "openshift-controller-manager"}}, &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "etcd-client", Namespace: "kube-system"}}, @@ -70,7 +69,8 @@ func TestExpectedConfigMap(t *testing.T) { LeaderElection: configv1.LeaderElection{ Name: "openshift-master-controllers", }, - Controllers: []string{"*", + Controllers: []string{ + "*", "-openshift.io/build", "-openshift.io/build-config-change", "-openshift.io/builder-rolebindings", @@ -124,7 +124,6 @@ func TestExpectedConfigMap(t *testing.T) { } func TestControllerDisabling(t *testing.T) { - testCases := []struct { name string versionLister configlisterv1.ClusterVersionLister @@ -145,9 +144,11 @@ func TestControllerDisabling(t *testing.T) { configv1.ClusterVersionCapabilityImageRegistry, }, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/default-rolebindings", - }}, + }, + }, }, { name: "BuildCapDisabled", @@ -156,13 +157,15 @@ func TestControllerDisabling(t *testing.T) { }, enabledCapabilities: []v1.ClusterVersionCapability{}, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/build", "-openshift.io/build-config-change", "-openshift.io/builder-rolebindings", "-openshift.io/builder-serviceaccount", "-openshift.io/default-rolebindings", - }}, + }, + }, }, { name: "DeploymentConfigCapDisabled", @@ -171,13 +174,15 @@ func TestControllerDisabling(t *testing.T) { }, enabledCapabilities: []v1.ClusterVersionCapability{}, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/default-rolebindings", "-openshift.io/deployer", "-openshift.io/deployer-rolebindings", "-openshift.io/deployer-serviceaccount", "-openshift.io/deploymentconfig", - }}, + }, + }, }, { name: "ImageRegistryCapDisabled", @@ -186,11 +191,13 @@ func TestControllerDisabling(t *testing.T) { }, enabledCapabilities: []v1.ClusterVersionCapability{}, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/default-rolebindings", "-openshift.io/image-puller-rolebindings", "-openshift.io/serviceaccount-pull-secrets", - }}, + }, + }, }, { name: "CapabilitiesDisabled", @@ -201,7 +208,8 @@ func TestControllerDisabling(t *testing.T) { }, enabledCapabilities: []v1.ClusterVersionCapability{}, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/build", "-openshift.io/build-config-change", "-openshift.io/builder-rolebindings", @@ -213,16 +221,19 @@ func TestControllerDisabling(t *testing.T) { "-openshift.io/deploymentconfig", "-openshift.io/image-puller-rolebindings", "-openshift.io/serviceaccount-pull-secrets", - }}, + }, + }, }, { name: "CapabilitiesDisabledButUnknown", knownCapabilities: []v1.ClusterVersionCapability{}, enabledCapabilities: []v1.ClusterVersionCapability{}, result: map[string][]string{ - "controllers": {"*", + "controllers": { + "*", "-openshift.io/default-rolebindings", - }}, + }, + }, }, } @@ -623,7 +634,6 @@ type conditionTestCase struct { func testControllerManagerCondition(t *testing.T, conditionType string, testCases []conditionTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if len(tc.version) > 0 { os.Setenv("RELEASE_VERSION", tc.version) } else { @@ -739,6 +749,10 @@ func TestDeploymentWithProxy(t *testing.T) { }, }, }, + { + Name: "REGISTRY_AUTH_FILE", + Value: "/var/run/secrets/image-auth/auth.json", + }, { Name: "HTTPS_PROXY", Value: "https://my-proxy", @@ -771,6 +785,10 @@ func TestDeploymentWithProxy(t *testing.T) { Name: "POD_NAME", Value: "my-pod", }, + { + Name: "REGISTRY_AUTH_FILE", + Value: "/var/run/secrets/image-auth/auth.json", + }, } } @@ -798,6 +816,10 @@ func TestDeploymentWithProxy(t *testing.T) { Name: "POD_NAME", Value: "my-pod", }, + { + Name: "REGISTRY_AUTH_FILE", + Value: "/var/run/secrets/image-auth/auth.json", + }, // HTTPS_PROXY is added as it isn't in the template, but it's present in the proxy config. { Name: "HTTPS_PROXY", @@ -874,7 +896,6 @@ func TestDeploymentWithProxy(t *testing.T) { proxyLister, specAnnotations, ) - if err != nil { t.Fatalf("unexpected error: %s", err.Error()) } From 1ed86f92297d9fcc243edbd5cec0b12715c0e5aa Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Wed, 10 Jun 2026 10:23:31 -0400 Subject: [PATCH 5/9] fixup! remove seccompprofile from openshift-controller-manager deployment Signed-off-by: Bryce Palmer --- bindata/assets/openshift-controller-manager/deploy.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/bindata/assets/openshift-controller-manager/deploy.yaml b/bindata/assets/openshift-controller-manager/deploy.yaml index bdea21be7..06292f9ca 100644 --- a/bindata/assets/openshift-controller-manager/deploy.yaml +++ b/bindata/assets/openshift-controller-manager/deploy.yaml @@ -39,9 +39,6 @@ spec: controller-manager: "true" spec: hostUsers: false - securityContext: - seccompProfile: - type: RuntimeDefault priorityClassName: system-node-critical serviceAccountName: openshift-controller-manager-sa containers: From 38f570c6c0ebbecbb901d36012e0dd1928ebd4d5 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Wed, 10 Jun 2026 11:07:43 -0400 Subject: [PATCH 6/9] fixup! add apigroup to rolebinding Signed-off-by: Bryce Palmer --- bindata/assets/openshift-controller-manager/scc-rolebinding.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml b/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml index 5ed5a9822..c56df2f50 100644 --- a/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml +++ b/bindata/assets/openshift-controller-manager/scc-rolebinding.yaml @@ -5,6 +5,7 @@ metadata: namespace: openshift-controller-manager name: system:openshift-controller-manager:hostaccess-rolebinding roleRef: + apiGroup: rbac.authorization.k8s.io kind: Role name: system:openshift-controller-manager:hostaccess-role subjects: From 1643cc16248925127829991b439e4c2f6e8c8447 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Thu, 11 Jun 2026 09:13:40 -0400 Subject: [PATCH 7/9] fixup! inverted pull secret syncing Signed-off-by: Bryce Palmer --- pkg/operator/starter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index 0918d9f74..2fd7fa9a2 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -132,8 +132,8 @@ func RunOperator(ctx context.Context, controllerConfig *controllercmd.Controller ) err = resourceSyncer.SyncSecret( - resourcesynccontroller.ResourceLocation{Namespace: "openshift-config", Name: "pull-secret"}, resourcesynccontroller.ResourceLocation{Namespace: util.TargetNamespace, Name: "pull-secret"}, + resourcesynccontroller.ResourceLocation{Namespace: "openshift-config", Name: "pull-secret"}, ) if err != nil { return fmt.Errorf("configuring global pull-secret syncing: %w", err) From 038c418bce2ff67c6d084552aae7e6289a456da5 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Fri, 12 Jun 2026 08:32:42 -0400 Subject: [PATCH 8/9] fixup! Add PSA privileged labels to ns Signed-off-by: Bryce Palmer --- bindata/assets/openshift-controller-manager/ns.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bindata/assets/openshift-controller-manager/ns.yaml b/bindata/assets/openshift-controller-manager/ns.yaml index 9449dd6ef..0acc9926e 100644 --- a/bindata/assets/openshift-controller-manager/ns.yaml +++ b/bindata/assets/openshift-controller-manager/ns.yaml @@ -8,3 +8,6 @@ metadata: labels: openshift.io/cluster-monitoring: "true" openshift.io/run-level: "" # specify no run-level turns it off on install and upgrades + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: privileged From 28a62c9fde5a435fe1656f7e1bf5695f1247fd86 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Fri, 12 Jun 2026 14:05:30 -0400 Subject: [PATCH 9/9] fixup! dockerconfigjson Signed-off-by: Bryce Palmer --- bindata/assets/openshift-controller-manager/deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindata/assets/openshift-controller-manager/deploy.yaml b/bindata/assets/openshift-controller-manager/deploy.yaml index 06292f9ca..df2ebb45a 100644 --- a/bindata/assets/openshift-controller-manager/deploy.yaml +++ b/bindata/assets/openshift-controller-manager/deploy.yaml @@ -122,7 +122,7 @@ spec: secret: secretName: pull-secret items: - - key: .dockercfgjson + - key: .dockerconfigjson path: auth.json nodeSelector: node-role.kubernetes.io/master: ""