Skip to content

Commit

Permalink
Add TaskRun to v1alpha2 🎋
Browse files Browse the repository at this point in the history
This modify how `TaskRunSpec` looks from v1alpha1:
- params is now directly under spec
- no more inputs and outputs, get replaced by resources
- resource has input and output resource declaration fields, similar
  to how it is used in Pipeline

The next step are :
- Add more types (Pipeline, PipelineRun, Condition)
- Refactor v1alpha1 to embedded v1alpha2 (for storage purpose)
- Auto-conversion from v1alpha1

Signed-off-by: Vincent Demeester <[email protected]>
  • Loading branch information
vdemeester committed Dec 16, 2019
1 parent 0f20c35 commit f12eea0
Show file tree
Hide file tree
Showing 28 changed files with 2,637 additions and 121 deletions.
17 changes: 5 additions & 12 deletions pkg/apis/pipeline/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"
"github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand All @@ -35,13 +36,13 @@ type PipelineSpec struct {

// Check that Pipeline may be validated and defaulted.
// TaskKind defines the type of Task used by the pipeline.
type TaskKind string
type TaskKind = v1alpha2.TaskKind

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

// +genclient
Expand Down Expand Up @@ -209,15 +210,7 @@ type PipelineTaskOutputResource struct {

// TaskRef can be used to refer to a specific instance of a task.
// Copied from CrossVersionObjectReference: https://github.com/kubernetes/kubernetes/blob/169df7434155cbbc22f1532cba8e0a9588e29ad8/pkg/apis/autoscaling/types.go#L64
type TaskRef struct {
// Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
Name string `json:"name,omitempty"`
// 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"`
}
type TaskRef = v1alpha2.TaskRef

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

Expand Down
40 changes: 2 additions & 38 deletions pkg/apis/pipeline/v1alpha1/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,7 @@ limitations under the License.

package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
)
import "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"

// PodTemplate holds pod specific configuration
type PodTemplate struct {
// NodeSelector is a selector which must be true for the pod to fit on a node.
// Selector which must match a node's labels for the pod to be scheduled on that node.
// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`

// If specified, the pod's tolerations.
// +optional
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`

// If specified, the pod's scheduling constraints
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty"`

// SecurityContext holds pod-level security attributes and common container settings.
// Optional: Defaults to empty. See type description for default values of each field.
// +optional
SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`

// List of volumes that can be mounted by containers belonging to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"`

// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io
// group, which should be used to run this pod. If no RuntimeClass resource
// matches the named class, the pod will not be run. If unset or empty, the
// "legacy" RuntimeClass will be used, which is an implicit class with an
// empty definition that uses the default runtime handler.
// More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md
// This is a beta feature as of Kubernetes v1.14.
// +optional
RuntimeClassName *string `json:"runtimeClassName,omitempty" protobuf:"bytes,2,opt,name=runtimeClassName"`
}
type PodTemplate = v1alpha2.PodTemplate
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/taskrun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"time"

"github.com/tektoncd/pipeline/pkg/apis/pipeline"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"knative.dev/pkg/apis"
Expand Down Expand Up @@ -54,12 +55,12 @@ type TaskRunSpec struct {
}

// TaskRunSpecStatus defines the taskrun spec status the user can provide
type TaskRunSpecStatus string
type TaskRunSpecStatus = v1alpha2.TaskRunSpecStatus

const (
// TaskRunSpecStatusCancelled indicates that the user wants to cancel the task,
// if not already cancelled or terminated
TaskRunSpecStatusCancelled = "TaskRunCancelled"
TaskRunSpecStatusCancelled = v1alpha2.TaskRunSpecStatusCancelled
)

// TaskRunInputs holds the input values that this task was invoked with.
Expand Down
70 changes: 1 addition & 69 deletions pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions pkg/apis/pipeline/v1alpha2/pod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright 2019 The Tekton 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 v1alpha2

import (
corev1 "k8s.io/api/core/v1"
)

// PodTemplate holds pod specific configuration
type PodTemplate struct {
// NodeSelector is a selector which must be true for the pod to fit on a node.
// Selector which must match a node's labels for the pod to be scheduled on that node.
// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`

// If specified, the pod's tolerations.
// +optional
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`

// If specified, the pod's scheduling constraints
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty"`

// SecurityContext holds pod-level security attributes and common container settings.
// Optional: Defaults to empty. See type description for default values of each field.
// +optional
SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`

// List of volumes that can be mounted by containers belonging to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"`

// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io
// group, which should be used to run this pod. If no RuntimeClass resource
// matches the named class, the pod will not be run. If unset or empty, the
// "legacy" RuntimeClass will be used, which is an implicit class with an
// empty definition that uses the default runtime handler.
// More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md
// This is a beta feature as of Kubernetes v1.14.
// +optional
RuntimeClassName *string `json:"runtimeClassName,omitempty" protobuf:"bytes,2,opt,name=runtimeClassName"`
}
17 changes: 17 additions & 0 deletions pkg/apis/pipeline/v1alpha2/pod_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Copyright 2019 The Tekton 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 v1alpha2_test
41 changes: 41 additions & 0 deletions pkg/apis/pipeline/v1alpha2/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ type TaskResource struct {
ResourceDeclaration `json:",inline"`
}

