diff --git a/pkg/reconciler/kubernetes/tektoninstallerset/const.go b/pkg/reconciler/kubernetes/tektoninstallerset/const.go index fec53ec404..2bf1124691 100644 --- a/pkg/reconciler/kubernetes/tektoninstallerset/const.go +++ b/pkg/reconciler/kubernetes/tektoninstallerset/const.go @@ -17,9 +17,10 @@ limitations under the License. package tektoninstallerset const ( - LastAppliedHashKey = "operator.tekton.dev/last-applied-hash" - CreatedByKey = "operator.tekton.dev/created-by" - ReleaseVersionKey = "operator.tekton.dev/release-version" - TargetNamespaceKey = "operator.tekton.dev/target-namespace" - InstallerSetType = "operator.tekton.dev/type" + LastAppliedHashKey = "operator.tekton.dev/last-applied-hash" + CreatedByKey = "operator.tekton.dev/created-by" + ReleaseVersionKey = "operator.tekton.dev/release-version" + ReleaseMinorVersionKey = "operator.tekton.dev/release-minor-version" + TargetNamespaceKey = "operator.tekton.dev/target-namespace" + InstallerSetType = "operator.tekton.dev/type" ) diff --git a/pkg/reconciler/openshift/tektonaddon/const.go b/pkg/reconciler/openshift/tektonaddon/const.go index ab16071419..c82b9e19fb 100644 --- a/pkg/reconciler/openshift/tektonaddon/const.go +++ b/pkg/reconciler/openshift/tektonaddon/const.go @@ -18,6 +18,7 @@ package tektonaddon const ( ClusterTaskInstallerSet = "ClusterTask" + VersionedClusterTaskInstallerSet = "VersionedClusterTask" PipelinesTemplateInstallerSet = "PipelinesTemplate" TriggersResourcesInstallerSet = "TriggersResources" ConsoleCLIInstallerSet = "ConsoleCLI" diff --git a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go index 07a19cfc2f..e7a8899d2e 100644 --- a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go +++ b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go @@ -36,6 +36,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "knative.dev/pkg/apis" "knative.dev/pkg/logging" pkgreconciler "knative.dev/pkg/reconciler" @@ -196,6 +197,35 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon return nil } + // If clusterTasks are enabled then create an InstallerSet + // with the versioned clustertask manifest + if ctVal == "true" { + + // here pass two labels one for type and other for minor release version to remove the previous minor release installerset only not all + exist, err := checkIfInstallerSetExist(ctx, r.operatorClientSet, r.version, + fmt.Sprintf("%s=%s,%s=%s", tektoninstallerset.InstallerSetType, VersionedClusterTaskInstallerSet, tektoninstallerset.ReleaseMinorVersionKey, getPatchVersionTrimmed(r.version)), + ) + if err != nil { + return err + } + + if !exist { + return r.ensureVersionedClusterTasks(ctx, ta) + } + } else { + // if disabled then delete the installer Set if exist + if err := r.deleteInstallerSet(ctx, + fmt.Sprintf("%s=%s", tektoninstallerset.InstallerSetType, VersionedClusterTaskInstallerSet)); err != nil { + return err + } + } + + // here pass two labels one for type and other for operator release version to get the latest installerset of current version + if err := r.checkComponentStatus(ctx, fmt.Sprintf("%s=%s,%s=%s", tektoninstallerset.InstallerSetType, VersionedClusterTaskInstallerSet, tektoninstallerset.ReleaseVersionKey, r.version)); err != nil { + ta.Status.MarkInstallerSetNotReady(err.Error()) + return nil + } + // If pipeline templates are enabled then create an InstallerSet // with their manifest if ptVal == "true" { @@ -325,6 +355,7 @@ func (r *Reconciler) ensurePipelineTemplates(ctx context.Context, ta *v1alpha1.T return nil } +// installerset for non versioned clustertask like buildah and community clustertask func (r *Reconciler) ensureClusterTasks(ctx context.Context, ta *v1alpha1.TektonAddon) error { clusterTaskManifest := r.manifest // Read clusterTasks from ko data @@ -336,8 +367,11 @@ func (r *Reconciler) ensureClusterTasks(ctx context.Context, ta *v1alpha1.Tekton return err } - communityClusterTaskManifest := r.manifest + clusterTaskManifest = clusterTaskManifest.Filter( + mf.Not(byContains(getFormattedVersion(r.version))), + ) + communityClusterTaskManifest := r.manifest if err := r.appendCommunityTarget(ctx, &communityClusterTaskManifest, ta); err != nil { // Continue if failed to resolve community task URL. // (Ex: on disconnected cluster community tasks won't be reachable because of proxy). @@ -358,6 +392,30 @@ func (r *Reconciler) ensureClusterTasks(ctx context.Context, ta *v1alpha1.Tekton return nil } +// installerset for versioned clustertask like buildah-1-6-0 +func (r *Reconciler) ensureVersionedClusterTasks(ctx context.Context, ta *v1alpha1.TektonAddon) error { + clusterTaskManifest := r.manifest + // Read clusterTasks from ko data + if err := applyAddons(&clusterTaskManifest, "02-clustertasks"); err != nil { + return err + } + // Run transformers + if err := r.addonTransform(ctx, &clusterTaskManifest, ta); err != nil { + return err + } + + clusterTaskManifest = clusterTaskManifest.Filter( + byContains(getFormattedVersion(r.version)), + ) + + if err := createInstallerSet(ctx, r.operatorClientSet, ta, clusterTaskManifest, + r.version, VersionedClusterTaskInstallerSet, "addon-versioned-clustertasks"); err != nil { + return err + } + + return nil +} + // checkIfInstallerSetExist checks if installer set exists for a component and return true/false based on it // and if installer set which already exist is of older version then it deletes and return false to create a new // installer set @@ -418,14 +476,20 @@ func createInstallerSet(ctx context.Context, oc clientset.Interface, ta *v1alpha func makeInstallerSet(ta *v1alpha1.TektonAddon, manifest mf.Manifest, prefix, releaseVersion, component, specHash string) *v1alpha1.TektonInstallerSet { ownerRef := *metav1.NewControllerRef(ta, ta.GetGroupVersionKind()) + labels := map[string]string{ + tektoninstallerset.CreatedByKey: CreatedByValue, + tektoninstallerset.InstallerSetType: component, + tektoninstallerset.ReleaseVersionKey: releaseVersion, + } + // special label to make sure no two versioned clustertask installerset exist + // for all patch releases + if component == VersionedClusterTaskInstallerSet { + labels[tektoninstallerset.ReleaseMinorVersionKey] = getPatchVersionTrimmed(releaseVersion) + } return &v1alpha1.TektonInstallerSet{ ObjectMeta: metav1.ObjectMeta{ GenerateName: fmt.Sprintf("%s-", prefix), - Labels: map[string]string{ - tektoninstallerset.CreatedByKey: CreatedByValue, - tektoninstallerset.InstallerSetType: component, - tektoninstallerset.ReleaseVersionKey: releaseVersion, - }, + Labels: labels, Annotations: map[string]string{ tektoninstallerset.TargetNamespaceKey: ta.Spec.TargetNamespace, tektoninstallerset.LastAppliedHashKey: specHash, @@ -506,3 +570,25 @@ func findValue(params []v1alpha1.Param, name string) (string, bool) { } return "", false } + +// byContains returns resources with specific string in name +func byContains(name string) mf.Predicate { + return func(u *unstructured.Unstructured) bool { + return strings.Contains(u.GetName(), name) + } +} + +// To get the version in the format as in clustertask name i.e. 1-6 +func getFormattedVersion(version string) string { + version = strings.TrimPrefix(getPatchVersionTrimmed(version), "v") + return strings.Replace(version, ".", "-", -1) +} + +// To get the minor major version for label i.e. v1.6 +func getPatchVersionTrimmed(version string) string { + endIndex := strings.LastIndex(version, ".") + if endIndex != -1 { + version = version[:endIndex] + } + return version +}