Skip to content

Commit

Permalink
Add functionality to set task run spec
Browse files Browse the repository at this point in the history
Currently it is not possible to set task run specs on each individual tasks. This PR aims to fix that and give the user more flexibility to set podTemplate for each task.
  • Loading branch information
NikeNano committed Apr 18, 2020
1 parent 62737cf commit e9247fe
Show file tree
Hide file tree
Showing 10 changed files with 600 additions and 5 deletions.
19 changes: 19 additions & 0 deletions docs/pipelineruns.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Creation of a `PipelineRun` will trigger the creation of
- [Params](#params)
- [Service Account](#service-account)
- [Service Accounts](#service-accounts)
- [TaskRunSpecs](#task-run-specs)
- [Pod Template](#pod-template)
- [PersistentVolumeClaims](#persistentvolumeclaims)
- [Workspaces](#workspaces)
Expand Down Expand Up @@ -59,6 +60,7 @@ following fields:
there is no timeout. `PipelineRun` shares the same default timeout as `TaskRun`. You can
follow the instruction [here](taskruns.md#Configuring-default-timeout) to configure the
default timeout, the same way as `TaskRun`.
- [`taskSpec`](#task-spec) - Specifies a list of `PipelineRunTaskSpec` which allows for setting `ServiceAccount` and [pod template](./podtemplates.md) for each task.
- [`podTemplate`](#pod-template) - Specifies a [pod template](./podtemplates.md) that will be used as the basis for the `Task` pod.

[kubernetes-overview]:
Expand Down Expand Up @@ -356,3 +358,20 @@ Except as otherwise noted, the content of this page is licensed under the
[Creative Commons Attribution 4.0 License](https://creativecommons.org/licenses/by/4.0/),
and code samples are licensed under the
[Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0).

## Task Run Specs

Specifies a list of ```ServiceAccount``` ,```PodTemplate``` and ```PipelineTask```. A specified PipelineTask will be run with the configured ```ServiceAccount``` and ```PodTemplate``` overwriting the [`serviceAccountName`](#service-account) and [`podTemplate`](#pod-template) configuration, for example:

```yaml
spec:
podTemplate:
securityContext:
runAsNonRoot: true
taskRunSpecs:
- taskName: build-task
runAsNonRoot: false
serviceAccountName: sa-for-build
```

If used with this ```Pipeline```, test-task will use the pipeline scoped ```podTemplate```(```runAsNonRoot``` set to true) while the ```build-task``` will use the task specific pod template (```runAsNonRoot``` set to false).
263 changes: 263 additions & 0 deletions examples/v1beta1/pipelineruns/pipelinerun-taskrunspecs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-image-leeroy-app
spec:
type: image
params:
- name: url
value: gcr.io/christiewilson-catfactory/leeroy-app
---
# This demo modifies the cluster (deploys to it) you must use a service
# account with permission to admin the cluster (or make your default user an admin
# of the `default` namespace with default-cluster-admin.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
generateName: default-cluster-admin-
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-image-leeroy-web-pipelinerun
spec:
type: image
params:
- name: url
value: gcr.io/christiewilson-catfactory/leeroy-web
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-git-pipelinerun
spec:
type: git
params:
- name: revision
value: v0.32.0
- name: url
value: https://github.com/GoogleContainerTools/skaffold
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: unit-tests
spec:
resources:
inputs:
- name: workspace
type: git
targetPath: go/src/github.com/GoogleContainerTools/skaffold
steps:
- name: run-tests
image: golang
env:
- name: GOPATH
value: /workspace/go
workingDir: /workspace/go/src/github.com/GoogleContainerTools/skaffold
command:
- echo
args:
- "pass"
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-push
spec:
params:
- name: pathToDockerFile
description: The path to the dockerfile to build
default: /workspace/workspace/Dockerfile
- name: pathToContext
description: The build context used by Kaniko (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
default: /workspace/workspace
resources:
inputs:
- name: workspace
type: git
outputs:
- name: builtImage
type: image
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.17.1
# specifying DOCKER_CONFIG is required to allow kaniko to detect docker credential
env:
- name: "DOCKER_CONFIG"
value: "/tekton/home/.docker/"
command:
- /kaniko/executor
args:
- --dockerfile=$(params.pathToDockerFile)
- --destination=$(resources.outputs.builtImage.url)
- --context=$(params.pathToContext)
---
# This task deploys with kubectl apply -f <filename>
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: demo-deploy-kubectl
spec:
params:
- name: path
description: Path to the manifest to apply
- name: yqArg
description: Okay this is a hack, but I didn't feel right hard-codeing `-d1` down below
- name: yamlPathToImage
description: The path to the image to replace in the yaml manifest (arg to yq)
resources:
inputs:
- name: workspace
type: git
- name: image
type: image
steps:
- name: replace-image
image: mikefarah/yq
command: ['yq']
args:
- "w"
- "-i"
- "$(params.yqArg)"
- "$(params.path)"
- "$(params.yamlPathToImage)"
- "$(resources.inputs.image.url)"
- name: run-kubectl
image: lachlanevenson/k8s-kubectl
command: ['kubectl']
args:
- 'apply'
- '-f'
- '$(params.path)'
---
# This Pipeline Builds two microservice images(https://github.com/GoogleContainerTools/skaffold/tree/master/examples/microservices)
# from the Skaffold repo (https://github.com/GoogleContainerTools/skaffold) and deploys them to the repo currently running Tekton Pipelines.

# **Note** : It does this using the k8s `Deployment` in the skaffold repos's existing yaml
# files, so at the moment there is no guarantee that the image that are built and
# pushed are the ones that are deployed (that would require using the digest of
# the built image, see https://github.com/tektoncd/pipeline/issues/216).

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: demo-pipeline
spec:
resources:
- name: source-repo
type: git
- name: web-image
type: image
- name: app-image
type: image
tasks:
- name: skaffold-unit-tests
taskRef:
name: unit-tests
resources:
inputs:
- name: workspace
resource: source-repo
- name: build-skaffold-web
runAfter: [skaffold-unit-tests]
taskRef:
name: build-push
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/workspace/examples/microservices/leeroy-web
resources:
inputs:
- name: workspace
resource: source-repo
outputs:
- name: builtImage
resource: web-image
- name: build-skaffold-app
runAfter: [skaffold-unit-tests]
taskRef:
name: build-push
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/workspace/examples/microservices/leeroy-app
resources:
inputs:
- name: workspace
resource: source-repo
outputs:
- name: builtImage
resource: app-image
- name: deploy-app
taskRef:
name: demo-deploy-kubectl
resources:
inputs:
- name: workspace
resource: source-repo
- name: image
resource: app-image
from:
- build-skaffold-app
params:
- name: path
value: /workspace/workspace/examples/microservices/leeroy-app/kubernetes/deployment.yaml
- name: yqArg
value: "-d1"
- name: yamlPathToImage
value: "spec.template.spec.containers[0].image"
- name: deploy-web
taskRef:
name: demo-deploy-kubectl
resources:
inputs:
- name: workspace
resource: source-repo
- name: image
resource: web-image
from:
- build-skaffold-web
params:
- name: path
value: /workspace/workspace/examples/microservices/leeroy-web/kubernetes/deployment.yaml
- name: yqArg
value: "-d1"
- name: yamlPathToImage
value: "spec.template.spec.containers[0].image"
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: demo-pipeline-run-1
spec:
pipelineRef:
name: demo-pipeline
serviceAccountName: 'default'
taskRunSpecs:
- PipelineTaskName: skaffold-unit-tests
TaskServiceAccountName: "TaskOne"
- PipelineTaskName: build-skaffold-web
TaskServiceAccountName: "TaskTwo"
resources:
- name: source-repo
resourceRef:
name: skaffold-git-pipelinerun
- name: web-image
resourceRef:
name: skaffold-image-leeroy-web-pipelinerun
- name: app-image
resourceRef:
name: skaffold-image-leeroy-app
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.13

require (
cloud.google.com/go v0.47.0 // indirect
cloud.google.com/go/storage v1.0.0
contrib.go.opencensus.io/exporter/stackdriver v0.12.8 // indirect
github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher v0.0.0-20191203181535-308b93ad1f39
github.com/cloudevents/sdk-go/v2 v2.0.0-preview8
Expand Down Expand Up @@ -41,7 +40,6 @@ require (
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.0.0-20200214144324-88be01311a71 // indirect
gomodules.xyz/jsonpatch/v2 v2.1.0
google.golang.org/api v0.15.0
google.golang.org/appengine v1.6.5 // indirect
k8s.io/api v0.17.3
k8s.io/apiextensions-apiserver v0.17.3 // indirect
Expand Down
26 changes: 26 additions & 0 deletions pkg/apis/pipeline/v1alpha1/pipelinerun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ type PipelineRunSpec struct {
// with those declared in the pipeline.
// +optional
Workspaces []WorkspaceBinding `json:"workspaces,omitempty"`
// TaskRunSpecs holds a set of runtime specs
// +optional
TaskRunSpecs []PipelineTaskRunSpec `json:"taskRunSpecs,omitempty"`
}

// PipelineRunSpecStatus defines the pipelinerun spec status the user can provide
Expand Down Expand Up @@ -217,3 +220,26 @@ func (pr *PipelineRun) HasVolumeClaimTemplate() bool {
}
return false
}
// PipelineTaskRunSpec can be used to configure specific
// specs for a concrete Task
type PipelineTaskRunSpec struct {
PipelineTaskName string `json:"taskName,omitempty"`
TaskServiceAccountName string `json:"serviceAccountName,omitempty"`
TaskPodTemplate *PodTemplate `json:"podTemplate,omitempty"`
}

// GetTaskRunSpecs returns the task specific spec for a given
// PipelineTask if configured, otherwise it returns the PipelineRun's default.
func (pr *PipelineRun) GetTaskRunSpecs(pipelineTaskName string) (string, *PodTemplate) {
// To make it backward compatible, until ServiceAccountNames is dispatched.
// serviceAccountName := pr.Spec.ServiceAccountName
serviceAccountName := pr.GetServiceAccountName(pipelineTaskName)
taskPodTemplate := pr.Spec.PodTemplate
for _, task := range pr.Spec.TaskRunSpecs {
if task.PipelineTaskName == pipelineTaskName {
taskPodTemplate = task.TaskPodTemplate
serviceAccountName = task.TaskServiceAccountName
}
}
return serviceAccountName, taskPodTemplate
}
Loading

0 comments on commit e9247fe

Please sign in to comment.