Repository: tektoncd/operator
Pull request #634 (2022-02-25 13:33:02)

[OpenShift] Fix RBAC bugs

Signed-off-by: Nikhil Thomas <nikthoma@redhat.com>

# Changes

- Rename rolebinding created by RBAC reconciler to
  'openshift-pipelines-edit' (was 'edit' earlier)

- Add mechanism to ensure that missing RBAC resources are recreated if
  the RBAC installerSet is recreated during an upgrade.
  - this ensures that RBAC in the version label user 
    namespaces are removed during an upgrade and the presence of RBAC
resources are re-verified

- Make TektonConfig reconciler listen to TektonInstallerSet events so
  that it can recreate RBAC InstallerSet if it is deleted manually from
a cluster

- Add a mechanism to remove ownerReference and 'pipeline' sa subject
  from 'edit' rolebinding in namespaces
  - This ensures that operator upgrades won't delete/reset 'edit'
    rolebinding in usernamespaces.
  - This mechanism will delete the edit role binding if the only subject is `pipeline` serviceaccount.
    


<!-- 🎉🎉🎉 Thank you for the PR!!! 🎉🎉🎉 -->

<!-- Describe your changes here- ideally you can get that description straight from
your descriptive commit message(s)! -->

# Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

- [ ] Includes [tests](https://github.com/tektoncd/community/blob/master/standards.md#principles) (if functionality changed/added)
- [ ] Includes [docs](https://github.com/tektoncd/community/blob/master/standards.md#principles) (if user facing)
- [X] Commit messages follow [commit message best practices](https://github.com/tektoncd/community/blob/master/standards.md#commit-messages)

_See [the contribution guide](https://github.com/tektoncd/operator/blob/master/CONTRIBUTING.md) for more details._

# Release Notes

<!--
Describe any user facing changes here, or delete this block.

Examples of user facing changes:
- API changes
- Bug fixes
- Any changes in behavior
- Changes requiring upgrade notices or deprecation warnings

For pull requests with a release note:

```release-note
Your release note here
```

For pull requests that require additional action from users switching to the new release, include the string "action required" (case insensitive) in the release note:

```release-note
action required: your release note here
```

For pull requests that don't need to be mentioned at release time, use the `/release-note-none` Prow command to add the `release-note-none` label to the PR. You can also write the string "NONE" as a release note in your PR description:

```release-note
NONE
```
-->
```release-note
Name of rolebinding which binds ClusterRole edit to 'pipeline' ServiceAccount in usernamespaces is now 'openshift-pipelines-edit' instead of 'edit'.
```

tekton-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **nikhil-thomas**
You can assign the PR to them by writing `/assign @nikhil-thomas` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=tektoncd%2Foperator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/tektoncd/operator/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["nikhil-thomas"]} -->
nikhil-thomas: /hold
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0d14f5e4615b97e70df95dcb14a463d9fc780b74 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1497206347232448512/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0d14f5e4615b97e70df95dcb14a463d9fc780b74 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1497206347232448512/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0ce60553a0c60b7a4312db89eb9777c110c870c8 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1498206940143030274/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0ce60553a0c60b7a4312db89eb9777c110c870c8 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1498206940143030274/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
nikhil-thomas: /retest
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0ce60553a0c60b7a4312db89eb9777c110c870c8 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1498589337808277504/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
tekton-robot: @nikhil-thomas: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-tekton-operator-integration-tests | 0ce60553a0c60b7a4312db89eb9777c110c870c8 | [link](https://tekton-releases.appspot.com/build/tekton-prow/pr-logs/pull/tektoncd_operator/634/pull-tekton-operator-integration-tests/1498589337808277504/) | `/test pull-tekton-operator-integration-tests`

[Full PR test history](https://tekton-releases.appspot.com/pr/tektoncd_operator/634). [Your PR dashboard](https://prow.tekton.dev/pr/nikhil-thomas).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
nikhil-thomas: /retest
nikhil-thomas: /hold cancel
sm43: /lgtm
tekton-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/tektoncd/operator/pull/634#pullrequestreview-899919684" title="Approved">vdemeester</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=tektoncd%2Foperator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/tektoncd/operator/blob/main/OWNERS)~~ [vdemeester]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
tekton-robot: New changes are detected. LGTM label has been removed.

Patch:
diff --git a/config/openshift/base/operator.yaml b/config/openshift/base/operator.yaml
index e85a0c64c..9f7093810 100644
--- a/config/openshift/base/operator.yaml
+++ b/config/openshift/base/operator.yaml
@@ -64,6 +64,8 @@ spec:
               key: DEFAULT_TARGET_NAMESPACE
         - name: CONFIG_OBSERVABILITY_NAME
           value: tekton-config-observability
+        - name: IMAGE_HUB_DB
+          value: registry.redhat.io/rhel8/postgresql-13:1-18
 #          - name: IMAGE_ADDONS_TKN_CLI_SERVE
 #            value: docker.io/rupali/serve-tkn:v2
 #          - name: IMAGE_ADDONS_PARAM_TKN_IMAGE
diff --git a/pkg/reconciler/common/certificates.go b/pkg/reconciler/common/certificates.go
new file mode 100644
index 000000000..391786793
--- /dev/null
+++ b/pkg/reconciler/common/certificates.go
@@ -0,0 +1,153 @@
+/*
+Copyright 2022 The Tekton Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package common
+
+import (
+	corev1 "k8s.io/api/core/v1"
+	"path/filepath"
+	"strings"
+)
+
+const (
+	// user-provided and system CA certificates
+	TrustedCAConfigMapName   = "config-trusted-cabundle"
+	TrustedCAConfigMapVolume = "config-trusted-cabundle-volume"
+	TrustedCAKey             = "ca-bundle.crt"
+
+	// service serving certificates (required to talk to the internal registry)
+	ServiceCAConfigMapName   = "config-service-cabundle"
+	ServiceCAConfigMapVolume = "config-service-cabundle-volume"
+	ServiceCAKey             = "service-ca.crt"
+)
+
+// newVolumeWithConfigMap creates a new volume with the given ConfigMap
+func newVolumeWithConfigMap(volumeName, configMapName, configMapKey, configMapPath string) corev1.Volume {
+	return corev1.Volume{
+		Name: volumeName,
+		VolumeSource: corev1.VolumeSource{
+			ConfigMap: &corev1.ConfigMapVolumeSource{
+				LocalObjectReference: corev1.LocalObjectReference{Name: configMapName},
+				Items: []corev1.KeyToPath{
+					{
+						Key:  configMapKey,
+						Path: configMapPath,
+					},
+				},
+			},
+		},
+	}
+}
+
+// AddCABundleConfigMapsToVolumes adds the config-trusted-cabundle and config-service-cabundle
+// ConfigMaps to the given list of volumes and removes duplicates, if any
+func AddCABundleConfigMapsToVolumes(volumes []corev1.Volume) []corev1.Volume {
+	// If CA bundle volumes already exists in the pod's volumes, then remove it
+	for _, volumeName := range []string{TrustedCAConfigMapVolume, ServiceCAConfigMapVolume} {
+		for i, v := range volumes {
+			if v.Name == volumeName {
+				volumes = append(volumes[:i], volumes[i+1:]...)
+				break
+			}
+		}
+	}
+
+	return append(
+		volumes,
+		newVolumeWithConfigMap(TrustedCAConfigMapVolume, TrustedCAConfigMapName, TrustedCAKey, TrustedCAKey),
+		newVolumeWithConfigMap(ServiceCAConfigMapVolume, ServiceCAConfigMapName, ServiceCAKey, ServiceCAKey),
+	)
+}
+
+// AddCABundlesToContainerVolumes adds the CA bundles to the container via VolumeMounts.
+// SSL_CERT_DIR environment variable is also set if it does not exist already.
+func AddCABundlesToContainerVolumes(c *corev1.Container) {
+	volumeMounts := c.VolumeMounts
+
+	// If volume mounts for CA bundles already exist then remove them
+	for _, volumeName := range []string{TrustedCAConfigMapVolume, ServiceCAConfigMapVolume} {
+		for i, vm := range volumeMounts {
+			if vm.Name == volumeName {
+				volumeMounts = append(volumeMounts[:i], volumeMounts[i+1:]...)
+				break
+			}
+		}
+	}
+
+	// We will mount the certs at /tekton-custom-certs so we don't override the existing certs
+	sslCertDir := "/tekton-custom-certs"
+	certEnvAvailable := false
+
+	for _, env := range c.Env {
+		// If SSL_CERT_DIR env var already exists, then we don't mess with
+		// it and simply carry it forward as it is
+		if env.Name == "SSL_CERT_DIR" {
+			sslCertDir = env.Value
+			certEnvAvailable = true
+			break
+		}
+	}
+
+	if !certEnvAvailable {
+		// Here, we need to set the default value for SSL_CERT_DIR.
+		// Keep in mind that if SSL_CERT_DIR is set, then it overrides the
+		// system default, i.e. the system default directories will "NOT"
+		// be scanned for certificates. This is risky and we don't want to
+		// do this because users mount certificates at these locations or
+		// build images with certificates "in" them and expect certificates
+		// to get picked up, and rightfully so since this is the documented
+		// way of achieving this.
+		// So, let's keep the system wide default locations in place and
+		// "append" our custom location to those.
+		//
+		// certDirectories copied from
+		// https://golang.org/src/crypto/x509/root_linux.go
+		var certDirectories = []string{
+			// Ordering is important here - we will be using the "first"
+			// element in SSL_CERT_DIR to do the volume mounts.
+			sslCertDir,                     // /tekton-custom-certs
+			"/etc/ssl/certs",               // SLES10/SLES11, https://golang.org/issue/12139
+			"/etc/pki/tls/certs",           // Fedora/RHEL
+			"/system/etc/security/cacerts", // Android
+		}
+
+		// SSL_CERT_DIR accepts a colon separated list of directories
+		sslCertDir = strings.Join(certDirectories, ":")
+		c.Env = append(c.Env, corev1.EnvVar{
+			Name:  "SSL_CERT_DIR",
+			Value: sslCertDir,
+		})
+	}
+
+	// Let's mount the certificates now.
+	volumeMounts = append(volumeMounts,
+		corev1.VolumeMount{
+			Name: TrustedCAConfigMapVolume,
+			// We only want the first entry in SSL_CERT_DIR for the mount
+			MountPath: filepath.Join(strings.Split(sslCertDir, ":")[0], TrustedCAKey),
+			SubPath:   TrustedCAKey,
+			ReadOnly:  true,
+		},
+		corev1.VolumeMount{
+			Name: ServiceCAConfigMapVolume,
+			// We only want the first entry in SSL_CERT_DIR for the mount
+			MountPath: filepath.Join(strings.Split(sslCertDir, ":")[0], ServiceCAKey),
+			SubPath:   ServiceCAKey,
+			ReadOnly:  true,
+		},
+	)
+	c.VolumeMounts = volumeMounts
+}
diff --git a/pkg/reconciler/common/transformers.go b/pkg/reconciler/common/transformers.go
index b7bb2cfe1..e46af0025 100644
--- a/pkg/reconciler/common/transformers.go
+++ b/pkg/reconciler/common/transformers.go
@@ -41,6 +41,7 @@ const (
 	TriggersImagePrefix           = "IMAGE_TRIGGERS_"
 	AddonsImagePrefix             = "IMAGE_ADDONS_"
 	ChainsImagePrefix             = "IMAGE_CHAINS_"
+	HubDbImagePrefix              = "IMAGE_HUB_"
 
 	ArgPrefix   = "arg_"
 	ParamPrefix = "param_"
diff --git a/pkg/reconciler/kubernetes/tektonhub/tektonhub.go b/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
index 0c970c33e..dfbc8068d 100644
--- a/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
+++ b/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
@@ -441,10 +441,17 @@ func (r *Reconciler) setupAndCreateInstallerSet(ctx context.Context, manifestLoc
 
 	manifest = manifest.Filter(mf.Not(mf.Any(mf.ByKind("Secret"), mf.ByKind("Namespace"), mf.ByKind("ConfigMap"))))
 
-	manifest, err := manifest.Transform(
+	images := common.ToLowerCaseKeys(common.ImagesFromEnv(common.HubDbImagePrefix))
+	trans := r.extension.Transformers(th)
+	extra := []mf.Transformer{
 		mf.InjectOwner(th),
 		mf.InjectNamespace(namespace),
-	)
+		common.DeploymentImages(images),
+	}
+	trans = append(trans, extra...)
+
+	manifest, err := manifest.Transform(trans...)
+
 	if err != nil {
 		logger.Error("failed to transform manifest")
 		return err
diff --git a/pkg/reconciler/openshift/common/cabundle.go b/pkg/reconciler/openshift/common/cabundle.go
index f6252c0bf..15a10f543 100644
--- a/pkg/reconciler/openshift/common/cabundle.go
+++ b/pkg/reconciler/openshift/common/cabundle.go
@@ -18,28 +18,14 @@ package common
 
 import (
 	"encoding/json"
-	"path/filepath"
-	"strings"
 
+	"github.com/tektoncd/operator/pkg/reconciler/common"
 	appsv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes/scheme"
 )
 
-const (
-	// user-provided and system CA certificates
-	trustedCAConfigMapName   = "config-trusted-cabundle"
-	trustedCAConfigMapVolume = "config-trusted-cabundle-volume"
-	trustedCAKey             = "ca-bundle.crt"
-
-	// service serving certificates (required to talk to the internal registry)
-	serviceCAConfigMapName   = "config-service-cabundle"
-	serviceCAConfigMapVolume = "config-service-cabundle-volume"
-	serviceCAKey             = "service-ca.crt"
-)
-
 // ApplyCABundles is a transformer that add the trustedCA volume, mount and
 // environment variables so that the deployment uses it.
 func ApplyCABundles(u *unstructured.Unstructured) error {
@@ -53,94 +39,14 @@ func ApplyCABundles(u *unstructured.Unstructured) error {
 		return err
 	}
 
-	volumes := deployment.Spec.Template.Spec.Volumes
-
-	// If CA bundle volumes already exists in the PodSpec, then remove it
-	for _, volumeName := range []string{trustedCAConfigMapVolume, serviceCAConfigMapVolume} {
-		for i, v := range volumes {
-			if v.Name == volumeName {
-				volumes = append(volumes[:i], volumes[i+1:]...)
-				break
-			}
-		}
-	}
-
 	// Let's add the trusted and service CA bundle ConfigMaps as a volume in
 	// the PodSpec which will later be mounted to add certs in the pod.
-	volumes = append(volumes,
-		// Add trusted CA bundle
-		corev1.Volume{
-			Name: trustedCAConfigMapVolume,
-			VolumeSource: corev1.VolumeSource{
-				ConfigMap: &corev1.ConfigMapVolumeSource{
-					LocalObjectReference: corev1.LocalObjectReference{Name: trustedCAConfigMapName},
-					Items: []corev1.KeyToPath{
-						{
-							Key:  trustedCAKey,
-							Path: trustedCAKey,
-						},
-					},
-				},
-			},
-		},
-		// Add service serving certificates bundle
-		corev1.Volume{
-			Name: serviceCAConfigMapVolume,
-			VolumeSource: corev1.VolumeSource{
-				ConfigMap: &corev1.ConfigMapVolumeSource{
-					LocalObjectReference: corev1.LocalObjectReference{Name: serviceCAConfigMapName},
-					Items: []corev1.KeyToPath{
-						{
-							Key:  serviceCAKey,
-							Path: serviceCAKey,
-						},
-					},
-				},
-			},
-		})
-	deployment.Spec.Template.Spec.Volumes = volumes
+	deployment.Spec.Template.Spec.Volumes = common.AddCABundleConfigMapsToVolumes(deployment.Spec.Template.Spec.Volumes)
 
 	// Now that the injected certificates have been added as a volume, let's
 	// mount them via volumeMounts in the containers
 	for i, c := range deployment.Spec.Template.Spec.Containers {
-		volumeMounts := c.VolumeMounts
-
-		// If volume mounts for injected certificates already exist then remove them
-		for _, volumeName := range []string{trustedCAConfigMapVolume, serviceCAConfigMapVolume} {
-			for i, vm := range volumeMounts {
-				if vm.Name == volumeName {
-					volumeMounts = append(volumeMounts[:i], volumeMounts[i+1:]...)
-					break
-				}
-			}
-		}
-
-		// We will mount the certs at this location so we don't override the existing certs
-		sslCertDir := "/tekton-custom-certs"
-		for _, env := range c.Env {
-			if env.Name == "SSL_CERT_DIR" {
-				sslCertDir = env.Value
-			}
-		}
-
-		// Let's mount the certificates now.
-		volumeMounts = append(volumeMounts,
-			corev1.VolumeMount{
-				Name: trustedCAConfigMapVolume,
-				// We only want the first entry in SSL_CERT_DIR for the mount
-				MountPath: filepath.Join(strings.Split(sslCertDir, ":")[0], trustedCAKey),
-				SubPath:   trustedCAKey,
-				ReadOnly:  true,
-			},
-			corev1.VolumeMount{
-				Name: serviceCAConfigMapVolume,
-				// We only want the first entry in SSL_CERT_DIR for the mount
-				MountPath: filepath.Join(strings.Split(sslCertDir, ":")[0], serviceCAKey),
-				SubPath:   serviceCAKey,
-				ReadOnly:  true,
-			},
-		)
-		c.VolumeMounts = volumeMounts
+		common.AddCABundlesToContainerVolumes(&c)
 		deployment.Spec.Template.Spec.Containers[i] = c
 	}
 
diff --git a/pkg/reconciler/openshift/tektonconfig/common.go b/pkg/reconciler/openshift/tektonconfig/common.go
index eb02f686e..2204e37e3 100644
--- a/pkg/reconciler/openshift/tektonconfig/common.go
+++ b/pkg/reconciler/openshift/tektonconfig/common.go
@@ -103,40 +103,37 @@ func deleteInstallerSet(ctx context.Context, oc versioned.Interface, tc *v1alpha
 // and if installer set which already exist is of older version then it deletes and return false to create a new
 // installer set
 func checkIfInstallerSetExist(ctx context.Context, oc versioned.Interface, relVersion string,
-	tc *v1alpha1.TektonConfig, component string) (bool, error) {
+	tc *v1alpha1.TektonConfig, component string) (*v1alpha1.TektonInstallerSet, error) {
 
 	// Check if installer set is already created
 	compInstallerSet, ok := tc.Status.TektonInstallerSet[component]
-	if !ok {
-		return false, nil
+	if !ok || compInstallerSet == "" {
+		return nil, nil
 	}
 
-	if compInstallerSet != "" {
-		// if already created then check which version it is
-		ctIs, err := oc.OperatorV1alpha1().TektonInstallerSets().
-			Get(ctx, compInstallerSet, metav1.GetOptions{})
-		if err != nil {
-			if errors.IsNotFound(err) {
-				return false, nil
-			}
-			return false, err
+	// if already created then check which version it is
+	ctIs, err := oc.OperatorV1alpha1().TektonInstallerSets().
+		Get(ctx, compInstallerSet, metav1.GetOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			return nil, nil
 		}
+		return nil, err
+	}
 
-		if version, ok := ctIs.Annotations[v1alpha1.ReleaseVersionKey]; ok && version == relVersion {
-			// if installer set already exist and release version is same
-			// then ignore and move on
-			return true, nil
-		}
+	if version, ok := ctIs.Annotations[v1alpha1.ReleaseVersionKey]; ok && version == relVersion {
+		// if installer set already exist and release version is same
+		// then ignore and move on
+		return ctIs, nil
+	}
 
-		// release version doesn't exist or is different from expected
-		// deleted existing InstallerSet and create a new one
+	// release version doesn't exist or is different from expected
+	// deleted existing InstallerSet and create a new one
 
-		err = oc.OperatorV1alpha1().TektonInstallerSets().
-			Delete(ctx, compInstallerSet, metav1.DeleteOptions{})
-		if err != nil {
-			return false, err
-		}
+	err = oc.OperatorV1alpha1().TektonInstallerSets().
+		Delete(ctx, compInstallerSet, metav1.DeleteOptions{})
+	if err != nil {
+		return nil, err
 	}
-
-	return false, nil
+	return nil, v1alpha1.RECONCILE_AGAIN_ERR
 }
diff --git a/pkg/reconciler/openshift/tektonconfig/extension.go b/pkg/reconciler/openshift/tektonconfig/extension.go
index 4004aee54..3ebb79051 100644
--- a/pkg/reconciler/openshift/tektonconfig/extension.go
+++ b/pkg/reconciler/openshift/tektonconfig/extension.go
@@ -73,7 +73,7 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto
 		// then disable auto creation of RBAC resources by deleting installerSet
 		if v.Name == rbacParamName && v.Value == "false" {
 			createRBACResource = false
-			if err := deleteInstallerSet(ctx, r.operatorClientSet, r.tektonConfig, componentName); err != nil {
+			if err := deleteInstallerSet(ctx, r.operatorClientSet, r.tektonConfig, componentNameRBAC); err != nil {
 				return err
 			}
 			// remove openshift-pipelines.tekton.dev/namespace-reconcile-version label from namespaces while deleting RBAC resources.
@@ -83,10 +83,16 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto
 		}
 	}
 
+	// TODO: Remove this after v0.55.0 release, by following a depreciation notice
+	// --------------------
+	if err := r.cleanUpRBACNameChange(ctx); err != nil {
+		return err
+	}
+	// --------------------
+
 	if createRBACResource {
 		return r.createResources(ctx)
 	}
-
 	return nil
 }
 
diff --git a/pkg/reconciler/openshift/tektonconfig/rbac.go b/pkg/reconciler/openshift/tektonconfig/rbac.go
index 2b6771f90..b85c1527e 100644
--- a/pkg/reconciler/openshift/tektonconfig/rbac.go
+++ b/pkg/reconciler/openshift/tektonconfig/rbac.go
@@ -19,6 +19,7 @@ package tektonconfig
 import (
 	"context"
 	"fmt"
+	"math"
 	"regexp"
 
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
@@ -34,16 +35,21 @@ import (
 )
 
 const (
-	pipelinesSCCClusterRole  = "pipelines-scc-clusterrole"
-	pipelinesSCCRoleBinding  = "pipelines-scc-rolebinding"
-	pipelinesSCC             = "pipelines-scc"
-	pipelineSA               = "pipeline"
+	pipelinesSCCClusterRole = "pipelines-scc-clusterrole"
+	pipelinesSCCRoleBinding = "pipelines-scc-rolebinding"
+	pipelinesSCC            = "pipelines-scc"
+	pipelineSA              = "pipeline"
+	PipelineRoleBinding     = "openshift-pipelines-edit"
+	// TODO: Remove this after v0.55.0 release, by following a depreciation notice
+	// --------------------
+	pipelineRoleBindingOld = "edit"
+	// --------------------
 	serviceCABundleConfigMap = "config-service-cabundle"
 	trustedCABundleConfigMap = "config-trusted-cabundle"
 	clusterInterceptors      = "openshift-pipelines-clusterinterceptors"
 	namespaceVersionLabel    = "openshift-pipelines.tekton.dev/namespace-reconcile-version"
 	createdByValue           = "RBAC"
-	componentName            = "rhosp-rbac"
+	componentNameRBAC        = "rhosp-rbac"
 	rbacParamName            = "createRbacResource"
 )
 
@@ -80,6 +86,34 @@ func (r *rbac) cleanUp(ctx context.Context) error {
 	return nil
 }
 
+func (r *rbac) EnsureRBACInstallerSet(ctx context.Context) (*v1alpha1.TektonInstallerSet, error) {
+	rbacISet, err := checkIfInstallerSetExist(ctx, r.operatorClientSet, r.version, r.tektonConfig, componentNameRBAC)
+	if err != nil {
+		return nil, err
+	}
+
+	if rbacISet != nil {
+		return rbacISet, nil
+	}
+	// A new installer needs to be created
+	// either because of operator version upgrade or installerSet gone missing;
+	// therefore all relevant namespaces need to be reconciled for RBAC resources.
+	// Hence, remove the necessary labels to ensure that the namespaces will be 'not skipped'
+	// RBAC reconcile logic
+	err = r.cleanUp(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	err = createInstallerSet(ctx, r.operatorClientSet, r.tektonConfig, map[string]string{
+		v1alpha1.CreatedByKey: createdByValue,
+	}, r.version, componentNameRBAC, "rbac-resources")
+	if err != nil {
+		return nil, err
+	}
+	return nil, v1alpha1.RECONCILE_AGAIN_ERR
+}
+
 func (r *rbac) setDefault() {
 	var (
 		found = false
@@ -107,6 +141,13 @@ func (r *rbac) createResources(ctx context.Context) error {
 
 	logger := logging.FromContext(ctx)
 
+	rbacISet, err := r.EnsureRBACInstallerSet(ctx)
+	if err != nil {
+		return err
+	}
+
+	r.ownerRef = configOwnerRef(*rbacISet)
+
 	// fetch the list of all namespaces which doesn't have label
 	// `openshift-pipelines.tekton.dev/namespace-reconcile-version: <release-version>`
 	namespaces, err := r.kubeClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{
@@ -132,26 +173,6 @@ func (r *rbac) createResources(ctx context.Context) error {
 		return nil
 	}
 
-	exist, err := checkIfInstallerSetExist(ctx, r.operatorClientSet, r.version, r.tektonConfig, componentName)
-	if err != nil {
-		return err
-	}
-	if !exist {
-		if err := createInstallerSet(ctx, r.operatorClientSet, r.tektonConfig, map[string]string{
-			v1alpha1.CreatedByKey: createdByValue,
-		}, r.version, componentName, "rbac-resources"); err != nil {
-			return err
-		}
-	}
-
-	getdIs, err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-		Get(ctx, "rbac-resources", metav1.GetOptions{})
-	if err != nil {
-		return err
-	}
-
-	r.ownerRef = configOwnerRef(*getdIs)
-
 	// Maintaining a separate cluster role for the scc declaration.
 	// to assist us in managing this the scc association in a
 	// granular way.
@@ -455,14 +476,14 @@ func (r *rbac) updateRoleBinding(ctx context.Context, rb *rbacv1.RoleBinding, sa
 		return nil
 	}
 
-	logger.Info("update existing rolebinding edit")
+	logger.Infof("update existing rolebinding %s/%s", rb.Namespace, rb.Name)
 
 	_, err := rbacClient.RoleBindings(sa.Namespace).Update(ctx, rb, metav1.UpdateOptions{})
 	if err != nil {
-		logger.Error(err, "failed to update edit rb")
+		logger.Errorf("%v: failed to update rolebinding %s/%s", err, rb.Namespace, rb.Name)
 		return err
 	}
-	logger.Error(err, "successfully updated edit rb")
+	logger.Infof("successfully updated rolebinding %s/%s", rb.Namespace, rb.Name)
 	return nil
 }
 
@@ -487,10 +508,10 @@ func hasOwnerRefernce(old []metav1.OwnerReference, new metav1.OwnerReference) bo
 func (r *rbac) ensureRoleBindings(ctx context.Context, sa *corev1.ServiceAccount) error {
 	logger := logging.FromContext(ctx)
 
-	logger.Info("finding role-binding edit")
+	logger.Infof("finding role-binding: %s/%s", sa.Namespace, PipelineRoleBinding)
 	rbacClient := r.kubeClientSet.RbacV1()
 
-	editRB, err := rbacClient.RoleBindings(sa.Namespace).Get(ctx, "edit", metav1.GetOptions{})
+	editRB, err := rbacClient.RoleBindings(sa.Namespace).Get(ctx, PipelineRoleBinding, metav1.GetOptions{})
 
 	if err == nil {
 		logger.Infof("found rolebinding %s/%s", editRB.Namespace, editRB.Name)
@@ -507,7 +528,7 @@ func (r *rbac) ensureRoleBindings(ctx context.Context, sa *corev1.ServiceAccount
 func (r *rbac) createRoleBinding(ctx context.Context, sa *corev1.ServiceAccount) error {
 	logger := logging.FromContext(ctx)
 
-	logger.Info("create new rolebinding edit, in Namespace", sa.GetNamespace())
+	logger.Infof("create new rolebinding %s/%s", sa.Namespace, sa.Name)
 	rbacClient := r.kubeClientSet.RbacV1()
 
 	logger.Info("finding clusterrole edit")
@@ -518,7 +539,7 @@ func (r *rbac) createRoleBinding(ctx context.Context, sa *corev1.ServiceAccount)
 
 	rb := &rbacv1.RoleBinding{
 		ObjectMeta: metav1.ObjectMeta{
-			Name:            "edit",
+			Name:            PipelineRoleBinding,
 			Namespace:       sa.Namespace,
 			OwnerReferences: []metav1.OwnerReference{r.ownerRef},
 		},
@@ -527,7 +548,7 @@ func (r *rbac) createRoleBinding(ctx context.Context, sa *corev1.ServiceAccount)
 	}
 
 	if _, err := rbacClient.RoleBindings(sa.Namespace).Create(ctx, rb, metav1.CreateOptions{}); err != nil {
-		logger.Error(err, "creation of 'edit' rolebinding failed, in Namespace", sa.GetNamespace())
+		logger.Errorf("%v: failed creation of rolebinding %s/%s", err, rb.Namespace, rb.Name)
 		return err
 	}
 	return nil
@@ -672,3 +693,91 @@ func (r *rbac) removeAndUpdate(slice []metav1.OwnerReference, s int) []metav1.Ow
 	ownerRef = append(ownerRef, r.ownerRef)
 	return ownerRef
 }
+
+// TODO: Remove this after v0.55.0 release, by following a depreciation notice
+// --------------------
+// cleanUpRBACNameChange will check remove ownerReference: RBAC installerset from
+// 'edit' rolebindings from all relevant namespaces
+// it will also remove 'pipeline' sa from subject list as
+// the new 'openshift-pipelines-edit' rolebinding
+func (r *rbac) cleanUpRBACNameChange(ctx context.Context) error {
+	rbacClient := r.kubeClientSet.RbacV1()
+
+	// fetch the list of all namespaces
+	namespaces, err := r.kubeClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
+	if err != nil {
+		return err
+	}
+
+	for _, ns := range namespaces.Items {
+		nsName := ns.GetName()
+
+		// filter namespaces:
+		// ignore ns with name passing regex `^(openshift|kube)-`
+		if ignore := nsRegex.MatchString(nsName); ignore {
+			continue
+		}
+
+		// check if "edit" rolebinding exists in "ns" namespace
+		editRB, err := rbacClient.RoleBindings(ns.GetName()).
+			Get(ctx, pipelineRoleBindingOld, metav1.GetOptions{})
+		if err != nil {
+			// if "edit" rolebinding does not exists in "ns" namesapce, then do nothing
+			if errors.IsNotFound(err) {
+				continue
+			}
+			return err
+		}
+
+		// check if 'pipeline' serviceaccount is listed as a subject in 'edit' rolebinding
+		depSub := rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Name: pipelineSA, Namespace: nsName}
+		subIdx := math.MinInt16
+		for i, s := range editRB.Subjects {
+			if s.Name == depSub.Name && s.Kind == depSub.Kind && s.Namespace == depSub.Namespace {
+				subIdx = i
+				break
+			}
+		}
+
+		// if 'pipeline' serviceaccount is listed as a subject in 'edit' rolebinding
+		// remove 'pipeline' serviceaccount from subject list
+		if subIdx >= 0 {
+			editRB.Subjects = append(editRB.Subjects[:subIdx], editRB.Subjects[subIdx+1:]...)
+		}
+
+		// if 'pipeline' serviceaccount was the only item in the subject list of 'edit' rolebinding,
+		// then we can delete 'edit' rolebinding as nobody else is using it
+		if len(editRB.Subjects) == 0 {
+			if err := rbacClient.RoleBindings(nsName).Delete(ctx, editRB.GetName(), metav1.DeleteOptions{}); err != nil {
+				return err
+			}
+			continue
+		}
+
+		// remove TektonInstallerSet ownerReferece from "edit" rolebinding
+		ownerRefs := editRB.GetOwnerReferences()
+		ownerRefIdx := math.MinInt16
+		for i, ownerRef := range ownerRefs {
+			if ownerRef.Kind == "TektonInstallerSet" {
+				ownerRefIdx = i
+				break
+			}
+		}
+		if ownerRefIdx >= 0 {
+			ownerRefs := append(ownerRefs[:ownerRefIdx], ownerRefs[ownerRefIdx+1:]...)
+			editRB.SetOwnerReferences(ownerRefs)
+
+		}
+
+		// if ownerReference or subject was updated, then update editRB resource on cluster
+		if ownerRefIdx < 0 && subIdx < 0 {
+			continue
+		}
+		if _, err := rbacClient.RoleBindings(nsName).Update(ctx, editRB, metav1.UpdateOptions{}); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// --------------------
diff --git a/pkg/reconciler/openshift/tektonhub/extension.go b/pkg/reconciler/openshift/tektonhub/extension.go
index 1b926e875..dd7d00700 100644
--- a/pkg/reconciler/openshift/tektonhub/extension.go
+++ b/pkg/reconciler/openshift/tektonhub/extension.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"fmt"
 	"path/filepath"
+	"strings"
 
 	"github.com/go-logr/zapr"
 	mfc "github.com/manifestival/client-go-client"
@@ -31,7 +32,11 @@ import (
 	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
 	"github.com/tektoncd/operator/pkg/reconciler/common"
 	"go.uber.org/zap"
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/kubernetes"
 	kubeclient "knative.dev/pkg/client/injection/kube/client"
 	"knative.dev/pkg/injection"
@@ -44,6 +49,12 @@ const (
 	tektonHubUiResourceKey   string = "ui"
 )
 
+var replaceVal = map[string]string{
+	"POSTGRES_DB":       "POSTGRESQL_DATABASE",
+	"POSTGRES_USER":     "POSTGRESQL_USER",
+	"POSTGRES_PASSWORD": "POSTGRESQL_PASSWORD",
+}
+
 func OpenShiftExtension(ctx context.Context) common.Extension {
 	logger := logging.FromContext(ctx)
 	mfclient, err := mfc.NewClient(injection.GetConfig(ctx))
@@ -71,7 +82,7 @@ type openshiftExtension struct {
 }
 
 func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer {
-	return nil
+	return []mf.Transformer{UpdateDbDeployment()}
 }
 
 func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.TektonComponent) error {
@@ -197,3 +208,59 @@ func getRouteHost(manifest *mf.Manifest, routeName string) (string, error) {
 	}
 	return hostUrl, nil
 }
+
+func UpdateDbDeployment() mf.Transformer {
+	return func(u *unstructured.Unstructured) error {
+		if u.GetKind() != "Deployment" {
+			return nil
+		}
+
+		d := &appsv1.Deployment{}
+		err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, d)
+		if err != nil {
+			return err
+		}
+
+		if d.Name == "db" {
+			env := d.Spec.Template.Spec.Containers[0].Env
+
+			replaceEnv(env)
+
+			d.Spec.Template.Spec.Containers[0].Env = env
+
+			mountPath := "/var/lib/pgsql/data"
+			d.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath = mountPath
+
+			replaceProbeCommand(d.Spec.Template.Spec.Containers[0].ReadinessProbe.Exec.Command)
+			replaceProbeCommand(d.Spec.Template.Spec.Containers[0].LivenessProbe.Exec.Command)
+
+			unstrObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(d)
+			if err != nil {
+				return err
+			}
+			u.SetUnstructuredContent(unstrObj)
+
+			return nil
+		}
+
+		return nil
+	}
+}
+
+func replaceProbeCommand(data []string) {
+	if strings.Contains(data[2], "POSTGRES_USER") {
+		data[2] = strings.ReplaceAll(data[2], "POSTGRES_USER", "POSTGRESQL_USER")
+	}
+	if strings.Contains(data[2], "POSTGRES_DB") {
+		data[2] = strings.ReplaceAll(data[2], "POSTGRES_DB", "POSTGRESQL_DATABASE")
+	}
+}
+
+func replaceEnv(envs []corev1.EnvVar) {
+	for i, e := range envs {
+		_, ok := replaceVal[e.Name]
+		if ok {
+			envs[i].Name = replaceVal[e.Name]
+		}
+	}
+}
diff --git a/pkg/reconciler/proxy/proxy.go b/pkg/reconciler/proxy/proxy.go
index 2ca6ce1e6..794a0d2ca 100644
--- a/pkg/reconciler/proxy/proxy.go
+++ b/pkg/reconciler/proxy/proxy.go
@@ -21,8 +21,8 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"github.com/tektoncd/operator/pkg/reconciler/common"
 	"os"
-	"path/filepath"
 	"strings"
 
 	"github.com/markbates/inflect"
@@ -50,18 +50,6 @@ import (
 	certresources "knative.dev/pkg/webhook/certificates/resources"
 )
 
-const (
-	// user-provided and system CA certificates
-	trustedCAConfigMapName   = "config-trusted-cabundle"
-	trustedCAConfigMapVolume = "config-trusted-cabundle-volume"
-	trustedCAKey             = "ca-bundle.crt"
-
-	// service serving certificates (required to talk to the internal registry)
-	serviceCAConfigMapName   = "config-service-cabundle"
-	serviceCAConfigMapVolume = "config-service-cabundle-volume"
-	serviceCAKey             = "service-ca.crt"
-)
-
 // reconciler implements the AdmissionController for resources
 type reconciler struct {
 	webhook.StatelessAdmissionImpl
@@ -319,22 +307,17 @@ func setDefaults(client kubernetes.Interface, ctx context.Context, patches duck.
 		}
 	}
 
-	exist, err := checkConfigMapExist(client, ctx, after.Namespace, trustedCAConfigMapName)
+	trustedConfigMapExists, err := checkConfigMapExist(client, ctx, after.Namespace, common.TrustedCAConfigMapName)
 	if err != nil {
 		return nil, err
 	}
-	if exist {
-		after = updateVolume(after, trustedCAConfigMapVolume, trustedCAConfigMapName, trustedCAKey)
-	}
-
-	exist, err = checkConfigMapExist(client, ctx, after.Namespace, serviceCAConfigMapName)
+	serviceConfigMapExists, err := checkConfigMapExist(client, ctx, after.Namespace, common.ServiceCAConfigMapName)
 	if err != nil {
 		return nil, err
 	}
-	if exist {
-		after = updateVolume(after, serviceCAConfigMapVolume, serviceCAConfigMapName, serviceCAKey)
+	if trustedConfigMapExists && serviceConfigMapExists {
+		after = updateVolume(after)
 	}
-
 	patch, err := duck.CreatePatch(before, after)
 	if err != nil {
 		return nil, err
@@ -358,104 +341,15 @@ func checkConfigMapExist(client kubernetes.Interface, ctx context.Context, ns st
 }
 
 // update volume and volume mounts to mount the certs configmap
-func updateVolume(pod corev1.Pod, volumeName, configmapName, key string) corev1.Pod {
-	volumes := pod.Spec.Volumes
-
-	for i, v := range volumes {
-		if v.Name == volumeName {
-			volumes = append(volumes[:i], volumes[i+1:]...)
-			break
-		}
-	}
-
+func updateVolume(pod corev1.Pod) corev1.Pod {
 	// Let's add the trusted and service CA bundle ConfigMaps as a volume in
-	// the PodSpec which will later be mounted to add certs in the pod.
-	volumes = append(volumes,
-		// Add trusted CA bundle
-		corev1.Volume{
-			Name: volumeName,
-			VolumeSource: corev1.VolumeSource{
-				ConfigMap: &corev1.ConfigMapVolumeSource{
-					LocalObjectReference: corev1.LocalObjectReference{Name: configmapName},
-					Items: []corev1.KeyToPath{
-						{
-							Key:  key,
-							Path: key,
-						},
-					},
-				},
-			},
-		},
-	)
-	pod.Spec.Volumes = volumes
+	// the PodSpec which will later be mounted to add certs in the pod
+	pod.Spec.Volumes = common.AddCABundleConfigMapsToVolumes(pod.Spec.Volumes)
 
-	// Now that the injected certificates have been added as a volume, let's
-	// mount them via volumeMounts in the containers
+	// Now that the ConfigMaps have been added as volumes, let's
+	// mount them via VolumeMounts in the containers
 	for i, c := range pod.Spec.Containers {
-		volumeMounts := c.VolumeMounts
-
-		// If volume mounts for injected certificates already exist then remove them
-		for i, vm := range volumeMounts {
-			if vm.Name == volumeName {
-				volumeMounts = append(volumeMounts[:i], volumeMounts[i+1:]...)
-				break
-			}
-		}
-
-		// We will mount the certs at this location so we don't override the existing certs
-		sslCertDir := "/tekton-custom-certs"
-		certEnvAvaiable := false
-
-		for _, env := range c.Env {
-			// If SSL_CERT_DIR env var already exists, then we don't mess with
-			// it and simply carry it forward as it is
-			if env.Name == "SSL_CERT_DIR" {
-				sslCertDir = env.Value
-				certEnvAvaiable = true
-			}
-		}
-
-		if !certEnvAvaiable {
-			// Here, we need to set the default value for SSL_CERT_DIR.
-			// Keep in mind that if SSL_CERT_DIR is set, then it overrides the
-			// system default, i.e. the system default directories will "NOT"
-			// be scanned for certificates. This is risky and we don't want to
-			// do this because users mount certificates at these locations or
-			// build images with certificates "in" them and expect certificates
-			// to get picked up, and rightfully so since this is the documented
-			// way of achieving this.
-			// So, let's keep the system wide default locations in place and
-			// "append" our custom location to those.
-			//
-			// Copied from https://golang.org/src/crypto/x509/root_linux.go
-			var certDirectories = []string{
-				// Ordering is important here - we will be using the "first"
-				// element in SSL_CERT_DIR to do the volume mounts.
-				sslCertDir,                     // /tekton-custom-certs
-				"/etc/ssl/certs",               // SLES10/SLES11, https://golang.org/issue/12139
-				"/etc/pki/tls/certs",           // Fedora/RHEL
-				"/system/etc/security/cacerts", // Android
-			}
-
-			// SSL_CERT_DIR accepts a colon separated list of directories
-			sslCertDir = strings.Join(certDirectories, ":")
-			c.Env = append(c.Env, corev1.EnvVar{
-				Name:  "SSL_CERT_DIR",
-				Value: sslCertDir,
-			})
-		}
-
-		// Let's mount the certificates now.
-		volumeMounts = append(volumeMounts,
-			corev1.VolumeMount{
-				Name: volumeName,
-				// We only want the first entry in SSL_CERT_DIR for the mount
-				MountPath: filepath.Join(strings.Split(sslCertDir, ":")[0], key),
-				SubPath:   key,
-				ReadOnly:  true,
-			},
-		)
-		c.VolumeMounts = volumeMounts
+		common.AddCABundlesToContainerVolumes(&c)
 		pod.Spec.Containers[i] = c
 	}
 	return pod
diff --git a/pkg/reconciler/shared/tektonconfig/controller.go b/pkg/reconciler/shared/tektonconfig/controller.go
index 1a1b29912..97237f487 100644
--- a/pkg/reconciler/shared/tektonconfig/controller.go
+++ b/pkg/reconciler/shared/tektonconfig/controller.go
@@ -35,6 +35,7 @@ import (
 	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
 	tektonChainsinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonchains"
 	tektonConfiginformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonconfig"
+	tektonInstallerinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektoninstallerset"
 	tektonPipelineinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonpipeline"
 	tektonTriggerinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektontrigger"
 	tektonConfigreconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonconfig"
@@ -99,6 +100,11 @@ func NewExtensibleController(generator common.ExtensionGenerator) injection.Cont
 			Handler:    controller.HandleAll(impl.EnqueueControllerOf),
 		})
 
+		tektonInstallerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
+			FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}),
+			Handler:    controller.HandleAll(impl.EnqueueControllerOf),
+		})
+
 		namespaceinformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(enqueueCustomName(impl, v1alpha1.ConfigResourceName)))
 
 		if os.Getenv("AUTOINSTALL_COMPONENTS") == "true" {


Test patch:
diff --git a/pkg/reconciler/openshift/common/cabundle_test.go b/pkg/reconciler/openshift/common/cabundle_test.go
index ca0b87892..226f3c599 100644
--- a/pkg/reconciler/openshift/common/cabundle_test.go
+++ b/pkg/reconciler/openshift/common/cabundle_test.go
@@ -18,6 +18,7 @@ package common
 
 import (
 	"encoding/json"
+	"github.com/tektoncd/operator/pkg/reconciler/common"
 	"path/filepath"
 	"testing"
 
@@ -32,29 +33,35 @@ import (
 func TestApplyCABundles(t *testing.T) {
 	actual := unstructuredDeployment(t)
 	expected := unstructuredDeployment(t,
+		withEnvs(
+			corev1.EnvVar{
+				Name:  "SSL_CERT_DIR",
+				Value: "/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts",
+			},
+		),
 		withVolumes(corev1.Volume{
-			Name: trustedCAConfigMapVolume,
+			Name: common.TrustedCAConfigMapVolume,
 			VolumeSource: corev1.VolumeSource{
 				ConfigMap: &corev1.ConfigMapVolumeSource{
-					LocalObjectReference: corev1.LocalObjectReference{Name: trustedCAConfigMapName},
+					LocalObjectReference: corev1.LocalObjectReference{Name: common.TrustedCAConfigMapName},
 					Items: []corev1.KeyToPath{
 						{
-							Key:  trustedCAKey,
-							Path: trustedCAKey,
+							Key:  common.TrustedCAKey,
+							Path: common.TrustedCAKey,
 						},
 					},
 				},
 			},
 		},
 			corev1.Volume{
-				Name: serviceCAConfigMapVolume,
+				Name: common.ServiceCAConfigMapVolume,
 				VolumeSource: corev1.VolumeSource{
 					ConfigMap: &corev1.ConfigMapVolumeSource{
-						LocalObjectReference: corev1.LocalObjectReference{Name: serviceCAConfigMapName},
+						LocalObjectReference: corev1.LocalObjectReference{Name: common.ServiceCAConfigMapName},
 						Items: []corev1.KeyToPath{
 							{
-								Key:  serviceCAKey,
-								Path: serviceCAKey,
+								Key:  common.ServiceCAKey,
+								Path: common.ServiceCAKey,
 							},
 						},
 					},
@@ -62,15 +69,15 @@ func TestApplyCABundles(t *testing.T) {
 			}),
 		withVolumeMounts(
 			corev1.VolumeMount{
-				Name:      trustedCAConfigMapVolume,
-				MountPath: filepath.Join("/tekton-custom-certs", trustedCAKey),
-				SubPath:   trustedCAKey,
+				Name:      common.TrustedCAConfigMapVolume,
+				MountPath: filepath.Join("/tekton-custom-certs", common.TrustedCAKey),
+				SubPath:   common.TrustedCAKey,
 				ReadOnly:  true,
 			},
 			corev1.VolumeMount{
-				Name:      serviceCAConfigMapVolume,
-				MountPath: filepath.Join("/tekton-custom-certs", serviceCAKey),
-				SubPath:   serviceCAKey,
+				Name:      common.ServiceCAConfigMapVolume,
+				MountPath: filepath.Join("/tekton-custom-certs", common.ServiceCAKey),
+				SubPath:   common.ServiceCAKey,
 				ReadOnly:  true,
 			},
 		),
@@ -133,6 +140,15 @@ func unstructuredDeployment(t *testing.T, modifiers ...deploymentModifier) *unst
 	return ud
 }
 
+func withEnvs(envs ...corev1.EnvVar) func(*appsv1.Deployment) {
+	return func(d *appsv1.Deployment) {
+		for i, c := range d.Spec.Template.Spec.Containers {
+			c.Env = append(c.Env, envs...)
+			d.Spec.Template.Spec.Containers[i] = c
+		}
+	}
+}
+
 func withVolumes(volumes ...corev1.Volume) func(*appsv1.Deployment) {
 	return func(d *appsv1.Deployment) {
 		d.Spec.Template.Spec.Volumes = append(d.Spec.Template.Spec.Volumes, volumes...)
diff --git a/pkg/reconciler/openshift/tektonhub/extension_test.go b/pkg/reconciler/openshift/tektonhub/extension_test.go
new file mode 100644
index 000000000..a7beeee1d
--- /dev/null
+++ b/pkg/reconciler/openshift/tektonhub/extension_test.go
@@ -0,0 +1,51 @@
+/*
+Copyright 2022 The Tekton Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tektonhub
+
+import (
+	"path"
+	"strings"
+	"testing"
+
+	mf "github.com/manifestival/manifestival"
+	"gotest.tools/v3/assert"
+	appsv1 "k8s.io/api/apps/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+)
+
+func TestUpdateDbDeployment(t *testing.T) {
+	testData := path.Join("testdata", "update-db-deployment.yaml")
+
+	manifest, err := mf.ManifestFrom(mf.Recursive(testData))
+	assert.NilError(t, err)
+
+	newManifest, err := manifest.Transform(UpdateDbDeployment())
+	assert.NilError(t, err)
+
+	d := &appsv1.Deployment{}
+	err = runtime.DefaultUnstructuredConverter.FromUnstructured(newManifest.Resources()[0].Object, d)
+	assert.NilError(t, err)
+
+	env := d.Spec.Template.Spec.Containers[0].Env
+	assert.Equal(t, env[0].Name, "POSTGRESQL_DATABASE")
+
+	mountPath := d.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath
+	assert.Equal(t, mountPath, "/var/lib/pgsql/data")
+
+	cmd := d.Spec.Template.Spec.Containers[0].ReadinessProbe.Exec.Command
+	assert.Equal(t, strings.Contains(cmd[2], "POSTGRESQL_USER"), true)
+}
diff --git a/pkg/reconciler/openshift/tektonhub/testdata/update-db-deployment.yaml b/pkg/reconciler/openshift/tektonhub/testdata/update-db-deployment.yaml
new file mode 100644
index 000000000..bec88c0bf
--- /dev/null
+++ b/pkg/reconciler/openshift/tektonhub/testdata/update-db-deployment.yaml
@@ -0,0 +1,75 @@
+# Copyright © 2022 The Tekton Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: db
+  labels:
+    app: db
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: db
+  template:
+    metadata:
+      labels:
+        app: db
+    spec:
+      containers:
+        - name: db
+          image: postgres:13@sha256:260a98d976574b439712c35914fdcb840755233f79f3e27ea632543f78b7a21e
+          imagePullPolicy: IfNotPresent
+          ports:
+            - containerPort: 5432
+              protocol: TCP
+          env:
+            - name: POSTGRES_DB
+              valueFrom:
+                secretKeyRef:
+                  name: db
+                  key: POSTGRES_DB
+            - name: POSTGRES_USER
+              valueFrom:
+                secretKeyRef:
+                  name: db
+                  key: POSTGRES_USER
+            - name: POSTGRES_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: db
+                  key: POSTGRES_PASSWORD
+            - name: PGDATA
+              value: /var/lib/postgresql/data/pgdata
+          volumeMounts:
+            - name: db
+              mountPath: /var/lib/postgresql/data
+          readinessProbe:
+            exec:
+              command: [bash, -c, "psql -w -U ${POSTGRES_USER} -d ${POSTGRES_DB} -c 'SELECT 1'"]
+            initialDelaySeconds: 15
+            timeoutSeconds: 2
+            periodSeconds: 15
+          livenessProbe:
+            exec:
+              command: [bash, -c, "psql -w -U ${POSTGRES_USER} -d ${POSTGRES_DB} -c 'SELECT 1'"]
+            initialDelaySeconds: 45
+            timeoutSeconds: 2
+            periodSeconds: 15
+      volumes:
+        - name: db
+          persistentVolumeClaim:
+            claimName: db
+      restartPolicy: Always
\ No newline at end of file
diff --git a/pkg/reconciler/proxy/proxy_test.go b/pkg/reconciler/proxy/proxy_test.go
index c626cb97c..57a3f4024 100644
--- a/pkg/reconciler/proxy/proxy_test.go
+++ b/pkg/reconciler/proxy/proxy_test.go
@@ -35,14 +35,20 @@ func TestUpdateVolume(t *testing.T) {
 			},
 		},
 	}
-	podUpdated := updateVolume(pod, "testv", "testcm", "testkey")
-	assert.DeepEqual(t, len(podUpdated.Spec.Volumes), 1)
+	podUpdated := updateVolume(pod)
 	assert.DeepEqual(t, len(podUpdated.Spec.Containers[0].Env), 1)
 	assert.DeepEqual(t, podUpdated.Spec.Containers[0].Env[0].Name, "SSL_CERT_DIR")
 	assert.DeepEqual(t, podUpdated.Spec.Containers[0].Env[0].Value, "/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts")
-	assert.DeepEqual(t, podUpdated.Spec.Volumes[0].Name, "testv")
-	assert.DeepEqual(t, podUpdated.Spec.Volumes[0].ConfigMap.Name, "testcm")
-	assert.DeepEqual(t, len(podUpdated.Spec.Containers[0].VolumeMounts), 1)
-	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[0].Name, "testv")
-	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[0].SubPath, "testkey")
+
+	assert.DeepEqual(t, len(podUpdated.Spec.Volumes), 2)
+	assert.DeepEqual(t, podUpdated.Spec.Volumes[0].Name, "config-trusted-cabundle-volume")
+	assert.DeepEqual(t, podUpdated.Spec.Volumes[0].ConfigMap.Name, "config-trusted-cabundle")
+	assert.DeepEqual(t, podUpdated.Spec.Volumes[1].Name, "config-service-cabundle-volume")
+	assert.DeepEqual(t, podUpdated.Spec.Volumes[1].ConfigMap.Name, "config-service-cabundle")
+
+	assert.DeepEqual(t, len(podUpdated.Spec.Containers[0].VolumeMounts), 2)
+	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[0].Name, "config-trusted-cabundle-volume")
+	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[0].SubPath, "ca-bundle.crt")
+	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[1].Name, "config-service-cabundle-volume")
+	assert.DeepEqual(t, podUpdated.Spec.Containers[0].VolumeMounts[1].SubPath, "service-ca.crt")
 }
diff --git a/test/e2e/common/00_tektonconfigdeployment_test.go b/test/e2e/common/00_tektonconfigdeployment_test.go
index 8eb319d99..e12725fb8 100644
--- a/test/e2e/common/00_tektonconfigdeployment_test.go
+++ b/test/e2e/common/00_tektonconfigdeployment_test.go
@@ -29,6 +29,7 @@ import (
 	"github.com/tektoncd/operator/pkg/reconciler/common"
 	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektonpipeline"
 	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektontrigger"
+	tconfig "github.com/tektoncd/operator/pkg/reconciler/openshift/tektonconfig"
 	"github.com/tektoncd/operator/test/client"
 	"github.com/tektoncd/operator/test/resources"
 	"github.com/tektoncd/operator/test/utils"
@@ -440,7 +441,7 @@ func runRbacTest(t *testing.T, clients *utils.Clients) {
 	})
 
 	pipelinesSCCRoleBinding := "pipelines-scc-rolebinding"
-	editRoleBinding := "edit"
+	editRoleBinding := tconfig.PipelineRoleBinding
 
 	// Test whether the roleBindings are created
 	t.Run("verify-rolebindings", func(t *testing.T) {