From e2adcc04e903db213cb722cd636ac4881c9e47db Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Tue, 18 Aug 2026 00:06:47 +0300 Subject: [PATCH 1/9] fix(chart): template openshift operator SA name The openshift RBAC template hardcoded the ServiceAccount name (openshift-pipelines-operator) while the operator Deployment resolves the name via the tekton-operator.serviceAccountName helper. With rbac.create enabled the pod referenced a ServiceAccount the chart never created, so OpenShift users had to set rbac.serviceAccount.name manually. Use the same helper for the ServiceAccount and its ClusterRoleBinding subject so both flavors follow the chart fullname default and the rbac.serviceAccount.name override. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/openshift-rbac.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/tekton-operator/templates/openshift-rbac.yaml b/charts/tekton-operator/templates/openshift-rbac.yaml index 56dbeb2647..cf3e3a261f 100644 --- a/charts/tekton-operator/templates/openshift-rbac.yaml +++ b/charts/tekton-operator/templates/openshift-rbac.yaml @@ -3,7 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: openshift-pipelines-operator + name: {{ include "tekton-operator.serviceAccountName" . }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -467,6 +467,6 @@ roleRef: name: tekton-operator subjects: - kind: ServiceAccount - name: openshift-pipelines-operator + name: {{ include "tekton-operator.serviceAccountName" . }} namespace: {{ .Release.Namespace }} {{- end -}} \ No newline at end of file From 6d84cb3edf8091662a79107f8afd42fada0eba9e Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Tue, 18 Aug 2026 14:25:14 +0300 Subject: [PATCH 2/9] fix(chart): set PLATFORM=openshift in openshift flavor The operator and webhook Deployments never set the PLATFORM env, so the openshift chart flavor ran the operator in kubernetes mode: IsOpenShiftPlatform() returned false and the openshift-specific reconciler branches, defaults, and TektonConfig platform validation never activated. Set PLATFORM=openshift on the lifecycle and webhook containers when openshift.enabled is true, mirroring the upstream openshift kustomize overlay (the tektoninstallerset cluster-operations container does not use it). Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/deployment.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/charts/tekton-operator/templates/deployment.yaml b/charts/tekton-operator/templates/deployment.yaml index 5045360cd5..d3084b24b0 100644 --- a/charts/tekton-operator/templates/deployment.yaml +++ b/charts/tekton-operator/templates/deployment.yaml @@ -48,6 +48,10 @@ spec: value: tekton-operator {{- end }} {{- end }} + {{- if .Values.openshift.enabled }} + - name: PLATFORM + value: openshift + {{- end }} - name: IMAGE_PIPELINES_PROXY value: {{ include "tekton-operator.webhook-proxy-image" . }} - name: IMAGE_JOB_PRUNER_TKN @@ -209,6 +213,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- if .Values.openshift.enabled }} + - name: PLATFORM + value: openshift + {{- end }} - name: CONFIG_LOGGING_NAME value: {{ include "tekton-operator.fullname" . }}-config-logging - name: WEBHOOK_POD_NAME From d1feafab1487879c01fa88e7c39d9f177d63f5ba Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 14:41:11 +0300 Subject: [PATCH 3/9] fix(chart): add missing RBAC roles and align rules Add the pac-controller, result-read and scheduler ClusterRoles and bindings that the kustomize installation ships but the chart never did (scheduler and result-read are shared by both flavors and live in a new common-rbac.yaml; pac is kubernetes-only). The new roles are fullname-prefixed like the rest of the chart resources. Also align the openshift operator ClusterRole rules with config/openshift/base/role.yaml: nodes:list, securitycontextconstraints list, config.openshift.io apiservers/clusterversions reads, routes/custom-host, events.k8s.io event creation, consoleplugins, pipelinesascode.tekton.dev in the tekton api-group wildcard, and resolutionrequests/status with update. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- .../templates/common-rbac.yaml | 95 +++++++++++++++++++ .../templates/kubernetes-rbac.yaml | 37 ++++++++ .../templates/openshift-rbac.yaml | 45 +++++++++ 3 files changed, 177 insertions(+) create mode 100644 charts/tekton-operator/templates/common-rbac.yaml diff --git a/charts/tekton-operator/templates/common-rbac.yaml b/charts/tekton-operator/templates/common-rbac.yaml new file mode 100644 index 0000000000..43436b62af --- /dev/null +++ b/charts/tekton-operator/templates/common-rbac.yaml @@ -0,0 +1,95 @@ +{{- if .Values.rbac.create -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "tekton-operator.fullname" . }}-scheduler-role + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +rules: + - apiGroups: + - kueue.x-k8s.io + resources: + - resourceflavors + - workloads + - workloads/finalizers + - workloads/status + - workloadpriorityclasses + - multikueueclusters + verbs: + - get + - list + - create + - update + - delete + - patch + - watch + - apiGroups: + - scheduling.k8s.io + resources: + - priorityclasses + verbs: + - get + - list + - watch + - apiGroups: + - cert-manager.io + resources: + - certificates + - issuers + verbs: + - get + - create + - update + - list + - nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "tekton-operator.fullname" . }}-scheduler-rolebinding + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "tekton-operator.fullname" . }}-scheduler-role +subjects: + - kind: ServiceAccount + name: {{ include "tekton-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "tekton-operator.fullname" . }}-result-read-role + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +rules: + - apiGroups: + - operator.tekton.dev + resources: + - tektonresults + verbs: + - get + - watch + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "tekton-operator.fullname" . }}-result-read-rolebinding + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "tekton-operator.fullname" . }}-result-read-role +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated +{{- end -}} diff --git a/charts/tekton-operator/templates/kubernetes-rbac.yaml b/charts/tekton-operator/templates/kubernetes-rbac.yaml index 73a6ae7a49..273e54daf2 100644 --- a/charts/tekton-operator/templates/kubernetes-rbac.yaml +++ b/charts/tekton-operator/templates/kubernetes-rbac.yaml @@ -506,4 +506,41 @@ subjects: - kind: ServiceAccount name: {{ include "tekton-operator.fullname" . }} namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "tekton-operator.fullname" . }}-pac-controller-role + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +rules: + - apiGroups: + - pipelinesascode.tekton.dev + resources: + - repositories + - webhooks + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - deletecollection +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "tekton-operator.fullname" . }}-pac-controller-role-binding + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "tekton-operator.fullname" . }}-pac-controller-role +subjects: + - kind: ServiceAccount + name: {{ include "tekton-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} {{- end -}} diff --git a/charts/tekton-operator/templates/openshift-rbac.yaml b/charts/tekton-operator/templates/openshift-rbac.yaml index cf3e3a261f..d7d5749f87 100644 --- a/charts/tekton-operator/templates/openshift-rbac.yaml +++ b/charts/tekton-operator/templates/openshift-rbac.yaml @@ -63,6 +63,12 @@ metadata: labels: {{- include "tekton-operator.labels" . | nindent 4 }} rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - list - apiGroups: - "" resources: @@ -270,6 +276,7 @@ rules: - tekton.dev - triggers.tekton.dev - operator.tekton.dev + - pipelinesascode.tekton.dev resources: - '*' verbs: @@ -303,9 +310,19 @@ rules: verbs: - use - get + - list - create - update - delete + - apiGroups: + - config.openshift.io + resources: + - apiservers + - clusterversions + verbs: + - get + - list + - watch - apiGroups: - route.openshift.io resources: @@ -319,6 +336,31 @@ rules: - list - update - watch + - apiGroups: + - route.openshift.io + resources: + - routes/custom-host + verbs: + - create + - update + - apiGroups: + - events.k8s.io + resources: + - events + verbs: + - create + - apiGroups: + - console.openshift.io + resources: + - consoleplugins + verbs: + - delete + - create + - patch + - get + - list + - update + - watch - apiGroups: - coordination.k8s.io resources: @@ -409,12 +451,15 @@ rules: - resolution.tekton.dev resources: - resolutionrequests + - resolutionrequests/status verbs: - get - list - watch - create - delete + - update + - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding From 59d667f77cb5f45ee64de5c46601a3f1c35ed5a1 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 14:41:22 +0300 Subject: [PATCH 4/9] fix(chart): use platform images and controllers per flavor The openshift flavor selected the kubernetes operator, webhook and proxy-webhook images, and PLATFORM alone does not switch the compiled binary. Point the openshift branches of the image helpers at the openshift image repositories (digest-pinned from the v0.81.0 openshift release) and give the controllers flag a flavor-aware default helper, matching the kustomize overlays: - kubernetes adds tektonscheduler and tektonmulticlusterproxyaae which were missing from the chart default (additive change; openshiftpipelinesascode remains) - openshift uses tektonaddon and syncerservice instead of tektondashboard, which the openshift binary does not register The chart deliberately does not set IMAGE_ADDONS_*: addon image defaults come from the operator's built-in manifests and can be rewritten with TEKTON_REGISTRY_OVERRIDE (documented in values.yaml). Fixes review feedback on #3945. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/_helpers.tpl | 26 ++++++++++++------- .../tekton-operator/templates/deployment.yaml | 2 +- charts/tekton-operator/values.yaml | 19 ++++++++++++-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/charts/tekton-operator/templates/_helpers.tpl b/charts/tekton-operator/templates/_helpers.tpl index 76a01005fc..af70ac361c 100644 --- a/charts/tekton-operator/templates/_helpers.tpl +++ b/charts/tekton-operator/templates/_helpers.tpl @@ -96,6 +96,14 @@ tekton-operator {{- end -}} {{- end -}} +{{- define "tekton-operator.controllers" -}} +{{- if .Values.openshift.enabled -}} +tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonaddon,tektonresult,openshiftpipelinesascode,manualapprovalgate,tektonpruner,tektonscheduler,tektonmulticlusterproxyaae,syncerservice +{{- else -}} +tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult,tektondashboard,manualapprovalgate,tektonpruner,tektonscheduler,tektonmulticlusterproxyaae,openshiftpipelinesascode +{{- end -}} +{{- end -}} + {{- define "tekton-operator.operator-image" -}} {{- $tag := default .Chart.AppVersion .Values.operator.image.tag -}} {{- $image := "" -}} @@ -103,10 +111,10 @@ tekton-operator {{- $image = .Values.operator.image.repository }} {{- else -}} {{- if .Values.openshift.enabled -}} + {{- $image = "ghcr.io/tektoncd/operator/operator-1d69a75f22dd094880847eac907fb2c1" -}} + {{- else -}} {{- $image = "ghcr.io/tektoncd/operator/operator-303303c315a48490ba6517859ef65b77" -}} -{{- else -}} - {{- $image = "ghcr.io/tektoncd/operator/operator-303303c315a48490ba6517859ef65b77" -}} -{{- end -}} + {{- end -}} {{- end -}} {{- printf "%s:%s" $image $tag -}} {{- end -}} @@ -126,10 +134,10 @@ tekton-operator {{- $image = .Values.webhook.image.repository }} {{- else -}} {{- if .Values.openshift.enabled -}} + {{- $image = "ghcr.io/tektoncd/operator/webhook-340ad78e88ca5477447aa144fedfe1a1" -}} + {{- else -}} {{- $image = "ghcr.io/tektoncd/operator/webhook-f2bb711aa8f0c0892856a4cbf6d9ddd8" -}} -{{- else -}} - {{- $image = "ghcr.io/tektoncd/operator/webhook-f2bb711aa8f0c0892856a4cbf6d9ddd8" -}} -{{- end -}} + {{- end -}} {{- end -}} {{- printf "%s:%s" $image $tag -}} {{- end -}} @@ -149,10 +157,10 @@ tekton-operator {{- $image = .Values.webhookProxy.image.repository }} {{- else -}} {{- if .Values.openshift.enabled -}} + {{- $image = "ghcr.io/tektoncd/operator/proxy-webhook-f8f95c9cea9508fe8915ae3d012d15fb" -}} + {{- else -}} {{- $image = "ghcr.io/tektoncd/operator/proxy-webhook-f6167da7bc41b96a27c5529f850e63d1" -}} -{{- else -}} - {{- $image = "ghcr.io/tektoncd/operator/proxy-webhook-f6167da7bc41b96a27c5529f850e63d1" -}} -{{- end -}} + {{- end -}} {{- end -}} {{- printf "%s:%s" $image $tag -}} {{- end -}} diff --git a/charts/tekton-operator/templates/deployment.yaml b/charts/tekton-operator/templates/deployment.yaml index d3084b24b0..617ef0a128 100644 --- a/charts/tekton-operator/templates/deployment.yaml +++ b/charts/tekton-operator/templates/deployment.yaml @@ -83,7 +83,7 @@ spec: {{- end }} args: - "-controllers" - - {{ .Values.controllers | default "tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult,tektondashboard,manualapprovalgate,tektonpruner,openshiftpipelinesascode" | quote }} + - {{ .Values.controllers | default (include "tekton-operator.controllers" .) | quote }} - "-unique-process-name" - "tekton-operator-lifecycle" image: {{ include "tekton-operator.operator-image" . }} diff --git a/charts/tekton-operator/values.yaml b/charts/tekton-operator/values.yaml index 52b4d4bd2c..90e291a51a 100644 --- a/charts/tekton-operator/values.yaml +++ b/charts/tekton-operator/values.yaml @@ -12,6 +12,12 @@ kubernetesMinVersion: "v1.34.0" ## Choose between the vanilla Kubernetes flavor and the Openshift flavor of this Helm chart ## Container images, RBAC resources and operator settings will be adjusted automatically, ## unless explicitly overridden by a Helm value. +## +## Note for the Openshift flavor: the chart does not set the IMAGE_ADDONS_* env vars. +## TektonAddon image defaults come from the operator's built-in manifests; to use a +## custom registry (e.g. a mirror of registry.redhat.io), set TEKTON_REGISTRY_OVERRIDE +## or the per-image IMAGE_ADDONS_* env vars via operator.additionalEnvs — see +## https://github.com/tektoncd/operator/blob/main/docs/AirGapImageConfiguration.md openshift: enabled: false @@ -19,8 +25,17 @@ openshift: ## Setting this to true will cause a cascade deletion of all Tekton resources when you uninstall the chart - danger! installCRDs: false -## Controllers to install -controllers: "tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult,tektondashboard,manualapprovalgate,tektonpruner,openshiftpipelinesascode" +## Controllers to install (comma-separated list passed to the operator's +## -controllers flag). Leave empty for the flavor default: +## kubernetes: tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult, +## tektondashboard,manualapprovalgate,tektonpruner,tektonscheduler, +## tektonmulticlusterproxyaae,openshiftpipelinesascode +## openshift: tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonaddon, +## tektonresult,openshiftpipelinesascode,manualapprovalgate,tektonpruner, +## tektonscheduler,tektonmulticlusterproxyaae,syncerservice +## Note: the previous kubernetes default was missing tektonscheduler and +## tektonmulticlusterproxyaae; the new default adds them (additive change). +controllers: "" ## Control the creation of RBAC resources (Serviceaccount, Role, ClusterRole, ClusterRoleBinding) rbac: From ee0375e71133caeca366f3dc5b084437877fd123 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 14:41:41 +0300 Subject: [PATCH 5/9] fix(chart): wire leader election and add missing configmaps Set CONFIG_LEADERELECTION_NAME on the lifecycle, cluster-operations and webhook containers, and ship the controller and webhook leader election ConfigMaps the operator expects (both were absent, so the knative leader election machinery fell back to default ConfigMap names the chart never created - relevant now that replicas >= 2 is documented as supported). Add the tekton-operator-info ConfigMap consumed by tkn version; the chart already shipped the Role granting read access to it but never created the object. On the cluster-operations container, replace envs that only the tektonconfig/tektonpipeline reconcilers read (IMAGE_PIPELINES_PROXY, AUTOINSTALL_COMPONENTS, DEFAULT_TARGET_NAMESPACE) with the envs the kustomize deployment sets (PROFILING_PORT) while keeping CONFIG_LOGGING_NAME/CONFIG_OBSERVABILITY_NAME, which stay necessary because the chart names those ConfigMaps after the release instead of the knative defaults. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/config.yaml | 79 +++++++++++++++++++ .../tekton-operator/templates/deployment.yaml | 22 ++---- 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/charts/tekton-operator/templates/config.yaml b/charts/tekton-operator/templates/config.yaml index d3aef19a89..94e527d317 100644 --- a/charts/tekton-operator/templates/config.yaml +++ b/charts/tekton-operator/templates/config.yaml @@ -75,6 +75,85 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: {{ include "tekton-operator.fullname" . }}-controller-config-leader-election + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +data: + _example: | + ################################ + # # + # EXAMPLE CONFIGURATION # + # # + ################################ + # This block is not actually functional configuration, + # but serves to illustrate the available configuration + # options and document them in a way that is accessible + # to users that `kubectl edit` this config map. + # + # lease-duration is how long non-leaders will wait to try to acquire the + # lock; 15 seconds is the value used by core kubernetes controllers. + lease-duration: "60s" + # renew-deadline is how long a leader will try to renew the lease before + # giving up; 10 seconds is the value used by core kubernetes controllers. + renew-deadline: "40s" + # retry-period is how long the leader election client waits between tries of + # actions; 2 seconds is the value used by core kubernetes controllers. + retry-period: "10s" + # buckets is the number of buckets used to partition key space of each + # Reconciler. If this number is M and the replica number of the controller + # is N, the N replicas will compete for the M buckets. The owner of a + # bucket will take care of the reconciling for the keys partitioned into + # that bucket. + buckets: "1" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "tekton-operator.fullname" . }}-webhook-config-leader-election + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +data: + _example: | + ################################ + # # + # EXAMPLE CONFIGURATION # + # # + ################################ + # This block is not actually functional configuration, + # but serves to illustrate the available configuration + # options and document them in a way that is accessible + # to users that `kubectl edit` this config map. + # + # lease-duration is how long non-leaders will wait to try to acquire the + # lock; 15 seconds is the value used by core kubernetes controllers. + lease-duration: "60s" + # renew-deadline is how long a leader will try to renew the lease before + # giving up; 10 seconds is the value used by core kubernetes controllers. + renew-deadline: "40s" + # retry-period is how long the leader election client waits between tries of + # actions; 2 seconds is the value used by core kubernetes controllers. + retry-period: "10s" + # buckets is the number of buckets used to partition key space of each + # Reconciler. If this number is M and the replica number of the controller + # is N, the N replicas will compete for the M buckets. The owner of a + # bucket will take care of the reconciling for the keys partitioned into + # that bucket. + buckets: "1" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: tekton-operator-info + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +data: + # Contains operator version which can be queried by external + # tools such as CLI. + version: {{ .Chart.AppVersion | quote }} +--- +apiVersion: v1 +kind: ConfigMap metadata: name: {{ include "tekton-operator.fullname" . }}-observability labels: diff --git a/charts/tekton-operator/templates/deployment.yaml b/charts/tekton-operator/templates/deployment.yaml index 617ef0a128..84dc6b4987 100644 --- a/charts/tekton-operator/templates/deployment.yaml +++ b/charts/tekton-operator/templates/deployment.yaml @@ -76,6 +76,8 @@ spec: value: {{ include "tekton-operator.fullname" . }}-config-logging - name: CONFIG_OBSERVABILITY_NAME value: {{ include "tekton-operator.fullname" . }}-observability + - name: CONFIG_LEADERELECTION_NAME + value: {{ include "tekton-operator.fullname" . }}-controller-config-leader-election {{- include "tekton-operator.kubernetesMinVersionEnv" . | nindent 12 }} {{- range .Values.operator.additionalEnvs }} - name: {{ .name }} @@ -114,28 +116,18 @@ spec: value: tekton-operator {{- end }} {{- end }} - - name: IMAGE_PIPELINES_PROXY - value: {{ include "tekton-operator.webhook-proxy-image" . }} + - name: PROFILING_PORT + value: "9009" - name: METRICS_DOMAIN value: {{ .Values.service.metricsDomain }} - name: VERSION value: {{ .Values.webhook.image.tag | default .Chart.AppVersion | quote }} - - name: AUTOINSTALL_COMPONENTS - value: {{ .Values.operator.autoInstallComponents | quote }} - - name: DEFAULT_TARGET_NAMESPACE - {{- if .Values.operator.defaultTargetNamespace }} - value: {{ .Values.operator.defaultTargetNamespace | quote }} - {{- else }} - {{- if .Values.openshift.enabled }} - value: openshift-pipelines - {{- else }} - value: tekton-pipelines - {{- end }} - {{- end }} - name: CONFIG_LOGGING_NAME value: {{ include "tekton-operator.fullname" . }}-config-logging - name: CONFIG_OBSERVABILITY_NAME value: {{ include "tekton-operator.fullname" . }}-observability + - name: CONFIG_LEADERELECTION_NAME + value: {{ include "tekton-operator.fullname" . }}-controller-config-leader-election {{- include "tekton-operator.kubernetesMinVersionEnv" . | nindent 12 }} {{- range .Values.operator.additionalEnvs }} - name: {{ .name }} @@ -227,6 +219,8 @@ spec: value: {{ include "tekton-operator.fullname" . }}-webhook - name: WEBHOOK_SECRET_NAME value: {{ .Values.webhook.certSecret.name | default (include "tekton-operator.fullname" .) }}-webhook-certs + - name: CONFIG_LEADERELECTION_NAME + value: {{ include "tekton-operator.fullname" . }}-webhook-config-leader-election - name: WEBHOOK_PORT value: {{ .Values.webhook.httpsWebhookPort | quote }} - name: METRICS_DOMAIN From c3d009f763f5bf9662d6629399ff770485cd6900 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 14:41:46 +0300 Subject: [PATCH 6/9] fix(chart): wire webhook logLevel to the webhook container The webhook container was named after the operator name (redhat-openshift-pipelines-operator-webhook on openshift) while the logging ConfigMap writes loglevel.-webhook, so the webhook.logLevel value never matched any container and was silently ignored. Name the container after the fullname to match the ConfigMap key, as the kubernetes deployment manifest does. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/tekton-operator/templates/deployment.yaml b/charts/tekton-operator/templates/deployment.yaml index 84dc6b4987..f481fe592d 100644 --- a/charts/tekton-operator/templates/deployment.yaml +++ b/charts/tekton-operator/templates/deployment.yaml @@ -232,7 +232,7 @@ spec: {{- end }} image: {{ include "tekton-operator.webhook-image" . }} imagePullPolicy: {{ .Values.webhook.image.pullPolicy }} - name: {{ include "tekton-operator.operator-name" . -}}-webhook + name: {{ include "tekton-operator.fullname" . -}}-webhook resources: {{- toYaml .Values.webhook.resources | nindent 12 }} {{- with .Values.securityContext }} From afde9f7c0dde1113b32915ca4ab99a0333eed8a1 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 16:49:48 +0300 Subject: [PATCH 7/9] fix(chart): reject custom target namespace on openshift flavor The openshift addon sample pipelines hardcode the openshift-pipelines namespace in their cluster-resolver taskRefs, so a custom target namespace breaks them on the openshift flavor. Fail the render with an explanatory message instead of shipping a broken configuration, and document that the value is first-install-only: once the TektonConfig CR exists the operator never re-reads it, and retargeting requires deleting and recreating the CR. The kubernetes flavor is unaffected and keeps accepting any namespace. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/_helpers.tpl | 6 ++++++ charts/tekton-operator/templates/deployment.yaml | 1 + charts/tekton-operator/values.yaml | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/charts/tekton-operator/templates/_helpers.tpl b/charts/tekton-operator/templates/_helpers.tpl index af70ac361c..f3a8344057 100644 --- a/charts/tekton-operator/templates/_helpers.tpl +++ b/charts/tekton-operator/templates/_helpers.tpl @@ -104,6 +104,12 @@ tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult,tektondashboa {{- end -}} {{- end -}} +{{- define "tekton-operator.validateTargetNamespace" -}} +{{- if and .Values.openshift.enabled .Values.operator.defaultTargetNamespace (ne .Values.operator.defaultTargetNamespace "openshift-pipelines") -}} +{{- fail (printf "operator.defaultTargetNamespace must be \"openshift-pipelines\" when openshift.enabled=true (got %q). The openshift addon sample pipelines hardcode that namespace, so a custom value breaks them; this is also first-install-only - once the TektonConfig CR exists the operator never re-reads it. To change the target namespace, set spec.targetNamespace on the TektonConfig CR (requires deleting and recreating the CR)." .Values.operator.defaultTargetNamespace) -}} +{{- end -}} +{{- end -}} + {{- define "tekton-operator.operator-image" -}} {{- $tag := default .Chart.AppVersion .Values.operator.image.tag -}} {{- $image := "" -}} diff --git a/charts/tekton-operator/templates/deployment.yaml b/charts/tekton-operator/templates/deployment.yaml index f481fe592d..98847fa75e 100644 --- a/charts/tekton-operator/templates/deployment.yaml +++ b/charts/tekton-operator/templates/deployment.yaml @@ -1,3 +1,4 @@ +{{- include "tekton-operator.validateTargetNamespace" . -}} --- apiVersion: apps/v1 kind: Deployment diff --git a/charts/tekton-operator/values.yaml b/charts/tekton-operator/values.yaml index 90e291a51a..b9160735df 100644 --- a/charts/tekton-operator/values.yaml +++ b/charts/tekton-operator/values.yaml @@ -66,6 +66,11 @@ operator: autoInstallComponents: true # The namespace in which Tekton components should be deployed # Defaults to "tekton-pipelines" for Kubernetes and to "openshift-pipelines" for Openshift flavor. + # First-install-only: it seeds the auto-created TektonConfig CR; once the CR exists, + # the operator never re-reads this value. To change it later, set spec.targetNamespace + # on the TektonConfig CR (requires deleting and recreating the CR). + # On the Openshift flavor it must be "openshift-pipelines": the addon sample pipelines + # hardcode that namespace, so the chart fails to render with any other value. defaultTargetNamespace: "" # Log level of the operator logLevel: info From b7d7c433616a199f178efb009730b72fc54151a7 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 19 Aug 2026 19:58:39 +0300 Subject: [PATCH 8/9] chore(chart): add trailing newline to openshift-rbac template Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- charts/tekton-operator/templates/openshift-rbac.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/tekton-operator/templates/openshift-rbac.yaml b/charts/tekton-operator/templates/openshift-rbac.yaml index d7d5749f87..8e6a74d93c 100644 --- a/charts/tekton-operator/templates/openshift-rbac.yaml +++ b/charts/tekton-operator/templates/openshift-rbac.yaml @@ -514,4 +514,4 @@ subjects: - kind: ServiceAccount name: {{ include "tekton-operator.serviceAccountName" . }} namespace: {{ .Release.Namespace }} -{{- end -}} \ No newline at end of file +{{- end -}} From 2f345ab23383c7b070f8dad4372dd5e7796d63bd Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Thu, 20 Aug 2026 01:18:45 +0300 Subject: [PATCH 9/9] refactor(chart): dedupe shared RBAC into common-rbac Move the tekton-operator-info Role/RoleBinding and the tekton-config-read-role ClusterRole/ClusterRoleBinding, which were duplicated byte-identically in both flavor files, into common-rbac.yaml alongside the scheduler and result-read roles. The kubernetes flavor's info Role/RoleBinding drop the fullname prefix to use the literal tekton-operator-info name, the same as the ConfigMap they grant access to and the same as the openshift flavor and upstream. Upgrades rename the objects accordingly. Also align the pac binding name with the other bindings (*-rolebinding instead of *-role-binding) and restructure the controllers comment in values.yaml as common + per-flavor additions instead of transcribing both full lists. Signed-off-by: Abdullah Alaqeel Assisted-by: GLM (via opencode) --- .../templates/common-rbac.yaml | 61 ++++++++++++++++++ .../templates/kubernetes-rbac.yaml | 63 +------------------ .../templates/openshift-rbac.yaml | 61 ------------------ charts/tekton-operator/values.yaml | 13 ++-- 4 files changed, 67 insertions(+), 131 deletions(-) diff --git a/charts/tekton-operator/templates/common-rbac.yaml b/charts/tekton-operator/templates/common-rbac.yaml index 43436b62af..535126db15 100644 --- a/charts/tekton-operator/templates/common-rbac.yaml +++ b/charts/tekton-operator/templates/common-rbac.yaml @@ -1,6 +1,67 @@ {{- if .Values.rbac.create -}} --- apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: tekton-operator-info + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +rules: + - apiGroups: + - "" + resourceNames: + - tekton-operator-info + resources: + - configmaps + verbs: + - get + - describe +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: default + name: tekton-operator-info +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: tekton-operator-info +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: tekton-config-read-role + labels: + {{- include "tekton-operator.labels" . | nindent 4 }} +rules: + - apiGroups: + - operator.tekton.dev + resources: + - tektonconfigs + verbs: + - get + - watch + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: tekton-config-read-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: tekton-config-read-role +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ include "tekton-operator.fullname" . }}-scheduler-role diff --git a/charts/tekton-operator/templates/kubernetes-rbac.yaml b/charts/tekton-operator/templates/kubernetes-rbac.yaml index 273e54daf2..1dee0b3c4a 100644 --- a/charts/tekton-operator/templates/kubernetes-rbac.yaml +++ b/charts/tekton-operator/templates/kubernetes-rbac.yaml @@ -6,39 +6,6 @@ metadata: name: {{ include "tekton-operator.fullname" . }} --- apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "tekton-operator.fullname" . }}-info - labels: - {{- include "tekton-operator.labels" . | nindent 4 }} -rules: - - apiGroups: - - "" - resourceNames: - - tekton-operator-info - resources: - - configmaps - verbs: - - get - - describe ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: tekton-config-read-role - labels: - {{- include "tekton-operator.labels" . | nindent 4 }} -rules: - - apiGroups: - - operator.tekton.dev - resources: - - tektonconfigs - verbs: - - get - - watch - - list ---- -apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ include "tekton-operator.fullname" . }} @@ -467,34 +434,6 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/instance: default - name: {{ include "tekton-operator.fullname" . }}-info -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "tekton-operator.fullname" . }}-info -subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: tekton-config-read-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: tekton-config-read-role -subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated ---- -apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ include "tekton-operator.fullname" . }} @@ -532,7 +471,7 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: {{ include "tekton-operator.fullname" . }}-pac-controller-role-binding + name: {{ include "tekton-operator.fullname" . }}-pac-controller-rolebinding labels: {{- include "tekton-operator.labels" . | nindent 4 }} roleRef: diff --git a/charts/tekton-operator/templates/openshift-rbac.yaml b/charts/tekton-operator/templates/openshift-rbac.yaml index 8e6a74d93c..8adbce9ee3 100644 --- a/charts/tekton-operator/templates/openshift-rbac.yaml +++ b/charts/tekton-operator/templates/openshift-rbac.yaml @@ -24,39 +24,6 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: tekton-operator-info - labels: - {{- include "tekton-operator.labels" . | nindent 4 }} -rules: - - apiGroups: - - "" - resourceNames: - - tekton-operator-info - resources: - - configmaps - verbs: - - get - - describe ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: tekton-config-read-role - labels: - {{- include "tekton-operator.labels" . | nindent 4 }} -rules: - - apiGroups: - - operator.tekton.dev - resources: - - tektonconfigs - verbs: - - get - - watch - - list ---- -apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: tekton-operator @@ -475,34 +442,6 @@ subjects: namespace: openshift-monitoring --- apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/instance: default - name: tekton-operator-info -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: tekton-operator-info -subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: tekton-config-read-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: tekton-config-read-role -subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated ---- -apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tekton-operator diff --git a/charts/tekton-operator/values.yaml b/charts/tekton-operator/values.yaml index b9160735df..db07474a4a 100644 --- a/charts/tekton-operator/values.yaml +++ b/charts/tekton-operator/values.yaml @@ -27,14 +27,11 @@ installCRDs: false ## Controllers to install (comma-separated list passed to the operator's ## -controllers flag). Leave empty for the flavor default: -## kubernetes: tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult, -## tektondashboard,manualapprovalgate,tektonpruner,tektonscheduler, -## tektonmulticlusterproxyaae,openshiftpipelinesascode -## openshift: tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonaddon, -## tektonresult,openshiftpipelinesascode,manualapprovalgate,tektonpruner, -## tektonscheduler,tektonmulticlusterproxyaae,syncerservice -## Note: the previous kubernetes default was missing tektonscheduler and -## tektonmulticlusterproxyaae; the new default adds them (additive change). +## common: tektonconfig,tektonpipeline,tektontrigger,tektonchain,tektonresult, +## manualapprovalgate,tektonpruner,tektonscheduler,tektonmulticlusterproxyaae, +## openshiftpipelinesascode +## kubernetes: common + tektondashboard +## openshift: common + tektonaddon,syncerservice controllers: "" ## Control the creation of RBAC resources (Serviceaccount, Role, ClusterRole, ClusterRoleBinding)