diff --git a/Makefile b/Makefile index eedd5a7b0f..77a0e17dd4 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ ifeq ($(TARGET), openshift) rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-pruner rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/pipelines-as-code rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/addons/02-clustertasks/source_external/ + rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/addons/07-ecosystem/ rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/pipelines-as-code-templates/go.yaml rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/pipelines-as-code-templates/java.yaml rm -rf ./cmd/$(TARGET)/operator/kodata/tekton-addon/pipelines-as-code-templates/nodejs.yaml diff --git a/config/crs/openshift/config/all/operator_v1alpha1_config_cr.yaml b/config/crs/openshift/config/all/operator_v1alpha1_config_cr.yaml index 399c153218..18354ee21f 100644 --- a/config/crs/openshift/config/all/operator_v1alpha1_config_cr.yaml +++ b/config/crs/openshift/config/all/operator_v1alpha1_config_cr.yaml @@ -27,6 +27,8 @@ spec: value: "true" - name: communityClusterTasks value: "true" + - name: namespacedTasks + value: "true" params: - name: createRbacResource value: "true" diff --git a/docs/TektonAddon.md b/docs/TektonAddon.md index 91093522ff..db7860137a 100644 --- a/docs/TektonAddon.md +++ b/docs/TektonAddon.md @@ -6,7 +6,8 @@ weight: 6 --> # Tekton Addon -TektonAddon custom resource allows user to install resource like clusterTasks and pipelineTemplate along with Pipelines. +TektonAddon custom resource allows user to install resource like clusterTasks and pipelineTemplate along with Pipelines. +It also allows user to install various Tasks in openshift-pipelines namespace. **NOTE:** TektonAddon is currently available only for OpenShift Platform. This is roadmap to enable it for Kubernetes platform. @@ -25,6 +26,8 @@ spec: value: "true" - name: pipelineTemplates value: "true" + - name: namespacedTasks + value: "true" ``` You can install this component using [TektonConfig](./TektonConfig.md) by choosing appropriate `profile`. @@ -35,6 +38,7 @@ Available params are - `clusterTasks` (Default: `true`) - `pipelineTemplates` (Default: `true`) +- `namespacedTasks` (Default: `true`) User can disable the installation of resources by changing the value to `false`. diff --git a/docs/TektonConfig.md b/docs/TektonConfig.md index 0911c0a37c..9b465f8066 100644 --- a/docs/TektonConfig.md +++ b/docs/TektonConfig.md @@ -319,7 +319,7 @@ By default pruner job will be created from the global pruner config (`spec.prune > `keep: 100`
### Addon -TektonAddon install some resources along with Tekton Pipelines on the cluster. This provides few ClusterTasks, PipelineTemplates. +TektonAddon install some resources along with Tekton Pipelines on the cluster. This provides few ClusterTasks, PipelineTemplates, Tasks. This section allows to customize installation of those resources through params. You can read more about the supported params [here](./TektonAddon.md). @@ -331,6 +331,8 @@ addon: value: "true" - name: "pipelineTemplates" value: "true" + - name: "namespacedTasks" + value: "true" ``` **NOTE**: TektonAddon is currently available for OpenShift Platform only. Enabling this for Kubernetes platform is in roadmap diff --git a/hack/fetch-releases.sh b/hack/fetch-releases.sh index cb35b90414..91d858fa41 100755 --- a/hack/fetch-releases.sh +++ b/hack/fetch-releases.sh @@ -227,6 +227,8 @@ fetch_openshift_addon_tasks() { fetch_addon_task_script="${SCRIPT_DIR}/hack/openshift" local dest_dir="cmd/openshift/operator/kodata/tekton-addon/addons/02-clustertasks/source_external" ${fetch_addon_task_script}/fetch-tektoncd-catalog-tasks.sh ${dest_dir} + dest_dir='cmd/openshift/operator/kodata/tekton-addon/addons/07-ecosystem' + ${fetch_addon_task_script}/fetch-tektoncd-catalog-tasks.sh ${dest_dir} "ecosystem" } copy_pruner_yaml() { diff --git a/hack/openshift/fetch-tektoncd-catalog-tasks.sh b/hack/openshift/fetch-tektoncd-catalog-tasks.sh index 60bccdee6d..a50d47289a 100755 --- a/hack/openshift/fetch-tektoncd-catalog-tasks.sh +++ b/hack/openshift/fetch-tektoncd-catalog-tasks.sh @@ -53,6 +53,27 @@ declare -A TEKTON_CATALOG_TASKS=( # ["buildah"]="0.1" # ["openshift-client"]="0.2" ) +declare -r TEKTON_ECOSYSTEM="https://raw.githubusercontent.com/openshift-pipelines/tektoncd-catalog" +declare -A TEKTON_ECOSYSTEM_TASKS=( + ['task-buildah']="0.3.0" + ['task-git-cli']="0.3.0" + ['task-git-clone']='0.3.0' + ['task-kn-apply']='0.1.0' + ['task-kn']='0.1.0' + ['task-maven']="0.2.0" + ['task-opc']="0.1.0" + ['task-openshift-client']="0.1.0" + ['task-s2i-dotnet']='0.3.0' + ['task-s2i-go']='0.3.0' + ['task-s2i-java']='0.3.0' + ['task-s2i-nodejs']='0.3.0' + ['task-s2i-perl']='0.3.0' + ['task-s2i-php']='0.3.0' + ['task-s2i-python']='0.3.0' + ['task-s2i-ruby']='0.3.0' + ['task-skopeo-copy']='0.3.0' + ['task-tkn']='0.1.0' +) download_task() { local task_path="$1"; shift @@ -82,15 +103,18 @@ get_tasks() { local dest_dir="$1"; shift local catalog="$1"; shift local catalog_version="$1"; shift - local -n tasks=$1 - + local -n tasks=$1; shift + local type="$1" info "Downloading tasks from catalog $catalog to $dest_dir directory" for t in ${!tasks[@]} ; do # task filenames do not follow a naming convention, # some are taskname.yaml while others are taskname-task.yaml # so, try both before failing - local task_url="$catalog/$catalog_version/task/$t/${tasks[$t]}/${t}.yaml" - echo "$catalog/$catalog_version/task/$t/${tasks[$t]}/${t}.yaml" + if [[ "$type" == "ecosystem" ]]; then + local task_url="$catalog/$catalog_version/tasks/$t/${tasks[$t]}/${t}.yaml" + elif [[ "$type" == 'default' ]];then + local task_url="$catalog/$catalog_version/task/$t/${tasks[$t]}/${t}.yaml" + fi mkdir -p "$dest_dir/$t/" local task_path="$dest_dir/$t/$t-task.yaml" @@ -107,14 +131,31 @@ create_dir_or_die() { } main() { - - local dest_dir=${1:-'cmd/openshift/operator/kodata/tekton-addon/addons/02-clustertasks/source_external'} + local type=${2:-"default"} + + if [[ "$type" == "default" ]]; then + local dest_dir=${1:-'cmd/openshift/operator/kodata/tekton-addon/addons/02-clustertasks/source_external'} + local tasks=TEKTON_CATALOG_TASKS + local branch="main" + local catalog="$TEKTON_CATALOG" + + elif [[ "$type" == "ecosystem" ]]; then + local dest_dir=${1:-'cmd/openshift/operator/kodata/tekton-addon/addons/07-ecosystem'} + local tasks=TEKTON_ECOSYSTEM_TASKS + local branch="p" + local catalog="$TEKTON_ECOSYSTEM" + + else + echo "Invalid type specified: $type" + return $? + fi + [[ -z "$dest_dir" ]] && usage "missing destination directory" shift [[ ! -d "$dest_dir" ]] && create_dir_or_die "$dest_dir" || echo "$dest_dir" exists - get_tasks "$dest_dir" "$TEKTON_CATALOG" "main" TEKTON_CATALOG_TASKS + get_tasks "$dest_dir" $catalog $branch $tasks $type return $? } diff --git a/pkg/apis/operator/v1alpha1/const.go b/pkg/apis/operator/v1alpha1/const.go index b533570492..7859d6056e 100644 --- a/pkg/apis/operator/v1alpha1/const.go +++ b/pkg/apis/operator/v1alpha1/const.go @@ -36,6 +36,7 @@ const ( ClusterTasksParam = "clusterTasks" PipelineTemplatesParam = "pipelineTemplates" CommunityClusterTasks = "communityClusterTasks" + NamespacedTasks = "namespacedTasks" // Hub Params EnableDevconsoleIntegrationParam = "enable-devconsole-integration" @@ -112,6 +113,7 @@ var ( ClusterTasksParam: defaultParamValue, PipelineTemplatesParam: defaultParamValue, CommunityClusterTasks: defaultParamValue, + NamespacedTasks: defaultParamValue, } HubParams = map[string]ParamValue{ diff --git a/pkg/apis/operator/v1alpha1/tektonaddon_default_test.go b/pkg/apis/operator/v1alpha1/tektonaddon_default_test.go index 71b805ab06..fec01b535e 100644 --- a/pkg/apis/operator/v1alpha1/tektonaddon_default_test.go +++ b/pkg/apis/operator/v1alpha1/tektonaddon_default_test.go @@ -39,7 +39,7 @@ func Test_AddonSetDefaults_DefaultParamsWithValues(t *testing.T) { } ta.SetDefaults(context.TODO()) - assert.Equal(t, 3, len(ta.Spec.Params)) + assert.Equal(t, 4, len(ta.Spec.Params)) params := ParseParams(ta.Spec.Params) value, ok := params[ClusterTasksParam] @@ -70,7 +70,7 @@ func Test_AddonSetDefaults_ClusterTaskIsFalse(t *testing.T) { } ta.SetDefaults(context.TODO()) - assert.Equal(t, 3, len(ta.Spec.Params)) + assert.Equal(t, 4, len(ta.Spec.Params)) params := ParseParams(ta.Spec.Params) value, ok := params[PipelineTemplatesParam] diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_default_test.go b/pkg/apis/operator/v1alpha1/tektonconfig_default_test.go index 5849393ebf..764e460edc 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_default_test.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_default_test.go @@ -90,7 +90,7 @@ func Test_SetDefaults_Addon_Params(t *testing.T) { t.Setenv("PLATFORM", "openshift") tc.SetDefaults(context.TODO()) - if len(tc.Spec.Addon.Params) != 3 { + if len(tc.Spec.Addon.Params) != 4 { t.Error("Setting default failed for TektonConfig (spec.addon.params)") } } diff --git a/pkg/reconciler/openshift/tektonaddon/const.go b/pkg/reconciler/openshift/tektonaddon/const.go index 07717caa31..65c5a77835 100644 --- a/pkg/reconciler/openshift/tektonaddon/const.go +++ b/pkg/reconciler/openshift/tektonaddon/const.go @@ -17,6 +17,7 @@ limitations under the License. package tektonaddon const ( + NamespacedTaskInstallerSet = "NamespacedTask" ClusterTaskInstallerSet = "ClusterTask" OpenShiftConsoleInstallerSet = "OpenShiftConsole" CommunityClusterTaskInstallerSet = "CommunityClusterTask" diff --git a/pkg/reconciler/openshift/tektonaddon/controller.go b/pkg/reconciler/openshift/tektonaddon/controller.go index f53ab04bb8..51921c7489 100644 --- a/pkg/reconciler/openshift/tektonaddon/controller.go +++ b/pkg/reconciler/openshift/tektonaddon/controller.go @@ -78,6 +78,11 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro tisClient := operatorclient.Get(ctx).OperatorV1alpha1().TektonInstallerSets() metrics, _ := NewRecorder() + namespacedTaskManifest := &mf.Manifest{} + if err := applyAddons(namespacedTaskManifest, "07-ecosystem"); err != nil { + logger.Fatalf("failed to read namespaced tasks from kodata: %v", err) + } + clusterTaskManifest := &mf.Manifest{} if err := applyAddons(clusterTaskManifest, "02-clustertasks"); err != nil { logger.Fatalf("failed to read clustertask from kodata: %v", err) @@ -124,6 +129,7 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro triggerInformer: tektonTriggerinformer.Get(ctx), manifest: manifest, operatorVersion: version, + namespacedTaskManifest: namespacedTaskManifest, clusterTaskManifest: clusterTaskManifest, triggersResourcesManifest: triggersResourcesManifest, pipelineTemplateManifest: pipelineTemplateManifest, diff --git a/pkg/reconciler/openshift/tektonaddon/namespacedTask.go b/pkg/reconciler/openshift/tektonaddon/namespacedTask.go new file mode 100644 index 0000000000..96c66cc063 --- /dev/null +++ b/pkg/reconciler/openshift/tektonaddon/namespacedTask.go @@ -0,0 +1,40 @@ +package tektonaddon + +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" +) + +func (r *Reconciler) EnsureNamespacedTask(ctx context.Context, enable string, ta *v1alpha1.TektonAddon) error { + manifest := *r.namespacedTaskManifest + if enable == "true" { + if err := r.installerSetClient.CustomSet(ctx, ta, NamespacedTaskInstallerSet, &manifest, filterAndTransformNamespacedTask(), nil); err != nil { + return err + } + } else { + if err := r.installerSetClient.CleanupCustomSet(ctx, NamespacedTaskInstallerSet); err != nil { + return err + } + } + return nil +} + +func filterAndTransformNamespacedTask() client.FilterAndTransform { + return func(ctx context.Context, manifest *mf.Manifest, comp v1alpha1.TektonComponent) (*mf.Manifest, error) { + addon := comp.(*v1alpha1.TektonAddon) + addonImages := common.ToLowerCaseKeys(common.ImagesFromEnv(common.AddonsImagePrefix)) + tfs := []mf.Transformer{ + // replaceKind(KindTask, KindClusterTask), + injectLabel(labelProviderType, providerTypeRedHat, overwrite, "Task"), + common.TaskImages(addonImages), + } + if err := transformers(ctx, manifest, addon, tfs...); err != nil { + return nil, err + } + return manifest, nil + } +} diff --git a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go index 123aa97eb4..ee8261f412 100644 --- a/pkg/reconciler/openshift/tektonaddon/tektonaddon.go +++ b/pkg/reconciler/openshift/tektonaddon/tektonaddon.go @@ -48,6 +48,7 @@ type Reconciler struct { pipelineInformer informer.TektonPipelineInformer triggerInformer informer.TektonTriggerInformer operatorVersion string + namespacedTaskManifest *mf.Manifest clusterTaskManifest *mf.Manifest triggersResourcesManifest *mf.Manifest pipelineTemplateManifest *mf.Manifest @@ -130,6 +131,7 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon ptVal, _ := findValue(ta.Spec.Params, v1alpha1.PipelineTemplatesParam) ctVal, _ := findValue(ta.Spec.Params, v1alpha1.ClusterTasksParam) cctVal, _ := findValue(ta.Spec.Params, v1alpha1.CommunityClusterTasks) + ntVal, _ := findValue(ta.Spec.Params, v1alpha1.NamespacedTasks) if ptVal == "true" && ctVal == "false" { ta.Status.MarkNotReady("pipelineTemplates cannot be true if clusterTask is false") @@ -151,6 +153,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, ta *v1alpha1.TektonAddon ready := true var errorMsg string + if err := r.EnsureNamespacedTask(ctx, ntVal, ta); err != nil { + ready = false + errorMsg = fmt.Sprintf("namespaced tasks not yet ready: %v", err) + logger.Error(errorMsg) + } + if err := r.EnsureClusterTask(ctx, ctVal, ta); err != nil { ready = false errorMsg = fmt.Sprintf("cluster tasks not yet ready: %v", err)