Skip to content

Commit

Permalink
Adding support to enable resourceSpec
Browse files Browse the repository at this point in the history
Its now possible to embed the resource specifications into Pipeline Run
using resourceSpec, for example:

apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  name: pipelinerun-echo-greetings
spec:
  resources:
    - name: git-repo
        resourceRef:
          name: my-git-repo

Can be specified as:

apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
  name: pipelinerun-echo-greetings
spec:
  resources:
    - name: git-repo
      resourceSpec:
        type: git
        params:
          - name: url
            value: https://github.com/myrepo/myrepo.git
  • Loading branch information
pritidesai committed Sep 19, 2019
1 parent 454ddec commit a3f0f92
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 46 deletions.
31 changes: 29 additions & 2 deletions docs/pipelineruns.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,34 @@ spec:
name: skaffold-image-leeroy-app
```
Or you can embed the spec of the `Resource` directly in the `PipelineRun`:


```yaml
spec:
resources:
- name: source-repo
resourceSpec:
type: git
params:
- name: revision
value: v0.32.0
- name: url
value: https://github.com/GoogleContainerTools/skaffold
- name: web-image
resourceSpec:
type: image
params:
- name: url
value: gcr.io/christiewilson-catfactory/leeroy-web
- name: app-image
resourceSpec:
type: image
params:
- name: url
value: gcr.io/christiewilson-catfactory/leeroy-app
```

### Service Account

Specifies the `name` of a `ServiceAccount` resource object. Use the
Expand Down Expand Up @@ -121,7 +149,6 @@ spec:
- name: build-task
taskRef:
name: build-push
tasks:
- name: test-task
taskRef:
name: test
Expand Down Expand Up @@ -174,7 +201,7 @@ spec:
tasks:
- name: task1
taskRef:
name: myTask
name: myTask
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
Expand Down
66 changes: 66 additions & 0 deletions examples/pipelineruns/pipelinerun-with-resourcespec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: task-to-list-files
spec:
inputs:
resources:
- name: pipeline-git
type: git
outputs:
resources:
- name: pipeline-git
type: git
steps:
- name: list
image: ubuntu
command:
- bash
args:
- -c
- |
ls -al $(inputs.resources.pipeline-git.path)
---

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: pipeline-to-list-files
spec:
resources:
- name: pipeline-git
type: git
params:
- name: "path"
default: "README.md"
tasks:
- name: list-files
taskRef:
name: task-to-list-files
resources:
inputs:
- name: pipeline-git
resource: pipeline-git
outputs:
- name: pipeline-git
resource: pipeline-git

---

apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
name: demo-pipelinerun-with-resourcespec
spec:
pipelineRef:
name: pipeline-to-list-files
serviceAccount: 'default'
resources:
- name: pipeline-git
resourceSpec:
type: git
params:
- name: revision
value: master
- name: url
value: https://github.com/tektoncd/pipeline
10 changes: 5 additions & 5 deletions pkg/apis/pipeline/v1alpha1/pipelinerun_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ func TestPipelineRun_Invalidate(t *testing.T) {
},
}

for _, ts := range tests {
t.Run(ts.name, func(t *testing.T) {
err := ts.pr.Validate(context.Background())
if d := cmp.Diff(err.Error(), ts.want.Error()); d != "" {
t.Errorf("PipelineRun.Validate/%s (-want, +got) = %v", ts.name, d)
for _, ps := range tests {
t.Run(ps.name, func(t *testing.T) {
err := ps.pr.Validate(context.Background())
if d := cmp.Diff(err.Error(), ps.want.Error()); d != "" {
t.Errorf("PipelineRun.Validate/%s (-want, +got) = %v", ps.name, d)
}
})
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/pipeline/v1alpha1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ type PipelineResourceBinding struct {
// ResourceRef is a reference to the instance of the actual PipelineResource
// that should be used
ResourceRef PipelineResourceRef `json:"resourceRef,omitempty"`
// +optional
// ResourceSpec is specification of a resource that should be created and
// consumed by the task
ResourceSpec *PipelineResourceSpec `json:"resourceSpec,omitempty"`
}

// PipelineResourceResult used to export the image name and digest as json
Expand Down
33 changes: 25 additions & 8 deletions pkg/reconciler/pipelinerun/resources/input_output_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,23 @@ func GetOutputSteps(outputs map[string]*v1alpha1.PipelineResource, taskName, sto
var taskOutputResources []v1alpha1.TaskResourceBinding

for name, outputResource := range outputs {
taskOutputResources = append(taskOutputResources, v1alpha1.TaskResourceBinding{
Name: name,
ResourceRef: v1alpha1.PipelineResourceRef{
taskOutputResource := v1alpha1.TaskResourceBinding{
Name: name,
Paths: []string{filepath.Join(storageBasePath, taskName, name)},
}
if outputResource.Name != "" {
taskOutputResource.ResourceRef = v1alpha1.PipelineResourceRef{
Name: outputResource.Name,
APIVersion: outputResource.APIVersion,
},
Paths: []string{filepath.Join(storageBasePath, taskName, name)},
})
}
} else {
taskOutputResource.ResourceSpec = &v1alpha1.PipelineResourceSpec{
Type: outputResource.Spec.Type,
Params: outputResource.Spec.Params,
SecretParams: outputResource.Spec.SecretParams,
}
}
taskOutputResources = append(taskOutputResources, taskOutputResource)
}
return taskOutputResources
}
Expand All @@ -47,10 +56,18 @@ func GetInputSteps(inputs map[string]*v1alpha1.PipelineResource, pt *v1alpha1.Pi
for name, inputResource := range inputs {
taskInputResource := v1alpha1.TaskResourceBinding{
Name: name,
ResourceRef: v1alpha1.PipelineResourceRef{
}
if inputResource.Name != "" {
taskInputResource.ResourceRef = v1alpha1.PipelineResourceRef{
Name: inputResource.Name,
APIVersion: inputResource.APIVersion,
},
}
} else {
taskInputResource.ResourceSpec = &v1alpha1.PipelineResourceSpec{
Type: inputResource.Spec.Type,
Params: inputResource.Spec.Params,
SecretParams: inputResource.Spec.SecretParams,
}
}

var stepSourceNames []string
Expand Down
28 changes: 15 additions & 13 deletions pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ type GetTaskRun func(name string) (*v1alpha1.TaskRun, error)
// GetResourcesFromBindings will validate that all PipelineResources declared in Pipeline p are bound in PipelineRun pr
// and if so, will return a map from the declared name of the PipelineResource (which is how the PipelineResource will
// be referred to in the PipelineRun) to the ResourceRef.
func GetResourcesFromBindings(p *v1alpha1.Pipeline, pr *v1alpha1.PipelineRun) (map[string]v1alpha1.PipelineResourceRef, error) {
resources := map[string]v1alpha1.PipelineResourceRef{}
func GetResourcesFromBindings(p *v1alpha1.Pipeline, pr *v1alpha1.PipelineRun) (map[string]v1alpha1.PipelineResourceBinding, error) {
resources := map[string]v1alpha1.PipelineResourceBinding{}

required := make([]string, 0, len(p.Spec.Resources))
for _, resource := range p.Spec.Resources {
Expand All @@ -189,12 +189,12 @@ func GetResourcesFromBindings(p *v1alpha1.Pipeline, pr *v1alpha1.PipelineRun) (m
}

for _, resource := range pr.Spec.Resources {
resources[resource.Name] = resource.ResourceRef
resources[resource.Name] = resource
}
return resources, nil
}

func getPipelineRunTaskResources(pt v1alpha1.PipelineTask, providedResources map[string]v1alpha1.PipelineResourceRef) ([]v1alpha1.TaskResourceBinding, []v1alpha1.TaskResourceBinding, error) {
func getPipelineRunTaskResources(pt v1alpha1.PipelineTask, providedResources map[string]v1alpha1.PipelineResourceBinding) ([]v1alpha1.TaskResourceBinding, []v1alpha1.TaskResourceBinding, error) {
inputs, outputs := []v1alpha1.TaskResourceBinding{}, []v1alpha1.TaskResourceBinding{}
if pt.Resources != nil {
for _, taskInput := range pt.Resources.Inputs {
Expand All @@ -204,7 +204,8 @@ func getPipelineRunTaskResources(pt v1alpha1.PipelineTask, providedResources map
}
inputs = append(inputs, v1alpha1.TaskResourceBinding{
Name: taskInput.Name,
ResourceRef: resource,
ResourceRef: resource.ResourceRef,
ResourceSpec: resource.ResourceSpec,
})
}
for _, taskOutput := range pt.Resources.Outputs {
Expand All @@ -214,7 +215,8 @@ func getPipelineRunTaskResources(pt v1alpha1.PipelineTask, providedResources map
}
outputs = append(outputs, v1alpha1.TaskResourceBinding{
Name: taskOutput.Name,
ResourceRef: resource,
ResourceRef: resource.ResourceRef,
ResourceSpec: resource.ResourceSpec,
})
}
}
Expand Down Expand Up @@ -262,7 +264,7 @@ func ResolvePipelineRun(
getResource resources.GetResource,
getCondition GetCondition,
tasks []v1alpha1.PipelineTask,
providedResources map[string]v1alpha1.PipelineResourceRef,
providedResources map[string]v1alpha1.PipelineResourceBinding,
) (PipelineRunState, error) {

state := []*ResolvedPipelineRunTask{}
Expand Down Expand Up @@ -297,9 +299,11 @@ func ResolvePipelineRun(

spec := t.TaskSpec()
rtr, err := resources.ResolveTaskResources(&spec, t.TaskMetadata().Name, pt.TaskRef.Kind, inputs, outputs, getResource)

if err != nil {
return nil, &ResourceNotFoundError{Msg: err.Error()}
}

rprt.ResolvedTaskResources = rtr

taskRun, err := getTaskRun(rprt.TaskRunName)
Expand Down Expand Up @@ -492,7 +496,7 @@ func ValidateFrom(state PipelineRunState) error {
func resolveConditionChecks(pt *v1alpha1.PipelineTask,
taskRunStatus map[string]*v1alpha1.PipelineRunTaskRunStatus,
taskRunName string, getTaskRun resources.GetTaskRun, getCondition GetCondition,
getResource resources.GetResource, providedResources map[string]v1alpha1.PipelineResourceRef) ([]*ResolvedConditionCheck, error) {
getResource resources.GetResource, providedResources map[string]v1alpha1.PipelineResourceBinding) ([]*ResolvedConditionCheck, error) {
rccs := []*ResolvedConditionCheck{}
for _, ptc := range pt.Conditions {
cName := ptc.ConditionRef
Expand Down Expand Up @@ -533,22 +537,20 @@ func resolveConditionChecks(pt *v1alpha1.PipelineTask,

func resolveConditionResources(prc []v1alpha1.PipelineConditionResource,
getResource resources.GetResource,
providedResources map[string]v1alpha1.PipelineResourceRef,
providedResources map[string]v1alpha1.PipelineResourceBinding,
) (map[string]*v1alpha1.PipelineResource, error) {
rr := make(map[string]*v1alpha1.PipelineResource)
for _, r := range prc {
// First get a ref to actual resource name from its bound name
resourceRef, ok := providedResources[r.Resource]
resourceBinding, ok := providedResources[r.Resource]
if !ok {
return nil, xerrors.Errorf("resource %s not present in declared resources", r.Resource)
}

// Next, fetch the actual resource definition
gotResource, err := getResource(resourceRef.Name)
gotResource, err := getResource(resourceBinding.Name)
if err != nil {
return nil, xerrors.Errorf("could not retrieve resource %s: %w", r.Name, err)
}

// Finally add it to the resolved resources map
rr[r.Name] = gotResource
}
Expand Down
Loading

0 comments on commit a3f0f92

Please sign in to comment.