Skip to content

Commit

Permalink
Add ClusterTask new CRD
Browse files Browse the repository at this point in the history
 - issue 251: tektoncd#251
 - new type for ClusterTask
 - Add kind to TaskRef to differentiate between Task kinds
 - TaskInterface to be used by controllers, implemeted by
 Task and ClusterTask
 - update taskRun and pipelineRun to use TaskInterface
 - update docs

Signed-off-by: Nader Ziada <nziada@pivotal.io>
  • Loading branch information
nader-ziada committed Dec 4, 2018
1 parent f70944e commit 7219631
Show file tree
Hide file tree
Showing 35 changed files with 917 additions and 96 deletions.
4 changes: 4 additions & 0 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func main() {
buildInformerFactory := buildinformers.NewSharedInformerFactory(buildClient, opt.ResyncPeriod)

taskInformer := pipelineInformerFactory.Pipeline().V1alpha1().Tasks()
clusterTaskInformer := pipelineInformerFactory.Pipeline().V1alpha1().ClusterTasks()
taskRunInformer := pipelineInformerFactory.Pipeline().V1alpha1().TaskRuns()
resourceInformer := pipelineInformerFactory.Pipeline().V1alpha1().PipelineResources()
buildInformer := buildInformerFactory.Build().V1alpha1().Builds()
Expand All @@ -124,13 +125,15 @@ func main() {
taskrun.NewController(opt,
taskRunInformer,
taskInformer,
clusterTaskInformer,
buildInformer,
resourceInformer,
),
pipelinerun.NewController(opt,
pipelineRunInformer,
pipelineInformer,
taskInformer,
clusterTaskInformer,
taskRunInformer,
resourceInformer,
),
Expand All @@ -150,6 +153,7 @@ func main() {
logger.Info("Waiting for informer caches to sync")
for i, synced := range []cache.InformerSynced{
taskInformer.Informer().HasSynced,
clusterTaskInformer.Informer().HasSynced,
taskRunInformer.Informer().HasSynced,
buildInformer.Informer().HasSynced,
resourceInformer.Informer().HasSynced,
Expand Down
2 changes: 1 addition & 1 deletion config/200-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ rules:
resources: ["customresourcedefinitions"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["pipeline.knative.dev"]
resources: ["tasks", "taskruns", "pipelines", "pipelineruns", "pipelineresources"]
resources: ["tasks", "clustertasks", "taskruns", "pipelines", "pipelineruns", "pipelineresources"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["build.knative.dev"]
resources: ["builds", "buildtemplates", "clusterbuildtemplates"]
Expand Down
18 changes: 18 additions & 0 deletions config/300-clustertask.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
name: clustertasks.pipeline.knative.dev
spec:
group: pipeline.knative.dev
names:
kind: ClusterTask
plural: clustertasks
categories:
- all
- knative
- build-pipeline
scope: Cluster
version: v1alpha1
4 changes: 4 additions & 0 deletions docs/Concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ To run a step needs to pull an `Entrypoint` image. Maybe the image is hard to pu
in your environment, so we provide a way for you to configure that by edit the `image`'s
value in a configmap named [`config-entrypoint`](./../config/config-entrypoint.yaml).

### ClusterTask

Similar to `Tasks` but but with a cluster scope.

### Pipeline

`Pipelines` describes a graph of [Tasks](#Task) to execute.
Expand Down
23 changes: 23 additions & 0 deletions docs/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,29 @@ To access a `Param`, replace `resources` with `params` as below:
${inputs.params.NAME}
```

## Cluster Task

Similar to Task, but with a cluster scope.

In case of using a ClusterTask, the `TaskRef` kind should be added. The default kind is Task
which represents a namespaced Task

```yaml
apiVersion: pipeline.knative.dev/v1alpha1
kind: Pipeline
metadata:
name: demo-pipeline
namespace: default
spec:
tasks:
- name: build-skaffold-web
taskRef:
name: build-push
kind: ClusterTask
params:
....
```

## Running a Pipeline

In order to run a Pipeline, you will need to provide:
Expand Down
72 changes: 72 additions & 0 deletions pkg/apis/pipeline/v1alpha1/cluster_task_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright 2018 The Knative Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/knative/pkg/apis"
"github.com/knative/pkg/webhook"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func (t *ClusterTask) TaskSpec() TaskSpec {
return t.Spec
}

func (t *ClusterTask) TaskMetadata() metav1.ObjectMeta {
return t.ObjectMeta
}

func (t *ClusterTask) Copy() TaskInterface {
return t.DeepCopy()
}

func (t *ClusterTask) SetDefaults() {
t.Spec.SetDefaults()
}

// Check that Task may be validated and defaulted.
var _ apis.Validatable = (*ClusterTask)(nil)
var _ apis.Defaultable = (*ClusterTask)(nil)

// Assert that Task implements the GenericCRD interface.
var _ webhook.GenericCRD = (*ClusterTask)(nil)

// +genclient
// +genclient:noStatus
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterTask is a Task with a cluster scope
type ClusterTask struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec holds the desired state of the Task from the client
// +optional
Spec TaskSpec `json:"spec,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterTaskList contains a list of ClusterTask
type ClusterTaskList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []Task `json:"items"`
}
28 changes: 28 additions & 0 deletions pkg/apis/pipeline/v1alpha1/cluster_task_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Copyright 2018 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/knative/pkg/apis"
)

func (t *ClusterTask) Validate() *apis.FieldError {
if err := validateObjectMetadata(t.GetObjectMeta()); err != nil {
return err.ViaField("metadata")
}
return t.Spec.Validate()
}
8 changes: 7 additions & 1 deletion pkg/apis/pipeline/v1alpha1/pipeline_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ func (p *Pipeline) SetDefaults() {
p.Spec.SetDefaults()
}

func (ps *PipelineSpec) SetDefaults() {}
func (ps *PipelineSpec) SetDefaults() {
for _, pt := range ps.Tasks {
if pt.TaskRef.Kind == "" {
pt.TaskRef.Kind = NamespacedTaskKind
}
}
}
12 changes: 12 additions & 0 deletions pkg/apis/pipeline/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ type PipelineStatus struct {
var _ apis.Validatable = (*Pipeline)(nil)
var _ apis.Defaultable = (*Pipeline)(nil)

// TaskKind defines the type of Task used by the pipeline.
type TaskKind string

const (
// NamespacedTaskKind indicates that the task type has a namepace scope.
NamespacedTaskKind TaskKind = "Task"
// ClusterTaskKind indicates that task type has a cluster scope.
ClusterTaskKind TaskKind = "ClusterTask"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

Expand Down Expand Up @@ -90,6 +100,8 @@ type ResourceDependency struct {
type TaskRef struct {
// Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
Name string `json:"name"`
// TaskKind inficates the kind of the task, namespaced or cluster scoped.
Kind TaskKind `json:"kind,omitempty"`
// API version of the referent
// +optional
APIVersion string `json:"apiVersion,omitempty"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/pipeline/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Task{},
&TaskList{},
&ClusterTask{},
&ClusterTaskList{},
&TaskRun{},
&TaskRunList{},
&Pipeline{},
Expand Down
26 changes: 26 additions & 0 deletions pkg/apis/pipeline/v1alpha1/task_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright 2018 The Knative Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

// TaskInterface is implemented by Task and ClusterTask
type TaskInterface interface {
TaskMetadata() metav1.ObjectMeta
TaskSpec() TaskSpec
Copy() TaskInterface
}
22 changes: 13 additions & 9 deletions pkg/apis/pipeline/v1alpha1/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func (t *Task) TaskSpec() TaskSpec {
return t.Spec
}

func (t *Task) TaskMetadata() metav1.ObjectMeta {
return t.ObjectMeta
}

func (t *Task) Copy() TaskInterface {
return t.DeepCopy()
}

// TaskSpec defines the desired state of Task
type TaskSpec struct {
// +optional
Expand Down Expand Up @@ -62,12 +74,6 @@ type TaskSpec struct {
Affinity *corev1.Affinity `json:"affinity,omitempty"`
}

// TaskStatus does not contain anything because Tasks on their own
// do not have a status, they just hold data which is later used by a
// TaskRun.
type TaskStatus struct {
}

// Check that Task may be validated and defaulted.
var _ apis.Validatable = (*Task)(nil)
var _ apis.Defaultable = (*Task)(nil)
Expand All @@ -76,6 +82,7 @@ var _ apis.Defaultable = (*Task)(nil)
var _ webhook.GenericCRD = (*Task)(nil)

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Task is the Schema for the tasks API
Expand All @@ -88,9 +95,6 @@ type Task struct {
// Spec holds the desired state of the Task from the client
// +optional
Spec TaskSpec `json:"spec,omitempty"`
// Status communicates the observed state of the Task from the controller
// +optional
Status TaskStatus `json:"status,omitempty"`
}

// Inputs are the requirements that a task needs to run a Build.
Expand Down
27 changes: 27 additions & 0 deletions pkg/apis/pipeline/v1alpha1/taskrun_defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copyright 2018 The Knative Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

func (tr *TaskRun) SetDefaults() {
tr.Spec.SetDefaults()
}

func (trs *TaskRunSpec) SetDefaults() {
if trs.TaskRef.Kind == "" {
trs.TaskRef.Kind = NamespacedTaskKind
}
}
2 changes: 0 additions & 2 deletions pkg/apis/pipeline/v1alpha1/taskrun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ type TaskRunList struct {
Items []TaskRun `json:"items"`
}

func (tr *TaskRun) SetDefaults() {}

// GetBuildRef for task
func (tr *TaskRun) GetBuildRef() corev1.ObjectReference {
return corev1.ObjectReference{
Expand Down
Loading

0 comments on commit 7219631

Please sign in to comment.