Repository: tektoncd/operator
Pull request #1107 (2022-10-12 04:23:09)

Refactors tekton pipeline reconciler to use tektoninstallerset client
similar to tekton triggers, removes duplicate code

Signed-off-by: Shivam Mukhade <smukhade@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:

- [x] Run `make test lint` before submitting a PR
- [ ] 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
```
-->


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 ask for approval from **sm43** after the PR has been reviewed.

The full list of commands accepted by this bot can be found [here](https://prow.tekton.dev/command-help?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":["sm43"]} -->
tekton-robot: The following is the coverage report on the affected files.
Say `/test pull-tekton-operator-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go](https://storage.cloud.google.com/tekton-prow/pr-logs/pull/tektoncd_operator/1107/pull-tekton-operator-go-coverage/1580051429807099904/artifacts/line-cov.html#file2) | 75.0% | 72.2% | -2.8

sm43: @savitaashture updated!

tekton-robot: The following is the coverage report on the affected files.
Say `/test pull-tekton-operator-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go](https://storage.cloud.google.com/tekton-prow/pr-logs/pull/tektoncd_operator/1107/pull-tekton-operator-go-coverage/1581937913308909568/artifacts/line-cov.html#file2) | 75.0% | 72.2% | -2.8


Patch:
diff --git a/pkg/reconciler/common/common.go b/pkg/reconciler/common/common.go
index 1fb62b574..14518c46d 100644
--- a/pkg/reconciler/common/common.go
+++ b/pkg/reconciler/common/common.go
@@ -48,11 +48,7 @@ func PipelineReady(informer informer.TektonPipelineInformer) (*v1alpha1.TektonPi
 		}
 		return nil, err
 	}
-	upgradePending, err := CheckUpgradePending(ppln)
-	if err != nil {
-		return nil, err
-	}
-	if upgradePending {
+	if strings.Contains(ppln.GetStatus().GetCondition(apis.ConditionReady).Message, v1alpha1.UpgradePending) {
 		return nil, v1alpha1.DEPENDENCY_UPGRADE_PENDING_ERR
 	}
 	if !ppln.Status.IsReady() {
diff --git a/pkg/reconciler/common/releases.go b/pkg/reconciler/common/releases.go
index 77f990268..f510e4486 100644
--- a/pkg/reconciler/common/releases.go
+++ b/pkg/reconciler/common/releases.go
@@ -18,7 +18,6 @@ package common
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -112,7 +111,7 @@ func sanitizeSemver(version string) string {
 func allReleases(instance v1alpha1.TektonComponent) ([]string, error) {
 	// List all the directories available under kodata
 	pathname := ComponentDir(instance)
-	fileList, err := ioutil.ReadDir(pathname)
+	fileList, err := os.ReadDir(pathname)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/controller.go b/pkg/reconciler/kubernetes/tektonpipeline/controller.go
index d242ae906..36593135b 100644
--- a/pkg/reconciler/kubernetes/tektonpipeline/controller.go
+++ b/pkg/reconciler/kubernetes/tektonpipeline/controller.go
@@ -25,6 +25,7 @@ import (
 	tektonPipelineInformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonpipeline"
 	tektonPipelineReconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonpipeline"
 	"github.com/tektoncd/operator/pkg/reconciler/common"
+	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset/client"
 	"k8s.io/client-go/tools/cache"
 	kubeclient "knative.dev/pkg/client/injection/kube/client"
 	"knative.dev/pkg/configmap"
@@ -62,15 +63,15 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 		if err != nil {
 			logger.Fatal(err)
 		}
+		tisClient := operatorclient.Get(ctx).OperatorV1alpha1().TektonInstallerSets()
 
 		c := &Reconciler{
-			operatorClientSet: operatorclient.Get(ctx),
-			kubeClientSet:     kubeclient.Get(ctx),
-			extension:         generator(ctx),
-			manifest:          manifest,
-			operatorVersion:   operatorVer,
-			pipelineVersion:   pipelineVer,
-			metrics:           metrics,
+			kubeClientSet:   kubeclient.Get(ctx),
+			extension:       generator(ctx),
+			manifest:        manifest,
+			pipelineVersion: pipelineVer,
+			installerSetClient: client.NewInstallerSetClient(tisClient, &manifest,
+				operatorVer, pipelineVer, v1alpha1.KindTektonPipeline, filterAndTransform(generator(ctx)), metrics),
 		}
 		impl := tektonPipelineReconciler.NewImpl(ctx, c)
 
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/finalize.go b/pkg/reconciler/kubernetes/tektonpipeline/finalize.go
new file mode 100644
index 000000000..eed4ad383
--- /dev/null
+++ b/pkg/reconciler/kubernetes/tektonpipeline/finalize.go
@@ -0,0 +1,53 @@
+/*
+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 tektonpipeline
+
+import (
+	"context"
+
+	mf "github.com/manifestival/manifestival"
+	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
+	tektonpipelinereconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonpipeline"
+	"knative.dev/pkg/logging"
+	pkgreconciler "knative.dev/pkg/reconciler"
+)
+
+var _ tektonpipelinereconciler.Finalizer = (*Reconciler)(nil)
+
+// FinalizeKind removes all resources after deletion of a TektonPipeline.
+func (r *Reconciler) FinalizeKind(ctx context.Context, original *v1alpha1.TektonPipeline) pkgreconciler.Event {
+	logger := logging.FromContext(ctx)
+
+	// Delete CRDs before deleting rest of resources so that any instance
+	// of CRDs which has finalizer set will get deleted before we remove
+	// the controller;s deployment for it
+	if err := r.manifest.Filter(mf.CRDs).Delete(); err != nil {
+		logger.Error("Failed to delete CRDs for TektonPipeline")
+		return err
+	}
+
+	if err := r.installerSetClient.CleanupMainSet(ctx); err != nil {
+		logger.Error("failed to cleanup main installerset: ", err)
+		return err
+	}
+
+	if err := r.extension.Finalize(ctx, original); err != nil {
+		logger.Error("Failed to finalize platform resources: ", err)
+	}
+
+	return nil
+}
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/metrics.go b/pkg/reconciler/kubernetes/tektonpipeline/metrics.go
index 8ad8ced68..6aff172e1 100644
--- a/pkg/reconciler/kubernetes/tektonpipeline/metrics.go
+++ b/pkg/reconciler/kubernetes/tektonpipeline/metrics.go
@@ -24,6 +24,7 @@ import (
 	"go.opencensus.io/stats"
 	"go.opencensus.io/stats/view"
 	"go.opencensus.io/tag"
+	"go.uber.org/zap"
 	"knative.dev/pkg/metrics"
 )
 
@@ -33,11 +34,6 @@ var (
 		stats.UnitDimensionless)
 )
 
-const (
-	metricsNew     = "NewInstall"
-	metricsUpgrade = "Upgrade"
-)
-
 // Recorder holds keys for Tekton metrics
 type Recorder struct {
 	initialized bool
@@ -107,3 +103,10 @@ func (r *Recorder) Count(status, version string) error {
 	metrics.Record(ctx, pReconcileCount.M(1))
 	return nil
 }
+
+func (m *Recorder) LogMetrics(status, version string, logger *zap.SugaredLogger) {
+	err := m.Count(status, version)
+	if err != nil {
+		logger.Warnf("%v: Failed to log the metrics : %v", resourceKind, err)
+	}
+}
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/reconcile.go b/pkg/reconciler/kubernetes/tektonpipeline/reconcile.go
new file mode 100644
index 000000000..6ef81f439
--- /dev/null
+++ b/pkg/reconciler/kubernetes/tektonpipeline/reconcile.go
@@ -0,0 +1,125 @@
+/*
+Copyright 2019 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 tektonpipeline
+
+import (
+	"context"
+	"fmt"
+
+	mf "github.com/manifestival/manifestival"
+	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
+	tektonpipelinereconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonpipeline"
+	"github.com/tektoncd/operator/pkg/reconciler/common"
+	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset/client"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/kubernetes"
+	"knative.dev/pkg/logging"
+	pkgreconciler "knative.dev/pkg/reconciler"
+)
+
+const (
+	resourceKind = v1alpha1.KindTektonPipeline
+
+	proxyLabel = "operator.tekton.dev/disable-proxy=true"
+)
+
+// Reconciler implements controller.Reconciler for TektonPipeline resources.
+type Reconciler struct {
+	// installer Set client to do CRUD operations for components
+	installerSetClient *client.InstallerSetClient
+	//manifest has the source manifest of Tekton Pipeline for a
+	// particular version
+	manifest mf.Manifest
+	// Platform-specific behavior to affect the transform
+	extension common.Extension
+	// kube client to interact with core k8s resources
+	kubeClientSet kubernetes.Interface
+	// version of pipelines which we are installing
+	pipelineVersion string
+}
+
+// Check that our Reconciler implements controller.Reconciler
+var _ tektonpipelinereconciler.Interface = (*Reconciler)(nil)
+
+// ReconcileKind compares the actual state with the desired, and attempts to
+// converge the two.
+func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipeline) pkgreconciler.Event {
+	logger := logging.FromContext(ctx).With("name", tp.GetName())
+	tp.Status.InitializeConditions()
+	tp.Status.SetVersion(r.pipelineVersion)
+
+	if tp.GetName() != v1alpha1.PipelineResourceName {
+		msg := fmt.Sprintf("Resource ignored, Expected Name: %s, Got Name: %s",
+			v1alpha1.PipelineResourceName,
+			tp.GetName(),
+		)
+		logger.Error(msg)
+		tp.Status.MarkNotReady(msg)
+		return nil
+	}
+
+	// Pass the object through defaulting
+	tp.SetDefaults(ctx)
+
+	if err := r.targetNamespaceCheck(ctx, tp); err != nil {
+		return err
+	}
+
+	if err := r.extension.PreReconcile(ctx, tp); err != nil {
+		tp.Status.MarkPreReconcilerFailed(fmt.Sprintf("PreReconciliation failed: %s", err.Error()))
+		return err
+	}
+
+	// Mark PreReconcile Complete
+	tp.Status.MarkPreReconcilerComplete()
+
+	if err := r.installerSetClient.MainSet(ctx, tp); err != nil {
+		logger.Errorf("failed for main set: %v", err)
+		return err
+	}
+
+	if err := r.extension.PostReconcile(ctx, tp); err != nil {
+		tp.Status.MarkPostReconcilerFailed(fmt.Sprintf("PostReconciliation failed: %s", err.Error()))
+		return err
+	}
+
+	// Mark PostReconcile Complete
+	tp.Status.MarkPostReconcilerComplete()
+
+	return nil
+}
+
+func (r *Reconciler) targetNamespaceCheck(ctx context.Context, tp *v1alpha1.TektonPipeline) error {
+	labels := r.manifest.Filter(mf.ByKind("Namespace")).Resources()[0].GetLabels()
+
+	ns, err := r.kubeClientSet.CoreV1().Namespaces().Get(ctx, tp.GetSpec().GetTargetNamespace(), metav1.GetOptions{})
+	if err != nil {
+		if apierrors.IsNotFound(err) {
+			if err := common.CreateTargetNamespace(ctx, labels, tp, r.kubeClientSet); err != nil {
+				return err
+			}
+			return nil
+		}
+		return err
+	}
+	for key, value := range labels {
+		ns.Labels[key] = value
+	}
+	_, err = r.kubeClientSet.CoreV1().Namespaces().Update(ctx, ns, metav1.UpdateOptions{})
+	return err
+}
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go b/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go
deleted file mode 100644
index 61222de36..000000000
--- a/pkg/reconciler/kubernetes/tektonpipeline/tektonpipeline.go
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
-Copyright 2019 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 tektonpipeline
-
-import (
-	"context"
-	"fmt"
-
-	mf "github.com/manifestival/manifestival"
-	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
-	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
-	tektonpipelinereconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonpipeline"
-	"github.com/tektoncd/operator/pkg/reconciler/common"
-	installer "github.com/tektoncd/operator/pkg/reconciler/common/tektoninstallerset"
-	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset"
-	tisBuilder "github.com/tektoncd/operator/pkg/reconciler/shared/tektoninstallerset"
-	"go.uber.org/zap"
-	corev1 "k8s.io/api/core/v1"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/client-go/kubernetes"
-	"knative.dev/pkg/apis"
-	"knative.dev/pkg/logging"
-	pkgreconciler "knative.dev/pkg/reconciler"
-)
-
-const (
-	// Pipelines ConfigMap
-	FeatureFlag    = "feature-flags"
-	ConfigDefaults = "config-defaults"
-	ConfigMetrics  = "config-observability"
-
-	proxyLabel     = "operator.tekton.dev/disable-proxy=true"
-	createdByValue = "TektonPipeline"
-)
-
-// Reconciler implements controller.Reconciler for TektonPipeline resources.
-type Reconciler struct {
-	// operatorClientSet allows us to configure operator objects
-	operatorClientSet clientset.Interface
-	//manifest has the source manifest of Tekton Pipeline for a
-	// particular version
-	manifest mf.Manifest
-	// Platform-specific behavior to affect the transform
-	extension common.Extension
-	// metrics handles metrics for pipeline install
-	metrics         *Recorder
-	kubeClientSet   kubernetes.Interface
-	operatorVersion string
-	pipelineVersion string
-}
-
-var (
-	ls = metav1.LabelSelector{
-		MatchLabels: map[string]string{
-			v1alpha1.CreatedByKey:     createdByValue,
-			v1alpha1.InstallerSetType: v1alpha1.PipelineResourceName,
-		},
-	}
-)
-
-// Check that our Reconciler implements controller.Reconciler
-var _ tektonpipelinereconciler.Interface = (*Reconciler)(nil)
-var _ tektonpipelinereconciler.Finalizer = (*Reconciler)(nil)
-
-// FinalizeKind removes all resources after deletion of a TektonPipeline.
-func (r *Reconciler) FinalizeKind(ctx context.Context, original *v1alpha1.TektonPipeline) pkgreconciler.Event {
-	logger := logging.FromContext(ctx)
-
-	// Delete CRDs before deleting rest of resources so that any instance
-	// of CRDs which has finalizer set will get deleted before we remove
-	// the controller;s deployment for it
-	if err := r.manifest.Filter(mf.CRDs).Delete(); err != nil {
-		logger.Error("Failed to deleted CRDs for TektonPipeline")
-		return err
-	}
-
-	labelSelector, err := common.LabelSelector(ls)
-	if err != nil {
-		return err
-	}
-	if err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-		DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{
-			LabelSelector: labelSelector,
-		}); err != nil {
-		logger.Error("Failed to delete installer set created by TektonPipeline", err)
-		return err
-	}
-
-	if err := r.extension.Finalize(ctx, original); err != nil {
-		logger.Error("Failed to finalize platform resources", err)
-	}
-
-	return nil
-}
-
-// ReconcileKind compares the actual state with the desired, and attempts to
-// converge the two.
-func (r *Reconciler) ReconcileKind(ctx context.Context, tp *v1alpha1.TektonPipeline) pkgreconciler.Event {
-	logger := logging.FromContext(ctx)
-	tp.Status.InitializeConditions()
-
-	if tp.GetName() != v1alpha1.PipelineResourceName {
-		msg := fmt.Sprintf("Resource ignored, Expected Name: %s, Got Name: %s",
-			v1alpha1.PipelineResourceName,
-			tp.GetName(),
-		)
-		logger.Error(msg)
-		tp.Status.MarkNotReady(msg)
-		return nil
-	}
-
-	// Pass the object through defaulting
-	tp.SetDefaults(ctx)
-
-	// Mark TektonPipeline Instance as Not Ready if an upgrade is needed
-	if err := r.markUpgrade(ctx, tp); err != nil {
-		return err
-	}
-
-	if err := tektoninstallerset.CleanUpObsoleteResources(ctx, r.operatorClientSet, createdByValue); err != nil {
-		return err
-	}
-
-	if err := r.targetNamespaceCheck(ctx, tp); err != nil {
-		return err
-	}
-
-	if err := r.extension.PreReconcile(ctx, tp); err != nil {
-		tp.Status.MarkPreReconcilerFailed(fmt.Sprintf("PreReconciliation failed: %s", err.Error()))
-		return err
-	}
-
-	// Mark PreReconcile Complete
-	tp.Status.MarkPreReconcilerComplete()
-
-	// Check if an tekton installer set already exists, if not then create
-	labelSelector, err := common.LabelSelector(ls)
-	if err != nil {
-		return err
-	}
-	existingInstallerSet, err := tektoninstallerset.CurrentInstallerSetName(ctx, r.operatorClientSet, labelSelector)
-	if err != nil {
-		return err
-	}
-	if existingInstallerSet == "" {
-		createdIs, err := r.createInstallerSet(ctx, tp)
-		if err != nil {
-			return err
-		}
-		// If there was no existing installer set, that means its a new install
-		r.metrics.logMetrics(metricsNew, r.pipelineVersion, logger)
-
-		return r.updateTektonPipelineStatus(ctx, tp, createdIs)
-	}
-
-	// If exists, then fetch the TektonInstallerSet
-	installedTIS, err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-		Get(ctx, existingInstallerSet, metav1.GetOptions{})
-	if err != nil {
-		if apierrors.IsNotFound(err) {
-			createdIs, err := r.createInstallerSet(ctx, tp)
-			if err != nil {
-				return err
-			}
-			// if there is version diff then its a call for upgrade
-			if tp.Status.Version != r.pipelineVersion {
-				r.metrics.logMetrics(metricsUpgrade, r.pipelineVersion, logger)
-			}
-			return r.updateTektonPipelineStatus(ctx, tp, createdIs)
-		}
-		logger.Error("failed to get InstallerSet: %s", err)
-		return err
-	}
-
-	installerSetTargetNamespace := installedTIS.Annotations[v1alpha1.TargetNamespaceKey]
-	installerSetReleaseVersion := installedTIS.Labels[v1alpha1.ReleaseVersionKey]
-
-	// Check if TargetNamespace of existing TektonInstallerSet is same as expected
-	// Check if Release Version in TektonInstallerSet is same as expected
-	// If any of the thing above is not same then delete the existing TektonInstallerSet
-	// and create a new with expected properties
-
-	if installerSetTargetNamespace != tp.Spec.TargetNamespace || installerSetReleaseVersion != r.operatorVersion {
-		// Delete the existing TektonInstallerSet
-		err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-			Delete(ctx, existingInstallerSet, metav1.DeleteOptions{})
-		if err != nil {
-			logger.Error("failed to delete InstallerSet: %s", err)
-			return err
-		}
-
-		// Make sure the TektonInstallerSet is deleted
-		_, err = r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-			Get(ctx, existingInstallerSet, metav1.GetOptions{})
-		if err == nil {
-			tp.Status.MarkNotReady("Waiting for previous installer set to get deleted")
-			return v1alpha1.REQUEUE_EVENT_AFTER
-		}
-		if !apierrors.IsNotFound(err) {
-			logger.Error("failed to get InstallerSet: %s", err)
-			return err
-		}
-		return nil
-
-	} else {
-		// If target namespace and version are not changed then check if spec
-		// of TektonPipeline is changed by checking hash stored as annotation on
-		// TektonInstallerSet with computing new hash of TektonPipeline Spec
-
-		// Hash of TektonInstallerSet Spec
-		newIs, err := r.generateInstallerSet(ctx, tp)
-		if err != nil {
-			return err
-		}
-		expectedSpecHash := newIs.Annotations[v1alpha1.LastAppliedHashKey]
-
-		// spec hash stored on installerSet
-		lastAppliedHash := installedTIS.GetAnnotations()[v1alpha1.LastAppliedHashKey]
-
-		if lastAppliedHash != expectedSpecHash {
-			manifest := r.manifest
-			manifest, err := r.transform(ctx, &manifest, tp)
-			if err != nil {
-				logger.Error("manifest transformation failed:  ", err)
-				return err
-			}
-
-			// Update the spec hash
-			current := installedTIS.GetAnnotations()
-			current[v1alpha1.LastAppliedHashKey] = expectedSpecHash
-			installedTIS.SetAnnotations(current)
-
-			// Update the manifests
-			installedTIS.Spec.Manifests = manifest.Resources()
-
-			if _, err = r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
-				Update(ctx, installedTIS, metav1.UpdateOptions{}); err != nil {
-				return err
-			}
-
-			// after updating installer set enqueue after a duration
-			// to allow changes to get deployed
-			return v1alpha1.REQUEUE_EVENT_AFTER
-		}
-	}
-
-	// Mark InstallerSet Available
-	tp.Status.MarkInstallerSetAvailable()
-
-	ready := installedTIS.Status.GetCondition(apis.ConditionReady)
-	if ready == nil {
-		tp.Status.MarkInstallerSetNotReady("Waiting for installation")
-		return v1alpha1.REQUEUE_EVENT_AFTER
-	}
-
-	if ready.Status == corev1.ConditionUnknown {
-		tp.Status.MarkInstallerSetNotReady("Waiting for installation")
-		return v1alpha1.REQUEUE_EVENT_AFTER
-	} else if ready.Status == corev1.ConditionFalse {
-		tp.Status.MarkInstallerSetNotReady(ready.Message)
-		manifest, err := r.transform(ctx, &r.manifest, tp)
-		if err != nil {
-			logger.Error("manifest transformation failed:  ", err)
-			return err
-		}
-		err = common.PreemptDeadlock(ctx, &manifest, r.kubeClientSet, v1alpha1.PipelineResourceName)
-		if err != nil {
-			logger.Error("preempt deadlock error: %v", err)
-		}
-		return v1alpha1.REQUEUE_EVENT_AFTER
-	}
-
-	// Mark InstallerSet Ready
-	tp.Status.MarkInstallerSetReady()
-
-	if err := r.extension.PostReconcile(ctx, tp); err != nil {
-		tp.Status.MarkPostReconcilerFailed(fmt.Sprintf("PostReconciliation failed: %s", err.Error()))
-		return err
-	}
-
-	// Mark PostReconcile Complete
-	tp.Status.MarkPostReconcilerComplete()
-
-	// Update the object for any spec changes
-	if _, err := r.operatorClientSet.OperatorV1alpha1().TektonPipelines().Update(ctx, tp, v1.UpdateOptions{}); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (r *Reconciler) updateTektonPipelineStatus(ctx context.Context, tp *v1alpha1.TektonPipeline, createdIs *v1alpha1.TektonInstallerSet) error {
-	// update the tp with TektonInstallerSet and releaseVersion
-	tp.Status.SetTektonInstallerSet(createdIs.Name)
-	tp.Status.SetVersion(r.pipelineVersion)
-	return nil
-}
-
-func (r *Reconciler) createInstallerSet(ctx context.Context, tp *v1alpha1.TektonPipeline) (*v1alpha1.TektonInstallerSet, error) {
-
-	generatedIs, err := r.generateInstallerSet(ctx, tp)
-	if err != nil {
-		return nil, err
-	}
-
-	createdIs, err := tisBuilder.Create(ctx, generatedIs)
-	if err != nil {
-		return nil, err
-	}
-
-	return createdIs, nil
-}
-
-func (r *Reconciler) generateInstallerSet(ctx context.Context, tp *v1alpha1.TektonPipeline) (*v1alpha1.TektonInstallerSet, error) {
-	// Creates a new default installer
-	dis := installer.NewDefaultInstaller()
-
-	manifest, err := r.transform(ctx, &r.manifest, tp)
-	if err != nil {
-		tp.Status.MarkNotReady("transformation failed: " + err.Error())
-		return nil, err
-	}
-
-	// Adds the manifest to the installer
-	dis.AddManifest(manifest)
-
-	// Adds the labels to the installer
-	dis.AddCreatedByLabel(createdByValue)
-	dis.AddTypeLabel(v1alpha1.PipelineResourceName)
-	dis.AddReleaseVersionLabel(r.operatorVersion)
-
-	// Adds the ownerRef to the installer
-	ownerRef := *metav1.NewControllerRef(tp, tp.GetGroupVersionKind())
-	dis.AddOwnerReferences(ownerRef)
-
-	// Adds the annotations to the installer
-	dis.AddAnnotationsKeyVal(v1alpha1.TargetNamespaceKey, tp.Spec.TargetNamespace)
-
-	generatedIs, err := tisBuilder.GenerateInstallerSetWithPrefixName(ctx, dis, v1alpha1.PipelineResourceName)
-	if err != nil {
-		return nil, err
-	}
-
-	return generatedIs, nil
-}
-
-func (r *Reconciler) targetNamespaceCheck(ctx context.Context, tp *v1alpha1.TektonPipeline) error {
-	labels := r.manifest.Filter(mf.ByKind("Namespace")).Resources()[0].GetLabels()
-
-	ns, err := r.kubeClientSet.CoreV1().Namespaces().Get(ctx, tp.GetSpec().GetTargetNamespace(), metav1.GetOptions{})
-	if err != nil {
-		if apierrors.IsNotFound(err) {
-			if err := common.CreateTargetNamespace(ctx, labels, tp, r.kubeClientSet); err != nil {
-				return err
-			}
-			return nil
-		}
-		return err
-	}
-	for key, value := range labels {
-		ns.Labels[key] = value
-	}
-	_, err = r.kubeClientSet.CoreV1().Namespaces().Update(ctx, ns, metav1.UpdateOptions{})
-	return err
-}
-
-// transform mutates the passed manifest to one with common, component
-// and platform transformations applied
-func (r *Reconciler) transform(ctx context.Context, manifest *mf.Manifest, comp v1alpha1.TektonComponent) (mf.Manifest, error) {
-	pipeline := comp.(*v1alpha1.TektonPipeline)
-
-	filteredManifest := manifest.Filter(mf.Not(mf.ByKind("PodSecurityPolicy")), mf.Not(mf.ByKind("HorizontalPodAutoscaler")))
-
-	images := common.ToLowerCaseKeys(common.ImagesFromEnv(common.PipelinesImagePrefix))
-	instance := comp.(*v1alpha1.TektonPipeline)
-	// adding extension's transformers first to run them before `extra` transformers
-	trns := r.extension.Transformers(instance)
-	extra := []mf.Transformer{
-		common.InjectOperandNameLabelOverwriteExisting(v1alpha1.OperandTektoncdPipeline),
-		common.AddConfigMapValues(FeatureFlag, pipeline.Spec.PipelineProperties),
-		common.AddConfigMapValues(ConfigDefaults, pipeline.Spec.OptionalPipelineProperties),
-		common.AddConfigMapValues(ConfigMetrics, pipeline.Spec.PipelineMetricsProperties),
-		common.ApplyProxySettings,
-		common.DeploymentImages(images),
-		common.InjectLabelOnNamespace(proxyLabel),
-		common.AddConfiguration(pipeline.Spec.Config),
-	}
-	trns = append(trns, extra...)
-
-	if err := common.Transform(ctx, &filteredManifest, instance, trns...); err != nil {
-		return mf.Manifest{}, err
-	}
-	return filteredManifest, nil
-}
-
-func (m *Recorder) logMetrics(status, version string, logger *zap.SugaredLogger) {
-	err := m.Count(status, version)
-	if err != nil {
-		logger.Warnf("Failed to log the metrics : %v", err)
-	}
-}
-
-func (r *Reconciler) markUpgrade(ctx context.Context, tp *v1alpha1.TektonPipeline) error {
-	labels := tp.GetLabels()
-	ver, ok := labels[v1alpha1.ReleaseVersionKey]
-	if ok && ver == r.operatorVersion {
-		return nil
-	}
-	if ok && ver != r.operatorVersion {
-		tp.Status.MarkInstallerSetNotReady(v1alpha1.UpgradePending)
-		tp.Status.MarkPreReconcilerFailed(v1alpha1.UpgradePending)
-		tp.Status.MarkPostReconcilerFailed(v1alpha1.UpgradePending)
-		tp.Status.MarkNotReady(v1alpha1.UpgradePending)
-	}
-	if labels == nil {
-		labels = map[string]string{}
-	}
-	labels[v1alpha1.ReleaseVersionKey] = r.operatorVersion
-	tp.SetLabels(labels)
-
-	if _, err := r.operatorClientSet.OperatorV1alpha1().TektonPipelines().Update(ctx,
-		tp, v1.UpdateOptions{}); err != nil {
-		return err
-	}
-	return v1alpha1.RECONCILE_AGAIN_ERR
-}
diff --git a/pkg/reconciler/kubernetes/tektonpipeline/transform.go b/pkg/reconciler/kubernetes/tektonpipeline/transform.go
new file mode 100644
index 000000000..89c23be20
--- /dev/null
+++ b/pkg/reconciler/kubernetes/tektonpipeline/transform.go
@@ -0,0 +1,62 @@
+/*
+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 tektonpipeline
+
+import (
+	"context"
+
+	mf "github.com/manifestival/manifestival"
+	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
+	"github.com/tektoncd/operator/pkg/reconciler/common"
+	"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset/client"
+)
+
+const (
+	// Pipelines ConfigMap
+	FeatureFlag    = "feature-flags"
+	ConfigDefaults = "config-defaults"
+	ConfigMetrics  = "config-observability"
+)
+
+func filterAndTransform(extension common.Extension) client.FilterAndTransform {
+	return func(ctx context.Context, manifest *mf.Manifest, comp v1alpha1.TektonComponent) (*mf.Manifest, error) {
+		pipeline := comp.(*v1alpha1.TektonPipeline)
+
+		filteredManifest := manifest.Filter(mf.Not(mf.ByKind("PodSecurityPolicy")), mf.Not(mf.ByKind("HorizontalPodAutoscaler")))
+
+		images := common.ToLowerCaseKeys(common.ImagesFromEnv(common.PipelinesImagePrefix))
+		instance := comp.(*v1alpha1.TektonPipeline)
+		// adding extension's transformers first to run them before `extra` transformers
+		trns := extension.Transformers(instance)
+		extra := []mf.Transformer{
+			common.InjectOperandNameLabelOverwriteExisting(v1alpha1.OperandTektoncdPipeline),
+			common.AddConfigMapValues(FeatureFlag, pipeline.Spec.PipelineProperties),
+			common.AddConfigMapValues(ConfigDefaults, pipeline.Spec.OptionalPipelineProperties),
+			common.AddConfigMapValues(ConfigMetrics, pipeline.Spec.PipelineMetricsProperties),
+			common.ApplyProxySettings,
+			common.DeploymentImages(images),
+			common.InjectLabelOnNamespace(proxyLabel),
+			common.AddConfiguration(pipeline.Spec.Config),
+		}
+		trns = append(trns, extra...)
+
+		if err := common.Transform(ctx, &filteredManifest, instance, trns...); err != nil {
+			return &mf.Manifest{}, err
+		}
+		return &filteredManifest, nil
+	}
+}
diff --git a/pkg/reconciler/kubernetes/tektontrigger/controller.go b/pkg/reconciler/kubernetes/tektontrigger/controller.go
index 4d72e4db6..a52063c02 100644
--- a/pkg/reconciler/kubernetes/tektontrigger/controller.go
+++ b/pkg/reconciler/kubernetes/tektontrigger/controller.go
@@ -74,7 +74,6 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
 			extension:       generator(ctx),
 			manifest:        manifest,
 			triggersVersion: triggersVer,
-			metrics:         metrics,
 		}
 		impl := tektonTriggerreconciler.NewImpl(ctx, c)
 
diff --git a/pkg/reconciler/kubernetes/tektontrigger/finalize.go b/pkg/reconciler/kubernetes/tektontrigger/finalize.go
index ec51e383c..60f7c9bc4 100644
--- a/pkg/reconciler/kubernetes/tektontrigger/finalize.go
+++ b/pkg/reconciler/kubernetes/tektontrigger/finalize.go
@@ -40,8 +40,8 @@ func (r *Reconciler) FinalizeKind(ctx context.Context, original *v1alpha1.Tekton
 		return err
 	}
 
-	if err := r.installerSetClient.CleanupAll(ctx); err != nil {
-		logger.Error("failed to cleanup all installerset: ", err)
+	if err := r.installerSetClient.CleanupMainSet(ctx); err != nil {
+		logger.Error("failed to cleanup main installerset: ", err)
 		return err
 	}
 
diff --git a/pkg/reconciler/kubernetes/tektontrigger/reconcile.go b/pkg/reconciler/kubernetes/tektontrigger/reconcile.go
index d551d1168..bd96b0190 100644
--- a/pkg/reconciler/kubernetes/tektontrigger/reconcile.go
+++ b/pkg/reconciler/kubernetes/tektontrigger/reconcile.go
@@ -43,8 +43,6 @@ type Reconciler struct {
 	manifest mf.Manifest
 	// Platform-specific behavior to affect the transform
 	extension common.Extension
-	// metrics handles metrics for trigger install
-	metrics *Recorder
 	// version of triggers which we are installing
 	triggersVersion string
 }
diff --git a/pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go b/pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go
index 59068a33c..194a078ad 100644
--- a/pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go
+++ b/pkg/reconciler/shared/tektonconfig/pipeline/pipeline.go
@@ -20,11 +20,12 @@ import (
 	"context"
 	"fmt"
 	"reflect"
+	"strings"
 
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
+	"knative.dev/pkg/apis"
 
 	op "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1"
-	"github.com/tektoncd/operator/pkg/reconciler/common"
 	apierrs "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -120,12 +121,10 @@ func UpdatePipeline(ctx context.Context, old *v1alpha1.TektonPipeline, new *v1al
 
 // IsTektonPipelineReady will check the status conditions of the TektonPipeline and return true if the TektonPipeline is ready.
 func isTektonPipelineReady(s *v1alpha1.TektonPipeline, err error) (bool, error) {
-	upgradePending, errInternal := common.CheckUpgradePending(s)
-	if err != nil {
-		return false, errInternal
-	}
-	if upgradePending {
-		return false, v1alpha1.DEPENDENCY_UPGRADE_PENDING_ERR
+	if s.GetStatus() != nil && s.GetStatus().GetCondition(apis.ConditionReady) != nil {
+		if strings.Contains(s.GetStatus().GetCondition(apis.ConditionReady).Message, v1alpha1.UpgradePending) {
+			return false, v1alpha1.DEPENDENCY_UPGRADE_PENDING_ERR
+		}
 	}
 	return s.Status.IsReady(), err
 }
diff --git a/third_party/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/third_party/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
index 92d70934d..a0b97e3f7 100644
--- a/third_party/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
+++ b/third_party/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
@@ -34,6 +34,6 @@ type LRUCache interface {
 	// Clears all cache entries.
 	Purge()
 
-  // Resizes cache, returning number evicted
-  Resize(int) int
+	// Resizes cache, returning number evicted
+	Resize(int) int
 }
diff --git a/third_party/github.com/letsencrypt/boulder/core/proto/core.pb.go b/third_party/github.com/letsencrypt/boulder/core/proto/core.pb.go
index 02b3515bd..4793eac0f 100644
--- a/third_party/github.com/letsencrypt/boulder/core/proto/core.pb.go
+++ b/third_party/github.com/letsencrypt/boulder/core/proto/core.pb.go
@@ -7,10 +7,11 @@
 package proto
 
 import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	reflect "reflect"
 	sync "sync"
+
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 )
 
 const (
diff --git a/third_party/github.com/letsencrypt/boulder/sa/proto/sa.pb.go b/third_party/github.com/letsencrypt/boulder/sa/proto/sa.pb.go
index 6bb28e0f2..e1df2a7b4 100644
--- a/third_party/github.com/letsencrypt/boulder/sa/proto/sa.pb.go
+++ b/third_party/github.com/letsencrypt/boulder/sa/proto/sa.pb.go
@@ -7,12 +7,13 @@
 package proto
 
 import (
+	reflect "reflect"
+	sync "sync"
+
 	proto "github.com/letsencrypt/boulder/core/proto"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	emptypb "google.golang.org/protobuf/types/known/emptypb"
-	reflect "reflect"
-	sync "sync"
 )
 
 const (
diff --git a/third_party/github.com/letsencrypt/boulder/sa/proto/sa_grpc.pb.go b/third_party/github.com/letsencrypt/boulder/sa/proto/sa_grpc.pb.go
index 7534016eb..fbb3b699d 100644
--- a/third_party/github.com/letsencrypt/boulder/sa/proto/sa_grpc.pb.go
+++ b/third_party/github.com/letsencrypt/boulder/sa/proto/sa_grpc.pb.go
@@ -8,6 +8,7 @@ package proto
 
 import (
 	context "context"
+
 	proto "github.com/letsencrypt/boulder/core/proto"
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"


Test patch:
diff --git a/pkg/reconciler/shared/tektonconfig/pipeline/pipeline_test.go b/pkg/reconciler/shared/tektonconfig/pipeline/pipeline_test.go
index f52923b29..c8bd97ba3 100644
--- a/pkg/reconciler/shared/tektonconfig/pipeline/pipeline_test.go
+++ b/pkg/reconciler/shared/tektonconfig/pipeline/pipeline_test.go
@@ -43,7 +43,7 @@ func TestEnsureTektonPipelineExists(t *testing.T) {
 	// during second invocation instance exists but waiting on dependencies (pipeline, triggers)
 	// hence returns DEPENDENCY_UPGRADE_PENDING_ERR
 	_, err = EnsureTektonPipelineExists(ctx, c.OperatorV1alpha1().TektonPipelines(), tp)
-	util.AssertEqual(t, err, v1alpha1.DEPENDENCY_UPGRADE_PENDING_ERR)
+	util.AssertEqual(t, err, v1alpha1.RECONCILE_AGAIN_ERR)
 
 	// make upgrade checks pass
 	makeUpgradeCheckPass(t, ctx, c.OperatorV1alpha1().TektonPipelines())