Skip to content

Commit

Permalink
Implement template variable expansion for Resources.
Browse files Browse the repository at this point in the history
This commit builds upon #149 and makes resource keys available for expansion
inside a TaskRun.

Resources are available under the namespace 'inputs.resources', and each
resource is namespaced under it's own name.

This commit adds to the PipelineResourceInterface, requiring types to support a
Replacements method. This supplies keys to be replaced.
  • Loading branch information
dlorenc authored and knative-prow-robot committed Oct 17, 2018
1 parent b76e548 commit 170e628
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
18 changes: 18 additions & 0 deletions docs/pipeline-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,21 @@ spec:
- name: builtImage
type: image
```

#### Templating

Git Resources (like all Resources) support template expansion into BuildSpecs.
Git Resources support the following keys for replacement:

* name
* url
* type
* revision

These can be referenced in a TaskRun spec like:

```shell
${inputs.resources.NAME.KEY}
```

where NAME is the Resource Name and KEY is the key from the above list.
10 changes: 10 additions & 0 deletions pkg/apis/pipeline/v1alpha1/git_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,13 @@ func (s *GitResource) GetURL() string {

// GetParams returns the resoruce params
func (s GitResource) GetParams() []Param { return []Param{} }

// Replacements is used for template replacement on a GitResource inside of a Taskrun.
func (s *GitResource) Replacements() map[string]string {
return map[string]string{
"name": s.Name,
"type": string(s.Type),
"url": s.URL,
"revision": s.Revision,
}
}
12 changes: 12 additions & 0 deletions pkg/apis/pipeline/v1alpha1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1alpha1

import (
"fmt"

"github.com/knative/pkg/apis"
"github.com/knative/pkg/webhook"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -46,6 +48,7 @@ type PipelineResourceInterface interface {
GetType() PipelineResourceType
GetParams() []Param
GetVersion() string
Replacements() map[string]string
}

// PipelineResourceSpec defines an individual resources used in the pipeline.
Expand Down Expand Up @@ -112,3 +115,12 @@ type PipelineResourceList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []PipelineResource `json:"items"`
}

// ResourceFromType returns a
func ResourceFromType(r *PipelineResource) (PipelineResourceInterface, error) {
switch r.Spec.Type {
case PipelineResourceTypeGit:
return NewGitResource(r)
}
return nil, fmt.Errorf("%s is an invalid PipelineResource", r.Spec.Type)
}
28 changes: 27 additions & 1 deletion pkg/reconciler/v1alpha1/taskrun/taskrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,13 @@ func (c *Reconciler) createBuild(tr *v1alpha1.TaskRun) (*buildv1alpha1.Build, er
}

// Apply parameters from the taskrun.
build = applyParameters(b, t, tr)
build = applyParameters(build, t, tr)

// Apply resources from the taskrun.
build, err = applyResources(build, t, tr, c.resourceLister)
if err != nil {
return nil, err
}

return c.BuildClientSet.BuildV1alpha1().Builds(tr.Namespace).Create(build)
}
Expand All @@ -257,3 +263,23 @@ func applyParameters(b *buildv1alpha1.Build, t *v1alpha1.Task, tr *v1alpha1.Task

return builder.ApplyReplacements(b, replacements)
}

func applyResources(b *buildv1alpha1.Build, t *v1alpha1.Task, tr *v1alpha1.TaskRun, lister listers.PipelineResourceLister) (*buildv1alpha1.Build, error) {
replacements := map[string]string{}

for _, ir := range tr.Spec.Inputs.Resources {
pr, err := lister.PipelineResources(t.Namespace).Get(ir.ResourceRef.Name)
if err != nil {
return nil, err
}

resource, err := v1alpha1.ResourceFromType(pr)
if err != nil {
return nil, err
}
for k, v := range resource.Replacements() {
replacements[fmt.Sprintf("inputs.resources.%s.%s", ir.ResourceRef.Name, k)] = v
}
}
return builder.ApplyReplacements(b, replacements), nil
}
50 changes: 46 additions & 4 deletions pkg/reconciler/v1alpha1/taskrun/taskrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ var templatedTask = &v1alpha1.Task{
Image: "myimage",
Args: []string{"--my-arg=${inputs.params.myarg}"},
},
{
Name: "myothercontainer",
Image: "myotherimage",
Args: []string{"--my-other-arg=${inputs.resources.git-resource.url}"},
},
},
},
},
}

var gitResource = &v1alpha1.PipelineResource{
ObjectMeta: metav1.ObjectMeta{
Name: "git-resource",
Namespace: "foo",
},
Spec: v1alpha1.PipelineResourceSpec{
Type: "git",
Params: []v1alpha1.Param{
{
Name: "URL",
Value: "https://foo.git",
},
},
},
Expand Down Expand Up @@ -102,14 +123,24 @@ func TestReconcileBuildsCreated(t *testing.T) {
Value: "foo",
},
},
Resources: []v1alpha1.PipelineResourceVersion{
{
ResourceRef: v1alpha1.PipelineResourceRef{
Name: "git-resource",
APIVersion: "a1",
},
Version: "myversion",
},
},
},
},
},
}

d := testData{
taskruns: taskruns,
tasks: []*v1alpha1.Task{simpleTask, templatedTask},
taskruns: taskruns,
tasks: []*v1alpha1.Task{simpleTask, templatedTask},
resources: []*v1alpha1.PipelineResource{gitResource},
}
testcases := []struct {
name string
Expand Down Expand Up @@ -138,6 +169,11 @@ func TestReconcileBuildsCreated(t *testing.T) {
Image: "myimage",
Args: []string{"--my-arg=foo"},
},
{
Name: "myothercontainer",
Image: "myotherimage",
Args: []string{"--my-other-arg=https://foo.git"},
},
},
},
},
Expand Down Expand Up @@ -227,6 +263,11 @@ func getController(d testData) (*controller.Impl, *observer.ObservedLogs, *fakeb
for _, t := range d.tasks {
taskInformer.Informer().GetIndexer().Add(t)
}

for _, r := range d.resources {
resourceInformer.Informer().GetIndexer().Add(r)
}

// Create a log observer to record all error logs.
observer, logs := observer.New(zap.ErrorLevel)
return NewController(
Expand All @@ -252,6 +293,7 @@ func getLogMessages(logs *observer.ObservedLogs) []string {
}

type testData struct {
taskruns []*v1alpha1.TaskRun
tasks []*v1alpha1.Task
taskruns []*v1alpha1.TaskRun
tasks []*v1alpha1.Task
resources []*v1alpha1.PipelineResource
}

0 comments on commit 170e628

Please sign in to comment.