// TaskRunResources allows a TaskRun to declare inputs and outputs TaskResourceBinding
type TaskRunResources struct {
// Inputs holds the inputs resources this task was invoked with
Inputs []TaskResourceBinding `json:"inputs,omitempty"`
// Outputs holds the inputs resources this task was invoked with
Outputs []TaskResourceBinding `json:"outputs,omitempty"`
}

// ResourceDeclaration defines an input or output PipelineResource declared as a requirement
// by another type such as a Task or Condition. The Name field will be used to refer to these
// PipelineResources within the type's definition, and when provided as an Input, the Name will be the
Expand All @@ -101,6 +109,39 @@ type ResourceDeclaration struct {
Optional bool `json:"optional,omitempty"`
}

// PipelineResourceBinding connects a reference to an instance of a PipelineResource
// with a PipelineResource dependency that the Pipeline has declared
type PipelineResourceBinding struct {
// Name is the name of the PipelineResource in the Pipeline's declaration
Name string `json:"name,omitempty"`
// ResourceRef is a reference to the instance of the actual PipelineResource
// that should be used
// +optional
ResourceRef *PipelineResourceRef `json:"resourceRef,omitempty"`

// FIXME(vdemeester) cannot support this if PipelineResource stays in alpha and on the same group
// ResourceSpec is specification of a resource that should be created and
// consumed by the task
// +optional
// ResourceSpec *PipelineResourceSpec `json:"resourceSpec,omitempty"`
}

// PipelineResourceResult used to export the image name and digest as json
type PipelineResourceResult struct {
Key string `json:"key"`
Value string `json:"value"`
ResourceRef PipelineResourceRef `json:"resourceRef,omitempty"`
}

// PipelineResourceRef can be used to refer to a specific instance of a Resource
type PipelineResourceRef struct {
// Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names
Name string `json:"name,omitempty"`
// API version of the referent
// +optional
APIVersion string `json:"apiVersion,omitempty"`
}

// TaskModifier is an interface to be implemented by different PipelineResources
type TaskModifier interface {
GetStepsToPrepend() []Step
Expand Down
47 changes: 47 additions & 0 deletions pkg/apis/pipeline/v1alpha2/resource_types_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,50 @@ func validateResourceType(r TaskResource, path string) *apis.FieldError {
}
return apis.ErrInvalidValue(string(r.Type), path)
}

func (tr *TaskRunResources) Validate(ctx context.Context) *apis.FieldError {
if tr == nil {
return nil
}
if err := validateTaskRunResources(tr.Inputs, "spec.resources.inputs.name"); err != nil {
return err
}
if err := validateTaskRunResources(tr.Outputs, "spec.resources.outputs.name"); err != nil {
return err
}
return nil
}

// validateTaskRunResources validates that
// 1. resource is not declared more than once
// 2. if both resource reference and resource spec is defined at the same time
// 3. at least resource ref or resource spec is defined
func validateTaskRunResources(resources []TaskResourceBinding, path string) *apis.FieldError {
encountered := map[string]struct{}{}
for _, r := range resources {
// We should provide only one binding for each resource required by the Task.
name := strings.ToLower(r.Name)
if _, ok := encountered[strings.ToLower(name)]; ok {
return apis.ErrMultipleOneOf(path)
}
encountered[name] = struct{}{}
if r.ResourceRef == nil {
return apis.ErrMissingField(fmt.Sprintf("%s.resourceRef", path))
}
// FIXME(vdemeester) cannot support this if PipelineResource stays in alpha and on the same group
/*
// Check that both resource ref and resource Spec are not present
if r.ResourceRef != nil && r.ResourceSpec != nil {
return apis.ErrDisallowedFields(fmt.Sprintf("%s.ResourceRef", path), fmt.Sprintf("%s.ResourceSpec", path))
}
// Check that one of resource ref and resource Spec is present
if (r.ResourceRef == nil || r.ResourceRef.Name == "") && r.ResourceSpec == nil {
return apis.ErrMissingField(fmt.Sprintf("%s.ResourceRef", path), fmt.Sprintf("%s.ResourceSpec", path))
}
if r.ResourceSpec != nil && r.ResourceSpec.Validate(ctx) != nil {
return r.ResourceSpec.Validate(ctx)
}
*/
}
return nil
}
Loading

0 comments on commit f12eea0

Please sign in to comment.