Skip to content

Commit

Permalink
Add Task to v1alpha2 🎋
Browse files Browse the repository at this point in the history
This modify how `TaskSpec` 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, TaskRun, 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 authored and tekton-robot committed Dec 5, 2019
1 parent c56ce9a commit fb36ff3
Show file tree
Hide file tree
Showing 35 changed files with 3,155 additions and 323 deletions.
1 change: 1 addition & 0 deletions pkg/apis/pipeline/v1alpha1/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
// MergeStepsWithStepTemplate takes a possibly nil container template and a
// list of steps, merging each of the steps with the container template, if
// it's not nil, and returning the resulting list.
// Deprecated
func MergeStepsWithStepTemplate(template *v1.Container, steps []Step) ([]Step, error) {
if template == nil {
return steps, nil
Expand Down
94 changes: 9 additions & 85 deletions pkg/apis/pipeline/v1alpha1/param_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,113 +17,37 @@ limitations under the License.
package v1alpha1

import (
"context"
"encoding/json"
"fmt"

"github.com/tektoncd/pipeline/pkg/substitution"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"
)

// ParamSpec defines arbitrary parameters needed beyond typed inputs (such as
// resources). Parameter values are provided by users as inputs on a TaskRun
// or PipelineRun.
type ParamSpec struct {
// Name declares the name by which a parameter is referenced.
Name string `json:"name"`
// Type is the user-specified type of the parameter. The possible types
// are currently "string" and "array", and "string" is the default.
// +optional
Type ParamType `json:"type,omitempty"`
// Description is a user-facing description of the parameter that may be
// used to populate a UI.
// +optional
Description string `json:"description,omitempty"`
// Default is the value a parameter takes if no input value is supplied. If
// default is set, a Task may be executed without a supplied value for the
// parameter.
// +optional
Default *ArrayOrString `json:"default,omitempty"`
}

func (pp *ParamSpec) SetDefaults(ctx context.Context) {
if pp != nil && pp.Type == "" {
if pp.Default != nil {
// propagate the parsed ArrayOrString's type to the parent ParamSpec's type
pp.Type = pp.Default.Type
} else {
// ParamTypeString is the default value (when no type can be inferred from the default value)
pp.Type = ParamTypeString
}
}
}
type ParamSpec = v1alpha2.ParamSpec

// ResourceParam declares a string value to use for the parameter called Name, and is used in
// the specific context of PipelineResources.
type ResourceParam struct {
Name string `json:"name"`
Value string `json:"value"`
}
type ResourceParam = v1alpha2.ResourceParam

// Param declares an ArrayOrString to use for the parameter called name.
type Param struct {
Name string `json:"name"`
Value ArrayOrString `json:"value"`
}
type Param = v1alpha2.Param

// ParamType indicates the type of an input parameter;
// Used to distinguish between a single string and an array of strings.
type ParamType string
type ParamType = v1alpha2.ParamType

// Valid ParamTypes:
const (
ParamTypeString ParamType = "string"
ParamTypeArray ParamType = "array"
ParamTypeString ParamType = v1alpha2.ParamTypeString
ParamTypeArray ParamType = v1alpha2.ParamTypeArray
)

// AllParamTypes can be used for ParamType validation.
var AllParamTypes = []ParamType{ParamTypeString, ParamTypeArray}
var AllParamTypes = v1alpha2.AllParamTypes

// ArrayOrString is modeled after IntOrString in kubernetes/apimachinery:

// ArrayOrString is a type that can hold a single string or string array.
// Used in JSON unmarshalling so that a single JSON field can accept
// either an individual string or an array of strings.
type ArrayOrString struct {
Type ParamType // Represents the stored type of ArrayOrString.
StringVal string
ArrayVal []string
}

// UnmarshalJSON implements the json.Unmarshaller interface.
func (arrayOrString *ArrayOrString) UnmarshalJSON(value []byte) error {
if value[0] == '"' {
arrayOrString.Type = ParamTypeString
return json.Unmarshal(value, &arrayOrString.StringVal)
}
arrayOrString.Type = ParamTypeArray
return json.Unmarshal(value, &arrayOrString.ArrayVal)
}

// MarshalJSON implements the json.Marshaller interface.
func (arrayOrString ArrayOrString) MarshalJSON() ([]byte, error) {
switch arrayOrString.Type {
case ParamTypeString:
return json.Marshal(arrayOrString.StringVal)
case ParamTypeArray:
return json.Marshal(arrayOrString.ArrayVal)
default:
return []byte{}, fmt.Errorf("impossible ArrayOrString.Type: %q", arrayOrString.Type)
}
}

func (arrayOrString *ArrayOrString) ApplyReplacements(stringReplacements map[string]string, arrayReplacements map[string][]string) {
if arrayOrString.Type == ParamTypeString {
arrayOrString.StringVal = substitution.ApplyReplacements(arrayOrString.StringVal, stringReplacements)
} else {
var newArrayVal []string
for _, v := range arrayOrString.ArrayVal {
newArrayVal = append(newArrayVal, substitution.ApplyArrayReplacements(v, stringReplacements, arrayReplacements)...)
}
arrayOrString.ArrayVal = newArrayVal
}
}
type ArrayOrString = v1alpha2.ArrayOrString
64 changes: 14 additions & 50 deletions pkg/apis/pipeline/v1alpha1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,42 @@ package v1alpha1
import (
"github.com/google/go-cmp/cmp"
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"
"golang.org/x/xerrors"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// PipelineResourceType represents the type of endpoint the pipelineResource is, so that the
// controller will know this pipelineResource should be fetched and optionally what
// additional metatdata should be provided for it.
type PipelineResourceType string
type PipelineResourceType = v1alpha2.PipelineResourceType

var (
AllowedOutputResources = map[PipelineResourceType]bool{
PipelineResourceTypeStorage: true,
PipelineResourceTypeGit: true,
}
AllowedOutputResources = v1alpha2.AllowedOutputResources
)

const (
// PipelineResourceTypeGit indicates that this source is a GitHub repo.
PipelineResourceTypeGit PipelineResourceType = "git"
PipelineResourceTypeGit PipelineResourceType = v1alpha2.PipelineResourceTypeGit

// PipelineResourceTypeStorage indicates that this source is a storage blob resource.
PipelineResourceTypeStorage PipelineResourceType = "storage"
PipelineResourceTypeStorage PipelineResourceType = v1alpha2.PipelineResourceTypeStorage

// PipelineResourceTypeImage indicates that this source is a docker Image.
PipelineResourceTypeImage PipelineResourceType = "image"
PipelineResourceTypeImage PipelineResourceType = v1alpha2.PipelineResourceTypeImage

// PipelineResourceTypeCluster indicates that this source is a k8s cluster Image.
PipelineResourceTypeCluster PipelineResourceType = "cluster"
PipelineResourceTypeCluster PipelineResourceType = v1alpha2.PipelineResourceTypeCluster

// PipelineResourceTypePullRequest indicates that this source is a SCM Pull Request.
PipelineResourceTypePullRequest PipelineResourceType = "pullRequest"
PipelineResourceTypePullRequest PipelineResourceType = v1alpha2.PipelineResourceTypePullRequest

// PipelineResourceTypeCloudEvent indicates that this source is a cloud event URI
PipelineResourceTypeCloudEvent PipelineResourceType = "cloudEvent"
PipelineResourceTypeCloudEvent PipelineResourceType = v1alpha2.PipelineResourceTypeCloudEvent
)

// AllResourceTypes can be used for validation to check if a provided Resource type is one of the known types.
var AllResourceTypes = []PipelineResourceType{PipelineResourceTypeGit, PipelineResourceTypeStorage, PipelineResourceTypeImage, PipelineResourceTypeCluster, PipelineResourceTypePullRequest, PipelineResourceTypeCloudEvent}
var AllResourceTypes = v1alpha2.AllResourceTypes

// PipelineResourceInterface interface to be implemented by different PipelineResource types
type PipelineResourceInterface interface {
Expand All @@ -77,33 +74,10 @@ type PipelineResourceInterface interface {
}

// TaskModifier is an interface to be implemented by different PipelineResources
type TaskModifier interface {
GetStepsToPrepend() []Step
GetStepsToAppend() []Step
GetVolumes() []v1.Volume
}
type TaskModifier = v1alpha2.TaskModifier

// InternalTaskModifier implements TaskModifier for resources that are built-in to Tekton Pipelines.
type InternalTaskModifier struct {
StepsToPrepend []Step
StepsToAppend []Step
Volumes []v1.Volume
}

// GetStepsToPrepend returns a set of Steps to prepend to the Task.
func (tm *InternalTaskModifier) GetStepsToPrepend() []Step {
return tm.StepsToPrepend
}

// GetStepsToAppend returns a set of Steps to append to the Task.
func (tm *InternalTaskModifier) GetStepsToAppend() []Step {
return tm.StepsToAppend
}

// GetVolumes returns a set of Volumes to prepend to the Task pod.
func (tm *InternalTaskModifier) GetVolumes() []v1.Volume {
return tm.Volumes
}
type InternalTaskModifier = v1alpha2.InternalTaskModifier

func checkStepNotAlreadyAdded(s Step, steps []Step) error {
for _, step := range steps {
Expand All @@ -118,6 +92,7 @@ func checkStepNotAlreadyAdded(s Step, steps []Step) error {
// If steps with the same name exist in ts an error will be returned. If identical Volumes have
// been added, they will not be added again. If Volumes with the same name but different contents
// have been added, an error will be returned.
// FIXME(vdemeester) de-duplicate this
func ApplyTaskModifier(ts *TaskSpec, tm TaskModifier) error {
steps := tm.GetStepsToPrepend()
for _, step := range steps {
Expand Down Expand Up @@ -238,18 +213,7 @@ type PipelineResourceList struct {
// PipelineResources within the type's definition, and when provided as an Input, the Name will be the
// path to the volume mounted containing this PipelineResource as an input (e.g.
// an input Resource named `workspace` will be mounted at `/workspace`).
type ResourceDeclaration struct {
// Name declares the name by which a resource is referenced in the
// definition. Resources may be referenced by name in the definition of a
// Task's steps.
Name string `json:"name"`
// Type is the type of this resource;
Type PipelineResourceType `json:"type"`
// TargetPath is the path in workspace directory where the resource
// will be copied.
// +optional
TargetPath string `json:"targetPath,omitempty"`
}
type ResourceDeclaration = v1alpha2.ResourceDeclaration

// ResourceFromType returns an instance of the correct PipelineResource object type which can be
// used to add input and ouput containers as well as volumes to a TaskRun's pod in order to realize
Expand Down
15 changes: 4 additions & 11 deletions pkg/apis/pipeline/v1alpha1/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2"
)

func (t *Task) TaskSpec() TaskSpec {
Expand Down Expand Up @@ -63,14 +65,7 @@ type TaskSpec struct {

// Step embeds the Container type, which allows it to include fields not
// provided by Container.
type Step struct {
corev1.Container

// Script is the contents of an executable file to execute.
//
// If Script is not empty, the Step cannot have an Command or Args.
Script string `json:"script,omitempty"`
}
type Step = v1alpha2.Step

// +genclient
// +genclient:noStatus
Expand Down Expand Up @@ -111,9 +106,7 @@ type Inputs struct {
// the Task definition, and when provided as an Input, the Name will be the
// path to the volume mounted containing this Resource as an input (e.g.
// an input Resource named `workspace` will be mounted at `/workspace`).
type TaskResource struct {
ResourceDeclaration `json:",inline"`
}
type TaskResource = v1alpha2.TaskResource

// Outputs allow a task to declare what data the Build/Task will be producing,
// i.e. results such as logs and artifacts such as images.
Expand Down
Loading

0 comments on commit fb36ff3

Please sign in to comment.