diff --git a/pkg/jx/cmd/step/create/step_create_task.go b/pkg/jx/cmd/step/create/step_create_task.go index 73ff9489ea..a7ec6c0409 100644 --- a/pkg/jx/cmd/step/create/step_create_task.go +++ b/pkg/jx/cmd/step/create/step_create_task.go @@ -554,7 +554,15 @@ func (o *StepCreateTaskOptions) GenerateTektonCRDs(packsDir string, projectConfi tasks, pipeline = o.EnhanceTasksAndPipeline(tasks, pipeline, pipelineConfig.Env) resources := []*pipelineapi.PipelineResource{tekton.GenerateSourceRepoResource(pipelineResourceName, o.GitInfo, o.Revision)} - run := tekton.CreatePipelineRun(resources, pipeline.Name, pipeline.APIVersion, o.labels, o.Trigger, o.ServiceAccount, o.pipelineParams) + + var timeout *metav1.Duration + if parsed.Options != nil && parsed.Options.Timeout != nil { + timeout, err = parsed.Options.Timeout.ToDuration() + if err != nil { + return nil, errors.Wrapf(err, "parsing of pipeline timeout failed") + } + } + run := tekton.CreatePipelineRun(resources, pipeline.Name, pipeline.APIVersion, o.labels, o.Trigger, o.ServiceAccount, o.pipelineParams, timeout) tektonCRDs, err := tekton.NewCRDWrapper(pipeline, tasks, resources, structure, run) if err != nil { diff --git a/pkg/jx/cmd/step/create/step_create_task_test.go b/pkg/jx/cmd/step/create/step_create_task_test.go index 4dbdd2b605..3dab007299 100644 --- a/pkg/jx/cmd/step/create/step_create_task_test.go +++ b/pkg/jx/cmd/step/create/step_create_task_test.go @@ -287,6 +287,14 @@ func TestGenerateTektonCRDs(t *testing.T) { branch: "really-long", kind: "release", }, + { + name: "pipeline-timeout", + language: "none", + repoName: "js-test-repo", + organization: "abayer", + branch: "really-long", + kind: "release", + }, } k8sObjects := []runtime.Object{ @@ -380,8 +388,6 @@ func TestGenerateTektonCRDs(t *testing.T) { } if d := cmp.Diff(tekton_helpers_test.AssertLoadPipelineRun(t, caseDir), crds.PipelineRun()); d != "" { - pry, _ := yaml.Marshal(crds.PipelineRun()) - t.Logf("PR: %s", pry) t.Errorf("Generated PipelineRun did not match expected: %s", d) } if d := cmp.Diff(tekton_helpers_test.AssertLoadPipelineStructure(t, caseDir), crds.Structure()); d != "" { diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/from_yaml/pipelinerun.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/from_yaml/pipelinerun.yml index 1d06089cd6..2d6ce8f68a 100755 --- a/pkg/jx/cmd/step/create/test_data/step_create_task/from_yaml/pipelinerun.yml +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/from_yaml/pipelinerun.yml @@ -21,7 +21,6 @@ spec: name: abayer-js-test-repo-really-long serviceAccount: tekton-bot timeout: 240h0m0s - timeout: 240h0m0s trigger: type: manual status: {} diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/jenkins-x.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/jenkins-x.yml new file mode 100644 index 0000000000..6db407237e --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/jenkins-x.yml @@ -0,0 +1,44 @@ +pipelineConfig: + env: + - name: FRUIT + value: BANANA + pipelines: + release: + pipeline: + env: + - name: GIT_AUTHOR_NAME + value: somebodyelse + options: + timeout: + time: 10 + unit: hours + containerOptions: + resources: + requests: + cpu: 0.1 + memory: 64Mi + agent: + image: nodejs + stages: + - name: Build-a-really-long-stage-name-please-but-not-too-long-thanks + steps: + - command: echo + args: + - hello world + - command: ls + args: + - -la + env: + - name: ANOTHER_VAR + value: Another value + - name: Second + steps: + - command: echo + args: + - hi ${FRUIT} + options: + containerOptions: + resources: + limits: + cpu: 0.4 + memory: 256Mi diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipeline.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipeline.yml new file mode 100755 index 0000000000..b81e930e0b --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipeline.yml @@ -0,0 +1,48 @@ +apiVersion: tekton.dev/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: null + name: abayer-js-test-repo-really-long-1 + namespace: jx + labels: + branch: really-long + owner: abayer + repo: js-test-repo +spec: + params: + - default: 0.0.1 + description: the version number for this pipeline which is used as a tag on docker + images and helm charts + name: version + resources: + - name: abayer-js-test-repo-really-long + type: git + tasks: + - name: build-a-really-long-stage-name-please-but-not-too-long-thanks + params: + - name: version + value: ${params.version} + resources: + inputs: + - name: workspace + resource: abayer-js-test-repo-really-long + outputs: + - name: workspace + resource: abayer-js-test-repo-really-long + taskRef: + name: abayer-js-test-repo-really-long-build-a-really-long-stage-nam-1 + - name: second + params: + - name: version + value: ${params.version} + resources: + inputs: + - from: + - build-a-really-long-stage-name-please-but-not-too-long-thanks + name: workspace + resource: abayer-js-test-repo-really-long + runAfter: + - build-a-really-long-stage-name-please-but-not-too-long-thanks + taskRef: + name: abayer-js-test-repo-really-long-second-1 +status: {} diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelineresources.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelineresources.yml new file mode 100755 index 0000000000..9744b75e51 --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelineresources.yml @@ -0,0 +1,15 @@ +items: + - apiVersion: tekton.dev/v1alpha1 + kind: PipelineResource + metadata: + creationTimestamp: null + name: abayer-js-test-repo-really-long + spec: + params: + - name: revision + value: v0.0.1 + - name: url + value: https://github.com/abayer/js-test-repo + type: git + status: {} +metadata: {} \ No newline at end of file diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelinerun.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelinerun.yml new file mode 100755 index 0000000000..d1dd320bfd --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/pipelinerun.yml @@ -0,0 +1,26 @@ +apiVersion: tekton.dev/v1alpha1 +kind: PipelineRun +metadata: + creationTimestamp: null + labels: + branch: really-long + owner: abayer + repo: js-test-repo + name: abayer-js-test-repo-really-long-1 +spec: + params: + - name: version + value: 0.0.1 + pipelineRef: + apiVersion: tekton.dev/v1alpha1 + name: abayer-js-test-repo-really-long-1 + resources: + - name: abayer-js-test-repo-really-long + resourceRef: + apiVersion: tekton.dev/v1alpha1 + name: abayer-js-test-repo-really-long + serviceAccount: tekton-bot + timeout: 10h0m0s + trigger: + type: manual +status: {} diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/structure.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/structure.yml new file mode 100755 index 0000000000..4f888a1578 --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/structure.yml @@ -0,0 +1,17 @@ +metadata: + creationTimestamp: null + name: abayer-js-test-repo-really-long-1 + labels: + branch: really-long + owner: abayer + repo: js-test-repo +pipelineRef: null +pipelineRunRef: null +stages: + - depth: 0 + name: Build-a-really-long-stage-name-please-but-not-too-long-thanks + taskRef: abayer-js-test-repo-really-long-build-a-really-long-stage-nam-1 + - depth: 0 + name: Second + previous: Build-a-really-long-stage-name-please-but-not-too-long-thanks + taskRef: abayer-js-test-repo-really-long-second-1 diff --git a/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/tasks.yml b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/tasks.yml new file mode 100755 index 0000000000..c303e29027 --- /dev/null +++ b/pkg/jx/cmd/step/create/test_data/step_create_task/pipeline-timeout/tasks.yml @@ -0,0 +1,330 @@ +items: + - apiVersion: tekton.dev/v1alpha1 + kind: Task + metadata: + creationTimestamp: null + labels: + jenkins.io/task-stage-name: build-a-really-long-stage-name-please-but-not-too-long-thanks + branch: really-long + owner: abayer + repo: js-test-repo + name: abayer-js-test-repo-really-long-build-a-really-long-stage-nam-1 + namespace: jx + spec: + inputs: + params: + - default: 0.0.1 + description: the version number for this pipeline which is used as a tag on + docker images and helm charts + name: version + resources: + - name: workspace + targetPath: source + type: git + outputs: + resources: + - name: workspace + targetPath: "" + type: git + steps: + - args: + - step + - git + - merge + - --verbose + command: + - jx + env: + - name: FRUIT + value: BANANA + - name: GIT_AUTHOR_NAME + value: somebodyelse + - name: DOCKER_REGISTRY + - name: BUILD_NUMBER + value: "1" + - name: PIPELINE_KIND + value: release + - name: REPO_OWNER + value: abayer + - name: REPO_NAME + value: js-test-repo + - name: JOB_NAME + value: abayer/js-test-repo/really-long + - name: APP_NAME + value: js-test-repo + - name: BRANCH_NAME + value: really-long + - name: JX_BATCH_MODE + value: "true" + - name: VERSION + value: ${inputs.params.version} + - name: PREVIEW_VERSION + value: ${inputs.params.version} + image: rawlingsj/builder-jx:wip34 + name: git-merge + resources: + requests: + cpu: 100m + memory: 64Mi + volumeMounts: + - mountPath: /etc/podinfo + name: podinfo + readOnly: true + workingDir: /workspace/source + - args: + - echo hello world + command: + - /bin/sh + - -c + env: + - name: DOCKER_CONFIG + value: /home/jenkins/.docker/ + - name: DOCKER_REGISTRY + valueFrom: + configMapKeyRef: + key: docker.registry + name: jenkins-x-docker-registry + - name: FRUIT + value: BANANA + - name: GIT_AUTHOR_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_AUTHOR_NAME + value: somebodyelse + - name: GIT_COMMITTER_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_COMMITTER_NAME + value: jenkins-x-bot + - name: TILLER_NAMESPACE + value: kube-system + - name: XDG_CONFIG_HOME + value: /workspace/xdg_config + - name: BUILD_NUMBER + value: "1" + - name: PIPELINE_KIND + value: release + - name: REPO_OWNER + value: abayer + - name: REPO_NAME + value: js-test-repo + - name: JOB_NAME + value: abayer/js-test-repo/really-long + - name: APP_NAME + value: js-test-repo + - name: BRANCH_NAME + value: really-long + - name: JX_BATCH_MODE + value: "true" + - name: VERSION + value: ${inputs.params.version} + - name: PREVIEW_VERSION + value: ${inputs.params.version} + image: jenkinsxio/builder-nodejs:0.1.235 + name: step2 + resources: + requests: + cpu: 100m + memory: 64Mi + securityContext: + privileged: true + volumeMounts: + - mountPath: /home/jenkins + name: workspace-volume + - mountPath: /var/run/docker.sock + name: docker-daemon + - mountPath: /home/jenkins/.docker + name: volume-0 + - mountPath: /etc/podinfo + name: podinfo + readOnly: true + workingDir: /workspace/source + - args: + - ls -la + command: + - /bin/sh + - -c + env: + - name: ANOTHER_VAR + value: Another value + - name: DOCKER_CONFIG + value: /home/jenkins/.docker/ + - name: DOCKER_REGISTRY + valueFrom: + configMapKeyRef: + key: docker.registry + name: jenkins-x-docker-registry + - name: FRUIT + value: BANANA + - name: GIT_AUTHOR_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_AUTHOR_NAME + value: somebodyelse + - name: GIT_COMMITTER_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_COMMITTER_NAME + value: jenkins-x-bot + - name: TILLER_NAMESPACE + value: kube-system + - name: XDG_CONFIG_HOME + value: /workspace/xdg_config + - name: BUILD_NUMBER + value: "1" + - name: PIPELINE_KIND + value: release + - name: REPO_OWNER + value: abayer + - name: REPO_NAME + value: js-test-repo + - name: JOB_NAME + value: abayer/js-test-repo/really-long + - name: APP_NAME + value: js-test-repo + - name: BRANCH_NAME + value: really-long + - name: JX_BATCH_MODE + value: "true" + - name: VERSION + value: ${inputs.params.version} + - name: PREVIEW_VERSION + value: ${inputs.params.version} + image: jenkinsxio/builder-nodejs:0.1.235 + name: step3 + resources: + requests: + cpu: 100m + memory: 64Mi + securityContext: + privileged: true + volumeMounts: + - mountPath: /home/jenkins + name: workspace-volume + - mountPath: /var/run/docker.sock + name: docker-daemon + - mountPath: /home/jenkins/.docker + name: volume-0 + - mountPath: /etc/podinfo + name: podinfo + readOnly: true + workingDir: /workspace/source + volumes: + - hostPath: + path: /var/run/docker.sock + name: docker-daemon + - name: volume-0 + secret: + secretName: jenkins-docker-cfg + - emptyDir: {} + name: workspace-volume + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + name: podinfo + - apiVersion: tekton.dev/v1alpha1 + kind: Task + metadata: + creationTimestamp: null + labels: + jenkins.io/task-stage-name: second + branch: really-long + owner: abayer + repo: js-test-repo + name: abayer-js-test-repo-really-long-second-1 + namespace: jx + spec: + inputs: + params: + - default: 0.0.1 + description: the version number for this pipeline which is used as a tag on + docker images and helm charts + name: version + resources: + - name: workspace + targetPath: source + type: git + steps: + - args: + - echo hi ${FRUIT} + command: + - /bin/sh + - -c + env: + - name: DOCKER_CONFIG + value: /home/jenkins/.docker/ + - name: DOCKER_REGISTRY + valueFrom: + configMapKeyRef: + key: docker.registry + name: jenkins-x-docker-registry + - name: FRUIT + value: BANANA + - name: GIT_AUTHOR_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_AUTHOR_NAME + value: somebodyelse + - name: GIT_COMMITTER_EMAIL + value: jenkins-x@googlegroups.com + - name: GIT_COMMITTER_NAME + value: jenkins-x-bot + - name: TILLER_NAMESPACE + value: kube-system + - name: XDG_CONFIG_HOME + value: /workspace/xdg_config + - name: BUILD_NUMBER + value: "1" + - name: PIPELINE_KIND + value: release + - name: REPO_OWNER + value: abayer + - name: REPO_NAME + value: js-test-repo + - name: JOB_NAME + value: abayer/js-test-repo/really-long + - name: APP_NAME + value: js-test-repo + - name: BRANCH_NAME + value: really-long + - name: JX_BATCH_MODE + value: "true" + - name: VERSION + value: ${inputs.params.version} + - name: PREVIEW_VERSION + value: ${inputs.params.version} + image: jenkinsxio/builder-nodejs:0.1.235 + name: step2 + resources: + limits: + cpu: 400m + memory: 256Mi + requests: + cpu: 100m + memory: 64Mi + securityContext: + privileged: true + volumeMounts: + - mountPath: /home/jenkins + name: workspace-volume + - mountPath: /var/run/docker.sock + name: docker-daemon + - mountPath: /home/jenkins/.docker + name: volume-0 + - mountPath: /etc/podinfo + name: podinfo + readOnly: true + workingDir: /workspace/source + volumes: + - hostPath: + path: /var/run/docker.sock + name: docker-daemon + - name: volume-0 + secret: + secretName: jenkins-docker-cfg + - emptyDir: {} + name: workspace-volume + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + name: podinfo +metadata: {} diff --git a/pkg/tekton/pipelines.go b/pkg/tekton/pipelines.go index 789ee20ac0..66fa8be771 100644 --- a/pkg/tekton/pipelines.go +++ b/pkg/tekton/pipelines.go @@ -189,7 +189,8 @@ func CreatePipelineRun(resources []*pipelineapi.PipelineResource, labels map[string]string, trigger string, serviceAccount string, - pipelineParams []pipelineapi.Param) *pipelineapi.PipelineRun { + pipelineParams []pipelineapi.Param, + timeout *metav1.Duration) *pipelineapi.PipelineRun { var resourceBindings []pipelineapi.PipelineResourceBinding for _, resource := range resources { resourceBindings = append(resourceBindings, pipelineapi.PipelineResourceBinding{ @@ -201,6 +202,10 @@ func CreatePipelineRun(resources []*pipelineapi.PipelineResource, }) } + if timeout == nil { + timeout = &metav1.Duration{Duration: 240 * time.Hour} + } + pipelineRun := &pipelineapi.PipelineRun{ TypeMeta: metav1.TypeMeta{ APIVersion: syntax.TektonAPIVersion, @@ -221,8 +226,8 @@ func CreatePipelineRun(resources []*pipelineapi.PipelineResource, }, Resources: resourceBindings, Params: pipelineParams, - // TODO: This should be configurable, and we shouldn't have to set a timeout in the first place. See https://github.com/tektoncd/pipeline/issues/978 - Timeout: &metav1.Duration{ Duration: 240 * time.Hour}, + // TODO: We shouldn't have to set a default timeout in the first place. See https://github.com/tektoncd/pipeline/issues/978 + Timeout: timeout, }, } diff --git a/pkg/tekton/syntax/pipeline.go b/pkg/tekton/syntax/pipeline.go index 1dc03e2535..0d0ef84c27 100644 --- a/pkg/tekton/syntax/pipeline.go +++ b/pkg/tekton/syntax/pipeline.go @@ -95,7 +95,8 @@ type Timeout struct { Unit TimeoutUnit `json:"unit,omitempty"` } -func (t Timeout) toDuration() (*metav1.Duration, error) { +// ToDuration generates a duration struct from a Timeout +func (t *Timeout) ToDuration() (*metav1.Duration, error) { durationStr := "" // TODO: Populate a default timeout unit, most likely seconds. if t.Unit != "" {