Repository: tektoncd/operator
Pull request #712 (2022-03-23 06:01:09)

Add a script to replace verion labels during a release
Add a script to replace all version and release related labels to the
release version

Signed-off-by: Nikhil Thomas <nikthoma@redhat.com>

# Changes

<!-- 🎉🎉🎉 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)
- [ ] 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
NONE
```


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"]} -->
tekton-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/tektoncd/operator/pull/712#pullrequestreview-918228054" title="LGTM">concaf</a>*
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"]} -->
PuneetPunamiya: /lgtm
tekton-robot: @PuneetPunamiya: changing LGTM is restricted to collaborators

<details>

In response to [this](https://github.com/tektoncd/operator/pull/712#issuecomment-1075956659):

>/lgtm


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.
</details>

Patch:
diff --git a/config/base/operator-config.yaml b/config/base/config-info.yaml
similarity index 100%
rename from config/base/operator-config.yaml
rename to config/base/config-info.yaml
diff --git a/cmd/openshift/operator/kodata/info/operator-config.yaml b/config/base/config-info_role.yaml
similarity index 62%
rename from cmd/openshift/operator/kodata/info/operator-config.yaml
rename to config/base/config-info_role.yaml
index 324b648b5..ef10354f5 100644
--- a/cmd/openshift/operator/kodata/info/operator-config.yaml
+++ b/config/base/config-info_role.yaml
@@ -12,13 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-apiVersion: v1
-kind: ConfigMap
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
 metadata:
-  name: operators-info
+  name: tekton-operator-info
   labels:
     app.kubernetes.io/instance: default
-data:
-  # Contains operator version which can be queried by external
-  # tools such as CLI.
-  version: 'devel'
+rules:
+  # All system:authenticated users need to have access
+  # to the tekton-operator-info ConfigMap even if they don't
+  # have access to other resources present in the
+  # installed namespace
+  - apiGroups: [""]
+    resources: ["configmaps"]
+    resourceNames: ["tekton-operator-info"]
+    verbs: ["get"]
diff --git a/cmd/kubernetes/operator/kodata/info/operator-config.yaml b/config/base/config-info_role_binding.yaml
similarity index 62%
rename from cmd/kubernetes/operator/kodata/info/operator-config.yaml
rename to config/base/config-info_role_binding.yaml
index 324b648b5..23ccc283d 100644
--- a/cmd/kubernetes/operator/kodata/info/operator-config.yaml
+++ b/config/base/config-info_role_binding.yaml
@@ -12,13 +12,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-apiVersion: v1
-kind: ConfigMap
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
 metadata:
-  name: operators-info
+  name: tekton-operator-info
   labels:
     app.kubernetes.io/instance: default
-data:
-  # Contains operator version which can be queried by external
-  # tools such as CLI.
-  version: 'devel'
+subjects:
+  # Giving all system:authenticated users the access to the
+  # ConfigMap which contains version information
+  - kind: Group
+    name: system:authenticated
+    apiGroup: rbac.authorization.k8s.io
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: tekton-operator-info
diff --git a/config/base/kustomization.yaml b/config/base/kustomization.yaml
index a2898dcb3..846096c6f 100644
--- a/config/base/kustomization.yaml
+++ b/config/base/kustomization.yaml
@@ -29,4 +29,6 @@ resources:
 - operator.yaml
 - tekton_config_role.yaml
 - tekton_config_role_binding.yaml
-- operator-config.yaml
+- config-info.yaml
+- config-info_role.yaml
+- config-info_role_binding.yaml
diff --git a/hack/release-common.sh b/hack/release-common.sh
new file mode 100644
index 000000000..72a1d974f
--- /dev/null
+++ b/hack/release-common.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+set -u
+
+function set_version_label() {
+  local operator_version="v${1}"
+
+  shift
+  local operator_platforms=${*:-"kubernetes openshift"}
+
+  echo ${operator_platforms}
+  printf "%-20s: %s\n" "Platforms" "${operator_platforms}"
+  printf "%-20s: %s\n" "Operator version" "${operator_version}"
+  echo '---------------------'
+  for platform in ${operator_platforms}; do
+    echo updating version labels for platform: ${platform}, version: ${operator_version}
+    sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: '${operator_version}'/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: '${operator_version}'/g' -e 's/\(version\): "devel"/\1: '${operator_version}'/g' -e 's/\("-version"\), "devel"/\1, '${operator_version}'/g' config/base/*.yaml
+    sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: '${operator_version}'/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: '${operator_version}'/g' -e 's/\(version\): "devel"/\1: '${operator_version}'/g' -e 's/\("-version"\), "devel"/\1, '${operator_version}'/g' config/webhooks/*.yaml
+    sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: '${operator_version}'/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: '${operator_version}'/g' -e 's/\(version\): "devel"/\1: '${operator_version}'/g' -e 's/\("-version"\), "devel"/\1, '${operator_version}'/g' config/${platform}/base/*.yaml
+    sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: '${operator_version}'/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: '${operator_version}'/g' -e 's/\(version\): "devel"/\1: '${operator_version}'/g' -e 's/\("-version"\), "devel"/\1, '${operator_version}'/g' config/${platform}/overlays/default/*.yaml
+    sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: '${operator_version}'/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: '${operator_version}'/g' -e 's/\(version\): "devel"/\1: '${operator_version}'/g' -e 's/\("-version"\), "devel"/\1, '${operator_version}'/g' cmd/${platform}/operator/kodata/webhook/*.yaml
+    sed -i 's/\(value\): "devel"/\1: '${operator_version}'/g' config/${platform}/base/operator.yaml
+  done
+}
diff --git a/hack/release-setup-branch.sh b/hack/release-setup-branch.sh
new file mode 100755
index 000000000..90172c2a1
--- /dev/null
+++ b/hack/release-setup-branch.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -u
+
+source ./hack/release-common.sh
+
+OPERATOR_RELEASE_VERSION=${1}
+set_version_label ${OPERATOR_RELEASE_VERSION}
diff --git a/pkg/apis/operator/v1alpha1/const.go b/pkg/apis/operator/v1alpha1/const.go
index b84a0400e..82bc11ff1 100644
--- a/pkg/apis/operator/v1alpha1/const.go
+++ b/pkg/apis/operator/v1alpha1/const.go
@@ -16,7 +16,11 @@ limitations under the License.
 
 package v1alpha1
 
-import "fmt"
+import (
+	"fmt"
+	"knative.dev/pkg/controller"
+	"time"
+)
 
 const (
 	// operatorVersion
@@ -47,6 +51,8 @@ const (
 	InstallerSetType       = "operator.tekton.dev/type"
 
 	UpgradePending = "upgrade pending"
+
+	RequeueDelay = 10 * time.Second
 )
 
 var (
@@ -55,6 +61,8 @@ var (
 	// that we proceed ahead with updated object
 	RECONCILE_AGAIN_ERR = fmt.Errorf("reconcile again and proceed")
 
+	REQUEUE_EVENT_AFTER = controller.NewRequeueAfter(RequeueDelay)
+
 	// DEPENDENCY_UPGRADE_PENDING_ERR
 	// When a reconciler cannot proceed due to an upgrade in progress of a dependency
 	DEPENDENCY_UPGRADE_PENDING_ERR = fmt.Errorf("dependency upgrade pending")
diff --git a/pkg/reconciler/common/targetnamespace.go b/pkg/reconciler/common/targetnamespace.go
index 58c63288f..d231a4888 100644
--- a/pkg/reconciler/common/targetnamespace.go
+++ b/pkg/reconciler/common/targetnamespace.go
@@ -18,10 +18,7 @@ package common
 
 import (
 	"context"
-	"os"
-	"path/filepath"
 
-	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -51,27 +48,3 @@ func CreateTargetNamespace(ctx context.Context, labels map[string]string, obj v1
 	}
 	return nil
 }
-
-func CreateOperatorVersionConfigMap(manifest mf.Manifest, obj v1alpha1.TektonComponent) error {
-	koDataDir := os.Getenv(KoEnvKey)
-	operatorDir := filepath.Join(koDataDir, "info")
-
-	if err := AppendManifest(&manifest, operatorDir); err != nil {
-		return err
-	}
-
-	manifest, err := manifest.Transform(
-		mf.InjectNamespace(obj.GetSpec().GetTargetNamespace()),
-		mf.InjectOwner(obj),
-	)
-
-	if err != nil {
-		return err
-	}
-
-	if err = manifest.Apply(); err != nil {
-		return err
-	}
-
-	return nil
-}
diff --git a/pkg/reconciler/kubernetes/tektonchain/controller.go b/pkg/reconciler/kubernetes/tektonchain/controller.go
index 821c84eb7..8ee54bd30 100644
--- a/pkg/reconciler/kubernetes/tektonchain/controller.go
+++ b/pkg/reconciler/kubernetes/tektonchain/controller.go
@@ -72,9 +72,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonChainreconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for Tekton Chain")
 
 		tektonChaininformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektonchain/tektonchain.go b/pkg/reconciler/kubernetes/tektonchain/tektonchain.go
index 45ef6b56a..fe9e2d450 100644
--- a/pkg/reconciler/kubernetes/tektonchain/tektonchain.go
+++ b/pkg/reconciler/kubernetes/tektonchain/tektonchain.go
@@ -19,8 +19,6 @@ package tektonchain
 import (
 	"context"
 	"fmt"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -45,9 +43,7 @@ type Reconciler struct {
 	// particular version
 	manifest mf.Manifest
 	// Platform-specific behavior to affect the transform
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter func(obj interface{}, after time.Duration)
-	extension    common.Extension
+	extension common.Extension
 	// chainVersion describes the current chain version
 	chainVersion    string
 	operatorVersion string
@@ -176,8 +172,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonChain
 			Get(ctx, existingInstallerSet, metav1.GetOptions{})
 		if err == nil {
 			tc.Status.MarkNotReady("Waiting for previous installer set to get deleted")
-			r.enqueueAfter(tc, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		if !apierrors.IsNotFound(err) {
 			logger.Error("failed to get InstallerSet: %s", err)
@@ -233,8 +228,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonChain
 
 			// after updating installer set enqueue after a duration
 			// to allow changes to get deployed
-			r.enqueueAfter(tc, 20*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	}
 
@@ -244,18 +238,15 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonChain
 	ready := installedTIS.Status.GetCondition(apis.ConditionReady)
 	if ready == nil {
 		tc.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tc, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	if ready.Status == corev1.ConditionUnknown {
 		tc.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tc, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	} else if ready.Status == corev1.ConditionFalse {
 		tc.Status.MarkInstallerSetNotReady(ready.Message)
-		r.enqueueAfter(tc, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Mark InstallerSet Ready
diff --git a/pkg/reconciler/kubernetes/tektondashboard/controller.go b/pkg/reconciler/kubernetes/tektondashboard/controller.go
index 27e6fb17b..c7a09703b 100644
--- a/pkg/reconciler/kubernetes/tektondashboard/controller.go
+++ b/pkg/reconciler/kubernetes/tektondashboard/controller.go
@@ -76,9 +76,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonDashboardreconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for tekton-dashboard")
 
 		tektonDashboardInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektondashboard/tektondashboard.go b/pkg/reconciler/kubernetes/tektondashboard/tektondashboard.go
index 29d5149ab..9fdacf339 100644
--- a/pkg/reconciler/kubernetes/tektondashboard/tektondashboard.go
+++ b/pkg/reconciler/kubernetes/tektondashboard/tektondashboard.go
@@ -19,8 +19,6 @@ package tektondashboard
 import (
 	"context"
 	"fmt"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -51,8 +49,6 @@ type Reconciler struct {
 	// a particular version with readonly value as false
 	fullaccessManifest mf.Manifest
 	// Platform-specific behavior to affect the transform
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter     func(obj interface{}, after time.Duration)
 	extension        common.Extension
 	pipelineInformer pipelineinformer.TektonPipelineInformer
 	operatorVersion  string
@@ -137,8 +133,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, td *v1alpha1.TektonDashb
 		if err.Error() == common.PipelineNotReady {
 			td.Status.MarkDependencyInstalling("tekton-pipelines is still installing")
 			// wait for pipeline status to change
-			r.enqueueAfter(td, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 
 		}
 		// (tektonpipeline.opeator.tekton.dev instance not available yet)
@@ -210,8 +205,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, td *v1alpha1.TektonDashb
 			Get(ctx, existingInstallerSet, metav1.GetOptions{})
 		if err == nil {
 			td.Status.MarkNotReady("Waiting for previous installer set to get deleted")
-			r.enqueueAfter(td, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		if !apierrors.IsNotFound(err) {
 			logger.Error("failed to get InstallerSet: %s", err)
@@ -263,8 +257,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, td *v1alpha1.TektonDashb
 
 			// after updating installer set enqueue after a duration
 			// to allow changes to get deployed
-			r.enqueueAfter(td, 20*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	}
 
@@ -274,18 +267,15 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, td *v1alpha1.TektonDashb
 	ready := installedTIS.Status.GetCondition(apis.ConditionReady)
 	if ready == nil {
 		td.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(td, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	if ready.Status == corev1.ConditionUnknown {
 		td.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(td, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	} else if ready.Status == corev1.ConditionFalse {
 		td.Status.MarkInstallerSetNotReady(ready.Message)
-		r.enqueueAfter(td, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Mark InstallerSet Ready
diff --git a/pkg/reconciler/kubernetes/tektonhub/controller.go b/pkg/reconciler/kubernetes/tektonhub/controller.go
index 38abdcec2..9b391414e 100644
--- a/pkg/reconciler/kubernetes/tektonhub/controller.go
+++ b/pkg/reconciler/kubernetes/tektonhub/controller.go
@@ -68,9 +68,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonHubReconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers")
 
 		tektonHubInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektonhub/tektonhub.go b/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
index bbb4dc4ac..71ee22795 100644
--- a/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
+++ b/pkg/reconciler/kubernetes/tektonhub/tektonhub.go
@@ -20,12 +20,10 @@ package tektonhub
 import (
 	"context"
 	"fmt"
-	"path/filepath"
-	"time"
-
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"path/filepath"
 
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
@@ -51,8 +49,6 @@ type Reconciler struct {
 	manifest mf.Manifest
 	// Platform-specific behavior to affect the transform
 	extension common.Extension
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter func(obj interface{}, after time.Duration)
 }
 
 var (
@@ -175,8 +171,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, th *v1alpha1.TektonHub)
 
 func (r *Reconciler) handleError(err error, th *v1alpha1.TektonHub) error {
 	if err == v1alpha1.RECONCILE_AGAIN_ERR {
-		r.enqueueAfter(th, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 	return err
 }
@@ -184,8 +179,7 @@ func (r *Reconciler) handleError(err error, th *v1alpha1.TektonHub) error {
 func (r *Reconciler) manageUiComponent(ctx context.Context, th *v1alpha1.TektonHub, hubDir, version string) error {
 	if err := r.validateUiConfigMap(ctx, th); err != nil {
 		th.Status.MarkUiDependencyMissing(fmt.Sprintf("UI config map not present: %v", err.Error()))
-		r.enqueueAfter(th, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	th.Status.MarkUiDependenciesInstalled()
@@ -217,8 +211,7 @@ func (r *Reconciler) manageApiComponent(ctx context.Context, th *v1alpha1.Tekton
 	// Validate whether the secrets and configmap are created for API
 	if err := r.validateApiDependencies(ctx, th); err != nil {
 		th.Status.MarkApiDependencyMissing("api secrets not present")
-		r.enqueueAfter(th, 10*time.Second)
-		return err
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	th.Status.MarkApiDependenciesInstalled()
diff --git a/pkg/reconciler/kubernetes/tektoninstallerset/controller.go b/pkg/reconciler/kubernetes/tektoninstallerset/controller.go
index 754bfcd28..0794ce5b6 100644
--- a/pkg/reconciler/kubernetes/tektoninstallerset/controller.go
+++ b/pkg/reconciler/kubernetes/tektoninstallerset/controller.go
@@ -59,9 +59,6 @@ func NewExtendedController() injection.ControllerConstructor {
 		}
 		impl := tektonInstallerReconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for TektonInstallerSet")
 
 		tektonInstallerinformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektoninstallerset/tektoninstallerset.go b/pkg/reconciler/kubernetes/tektoninstallerset/tektoninstallerset.go
index 9ac793566..df5598d2e 100644
--- a/pkg/reconciler/kubernetes/tektoninstallerset/tektoninstallerset.go
+++ b/pkg/reconciler/kubernetes/tektoninstallerset/tektoninstallerset.go
@@ -19,8 +19,6 @@ package tektoninstallerset
 import (
 	"context"
 	"fmt"
-	"time"
-
 	"github.com/go-logr/logr"
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
@@ -36,7 +34,6 @@ type Reconciler struct {
 	operatorClientSet clientset.Interface
 	mfClient          mf.Client
 	mfLogger          logr.Logger
-	enqueueAfter      func(obj interface{}, after time.Duration)
 }
 
 // Reconciler implements controller.Reconciler
@@ -148,8 +145,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, installerSet *v1alpha1.T
 	err = installer.IsWebhookReady()
 	if err != nil {
 		installerSet.Status.MarkWebhookNotReady(err.Error())
-		r.enqueueAfter(installerSet, time.Second*10)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Update Status for Webhook
@@ -159,8 +155,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, installerSet *v1alpha1.T
 	err = installer.IsControllerReady()
 	if err != nil {
 		installerSet.Status.MarkControllerNotReady(err.Error())
-		r.enqueueAfter(installerSet, time.Second*10)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Update Ready status of Controller
@@ -179,8 +174,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, installerSet *v1alpha1.T
 	err = installer.AllDeploymentsReady()
 	if err != nil {
 		installerSet.Status.MarkAllDeploymentsNotReady(err.Error())
-		r.enqueueAfter(installerSet, time.Second*10)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Mark all deployments ready
@@ -191,8 +185,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, installerSet *v1alpha1.T
 
 func (r *Reconciler) handleError(err error, installerSet *v1alpha1.TektonInstallerSet) error {
 	if err == v1alpha1.RECONCILE_AGAIN_ERR {
-		r.enqueueAfter(installerSet, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 	return err
 }
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/controller.go b/pkg/reconciler/kubernetes/tektonpipeline/controller.go
index 894b31b5f..d242ae906 100644
--- a/pkg/reconciler/kubernetes/tektonpipeline/controller.go
+++ b/pkg/reconciler/kubernetes/tektonpipeline/controller.go
@@ -74,9 +74,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonPipelineReconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for TektonPipeline")
 
 		tektonPipelineInformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go b/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go
index 9b5f886a7..2d13dfe59 100644
--- a/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go
+++ b/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go
@@ -19,8 +19,6 @@ package tektonpipeline
 import (
 	"context"
 	"fmt"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -58,8 +56,6 @@ type Reconciler struct {
 	manifest mf.Manifest
 	// Platform-specific behavior to affect the transform
 	extension common.Extension
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter func(obj interface{}, after time.Duration)
 	// metrics handles metrics for pipeline install
 	metrics         *Recorder
 	kubeClientSet   kubernetes.Interface
@@ -212,8 +208,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipel
 			Get(ctx, existingInstallerSet, metav1.GetOptions{})
 		if err == nil {
 			tp.Status.MarkNotReady("Waiting for previous installer set to get deleted")
-			r.enqueueAfter(tp, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		if !apierrors.IsNotFound(err) {
 			logger.Error("failed to get InstallerSet: %s", err)
@@ -257,8 +252,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipel
 
 			// after updating installer set enqueue after a duration
 			// to allow changes to get deployed
-			r.enqueueAfter(tp, 20*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	}
 
@@ -268,14 +262,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipel
 	ready := installedTIS.Status.GetCondition(apis.ConditionReady)
 	if ready == nil {
 		tp.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tp, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	if ready.Status == corev1.ConditionUnknown {
 		tp.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tp, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	} else if ready.Status == corev1.ConditionFalse {
 		tp.Status.MarkInstallerSetNotReady(ready.Message)
 		manifest := r.manifest
@@ -284,8 +276,10 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipel
 			return err
 		}
 		err = common.PreemptDeadlock(ctx, &manifest, r.kubeClientSet, v1alpha1.PipelineResourceName)
-		r.enqueueAfter(tp, 10*time.Second)
-		return err
+		if err != nil {
+			logger.Error("preempt deadlock error: %v", err)
+		}
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Mark InstallerSet Ready
diff --git a/pkg/reconciler/kubernetes/tektontrigger/controller.go b/pkg/reconciler/kubernetes/tektontrigger/controller.go
index a8cf3c025..177520373 100644
--- a/pkg/reconciler/kubernetes/tektontrigger/controller.go
+++ b/pkg/reconciler/kubernetes/tektontrigger/controller.go
@@ -78,9 +78,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonTriggerreconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for TektonTrigger")
 
 		tektonTriggerinformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/kubernetes/tektontrigger/tektontrigger.go b/pkg/reconciler/kubernetes/tektontrigger/tektontrigger.go
index 8c435eb34..7776bd3b4 100644
--- a/pkg/reconciler/kubernetes/tektontrigger/tektontrigger.go
+++ b/pkg/reconciler/kubernetes/tektontrigger/tektontrigger.go
@@ -19,8 +19,6 @@ package tektontrigger
 import (
 	"context"
 	"fmt"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -62,11 +60,9 @@ type Reconciler struct {
 	metrics *Recorder
 
 	pipelineInformer pipelineinformer.TektonPipelineInformer
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter    func(obj interface{}, after time.Duration)
-	triggersVersion string
-	operatorVersion string
-	kubeClientSet   kubernetes.Interface
+	triggersVersion  string
+	operatorVersion  string
+	kubeClientSet    kubernetes.Interface
 }
 
 var (
@@ -135,8 +131,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tt *v1alpha1.TektonTrigg
 		if err.Error() == common.PipelineNotReady {
 			tt.Status.MarkDependencyInstalling("tekton-pipelines is still installing")
 			// wait for pipeline status to change
-			r.enqueueAfter(tt, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		// (tektonpipeline.operator.tekton.dev instance not available yet)
 		tt.Status.MarkDependencyMissing("tekton-pipelines does not exist")
@@ -226,8 +221,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tt *v1alpha1.TektonTrigg
 			Get(ctx, existingInstallerSet, metav1.GetOptions{})
 		if err == nil {
 			tt.Status.MarkNotReady("Waiting for previous installer set to get deleted")
-			r.enqueueAfter(tt, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		if !apierrors.IsNotFound(err) {
 			logger.Error("failed to get InstallerSet: %s", err)
@@ -273,8 +267,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tt *v1alpha1.TektonTrigg
 
 			// after updating installer set enqueue after a duration
 			// to allow changes to get deployed
-			r.enqueueAfter(tt, 20*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	}
 
@@ -284,14 +277,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tt *v1alpha1.TektonTrigg
 	ready := installedTIS.Status.GetCondition(apis.ConditionReady)
 	if ready == nil {
 		tt.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tt, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	if ready.Status == corev1.ConditionUnknown {
 		tt.Status.MarkInstallerSetNotReady("Waiting for installation")
-		r.enqueueAfter(tt, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	} else if ready.Status == corev1.ConditionFalse {
 		tt.Status.MarkInstallerSetNotReady(ready.Message)
 		manifest := r.manifest
@@ -300,8 +291,10 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tt *v1alpha1.TektonTrigg
 			return err
 		}
 		err = common.PreemptDeadlock(ctx, &manifest, r.kubeClientSet, v1alpha1.TriggerResourceName)
-		r.enqueueAfter(tt, 10*time.Second)
-		return err
+		if err != nil {
+			logger.Error("preempt deadlock error: %v", err)
+		}
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	// Mark InstallerSet Ready
diff --git a/pkg/reconciler/openshift/common/transformer.go b/pkg/reconciler/openshift/common/transformer.go
index c975b5a52..eca614eee 100644
--- a/pkg/reconciler/openshift/common/transformer.go
+++ b/pkg/reconciler/openshift/common/transformer.go
@@ -84,3 +84,34 @@ func RemoveRunAsGroup() mf.Transformer {
 		return nil
 	}
 }
+
+// RemoveFsGroup will remove FsGroup in a deployment
+func RemoveFsGroup(obj string) 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 == obj {
+			if d.Spec.Template.Spec.SecurityContext != nil {
+				d.Spec.Template.Spec.SecurityContext = nil
+			}
+
+			unstrObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(d)
+			if err != nil {
+				return err
+			}
+			u.SetUnstructuredContent(unstrObj)
+
+			return nil
+		}
+
+		return nil
+	}
+}
diff --git a/pkg/reconciler/openshift/tektonaddon/communityClusterTasks.go b/pkg/reconciler/openshift/tektonaddon/communityClusterTasks.go
index 83d58bc96..2997f27be 100644
--- a/pkg/reconciler/openshift/tektonaddon/communityClusterTasks.go
+++ b/pkg/reconciler/openshift/tektonaddon/communityClusterTasks.go
@@ -19,13 +19,14 @@ package tektonaddon
 import (
 	"context"
 	"fmt"
+	"strings"
+	"time"
+
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	"github.com/tektoncd/operator/pkg/reconciler/common"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"knative.dev/pkg/logging"
-	"strings"
-	"time"
 )
 
 var communityClusterTaskLS = metav1.LabelSelector{
@@ -103,8 +104,7 @@ func (r *Reconciler) ensureCommunityClusterTasks(ctx context.Context, ta *v1alph
 		// Continue if failed to resolve community task URL.
 		// (Ex: on disconnected cluster community tasks won't be reachable because of proxy).
 		logging.FromContext(ctx).Error("Failed to get community task: Skipping community tasks installation  ", err)
-		r.enqueueAfter(r, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	if err := r.communityTransform(ctx, &communityClusterTaskManifest, ta); err != nil {
diff --git a/pkg/reconciler/openshift/tektonaddon/controller.go b/pkg/reconciler/openshift/tektonaddon/controller.go
index 8744d4a9a..cc04b5420 100644
--- a/pkg/reconciler/openshift/tektonaddon/controller.go
+++ b/pkg/reconciler/openshift/tektonaddon/controller.go
@@ -79,9 +79,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		}
 		impl := tektonAddonreconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for TektonAddon")
 
 		tektonAddoninformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go
index 4b0491d13..5b1c67469 100644
--- a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go
+++ b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go
@@ -19,10 +19,6 @@ package tektonaddon
 import (
 	"context"
 	"fmt"
-	"os"
-	"path/filepath"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -33,6 +29,8 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"knative.dev/pkg/logging"
 	pkgreconciler "knative.dev/pkg/reconciler"
+	"os"
+	"path/filepath"
 )
 
 // Reconciler implements controller.Reconciler for TektonAddon resources.
@@ -41,9 +39,6 @@ type Reconciler struct {
 	operatorClientSet clientset.Interface
 	extension         common.Extension
 
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter func(obj interface{}, after time.Duration)
-
 	pipelineInformer informer.TektonPipelineInformer
 	triggerInformer  informer.TektonTriggerInformer
 
@@ -123,8 +118,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon
 		if err.Error() == common.PipelineNotReady {
 			ta.Status.MarkDependencyInstalling("tekton-pipelines is still installing")
 			// wait for pipeline status to change
-			r.enqueueAfter(ta, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		// (tektonpipeline.operator.tekton.dev instance not available yet)
 		ta.Status.MarkDependencyMissing("tekton-pipelines does not exist")
@@ -135,8 +129,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon
 		if err.Error() == common.TriggerNotReady {
 			ta.Status.MarkDependencyInstalling("tekton-triggers is still installing")
 			// wait for trigger status to change
-			r.enqueueAfter(ta, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		// (tektontrigger.operator.tekton.dev instance not available yet)
 		ta.Status.MarkDependencyMissing("tekton-triggers does not exist")
@@ -194,8 +187,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon
 
 	if err := r.extension.PostReconcile(ctx, ta); err != nil {
 		if err == v1alpha1.RECONCILE_AGAIN_ERR {
-			r.enqueueAfter(ta, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		ta.Status.MarkPostReconcilerFailed(err.Error())
 		return err
diff --git a/pkg/reconciler/openshift/tektonhub/extension.go b/pkg/reconciler/openshift/tektonhub/extension.go
index 8eddeea06..9c4e157c0 100644
--- a/pkg/reconciler/openshift/tektonhub/extension.go
+++ b/pkg/reconciler/openshift/tektonhub/extension.go
@@ -31,6 +31,7 @@ import (
 	"github.com/tektoncd/operator/pkg/client/clientset/versioned"
 	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
 	"github.com/tektoncd/operator/pkg/reconciler/common"
+	openshiftCommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common"
 	"go.uber.org/zap"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -88,7 +89,7 @@ type openshiftExtension struct {
 }
 
 func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer {
-	return []mf.Transformer{UpdateDbDeployment()}
+	return []mf.Transformer{UpdateDbDeployment(), openshiftCommon.RemoveFsGroup(api)}
 }
 
 func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.TektonComponent) error {
diff --git a/pkg/reconciler/shared/tektonconfig/controller.go b/pkg/reconciler/shared/tektonconfig/controller.go
index 66031b73f..45dd4f159 100644
--- a/pkg/reconciler/shared/tektonconfig/controller.go
+++ b/pkg/reconciler/shared/tektonconfig/controller.go
@@ -74,9 +74,6 @@ func NewExtensibleController(generator common.ExtensionGenerator) injection.Cont
 		}
 		impl := tektonConfigreconciler.NewImpl(ctx, c)
 
-		// Add enqueue func in reconciler
-		c.enqueueAfter = impl.EnqueueAfter
-
 		logger.Info("Setting up event handlers for TektonConfig")
 
 		tektonConfiginformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))
diff --git a/pkg/reconciler/shared/tektonconfig/tektonconfig.go b/pkg/reconciler/shared/tektonconfig/tektonconfig.go
index 8e0142827..968d3dd1b 100644
--- a/pkg/reconciler/shared/tektonconfig/tektonconfig.go
+++ b/pkg/reconciler/shared/tektonconfig/tektonconfig.go
@@ -19,8 +19,6 @@ package tektonconfig
 import (
 	"context"
 	"fmt"
-	"time"
-
 	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
@@ -43,9 +41,7 @@ type Reconciler struct {
 	// operatorClientSet allows us to configure operator objects
 	operatorClientSet clientset.Interface
 	// Platform-specific behavior to affect the transform
-	extension common.Extension
-	// enqueueAfter enqueues a obj after a duration
-	enqueueAfter    func(obj interface{}, after time.Duration)
+	extension       common.Extension
 	manifest        mf.Manifest
 	operatorVersion string
 }
@@ -106,8 +102,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi
 
 	if err := r.extension.PreReconcile(ctx, tc); err != nil {
 		if err == v1alpha1.RECONCILE_AGAIN_ERR {
-			r.enqueueAfter(tc, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		tc.Status.MarkPreInstallFailed(err.Error())
 		return err
@@ -119,8 +114,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi
 	if _, err := pipeline.EnsureTektonPipelineExists(ctx, r.operatorClientSet.OperatorV1alpha1().TektonPipelines(), tc); err != nil {
 		tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonPipeline: %s", err.Error()))
 		if err == v1alpha1.RECONCILE_AGAIN_ERR {
-			r.enqueueAfter(tc, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 		return nil
 	}
@@ -129,14 +123,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi
 	if tc.Spec.Profile == v1alpha1.ProfileAll || tc.Spec.Profile == v1alpha1.ProfileBasic {
 		if _, err := trigger.EnsureTektonTriggerExists(ctx, r.operatorClientSet.OperatorV1alpha1().TektonTriggers(), tc); err != nil {
 			tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonTrigger: %s", err.Error()))
-			r.enqueueAfter(tc, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	} else {
 		if err := trigger.TektonTriggerCRDelete(ctx, r.operatorClientSet.OperatorV1alpha1().TektonTriggers(), v1alpha1.TriggerResourceName); err != nil {
 			tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonTrigger: %s", err.Error()))
-			r.enqueueAfter(tc, 10*time.Second)
-			return nil
+			return v1alpha1.REQUEUE_EVENT_AFTER
 		}
 	}
 
@@ -149,8 +141,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi
 
 	if err := r.extension.PostReconcile(ctx, tc); err != nil {
 		tc.Status.MarkPostInstallFailed(err.Error())
-		r.enqueueAfter(tc, 10*time.Second)
-		return nil
+		return v1alpha1.REQUEUE_EVENT_AFTER
 	}
 
 	tc.Status.MarkPostInstallComplete()
diff --git a/tekton/build-publish-images-manifests.yaml b/tekton/build-publish-images-manifests.yaml
index 89fa841bf..fd5d9d721 100644
--- a/tekton/build-publish-images-manifests.yaml
+++ b/tekton/build-publish-images-manifests.yaml
@@ -123,7 +123,6 @@ spec:
       sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\("-version"\), "devel"/\1, "$(params.versionTag)"/g' ${PROJECT_ROOT}/config/base/*.yaml
       sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\("-version"\), "devel"/\1, "$(params.versionTag)"/g' ${PROJECT_ROOT}/config/${KUBE_DISTRO}/base/*.yaml
       sed -i -e 's/\(operator.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\("-version"\), "devel"/\1, "$(params.versionTag)"/g' ${PROJECT_ROOT}/config/${KUBE_DISTRO}/overlays/default/*.yaml
-      sed -i -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' ${PROJECT_ROOT}/cmd/${KUBE_DISTRO}/operator/kodata/info/operator-config.yaml
 
       # Publish images and create release.yaml
       mkdir -p $OUTPUT_RELEASE_DIR


Test patch:
diff --git a/pkg/reconciler/common/targetnamespace_test.go b/pkg/reconciler/common/targetnamespace_test.go
index 82ea893fb..a4c15f514 100644
--- a/pkg/reconciler/common/targetnamespace_test.go
+++ b/pkg/reconciler/common/targetnamespace_test.go
@@ -18,53 +18,14 @@ package common
 
 import (
 	"context"
-	"fmt"
-	"os"
 	"testing"
 
-	"github.com/google/go-cmp/cmp"
-	mf "github.com/manifestival/manifestival"
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	"gotest.tools/v3/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/client-go/kubernetes/fake"
 )
 
-type fakeClient struct {
-	err            error
-	getErr         error
-	createErr      error
-	resourcesExist bool
-	creates        []unstructured.Unstructured
-	deletes        []unstructured.Unstructured
-}
-
-var configMap = namespacedResource("v1", "ConfigMap", "test-ns", "operators-info")
-
-func (f *fakeClient) Get(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
-	var resource *unstructured.Unstructured
-	if f.resourcesExist {
-		resource = &unstructured.Unstructured{}
-	}
-	return resource, f.getErr
-}
-
-func (f *fakeClient) Create(obj *unstructured.Unstructured, options ...mf.ApplyOption) error {
-	obj.SetAnnotations(nil) // Deleting the extra annotation. Irrelevant for the test.
-	f.creates = append(f.creates, *obj)
-	return f.createErr
-}
-
-func (f *fakeClient) Delete(obj *unstructured.Unstructured, options ...mf.DeleteOption) error {
-	f.deletes = append(f.deletes, *obj)
-	return f.err
-}
-
-func (f *fakeClient) Update(obj *unstructured.Unstructured, options ...mf.ApplyOption) error {
-	return f.err
-}
-
 func TestCreateTargetNamespace(t *testing.T) {
 	targetNamespace := "test-ns"
 	component := &v1alpha1.TektonPipeline{
@@ -104,39 +65,3 @@ func TestTargetNamespaceNotFound(t *testing.T) {
 	_, err = fakeClientset.CoreV1().Namespaces().Get(context.Background(), "foo", metav1.GetOptions{})
 	assert.Equal(t, err.Error(), `namespaces "foo" not found`)
 }
-
-func TestOperatorVersionCreateConfigMap(t *testing.T) {
-	os.Setenv(KoEnvKey, "testdata/kodata")
-	defer os.Unsetenv(KoEnvKey)
-
-	targetNamespace := "test-ns"
-	component := &v1alpha1.TektonPipeline{
-		ObjectMeta: metav1.ObjectMeta{
-			Name: "test-name",
-		},
-		Spec: v1alpha1.TektonPipelineSpec{
-			CommonSpec: v1alpha1.CommonSpec{
-				TargetNamespace: targetNamespace,
-			},
-		},
-	}
-	fakeClientset := fake.NewSimpleClientset()
-
-	err := CreateTargetNamespace(context.Background(), nil, component, fakeClientset)
-	assert.Equal(t, err, nil)
-
-	var manifest mf.Manifest
-
-	client := &fakeClient{}
-	manifest, err = mf.ManifestFrom(mf.Slice(manifest.Resources()), mf.UseClient(client))
-	assert.Equal(t, err, nil)
-
-	err = CreateOperatorVersionConfigMap(manifest, component)
-	assert.Equal(t, err, nil)
-
-	want := []unstructured.Unstructured{configMap}
-
-	if len(want) != len(client.creates) {
-		t.Fatalf("Unexpected creates: %s", fmt.Sprintf("(-got, +want): %s", cmp.Diff(client.creates, want)))
-	}
-}
diff --git a/pkg/reconciler/openshift/common/testdata/test-remove-fs-group-expected.yaml b/pkg/reconciler/openshift/common/testdata/test-remove-fs-group-expected.yaml
new file mode 100644
index 000000000..a220b5bc5
--- /dev/null
+++ b/pkg/reconciler/openshift/common/testdata/test-remove-fs-group-expected.yaml
@@ -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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tekton-hub-api
+  labels:
+    app: tekton-hub-api
+spec:
+  selector:
+    matchLabels:
+      app: tekton-hub-api
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: tekton-hub-api
+    spec:
+      volumes:
+      - name: catalog-source
+        persistentVolumeClaim:
+          claimName: tekton-hub-api
+      - name: ssh-creds
+        secret:
+          secretName: tekton-hub-api-ssh-crds
+          optional: true
+      securityContext:
+        fsGroup: 101
+      containers:
+        - name: tekton-hub-api
+          image: quay.io/tekton-hub/api
+          volumeMounts:
+          - name: catalog-source
+            mountPath: "/tmp/catalog"
+          - name: ssh-creds
+            mountPath: "/home/hub/.ssh"
+          ports:
+            - containerPort: 8000
+            - containerPort: 4200
diff --git a/pkg/reconciler/openshift/common/testdata/test-remove-fs-group.yaml b/pkg/reconciler/openshift/common/testdata/test-remove-fs-group.yaml
new file mode 100644
index 000000000..480f29d19
--- /dev/null
+++ b/pkg/reconciler/openshift/common/testdata/test-remove-fs-group.yaml
@@ -0,0 +1,49 @@
+# 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: tekton-hub-api
+  labels:
+    app: tekton-hub-api
+spec:
+  selector:
+    matchLabels:
+      app: tekton-hub-api
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: tekton-hub-api
+    spec:
+      volumes:
+      - name: catalog-source
+        persistentVolumeClaim:
+          claimName: tekton-hub-api
+      - name: ssh-creds
+        secret:
+          secretName: tekton-hub-api-ssh-crds
+          optional: true
+      containers:
+        - name: tekton-hub-api
+          image: quay.io/tekton-hub/api
+          volumeMounts:
+          - name: catalog-source
+            mountPath: "/tmp/catalog"
+          - name: ssh-creds
+            mountPath: "/home/hub/.ssh"
+          ports:
+            - containerPort: 8000
+            - containerPort: 4200
diff --git a/pkg/reconciler/openshift/common/transformer_test.go b/pkg/reconciler/openshift/common/transformer_test.go
index 6abc4cd6d..f0c46fe28 100644
--- a/pkg/reconciler/openshift/common/transformer_test.go
+++ b/pkg/reconciler/openshift/common/transformer_test.go
@@ -118,3 +118,32 @@ func TestUpdateDeploymentsInterceptor(t *testing.T) {
 		t.Errorf("failed to update deployment %s", diff.PrintWantGot(d))
 	}
 }
+
+func TestRemoveFsGroup(t *testing.T) {
+	testData := path.Join("testdata", "test-remove-fs-group.yaml")
+	manifest, err := mf.ManifestFrom(mf.Recursive(testData))
+	assert.NilError(t, err)
+
+	testData = path.Join("testdata", "test-remove-fs-group-expected.yaml")
+	expectedManifest, err := mf.ManifestFrom(mf.Recursive(testData))
+	assert.NilError(t, err)
+
+	newManifest, err := expectedManifest.Transform(RemoveFsGroup("tekton-hub-api"))
+	assert.NilError(t, err)
+
+	got := &appsv1.Deployment{}
+	err = runtime.DefaultUnstructuredConverter.FromUnstructured(newManifest.Resources()[0].Object, got)
+	if err != nil {
+		t.Errorf("failed to load deployment yaml")
+	}
+
+	expected := &appsv1.Deployment{}
+	err = runtime.DefaultUnstructuredConverter.FromUnstructured(manifest.Resources()[0].Object, expected)
+	if err != nil {
+		t.Errorf("failed to load deployment yaml")
+	}
+
+	if d := cmp.Diff(expected, got); d != "" {
+		t.Errorf("failed to update deployment %s", diff.PrintWantGot(d))
+	}
+}