diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index 3636f315c2c..2211cf1fdd0 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -6322,6 +6322,8 @@ Resource Types:
CustomRun represents a single execution of a Custom Task.
+Field | +Description | +||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+apiVersion +string |
+
+
+tekton.dev/v1beta1
+
+ |
+||||||||||||||||||
+kind +string + |
+CustomRun |
+||||||||||||||||||
+metadata + + +Kubernetes meta/v1.ObjectMeta + + + |
+
+(Optional)
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
+ |
+||||||||||||||||||
+spec + + +CustomRunSpec + + + |
+
+(Optional)
+ + +
|
+||||||||||||||||||
+status + + +CustomRunStatus + + + |
++(Optional) + | +
CloudEventCondition is a string that represents the condition of the event.
Value | -Description | -
---|---|
"Failed" |
-CloudEventConditionFailed means that there was one or more attempts to -send the event, and none was successful so far. - |
-
"Sent" |
-CloudEventConditionSent means that the event was sent successfully - |
-
"Unknown" |
-CloudEventConditionUnknown means that the condition for the event to be -triggered was not met yet, or we don’t know the state yet. - |
-
@@ -7583,6 +7762,231 @@ int32 +
+(Appears on:CustomRun) +
+CustomRunSpec defines the desired state of CustomRun
+Field | +Description | +
---|---|
+customRef + + +TaskRef + + + |
++(Optional) + | +
+customSpec + + +EmbeddedCustomRunSpec + + + |
+
+(Optional)
+ Spec is a specification of a custom task + |
+
+params + + +[]Param + + + |
++(Optional) + | +
+status + + +CustomRunSpecStatus + + + |
+
+(Optional)
+ Used for cancelling a customrun (and maybe more later on) + |
+
+statusMessage + + +CustomRunSpecStatusMessage + + + |
+
+(Optional)
+ Status message for cancellation. + |
+
+retries + +int + + |
+
+(Optional)
+ Used for propagating retries count to custom tasks + |
+
+serviceAccountName + +string + + |
++(Optional) + | +
+timeout + + +Kubernetes meta/v1.Duration + + + |
+
+(Optional)
+ Time after which the custom-task times out. +Refer Go’s ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration + |
+
+workspaces + + +[]WorkspaceBinding + + + |
+
+(Optional)
+ Workspaces is a list of WorkspaceBindings from volumes to workspaces. + |
+
string
alias)+(Appears on:CustomRunSpec) +
+CustomRunSpecStatus defines the taskrun spec status the user can provide
+string
alias)+(Appears on:CustomRunSpec) +
+CustomRunSpecStatusMessage defines human readable status messages for the TaskRun.
++(Appears on:CustomRunSpec) +
+EmbeddedCustomRunSpec allows custom task definitions to be embedded
+Field | +Description | +||||
---|---|---|---|---|---|
+metadata + + +PipelineTaskMetadata + + + |
++(Optional) + | +||||
+spec + +k8s.io/apimachinery/pkg/runtime.RawExtension + + |
+
+(Optional)
+ Spec is a specification of a custom task ++ +
|
+
@@ -7730,25 +8134,10 @@ TaskSpec
OnErrorType defines a list of supported exiting behavior of a container on error
Value | -Description | -
---|---|
"continue" |
-Continue indicates continue executing the rest of the steps irrespective of the container exit code - |
-
"stopAndFail" |
-StopAndFail indicates exit the taskRun if the container exits with non-zero exit code - |
-
-(Appears on:RunSpec, PipelineRunSpec, PipelineTask, ResolverRef, TaskRunInputs, TaskRunSpec) +(Appears on:RunSpec, CustomRunSpec, PipelineRunSpec, PipelineTask, ResolverRef, TaskRunInputs, TaskRunSpec)
Param declares an ParamValues to use for the parameter called name.
@@ -7883,21 +8272,6 @@ parameter.ParamType indicates the type of an input parameter; Used to distinguish between a single string and an array of strings.
Value | -Description | -
---|---|
"array" |
-- |
"object" |
-- |
"string" |
-- |
@@ -8331,53 +8705,6 @@ ParamValue
PipelineRunReason represents a reason for the pipeline run “Succeeded” condition
Value | -Description | -
---|---|
"Cancelled" |
-PipelineRunReasonCancelled is the reason set when the PipelineRun cancelled by the user -This reason may be found with a corev1.ConditionFalse status, if the cancellation was processed successfully -This reason may be found with a corev1.ConditionUnknown status, if the cancellation is being processed or failed - |
-
"CancelledRunningFinally" |
-PipelineRunReasonCancelledRunningFinally indicates that pipeline has been gracefully cancelled -and no new Tasks will be scheduled by the controller, but final tasks are now running - |
-
"Completed" |
-PipelineRunReasonCompleted is the reason set when the PipelineRun completed successfully with one or more skipped Tasks - |
-
"Failed" |
-PipelineRunReasonFailed is the reason set when the PipelineRun completed with a failure - |
-
"PipelineRunPending" |
-PipelineRunReasonPending is the reason set when the PipelineRun is in the pending state - |
-
"Running" |
-PipelineRunReasonRunning is the reason set when the PipelineRun is running - |
-
"Started" |
-PipelineRunReasonStarted is the reason set when the PipelineRun has just started - |
-
"StoppedRunningFinally" |
-PipelineRunReasonStoppedRunningFinally indicates that pipeline has been gracefully stopped -and no new Tasks will be scheduled by the controller, but final tasks are now running - |
-
"PipelineRunStopping" |
-PipelineRunReasonStopping indicates that no new Tasks will be scheduled by the controller, and the -pipeline will stop once all running tasks complete their work - |
-
"Succeeded" |
-PipelineRunReasonSuccessful is the reason set when the PipelineRun completed successfully - |
-
"PipelineRunTimeout" |
-PipelineRunReasonTimedOut is the reason set when the PipelineRun has timed out - |
-
@@ -9257,7 +9584,7 @@ string
-(Appears on:EmbeddedRunSpec, EmbeddedTask, PipelineTaskRunSpec) +(Appears on:EmbeddedRunSpec, EmbeddedCustomRunSpec, EmbeddedTask, PipelineTaskRunSpec)
PipelineTaskMetadata contains the labels or annotations for an EmbeddedTask
@@ -9759,18 +10086,6 @@ string Note that ResultsType is another type which is used to define the data type (e.g. string, array, etc) we used for ResultsValue | -Description | -
---|---|
1 |
-TaskRunResultType default task run result value - |
-
string
alias)@@ -9781,23 +10096,8 @@ Note that ResultsType is another type which is used to define the data type Used to distinguish between a single string and an array of strings. Note that there is ResultType used to find out whether a PipelineResourceResult is from a task result or not, which is different from -this ResultsType.
-Value | -Description | -
---|---|
"array" |
-- |
"object" |
-- |
"string" |
-- |
@@ -10341,45 +10641,6 @@ SkippingReason
SkippingReason explains why a PipelineTask was skipped.
Value | -Description | -
---|---|
"PipelineRun Finally timeout has been reached" |
-FinallyTimedOutSkip means the task was skipped because the PipelineRun has passed its Timeouts.Finally. - |
-
"PipelineRun was gracefully cancelled" |
-GracefullyCancelledSkip means the task was skipped because the pipeline run has been gracefully cancelled - |
-
"PipelineRun was gracefully stopped" |
-GracefullyStoppedSkip means the task was skipped because the pipeline run has been gracefully stopped - |
-
"Results were missing" |
-MissingResultsSkip means the task was skipped because it’s missing necessary results - |
-
"None" |
-None means the task was not skipped - |
-
"Parent Tasks were skipped" |
-ParentTasksSkip means the task was skipped because its parent was skipped - |
-
"PipelineRun timeout has been reached" |
-PipelineTimedOutSkip means the task was skipped because the PipelineRun has passed its overall timeout. - |
-
"PipelineRun was stopping" |
-StoppingSkip means the task was skipped because the pipeline run is stopping - |
-
"PipelineRun Tasks timeout has been reached" |
-TasksTimedOutSkip means the task was skipped because the PipelineRun has passed its Timeouts.Tasks. - |
-
"When Expressions evaluated to false" |
-WhenExpressionsSkip means the task was skipped due to at least one of its when expressions evaluating to false - |
-
@@ -11328,21 +11589,6 @@ Default is false.
TaskKind defines the type of Task used by the pipeline.
Value | -Description | -
---|---|
"ClusterTask" |
-ClusterTaskKind indicates that task type has a cluster scope. - |
-
"Task" |
-NamespacedTaskKind indicates that the task type has a namespaced scope. - |
-
-(Appears on:RunSpec, PipelineTask, TaskRunSpec) +(Appears on:RunSpec, CustomRunSpec, PipelineTask, TaskRunSpec)
TaskRef can be used to refer to a specific instance of a task.
@@ -11742,36 +11988,6 @@ string the Succeeded condition that are controlled by the TaskRun itself. Failure reasons that emerge from underlying resources are not included hereValue | -Description | -
---|---|
"TaskRunCancelled" |
-TaskRunReasonCancelled is the reason set when the Taskrun is cancelled by the user - |
-
"Failed" |
-TaskRunReasonFailed is the reason set when the TaskRun completed with a failure - |
-
"TaskRunImagePullFailed" |
-TaskRunReasonImagePullFailed is the reason set when the step of a task fails due to image not being pulled - |
-
"Running" |
-TaskRunReasonRunning is the reason set when the TaskRun is running - |
-
"Started" |
-TaskRunReasonStarted is the reason set when the TaskRun has just started - |
-
"Succeeded" |
-TaskRunReasonSuccessful is the reason set when the TaskRun completed successfully - |
-
"TaskRunTimeout" |
-TaskRunReasonTimedOut is the reason set when the Taskrun has timed out - |
-
@@ -12144,22 +12360,6 @@ Kubernetes core/v1.ResourceRequirements
TaskRunSpecStatusMessage defines human readable status messages for the TaskRun.
Value | -Description | -
---|---|
"TaskRun cancelled as the PipelineRun it belongs to has been cancelled." |
-TaskRunCancelledByPipelineMsg indicates that the PipelineRun of which this -TaskRun was a part of has been cancelled. - |
-
"TaskRun cancelled as the PipelineRun it belongs to has timed out." |
-TaskRunCancelledByPipelineTimeoutMsg indicates that the TaskRun was cancelled because the PipelineRun running it timed out. - |
-
@@ -12677,7 +12877,7 @@ All of them need to evaluate to True for a guarded Task to be executed.
-(Appears on:RunSpec, PipelineRunSpec, TaskRunSpec) +(Appears on:RunSpec, CustomRunSpec, PipelineRunSpec, TaskRunSpec)
WorkspaceBinding maps a Task’s declared workspace to a Volume.
@@ -12992,6 +13192,184 @@ overriding any MountPath specified in the Task’s WorkspaceDeclaration. ++(Appears on:CustomRunStatusFields) +
+CustomRunResult used to describe the results of a task
+Field | +Description | +
---|---|
+name + +string + + |
+
+ Name the given name + |
+
+value + +string + + |
+
+ Value the given value of the result + |
+
+(Appears on:CustomRun, CustomRunStatusFields) +
+CustomRunStatus defines the observed state of CustomRun
+Field | +Description | +
---|---|
+Status + + +knative.dev/pkg/apis/duck/v1.Status + + + |
+
+
+(Members of |
+
+CustomRunStatusFields + + +CustomRunStatusFields + + + |
+
+
+(Members of CustomRunStatusFields inlines the status fields. + |
+
+(Appears on:CustomRunStatus) +
+CustomRunStatusFields holds the fields of CustomRun’s status. This is defined +separately and inlined so that other types can readily consume these fields +via duck typing.
+Field | +Description | +
---|---|
+startTime + + +Kubernetes meta/v1.Time + + + |
+
+(Optional)
+ StartTime is the time the build is actually started. + |
+
+completionTime + + +Kubernetes meta/v1.Time + + + |
+
+(Optional)
+ CompletionTime is the time the build completed. + |
+
+results + + +[]CustomRunResult + + + |
+
+(Optional)
+ Results reports any output result values to be consumed by later +tasks in a pipeline. + |
+
+retriesStatus + + +[]CustomRunStatus + + + |
+
+(Optional)
+ RetriesStatus contains the history of CustomRunStatus, in case of a retry. + |
+
+extraFields + +k8s.io/apimachinery/pkg/runtime.RawExtension + + |
+
+ ExtraFields holds arbitrary fields provided by the custom task +controller. + |
+
Generated with gen-crd-api-reference-docs
diff --git a/pkg/apis/pipeline/v1beta1/customrun_defaults.go b/pkg/apis/pipeline/v1beta1/customrun_defaults.go
new file mode 100644
index 00000000000..9105d16a6c1
--- /dev/null
+++ b/pkg/apis/pipeline/v1beta1/customrun_defaults.go
@@ -0,0 +1,41 @@
+/*
+Copyright 2020 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 v1beta1
+
+import (
+ "context"
+
+ "github.com/tektoncd/pipeline/pkg/apis/config"
+ "knative.dev/pkg/apis"
+)
+
+var _ apis.Defaultable = (*CustomRun)(nil)
+
+// SetDefaults implements apis.Defaultable
+func (r *CustomRun) SetDefaults(ctx context.Context) {
+ ctx = apis.WithinParent(ctx, r.ObjectMeta)
+ r.Spec.SetDefaults(apis.WithinSpec(ctx))
+}
+
+// SetDefaults implements apis.Defaultable
+func (rs *CustomRunSpec) SetDefaults(ctx context.Context) {
+ cfg := config.FromContextOrDefaults(ctx)
+ defaultSA := cfg.Defaults.DefaultServiceAccount
+ if rs.ServiceAccountName == "" && defaultSA != "" {
+ rs.ServiceAccountName = defaultSA
+ }
+}
diff --git a/pkg/apis/pipeline/v1beta1/customrun_types.go b/pkg/apis/pipeline/v1beta1/customrun_types.go
new file mode 100644
index 00000000000..d0d4fb752d0
--- /dev/null
+++ b/pkg/apis/pipeline/v1beta1/customrun_types.go
@@ -0,0 +1,246 @@
+/*
+Copyright 2020 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 v1beta1
+
+import (
+ "fmt"
+ "time"
+
+ apisconfig "github.com/tektoncd/pipeline/pkg/apis/config"
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline"
+ runv1beta1 "github.com/tektoncd/pipeline/pkg/apis/run/v1beta1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/clock"
+ "knative.dev/pkg/apis"
+ duckv1 "knative.dev/pkg/apis/duck/v1"
+)
+
+// EmbeddedCustomRunSpec allows custom task definitions to be embedded
+type EmbeddedCustomRunSpec struct {
+ runtime.TypeMeta `json:",inline"`
+
+ // +optional
+ Metadata PipelineTaskMetadata `json:"metadata,omitempty"`
+
+ // Spec is a specification of a custom task
+ // +optional
+ Spec runtime.RawExtension `json:"spec,omitempty"`
+}
+
+// CustomRunSpec defines the desired state of CustomRun
+type CustomRunSpec struct {
+ // +optional
+ CustomRef *TaskRef `json:"customRef,omitempty"`
+
+ // Spec is a specification of a custom task
+ // +optional
+ CustomSpec *EmbeddedCustomRunSpec `json:"customSpec,omitempty"`
+
+ // +optional
+ // +listType=atomic
+ Params []Param `json:"params,omitempty"`
+
+ // Used for cancelling a customrun (and maybe more later on)
+ // +optional
+ Status CustomRunSpecStatus `json:"status,omitempty"`
+
+ // Status message for cancellation.
+ // +optional
+ StatusMessage CustomRunSpecStatusMessage `json:"statusMessage,omitempty"`
+
+ // Used for propagating retries count to custom tasks
+ // +optional
+ Retries int `json:"retries,omitempty"`
+
+ // +optional
+ ServiceAccountName string `json:"serviceAccountName"`
+
+ // Time after which the custom-task times out.
+ // Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration
+ // +optional
+ Timeout *metav1.Duration `json:"timeout,omitempty"`
+
+ // Workspaces is a list of WorkspaceBindings from volumes to workspaces.
+ // +optional
+ // +listType=atomic
+ Workspaces []WorkspaceBinding `json:"workspaces,omitempty"`
+}
+
+// CustomRunSpecStatus defines the taskrun spec status the user can provide
+type CustomRunSpecStatus string
+
+const (
+ // CustomRunSpecStatusCancelled indicates that the user wants to cancel the run,
+ // if not already cancelled or terminated
+ CustomRunSpecStatusCancelled CustomRunSpecStatus = "RunCancelled"
+)
+
+// CustomRunSpecStatusMessage defines human readable status messages for the TaskRun.
+type CustomRunSpecStatusMessage string
+
+const (
+ // CustomRunCancelledByPipelineMsg indicates that the PipelineRun of which part this CustomRun was
+ // has been cancelled.
+ CustomRunCancelledByPipelineMsg CustomRunSpecStatusMessage = "CustomRun cancelled as the PipelineRun it belongs to has been cancelled."
+ // CustomRunCancelledByPipelineTimeoutMsg indicates that the Run was cancelled because the PipelineRun running it timed out.
+ CustomRunCancelledByPipelineTimeoutMsg CustomRunSpecStatusMessage = "CustomRun cancelled as the PipelineRun it belongs to has timed out."
+)
+
+// GetParam gets the Param from the CustomRunSpec with the given name
+// TODO(jasonhall): Move this to a Params type so other code can use it?
+func (rs CustomRunSpec) GetParam(name string) *Param {
+ for _, p := range rs.Params {
+ if p.Name == name {
+ return &p
+ }
+ }
+ return nil
+}
+
+const (
+ // CustomRunReasonCancelled must be used in the Condition Reason to indicate that a CustomRun was cancelled.
+ CustomRunReasonCancelled = "CustomRunCancelled"
+ // CustomRunReasonTimedOut must be used in the Condition Reason to indicate that a CustomRun was timed out.
+ CustomRunReasonTimedOut = "CustomRunTimedOut"
+ // CustomRunReasonWorkspaceNotSupported can be used in the Condition Reason to indicate that the
+ // CustomRun contains a workspace which is not supported by this custom task.
+ CustomRunReasonWorkspaceNotSupported = "CustomRunWorkspaceNotSupported"
+ // CustomRunReasonPodTemplateNotSupported can be used in the Condition Reason to indicate that the
+ // CustomRun contains a pod template which is not supported by this custom task.
+ CustomRunReasonPodTemplateNotSupported = "CustomRunPodTemplateNotSupported"
+)
+
+// CustomRunStatus defines the observed state of CustomRun.
+type CustomRunStatus = runv1beta1.CustomRunStatus
+
+var customrunCondSet = apis.NewBatchConditionSet()
+
+// GetConditionSet retrieves the condition set for this resource. Implements
+// the KRShaped interface.
+func (r *CustomRun) GetConditionSet() apis.ConditionSet { return customrunCondSet }
+
+// GetStatus retrieves the status of the Parallel. Implements the KRShaped
+// interface.
+func (r *CustomRun) GetStatus() *duckv1.Status { return &r.Status.Status }
+
+// CustomRunStatusFields holds the fields of CustomRun's status. This is defined
+// separately and inlined so that other types can readily consume these fields
+// via duck typing.
+type CustomRunStatusFields = runv1beta1.CustomRunStatusFields
+
+// CustomRunResult used to describe the results of a task
+type CustomRunResult = runv1beta1.CustomRunResult
+
+// +genclient
+// +genreconciler
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// CustomRun represents a single execution of a Custom Task.
+//
+// +k8s:openapi-gen=true
+type CustomRun struct {
+ metav1.TypeMeta `json:",inline"`
+ // +optional
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ // +optional
+ Spec CustomRunSpec `json:"spec,omitempty"`
+ // +optional
+ Status CustomRunStatus `json:"status,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// CustomRunList contains a list of CustomRun
+type CustomRunList struct {
+ metav1.TypeMeta `json:",inline"`
+ // +optional
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []CustomRun `json:"items"`
+}
+
+// GetStatusCondition returns the task run status as a ConditionAccessor
+func (r *CustomRun) GetStatusCondition() apis.ConditionAccessor {
+ return &r.Status
+}
+
+// GetGroupVersionKind implements kmeta.OwnerRefable.
+func (*CustomRun) GetGroupVersionKind() schema.GroupVersionKind {
+ return SchemeGroupVersion.WithKind(pipeline.RunControllerName)
+}
+
+// HasPipelineRunOwnerReference returns true of CustomRun has
+// owner reference of type PipelineRun
+func (r *CustomRun) HasPipelineRunOwnerReference() bool {
+ for _, ref := range r.GetOwnerReferences() {
+ if ref.Kind == pipeline.PipelineRunControllerName {
+ return true
+ }
+ }
+ return false
+}
+
+// IsCancelled returns true if the CustomRun's spec status is set to Cancelled state
+func (r *CustomRun) IsCancelled() bool {
+ return r.Spec.Status == CustomRunSpecStatusCancelled
+}
+
+// IsDone returns true if the CustomRun's status indicates that it is done.
+func (r *CustomRun) IsDone() bool {
+ return !r.Status.GetCondition(apis.ConditionSucceeded).IsUnknown()
+}
+
+// HasStarted function check whether taskrun has valid start time set in its status
+func (r *CustomRun) HasStarted() bool {
+ return r.Status.StartTime != nil && !r.Status.StartTime.IsZero()
+}
+
+// IsSuccessful returns true if the CustomRun's status indicates that it is done.
+func (r *CustomRun) IsSuccessful() bool {
+ return r != nil && r.Status.GetCondition(apis.ConditionSucceeded).IsTrue()
+}
+
+// GetCustomRunKey return the customrun's key for timeout handler map
+func (r *CustomRun) GetCustomRunKey() string {
+ // The address of the pointer is a threadsafe unique identifier for the customrun
+ return fmt.Sprintf("%s/%p", "CustomRun", r)
+}
+
+// HasTimedOut returns true if the CustomRun's running time is beyond the allowed timeout
+func (r *CustomRun) HasTimedOut(c clock.PassiveClock) bool {
+ if r.Status.StartTime == nil || r.Status.StartTime.IsZero() {
+ return false
+ }
+ timeout := r.GetTimeout()
+ // If timeout is set to 0 or defaulted to 0, there is no timeout.
+ if timeout == apisconfig.NoTimeoutDuration {
+ return false
+ }
+ runtime := c.Since(r.Status.StartTime.Time)
+ return runtime > timeout
+}
+
+// GetTimeout returns the timeout for this customrun, or the default if not configured
+func (r *CustomRun) GetTimeout() time.Duration {
+ // Use the platform default if no timeout is set
+ if r.Spec.Timeout == nil {
+ return apisconfig.DefaultTimeoutMinutes * time.Minute
+ }
+ return r.Spec.Timeout.Duration
+}
diff --git a/pkg/apis/pipeline/v1beta1/customrun_types_test.go b/pkg/apis/pipeline/v1beta1/customrun_types_test.go
new file mode 100644
index 00000000000..c562f439676
--- /dev/null
+++ b/pkg/apis/pipeline/v1beta1/customrun_types_test.go
@@ -0,0 +1,373 @@
+/*
+Copyright 2020 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 v1beta1_test
+
+import (
+ "testing"
+ "time"
+
+ "github.com/google/go-cmp/cmp"
+ apisconfig "github.com/tektoncd/pipeline/pkg/apis/config"
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/scheme"
+ "github.com/tektoncd/pipeline/test/diff"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ "knative.dev/pkg/apis"
+ duckv1 "knative.dev/pkg/apis/duck/v1"
+)
+
+func TestGetParams(t *testing.T) {
+ for _, c := range []struct {
+ desc string
+ spec v1beta1.CustomRunSpec
+ name string
+ want *v1beta1.Param
+ }{{
+ desc: "no params",
+ spec: v1beta1.CustomRunSpec{},
+ name: "anything",
+ want: nil,
+ }, {
+ desc: "found",
+ spec: v1beta1.CustomRunSpec{
+ Params: []v1beta1.Param{{
+ Name: "first",
+ Value: *v1beta1.NewStructuredValues("blah"),
+ }, {
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ }},
+ },
+ name: "foo",
+ want: &v1beta1.Param{
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ },
+ }, {
+ desc: "not found",
+ spec: v1beta1.CustomRunSpec{
+ Params: []v1beta1.Param{{
+ Name: "first",
+ Value: *v1beta1.NewStructuredValues("blah"),
+ }, {
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ }},
+ },
+ name: "bar",
+ want: nil,
+ }, {
+ // This shouldn't happen since it's invalid, but just in
+ // case, GetParams just returns the first param it finds with
+ // the specified name.
+ desc: "multiple with same name",
+ spec: v1beta1.CustomRunSpec{
+ Params: []v1beta1.Param{{
+ Name: "first",
+ Value: *v1beta1.NewStructuredValues("blah"),
+ }, {
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ }, {
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("second bar"),
+ }},
+ },
+ name: "foo",
+ want: &v1beta1.Param{
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ },
+ }} {
+ t.Run(c.desc, func(t *testing.T) {
+ got := c.spec.GetParam(c.name)
+ if d := cmp.Diff(c.want, got); d != "" {
+ t.Fatalf("Diff(-want,+got): %v", d)
+ }
+ })
+ }
+}
+
+func TestRunHasStarted(t *testing.T) {
+ params := []struct {
+ name string
+ runStatus v1beta1.CustomRunStatus
+ expectedValue bool
+ }{{
+ name: "runWithNoStartTime",
+ runStatus: v1beta1.CustomRunStatus{},
+ expectedValue: false,
+ }, {
+ name: "runWithStartTime",
+ runStatus: v1beta1.CustomRunStatus{
+ CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{Time: now},
+ },
+ },
+ expectedValue: true,
+ }, {
+ name: "runWithZeroStartTime",
+ runStatus: v1beta1.CustomRunStatus{
+ CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{},
+ },
+ },
+ expectedValue: false,
+ }}
+ for _, tc := range params {
+ t.Run(tc.name, func(t *testing.T) {
+ run := v1beta1.CustomRun{}
+ run.Status = tc.runStatus
+ if run.HasStarted() != tc.expectedValue {
+ t.Fatalf("Expected run HasStarted() to return %t but got %t", tc.expectedValue, run.HasStarted())
+ }
+ })
+ }
+}
+
+func TestRunIsDone(t *testing.T) {
+ customRun := v1beta1.CustomRun{
+ Status: v1beta1.CustomRunStatus{
+ Status: duckv1.Status{
+ Conditions: duckv1.Conditions{{
+ Type: apis.ConditionSucceeded,
+ Status: corev1.ConditionFalse,
+ }},
+ },
+ },
+ }
+
+ if !customRun.IsDone() {
+ t.Fatal("Expected run status to be done")
+ }
+}
+
+func TestRunIsCancelled(t *testing.T) {
+ customRun := v1beta1.CustomRun{
+ Spec: v1beta1.CustomRunSpec{
+ Status: v1beta1.CustomRunSpecStatusCancelled,
+ },
+ }
+ if !customRun.IsCancelled() {
+ t.Fatal("Expected run status to be cancelled")
+ }
+ expected := ""
+ if string(customRun.Spec.StatusMessage) != expected {
+ t.Fatalf("Expected StatusMessage is %s but got %s", expected, customRun.Spec.StatusMessage)
+ }
+}
+
+func TestRunIsCancelledWithMessage(t *testing.T) {
+ expectedStatusMessage := "test message"
+ customRun := v1beta1.CustomRun{
+ Spec: v1beta1.CustomRunSpec{
+ Status: v1beta1.CustomRunSpecStatusCancelled,
+ StatusMessage: v1beta1.CustomRunSpecStatusMessage(expectedStatusMessage),
+ },
+ }
+ if !customRun.IsCancelled() {
+ t.Fatal("Expected run status to be cancelled")
+ }
+
+ if string(customRun.Spec.StatusMessage) != expectedStatusMessage {
+ t.Fatalf("Expected StatusMessage is %s but got %s", expectedStatusMessage, customRun.Spec.StatusMessage)
+ }
+}
+
+// TestCustomRunStatus tests that extraFields in a CustomRunStatus can be parsed
+// from YAML.
+func TestCustomRunStatus(t *testing.T) {
+ in := `apiVersion: tekton.dev/v1beta1
+kind: CustomRun
+metadata:
+ name: run
+spec:
+ retries: 3
+ customRef:
+ apiVersion: example.dev/v0
+ kind: Example
+status:
+ conditions:
+ - type: "Succeeded"
+ status: "True"
+ results:
+ - name: foo
+ value: bar
+ extraFields:
+ simple: 'hello'
+ complex:
+ hello: ['w', 'o', 'r', 'l', 'd']
+`
+ var r v1beta1.CustomRun
+ if _, _, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(in), nil, &r); err != nil {
+ t.Fatalf("Decode YAML: %v", err)
+ }
+
+ want := &v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "tekton.dev/v1beta1",
+ Kind: "CustomRun",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "run",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ Retries: 3,
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "example.dev/v0",
+ Kind: "Example",
+ },
+ },
+ Status: v1beta1.CustomRunStatus{
+ Status: duckv1.Status{
+ Conditions: duckv1.Conditions{{
+ Type: apis.ConditionSucceeded,
+ Status: corev1.ConditionTrue,
+ }},
+ },
+ CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ // Results are parsed correctly.
+ Results: []v1beta1.CustomRunResult{{
+ Name: "foo",
+ Value: "bar",
+ }},
+ // Any extra fields are simply stored as JSON bytes.
+ ExtraFields: runtime.RawExtension{
+ Raw: []byte(`{"complex":{"hello":["w","o","r","l","d"]},"simple":"hello"}`),
+ },
+ },
+ },
+ }
+ if d := cmp.Diff(want, &r); d != "" {
+ t.Fatalf("Diff(-want,+got): %s", d)
+ }
+}
+
+func TestEncodeDecodeExtraFields(t *testing.T) {
+ type Mystatus struct {
+ S string
+ I int
+ }
+ status := Mystatus{S: "one", I: 1}
+ r := &v1beta1.CustomRunStatus{}
+ if err := r.EncodeExtraFields(&status); err != nil {
+ t.Fatalf("EncodeExtraFields failed: %s", err)
+ }
+ newStatus := Mystatus{}
+ if err := r.DecodeExtraFields(&newStatus); err != nil {
+ t.Fatalf("DecodeExtraFields failed: %s", err)
+ }
+ if d := cmp.Diff(status, newStatus); d != "" {
+ t.Fatalf("Diff(-want,+got): %s", d)
+ }
+}
+
+func TestRunGetTimeOut(t *testing.T) {
+ testCases := []struct {
+ name string
+ customRun v1beta1.CustomRun
+ expectedValue time.Duration
+ }{{
+ name: "runWithNoTimeout",
+ customRun: v1beta1.CustomRun{},
+ expectedValue: apisconfig.DefaultTimeoutMinutes * time.Minute,
+ }, {
+ name: "runWithTimeout",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Spec: v1beta1.CustomRunSpec{Timeout: &metav1.Duration{10 * time.Second}},
+ },
+ expectedValue: 10 * time.Second,
+ }}
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ result := tc.customRun.GetTimeout()
+ if d := cmp.Diff(result, tc.expectedValue); d != "" {
+ t.Fatalf(diff.PrintWantGot(d))
+ }
+ })
+ }
+}
+
+func TestRunHasTimedOut(t *testing.T) {
+ testCases := []struct {
+ name string
+ customRun v1beta1.CustomRun
+ expectedValue bool
+ }{{
+ name: "runWithNoStartTimeNoTimeout",
+ customRun: v1beta1.CustomRun{},
+ expectedValue: false,
+ }, {
+ name: "runWithStartTimeNoTimeout",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Status: v1beta1.CustomRunStatus{
+ CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{Time: now},
+ },
+ }},
+ expectedValue: false,
+ }, {
+ name: "runWithStartTimeNoTimeout2",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Status: v1beta1.CustomRunStatus{
+ CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{Time: now.Add(-1 * (apisconfig.DefaultTimeoutMinutes + 1) * time.Minute)},
+ },
+ }},
+ expectedValue: true,
+ }, {
+ name: "runWithStartTimeAndTimeout",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Spec: v1beta1.CustomRunSpec{Timeout: &metav1.Duration{10 * time.Second}},
+ Status: v1beta1.CustomRunStatus{CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{Time: now.Add(-1 * (apisconfig.DefaultTimeoutMinutes + 1) * time.Minute)},
+ }}},
+ expectedValue: true,
+ }, {
+ name: "runWithNoStartTimeAndTimeout",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Spec: v1beta1.CustomRunSpec{Timeout: &metav1.Duration{1 * time.Second}},
+ },
+ expectedValue: false,
+ }, {
+ name: "runWithStartTimeAndTimeout2",
+ customRun: v1beta1.CustomRun{
+ TypeMeta: metav1.TypeMeta{Kind: "kind", APIVersion: "apiVersion"},
+ Spec: v1beta1.CustomRunSpec{Timeout: &metav1.Duration{10 * time.Second}},
+ Status: v1beta1.CustomRunStatus{CustomRunStatusFields: v1beta1.CustomRunStatusFields{
+ StartTime: &metav1.Time{Time: now},
+ }}},
+ expectedValue: false,
+ }}
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ result := tc.customRun.HasTimedOut(testClock)
+ if d := cmp.Diff(result, tc.expectedValue); d != "" {
+ t.Fatalf(diff.PrintWantGot(d))
+ }
+ })
+ }
+}
diff --git a/pkg/apis/pipeline/v1beta1/customrun_validation.go b/pkg/apis/pipeline/v1beta1/customrun_validation.go
new file mode 100644
index 00000000000..51ede3d6ca7
--- /dev/null
+++ b/pkg/apis/pipeline/v1beta1/customrun_validation.go
@@ -0,0 +1,80 @@
+/*
+Copyright 2020 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 v1beta1
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/tektoncd/pipeline/pkg/apis/validate"
+ "k8s.io/apimachinery/pkg/api/equality"
+ "knative.dev/pkg/apis"
+)
+
+var _ apis.Validatable = (*CustomRun)(nil)
+
+// Validate customRun
+func (r *CustomRun) Validate(ctx context.Context) *apis.FieldError {
+ if err := validate.ObjectMetadata(r.GetObjectMeta()).ViaField("metadata"); err != nil {
+ return err
+ }
+ if apis.IsInDelete(ctx) {
+ return nil
+ }
+ return r.Spec.Validate(ctx)
+}
+
+// Validate CustomRun spec
+func (rs *CustomRunSpec) Validate(ctx context.Context) *apis.FieldError {
+ // this covers the case rs.customRef == nil && rs.customSpec == nil
+ if equality.Semantic.DeepEqual(rs, &CustomRunSpec{}) {
+ return apis.ErrMissingField("spec")
+ }
+
+ if rs.CustomRef != nil && rs.CustomSpec != nil {
+ return apis.ErrMultipleOneOf("spec.customRef", "spec.customSpec")
+ }
+ if rs.CustomRef == nil && rs.CustomSpec == nil {
+ return apis.ErrMissingOneOf("spec.customRef", "spec.customSpec")
+ }
+ if rs.CustomRef != nil {
+ if rs.CustomRef.APIVersion == "" {
+ return apis.ErrMissingField("spec.customRef.apiVersion")
+ }
+ if rs.CustomRef.Kind == "" {
+ return apis.ErrMissingField("spec.customRef.kind")
+ }
+ }
+ if rs.CustomSpec != nil {
+ if rs.CustomSpec.APIVersion == "" {
+ return apis.ErrMissingField("spec.customSpec.apiVersion")
+ }
+ if rs.CustomSpec.Kind == "" {
+ return apis.ErrMissingField("spec.customSpec.kind")
+ }
+ }
+ if rs.Status == "" {
+ if rs.StatusMessage != "" {
+ return apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", rs.StatusMessage), "statusMessage")
+ }
+ }
+ if err := ValidateParameters(ctx, rs.Params).ViaField("spec.params"); err != nil {
+ return err
+ }
+
+ return ValidateWorkspaceBindings(ctx, rs.Workspaces).ViaField("spec.workspaces")
+}
diff --git a/pkg/apis/pipeline/v1beta1/customrun_validation_test.go b/pkg/apis/pipeline/v1beta1/customrun_validation_test.go
new file mode 100644
index 00000000000..8e200879817
--- /dev/null
+++ b/pkg/apis/pipeline/v1beta1/customrun_validation_test.go
@@ -0,0 +1,357 @@
+/*
+Copyright 2020 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 v1beta1_test
+
+import (
+ "context"
+ "fmt"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ "github.com/tektoncd/pipeline/test/diff"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "knative.dev/pkg/apis"
+)
+
+func TestCustomRun_Invalid(t *testing.T) {
+ invalidStatusMessage := "test status message"
+ for _, c := range []struct {
+ name string
+ customRun *v1beta1.CustomRun
+ want *apis.FieldError
+ }{{
+ name: "missing spec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ },
+ want: apis.ErrMissingField("spec"),
+ }, {
+ name: "Empty spec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{},
+ },
+ want: apis.ErrMissingField("spec"),
+ }, {
+ name: "Both spec and ref missing",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: nil,
+ CustomSpec: nil,
+ ServiceAccountName: "test-sa",
+ },
+ },
+ want: apis.ErrMissingOneOf("spec.customRef", "spec.customSpec"),
+ }, {
+ name: "Both customRef and customSpec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "apiVersion",
+ Kind: "kind",
+ },
+ CustomSpec: &v1beta1.EmbeddedCustomRunSpec{
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: "apiVersion",
+ Kind: "kind",
+ },
+ },
+ },
+ },
+ want: apis.ErrMultipleOneOf("spec.customRef", "spec.customSpec"),
+ }, {
+ name: "missing apiVersion in customRef",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "",
+ },
+ },
+ },
+ want: apis.ErrMissingField("spec.customRef.apiVersion"),
+ }, {
+ name: "missing kind in customRef",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "",
+ },
+ },
+ },
+ want: apis.ErrMissingField("spec.customRef.kind"),
+ }, {
+ name: "missing apiVersion in customSpec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomSpec: &v1beta1.EmbeddedCustomRunSpec{
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: "",
+ },
+ },
+ },
+ },
+ want: apis.ErrMissingField("spec.customSpec.apiVersion"),
+ }, {
+ name: "missing kind in customSpec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomSpec: &v1beta1.EmbeddedCustomRunSpec{
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: "apiVersion",
+ Kind: "",
+ },
+ },
+ },
+ },
+ want: apis.ErrMissingField("spec.customSpec.kind"),
+ }, {
+ name: "invalid statusMessage in customSpec",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ StatusMessage: v1beta1.CustomRunSpecStatusMessage(invalidStatusMessage),
+ },
+ },
+ want: apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", invalidStatusMessage), "statusMessage"),
+ }, {
+ name: "non-unique params",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Params: []v1beta1.Param{{
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("foo"),
+ }, {
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("foo"),
+ }},
+ },
+ },
+ want: apis.ErrMultipleOneOf("spec.params[foo].name"),
+ }} {
+ t.Run(c.name, func(t *testing.T) {
+ err := c.customRun.Validate(context.Background())
+ if d := cmp.Diff(err.Error(), c.want.Error()); d != "" {
+ t.Error(diff.PrintWantGot(d))
+ }
+ })
+ }
+}
+
+func TestRun_Valid(t *testing.T) {
+ for _, c := range []struct {
+ name string
+ customRun *v1beta1.CustomRun
+ }{{
+ name: "no params",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ Name: "blah",
+ },
+ },
+ },
+ }, {
+ name: "unnamed",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ },
+ },
+ }, {
+ name: "unnamed_second",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Status: v1beta1.CustomRunSpecStatusCancelled,
+ StatusMessage: v1beta1.CustomRunSpecStatusMessage("test status vessage"),
+ },
+ },
+ }, {
+ name: "Spec with valid ApiVersion and Kind",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomSpec: &v1beta1.EmbeddedCustomRunSpec{
+ TypeMeta: runtime.TypeMeta{
+ APIVersion: "apiVersion",
+ Kind: "kind",
+ },
+ },
+ },
+ },
+ }, {
+ name: "unique params",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Params: []v1beta1.Param{{
+ Name: "foo",
+ Value: *v1beta1.NewStructuredValues("foo"),
+ }, {
+ Name: "bar",
+ Value: *v1beta1.NewStructuredValues("bar"),
+ }},
+ },
+ },
+ }, {
+ name: "valid workspace",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Workspaces: []v1beta1.WorkspaceBinding{{
+ Name: "workspace",
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
+ }},
+ },
+ },
+ }} {
+ t.Run(c.name, func(t *testing.T) {
+ if err := c.customRun.Validate(context.Background()); err != nil {
+ t.Fatalf("validating valid customRun: %v", err)
+ }
+ })
+ }
+}
+
+func TestRun_Workspaces_Invalid(t *testing.T) {
+ tests := []struct {
+ name string
+ customRun *v1beta1.CustomRun
+ wantErr *apis.FieldError
+ }{{
+ name: "make sure WorkspaceBinding validation invoked",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Workspaces: []v1beta1.WorkspaceBinding{{
+ Name: "workspace",
+ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
+ ClaimName: "",
+ },
+ }},
+ },
+ },
+ wantErr: apis.ErrMissingField("spec.workspaces[0].persistentvolumeclaim.claimname"),
+ }, {
+ name: "bind same workspace twice",
+ customRun: &v1beta1.CustomRun{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "temp",
+ },
+ Spec: v1beta1.CustomRunSpec{
+ CustomRef: &v1beta1.TaskRef{
+ APIVersion: "blah",
+ Kind: "blah",
+ },
+ Workspaces: []v1beta1.WorkspaceBinding{{
+ Name: "workspace",
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
+ }, {
+ Name: "workspace",
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
+ }},
+ },
+ },
+ wantErr: apis.ErrMultipleOneOf("spec.workspaces[1].name"),
+ }}
+ for _, ts := range tests {
+ t.Run(ts.name, func(t *testing.T) {
+ err := ts.customRun.Validate(context.Background())
+ if err == nil {
+ t.Errorf("Expected error for invalid customRun but got none")
+ } else if d := cmp.Diff(ts.wantErr.Error(), err.Error()); d != "" {
+ t.Errorf("Did not get expected error for %q: %s", ts.name, diff.PrintWantGot(d))
+ }
+ })
+ }
+}
diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go
index 0d9b519adb4..5f0c14759fd 100644
--- a/pkg/apis/pipeline/v1beta1/openapi_generated.go
+++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go
@@ -37,6 +37,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CloudEventDeliveryState": schema_pkg_apis_pipeline_v1beta1_CloudEventDeliveryState(ref),
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ClusterTask": schema_pkg_apis_pipeline_v1beta1_ClusterTask(ref),
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ClusterTaskList": schema_pkg_apis_pipeline_v1beta1_ClusterTaskList(ref),
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRun": schema_pkg_apis_pipeline_v1beta1_CustomRun(ref),
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRunList": schema_pkg_apis_pipeline_v1beta1_CustomRunList(ref),
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRunSpec": schema_pkg_apis_pipeline_v1beta1_CustomRunSpec(ref),
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.EmbeddedCustomRunSpec": schema_pkg_apis_pipeline_v1beta1_EmbeddedCustomRunSpec(ref),
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.EmbeddedTask": schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref),
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.InternalTaskModifier": schema_pkg_apis_pipeline_v1beta1_InternalTaskModifier(ref),
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param": schema_pkg_apis_pipeline_v1beta1_Param(ref),
@@ -607,6 +611,239 @@ func schema_pkg_apis_pipeline_v1beta1_ClusterTaskList(ref common.ReferenceCallba
}
}
+func schema_pkg_apis_pipeline_v1beta1_CustomRun(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "CustomRun represents a single execution of a Custom Task.",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "kind": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "apiVersion": {
+ SchemaProps: spec.SchemaProps{
+ Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "metadata": {
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
+ },
+ },
+ "spec": {
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRunSpec"),
+ },
+ },
+ "status": {
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/run/v1beta1.CustomRunStatus"),
+ },
+ },
+ },
+ },
+ },
+ Dependencies: []string{
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRunSpec", "github.com/tektoncd/pipeline/pkg/apis/run/v1beta1.CustomRunStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
+ }
+}
+
+func schema_pkg_apis_pipeline_v1beta1_CustomRunList(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "CustomRunList contains a list of CustomRun",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "kind": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "apiVersion": {
+ SchemaProps: spec.SchemaProps{
+ Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "metadata": {
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
+ },
+ },
+ "items": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRun"),
+ },
+ },
+ },
+ },
+ },
+ },
+ Required: []string{"items"},
+ },
+ },
+ Dependencies: []string{
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRun", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
+ }
+}
+
+func schema_pkg_apis_pipeline_v1beta1_CustomRunSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "CustomRunSpec defines the desired state of CustomRun",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "customRef": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRef"),
+ },
+ },
+ "customSpec": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Spec is a specification of a custom task",
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.EmbeddedCustomRunSpec"),
+ },
+ },
+ "params": {
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: spec.Extensions{
+ "x-kubernetes-list-type": "atomic",
+ },
+ },
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"),
+ },
+ },
+ },
+ },
+ },
+ "status": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Used for cancelling a customrun (and maybe more later on)",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "statusMessage": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Status message for cancellation.",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "retries": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Used for propagating retries count to custom tasks",
+ Type: []string{"integer"},
+ Format: "int32",
+ },
+ },
+ "serviceAccountName": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "timeout": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Time after which the custom-task times out. Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration",
+ Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"),
+ },
+ },
+ "workspaces": {
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: spec.Extensions{
+ "x-kubernetes-list-type": "atomic",
+ },
+ },
+ SchemaProps: spec.SchemaProps{
+ Description: "Workspaces is a list of WorkspaceBindings from volumes to workspaces.",
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Dependencies: []string{
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.EmbeddedCustomRunSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRef", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"},
+ }
+}
+
+func schema_pkg_apis_pipeline_v1beta1_EmbeddedCustomRunSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Description: "EmbeddedCustomRunSpec allows custom task definitions to be embedded",
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "apiVersion": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "kind": {
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "metadata": {
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskMetadata"),
+ },
+ },
+ "spec": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Spec is a specification of a custom task",
+ Default: map[string]interface{}{},
+ Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"),
+ },
+ },
+ },
+ },
+ },
+ Dependencies: []string{
+ "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskMetadata", "k8s.io/apimachinery/pkg/runtime.RawExtension"},
+ }
+}
+
func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json
index dc89ab213c8..4546ebaa0de 100644
--- a/pkg/apis/pipeline/v1beta1/swagger.json
+++ b/pkg/apis/pipeline/v1beta1/swagger.json
@@ -551,6 +551,132 @@
}
}
},
+ "v1beta1.CustomRun": {
+ "description": "CustomRun represents a single execution of a Custom Task.",
+ "type": "object",
+ "properties": {
+ "apiVersion": {
+ "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+ "type": "string"
+ },
+ "kind": {
+ "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "type": "string"
+ },
+ "metadata": {
+ "default": {},
+ "$ref": "#/definitions/v1.ObjectMeta"
+ },
+ "spec": {
+ "default": {},
+ "$ref": "#/definitions/v1beta1.CustomRunSpec"
+ },
+ "status": {
+ "default": {},
+ "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.run.v1beta1.CustomRunStatus"
+ }
+ }
+ },
+ "v1beta1.CustomRunList": {
+ "description": "CustomRunList contains a list of CustomRun",
+ "type": "object",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "apiVersion": {
+ "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+ "type": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "default": {},
+ "$ref": "#/definitions/v1beta1.CustomRun"
+ }
+ },
+ "kind": {
+ "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "type": "string"
+ },
+ "metadata": {
+ "default": {},
+ "$ref": "#/definitions/v1.ListMeta"
+ }
+ }
+ },
+ "v1beta1.CustomRunSpec": {
+ "description": "CustomRunSpec defines the desired state of CustomRun",
+ "type": "object",
+ "properties": {
+ "customRef": {
+ "$ref": "#/definitions/v1beta1.TaskRef"
+ },
+ "customSpec": {
+ "description": "Spec is a specification of a custom task",
+ "$ref": "#/definitions/v1beta1.EmbeddedCustomRunSpec"
+ },
+ "params": {
+ "type": "array",
+ "items": {
+ "default": {},
+ "$ref": "#/definitions/v1beta1.Param"
+ },
+ "x-kubernetes-list-type": "atomic"
+ },
+ "retries": {
+ "description": "Used for propagating retries count to custom tasks",
+ "type": "integer",
+ "format": "int32"
+ },
+ "serviceAccountName": {
+ "type": "string",
+ "default": ""
+ },
+ "status": {
+ "description": "Used for cancelling a customrun (and maybe more later on)",
+ "type": "string"
+ },
+ "statusMessage": {
+ "description": "Status message for cancellation.",
+ "type": "string"
+ },
+ "timeout": {
+ "description": "Time after which the custom-task times out. Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration",
+ "$ref": "#/definitions/v1.Duration"
+ },
+ "workspaces": {
+ "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.",
+ "type": "array",
+ "items": {
+ "default": {},
+ "$ref": "#/definitions/v1beta1.WorkspaceBinding"
+ },
+ "x-kubernetes-list-type": "atomic"
+ }
+ }
+ },
+ "v1beta1.EmbeddedCustomRunSpec": {
+ "description": "EmbeddedCustomRunSpec allows custom task definitions to be embedded",
+ "type": "object",
+ "properties": {
+ "apiVersion": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "metadata": {
+ "default": {},
+ "$ref": "#/definitions/v1beta1.PipelineTaskMetadata"
+ },
+ "spec": {
+ "description": "Spec is a specification of a custom task",
+ "default": {},
+ "$ref": "#/definitions/k8s.io.apimachinery.pkg.runtime.RawExtension"
+ }
+ }
+ },
"v1beta1.EmbeddedTask": {
"description": "EmbeddedTask is used to define a Task inline within a Pipeline's PipelineTasks.",
"type": "object",
diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go
index 38535abe30e..bcb361cc69e 100644
--- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go
+++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go
@@ -25,8 +25,8 @@ import (
pod "github.com/tektoncd/pipeline/pkg/apis/pipeline/pod"
v1alpha1 "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1"
runv1alpha1 "github.com/tektoncd/pipeline/pkg/apis/run/v1alpha1"
- v1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ corev1 "k8s.io/api/core/v1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -151,6 +151,131 @@ func (in *ClusterTaskList) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomRun) DeepCopyInto(out *CustomRun) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomRun.
+func (in *CustomRun) DeepCopy() *CustomRun {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomRun)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *CustomRun) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomRunList) DeepCopyInto(out *CustomRunList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]CustomRun, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomRunList.
+func (in *CustomRunList) DeepCopy() *CustomRunList {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomRunList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *CustomRunList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomRunSpec) DeepCopyInto(out *CustomRunSpec) {
+ *out = *in
+ if in.CustomRef != nil {
+ in, out := &in.CustomRef, &out.CustomRef
+ *out = new(TaskRef)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.CustomSpec != nil {
+ in, out := &in.CustomSpec, &out.CustomSpec
+ *out = new(EmbeddedCustomRunSpec)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Params != nil {
+ in, out := &in.Params, &out.Params
+ *out = make([]Param, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.Timeout != nil {
+ in, out := &in.Timeout, &out.Timeout
+ *out = new(v1.Duration)
+ **out = **in
+ }
+ if in.Workspaces != nil {
+ in, out := &in.Workspaces, &out.Workspaces
+ *out = make([]WorkspaceBinding, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomRunSpec.
+func (in *CustomRunSpec) DeepCopy() *CustomRunSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomRunSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EmbeddedCustomRunSpec) DeepCopyInto(out *EmbeddedCustomRunSpec) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.Metadata.DeepCopyInto(&out.Metadata)
+ in.Spec.DeepCopyInto(&out.Spec)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmbeddedCustomRunSpec.
+func (in *EmbeddedCustomRunSpec) DeepCopy() *EmbeddedCustomRunSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(EmbeddedCustomRunSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EmbeddedTask) DeepCopyInto(out *EmbeddedTask) {
*out = *in
@@ -190,7 +315,7 @@ func (in *InternalTaskModifier) DeepCopyInto(out *InternalTaskModifier) {
}
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
- *out = make([]v1.Volume, len(*in))
+ *out = make([]corev1.Volume, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -589,7 +714,7 @@ func (in *PipelineRunSpec) DeepCopyInto(out *PipelineRunSpec) {
}
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.PodTemplate != nil {
@@ -859,7 +984,7 @@ func (in *PipelineTask) DeepCopyInto(out *PipelineTask) {
}
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
return
@@ -1053,7 +1178,7 @@ func (in *PipelineTaskRunSpec) DeepCopyInto(out *PipelineTaskRunSpec) {
}
if in.ComputeResources != nil {
in, out := &in.ComputeResources, &out.ComputeResources
- *out = new(v1.ResourceRequirements)
+ *out = new(corev1.ResourceRequirements)
(*in).DeepCopyInto(*out)
}
return
@@ -1155,19 +1280,19 @@ func (in *Sidecar) DeepCopyInto(out *Sidecar) {
}
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
- *out = make([]v1.ContainerPort, len(*in))
+ *out = make([]corev1.ContainerPort, len(*in))
copy(*out, *in)
}
if in.EnvFrom != nil {
in, out := &in.EnvFrom, &out.EnvFrom
- *out = make([]v1.EnvFromSource, len(*in))
+ *out = make([]corev1.EnvFromSource, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]v1.EnvVar, len(*in))
+ *out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1175,39 +1300,39 @@ func (in *Sidecar) DeepCopyInto(out *Sidecar) {
in.Resources.DeepCopyInto(&out.Resources)
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
- *out = make([]v1.VolumeMount, len(*in))
+ *out = make([]corev1.VolumeMount, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.VolumeDevices != nil {
in, out := &in.VolumeDevices, &out.VolumeDevices
- *out = make([]v1.VolumeDevice, len(*in))
+ *out = make([]corev1.VolumeDevice, len(*in))
copy(*out, *in)
}
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.StartupProbe != nil {
in, out := &in.StartupProbe, &out.StartupProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.Lifecycle != nil {
in, out := &in.Lifecycle, &out.Lifecycle
- *out = new(v1.Lifecycle)
+ *out = new(corev1.Lifecycle)
(*in).DeepCopyInto(*out)
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
- *out = new(v1.SecurityContext)
+ *out = new(corev1.SecurityContext)
(*in).DeepCopyInto(*out)
}
if in.Workspaces != nil {
@@ -1283,19 +1408,19 @@ func (in *Step) DeepCopyInto(out *Step) {
}
if in.DeprecatedPorts != nil {
in, out := &in.DeprecatedPorts, &out.DeprecatedPorts
- *out = make([]v1.ContainerPort, len(*in))
+ *out = make([]corev1.ContainerPort, len(*in))
copy(*out, *in)
}
if in.EnvFrom != nil {
in, out := &in.EnvFrom, &out.EnvFrom
- *out = make([]v1.EnvFromSource, len(*in))
+ *out = make([]corev1.EnvFromSource, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]v1.EnvVar, len(*in))
+ *out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1303,44 +1428,44 @@ func (in *Step) DeepCopyInto(out *Step) {
in.Resources.DeepCopyInto(&out.Resources)
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
- *out = make([]v1.VolumeMount, len(*in))
+ *out = make([]corev1.VolumeMount, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.VolumeDevices != nil {
in, out := &in.VolumeDevices, &out.VolumeDevices
- *out = make([]v1.VolumeDevice, len(*in))
+ *out = make([]corev1.VolumeDevice, len(*in))
copy(*out, *in)
}
if in.DeprecatedLivenessProbe != nil {
in, out := &in.DeprecatedLivenessProbe, &out.DeprecatedLivenessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedReadinessProbe != nil {
in, out := &in.DeprecatedReadinessProbe, &out.DeprecatedReadinessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedStartupProbe != nil {
in, out := &in.DeprecatedStartupProbe, &out.DeprecatedStartupProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedLifecycle != nil {
in, out := &in.DeprecatedLifecycle, &out.DeprecatedLifecycle
- *out = new(v1.Lifecycle)
+ *out = new(corev1.Lifecycle)
(*in).DeepCopyInto(*out)
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
- *out = new(v1.SecurityContext)
+ *out = new(corev1.SecurityContext)
(*in).DeepCopyInto(*out)
}
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Workspaces != nil {
@@ -1419,19 +1544,19 @@ func (in *StepTemplate) DeepCopyInto(out *StepTemplate) {
}
if in.DeprecatedPorts != nil {
in, out := &in.DeprecatedPorts, &out.DeprecatedPorts
- *out = make([]v1.ContainerPort, len(*in))
+ *out = make([]corev1.ContainerPort, len(*in))
copy(*out, *in)
}
if in.EnvFrom != nil {
in, out := &in.EnvFrom, &out.EnvFrom
- *out = make([]v1.EnvFromSource, len(*in))
+ *out = make([]corev1.EnvFromSource, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]v1.EnvVar, len(*in))
+ *out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1439,39 +1564,39 @@ func (in *StepTemplate) DeepCopyInto(out *StepTemplate) {
in.Resources.DeepCopyInto(&out.Resources)
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
- *out = make([]v1.VolumeMount, len(*in))
+ *out = make([]corev1.VolumeMount, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.VolumeDevices != nil {
in, out := &in.VolumeDevices, &out.VolumeDevices
- *out = make([]v1.VolumeDevice, len(*in))
+ *out = make([]corev1.VolumeDevice, len(*in))
copy(*out, *in)
}
if in.DeprecatedLivenessProbe != nil {
in, out := &in.DeprecatedLivenessProbe, &out.DeprecatedLivenessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedReadinessProbe != nil {
in, out := &in.DeprecatedReadinessProbe, &out.DeprecatedReadinessProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedStartupProbe != nil {
in, out := &in.DeprecatedStartupProbe, &out.DeprecatedStartupProbe
- *out = new(v1.Probe)
+ *out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.DeprecatedLifecycle != nil {
in, out := &in.DeprecatedLifecycle, &out.DeprecatedLifecycle
- *out = new(v1.Lifecycle)
+ *out = new(corev1.Lifecycle)
(*in).DeepCopyInto(*out)
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
- *out = new(v1.SecurityContext)
+ *out = new(corev1.SecurityContext)
(*in).DeepCopyInto(*out)
}
return
@@ -1883,7 +2008,7 @@ func (in *TaskRunSpec) DeepCopyInto(out *TaskRunSpec) {
}
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.PodTemplate != nil {
@@ -1914,7 +2039,7 @@ func (in *TaskRunSpec) DeepCopyInto(out *TaskRunSpec) {
}
if in.ComputeResources != nil {
in, out := &in.ComputeResources, &out.ComputeResources
- *out = new(v1.ResourceRequirements)
+ *out = new(corev1.ResourceRequirements)
(*in).DeepCopyInto(*out)
}
return
@@ -2058,7 +2183,7 @@ func (in *TaskSpec) DeepCopyInto(out *TaskSpec) {
}
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
- *out = make([]v1.Volume, len(*in))
+ *out = make([]corev1.Volume, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -2105,17 +2230,17 @@ func (in *TimeoutFields) DeepCopyInto(out *TimeoutFields) {
*out = *in
if in.Pipeline != nil {
in, out := &in.Pipeline, &out.Pipeline
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Tasks != nil {
in, out := &in.Tasks, &out.Tasks
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Finally != nil {
in, out := &in.Finally, &out.Finally
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
return
@@ -2179,37 +2304,37 @@ func (in *WorkspaceBinding) DeepCopyInto(out *WorkspaceBinding) {
*out = *in
if in.VolumeClaimTemplate != nil {
in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate
- *out = new(v1.PersistentVolumeClaim)
+ *out = new(corev1.PersistentVolumeClaim)
(*in).DeepCopyInto(*out)
}
if in.PersistentVolumeClaim != nil {
in, out := &in.PersistentVolumeClaim, &out.PersistentVolumeClaim
- *out = new(v1.PersistentVolumeClaimVolumeSource)
+ *out = new(corev1.PersistentVolumeClaimVolumeSource)
**out = **in
}
if in.EmptyDir != nil {
in, out := &in.EmptyDir, &out.EmptyDir
- *out = new(v1.EmptyDirVolumeSource)
+ *out = new(corev1.EmptyDirVolumeSource)
(*in).DeepCopyInto(*out)
}
if in.ConfigMap != nil {
in, out := &in.ConfigMap, &out.ConfigMap
- *out = new(v1.ConfigMapVolumeSource)
+ *out = new(corev1.ConfigMapVolumeSource)
(*in).DeepCopyInto(*out)
}
if in.Secret != nil {
in, out := &in.Secret, &out.Secret
- *out = new(v1.SecretVolumeSource)
+ *out = new(corev1.SecretVolumeSource)
(*in).DeepCopyInto(*out)
}
if in.Projected != nil {
in, out := &in.Projected, &out.Projected
- *out = new(v1.ProjectedVolumeSource)
+ *out = new(corev1.ProjectedVolumeSource)
(*in).DeepCopyInto(*out)
}
if in.CSI != nil {
in, out := &in.CSI, &out.CSI
- *out = new(v1.CSIVolumeSource)
+ *out = new(corev1.CSIVolumeSource)
(*in).DeepCopyInto(*out)
}
return
diff --git a/pkg/apis/run/v1beta1/customrunstatus_types.go b/pkg/apis/run/v1beta1/customrunstatus_types.go
new file mode 100644
index 00000000000..16eee8746f2
--- /dev/null
+++ b/pkg/apis/run/v1beta1/customrunstatus_types.go
@@ -0,0 +1,147 @@
+/*
+Copyright 2020 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 v1beta1
+
+import (
+ "encoding/json"
+ "time"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "knative.dev/pkg/apis"
+ duckv1 "knative.dev/pkg/apis/duck/v1"
+)
+
+// This package contains common definitions needed by v1beta1.CustomRun and v1beta1.PipelineRun.
+
+// +k8s:deepcopy-gen=true
+
+// CustomRunStatus defines the observed state of CustomRun
+type CustomRunStatus struct {
+ duckv1.Status `json:",inline"`
+
+ // CustomRunStatusFields inlines the status fields.
+ CustomRunStatusFields `json:",inline"`
+}
+
+// +k8s:deepcopy-gen=true
+
+// CustomRunStatusFields holds the fields of CustomRun's status. This is defined
+// separately and inlined so that other types can readily consume these fields
+// via duck typing.
+type CustomRunStatusFields struct {
+ // StartTime is the time the build is actually started.
+ // +optional
+ StartTime *metav1.Time `json:"startTime,omitempty"`
+
+ // CompletionTime is the time the build completed.
+ // +optional
+ CompletionTime *metav1.Time `json:"completionTime,omitempty"`
+
+ // Results reports any output result values to be consumed by later
+ // tasks in a pipeline.
+ // +optional
+ Results []CustomRunResult `json:"results,omitempty"`
+
+ // RetriesStatus contains the history of CustomRunStatus, in case of a retry.
+ // +optional
+ RetriesStatus []CustomRunStatus `json:"retriesStatus,omitempty"`
+
+ // ExtraFields holds arbitrary fields provided by the custom task
+ // controller.
+ ExtraFields runtime.RawExtension `json:"extraFields,omitempty"`
+}
+
+// CustomRunResult used to describe the results of a task
+type CustomRunResult struct {
+ // Name the given name
+ Name string `json:"name"`
+ // Value the given value of the result
+ Value string `json:"value"`
+}
+
+var customRunCondSet = apis.NewBatchConditionSet()
+
+// GetCondition returns the Condition matching the given type.
+func (r *CustomRunStatus) GetCondition(t apis.ConditionType) *apis.Condition {
+ return customRunCondSet.Manage(r).GetCondition(t)
+}
+
+// InitializeConditions will set all conditions in customRunCondSet to unknown for the PipelineRun
+// and set the started time to the current time
+func (r *CustomRunStatus) InitializeConditions() {
+ started := false
+ if r.StartTime.IsZero() {
+ r.StartTime = &metav1.Time{Time: time.Now()}
+ started = true
+ }
+ conditionManager := customRunCondSet.Manage(r)
+ conditionManager.InitializeConditions()
+ // Ensure the started reason is set for the "Succeeded" condition
+ if started {
+ initialCondition := conditionManager.GetCondition(apis.ConditionSucceeded)
+ initialCondition.Reason = "Started"
+ conditionManager.SetCondition(*initialCondition)
+ }
+}
+
+// SetCondition sets the condition, unsetting previous conditions with the same
+// type as necessary.
+func (r *CustomRunStatus) SetCondition(newCond *apis.Condition) {
+ if newCond != nil {
+ customRunCondSet.Manage(r).SetCondition(*newCond)
+ }
+}
+
+// MarkCustomRunSucceeded changes the Succeeded condition to True with the provided reason and message.
+func (r *CustomRunStatus) MarkCustomRunSucceeded(reason, messageFormat string, messageA ...interface{}) {
+ customRunCondSet.Manage(r).MarkTrueWithReason(apis.ConditionSucceeded, reason, messageFormat, messageA...)
+ succeeded := r.GetCondition(apis.ConditionSucceeded)
+ r.CompletionTime = &succeeded.LastTransitionTime.Inner
+}
+
+// MarkCustomRunFailed changes the Succeeded condition to False with the provided reason and message.
+func (r *CustomRunStatus) MarkCustomRunFailed(reason, messageFormat string, messageA ...interface{}) {
+ customRunCondSet.Manage(r).MarkFalse(apis.ConditionSucceeded, reason, messageFormat, messageA...)
+ succeeded := r.GetCondition(apis.ConditionSucceeded)
+ r.CompletionTime = &succeeded.LastTransitionTime.Inner
+}
+
+// MarkCustomRunRunning changes the Succeeded condition to Unknown with the provided reason and message.
+func (r *CustomRunStatus) MarkCustomRunRunning(reason, messageFormat string, messageA ...interface{}) {
+ customRunCondSet.Manage(r).MarkUnknown(apis.ConditionSucceeded, reason, messageFormat, messageA...)
+}
+
+// DecodeExtraFields deserializes the extra fields in the CustomRun status.
+func (r *CustomRunStatus) DecodeExtraFields(into interface{}) error {
+ if len(r.ExtraFields.Raw) == 0 {
+ return nil
+ }
+ return json.Unmarshal(r.ExtraFields.Raw, into)
+}
+
+// EncodeExtraFields serializes the extra fields in the CustomRun status.
+func (r *CustomRunStatus) EncodeExtraFields(from interface{}) error {
+ data, err := json.Marshal(from)
+ if err != nil {
+ return err
+ }
+ r.ExtraFields = runtime.RawExtension{
+ Raw: data,
+ }
+ return nil
+}
diff --git a/pkg/apis/run/v1beta1/doc.go b/pkg/apis/run/v1beta1/doc.go
new file mode 100644
index 00000000000..1308f5f0e96
--- /dev/null
+++ b/pkg/apis/run/v1beta1/doc.go
@@ -0,0 +1,19 @@
+/*
+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 v1beta1 contains API Schema definitions for the customrun v1beta1 API group
+// +groupName=tekton.dev
+package v1beta1
diff --git a/pkg/apis/run/v1beta1/zz_generated.deepcopy.go b/pkg/apis/run/v1beta1/zz_generated.deepcopy.go
new file mode 100644
index 00000000000..12465a6cb9f
--- /dev/null
+++ b/pkg/apis/run/v1beta1/zz_generated.deepcopy.go
@@ -0,0 +1,77 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by deepcopy-gen. DO NOT EDIT.
+
+package v1beta1
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomRunStatus) DeepCopyInto(out *CustomRunStatus) {
+ *out = *in
+ in.Status.DeepCopyInto(&out.Status)
+ in.CustomRunStatusFields.DeepCopyInto(&out.CustomRunStatusFields)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomRunStatus.
+func (in *CustomRunStatus) DeepCopy() *CustomRunStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomRunStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomRunStatusFields) DeepCopyInto(out *CustomRunStatusFields) {
+ *out = *in
+ if in.StartTime != nil {
+ in, out := &in.StartTime, &out.StartTime
+ *out = (*in).DeepCopy()
+ }
+ if in.CompletionTime != nil {
+ in, out := &in.CompletionTime, &out.CompletionTime
+ *out = (*in).DeepCopy()
+ }
+ if in.Results != nil {
+ in, out := &in.Results, &out.Results
+ *out = make([]CustomRunResult, len(*in))
+ copy(*out, *in)
+ }
+ if in.RetriesStatus != nil {
+ in, out := &in.RetriesStatus, &out.RetriesStatus
+ *out = make([]CustomRunStatus, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ in.ExtraFields.DeepCopyInto(&out.ExtraFields)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunStatusFields.
+func (in *CustomRunStatusFields) DeepCopy() *CustomRunStatusFields {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomRunStatusFields)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/customrun.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/customrun.go
new file mode 100644
index 00000000000..a5755045bde
--- /dev/null
+++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/customrun.go
@@ -0,0 +1,195 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ "context"
+ "time"
+
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ scheme "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/scheme"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ rest "k8s.io/client-go/rest"
+)
+
+// CustomRunsGetter has a method to return a CustomRunInterface.
+// A group's client should implement this interface.
+type CustomRunsGetter interface {
+ CustomRuns(namespace string) CustomRunInterface
+}
+
+// CustomRunInterface has methods to work with CustomRun resources.
+type CustomRunInterface interface {
+ Create(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.CreateOptions) (*v1beta1.CustomRun, error)
+ Update(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (*v1beta1.CustomRun, error)
+ UpdateStatus(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (*v1beta1.CustomRun, error)
+ Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
+ DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
+ Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.CustomRun, error)
+ List(ctx context.Context, opts v1.ListOptions) (*v1beta1.CustomRunList, error)
+ Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
+ Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomRun, err error)
+ CustomRunExpansion
+}
+
+// customRuns implements CustomRunInterface
+type customRuns struct {
+ client rest.Interface
+ ns string
+}
+
+// newCustomRuns returns a CustomRuns
+func newCustomRuns(c *TektonV1beta1Client, namespace string) *customRuns {
+ return &customRuns{
+ client: c.RESTClient(),
+ ns: namespace,
+ }
+}
+
+// Get takes name of the customRun, and returns the corresponding customRun object, and an error if there is any.
+func (c *customRuns) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CustomRun, err error) {
+ result = &v1beta1.CustomRun{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("customruns").
+ Name(name).
+ VersionedParams(&options, scheme.ParameterCodec).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// List takes label and field selectors, and returns the list of CustomRuns that match those selectors.
+func (c *customRuns) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CustomRunList, err error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ result = &v1beta1.CustomRunList{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("customruns").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Watch returns a watch.Interface that watches the requested customRuns.
+func (c *customRuns) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ opts.Watch = true
+ return c.client.Get().
+ Namespace(c.ns).
+ Resource("customruns").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Watch(ctx)
+}
+
+// Create takes the representation of a customRun and creates it. Returns the server's representation of the customRun, and an error, if there is any.
+func (c *customRuns) Create(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.CreateOptions) (result *v1beta1.CustomRun, err error) {
+ result = &v1beta1.CustomRun{}
+ err = c.client.Post().
+ Namespace(c.ns).
+ Resource("customruns").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(customRun).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Update takes the representation of a customRun and updates it. Returns the server's representation of the customRun, and an error, if there is any.
+func (c *customRuns) Update(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (result *v1beta1.CustomRun, err error) {
+ result = &v1beta1.CustomRun{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("customruns").
+ Name(customRun.Name).
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(customRun).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *customRuns) UpdateStatus(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (result *v1beta1.CustomRun, err error) {
+ result = &v1beta1.CustomRun{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("customruns").
+ Name(customRun.Name).
+ SubResource("status").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(customRun).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Delete takes name of the customRun and deletes it. Returns an error if one occurs.
+func (c *customRuns) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("customruns").
+ Name(name).
+ Body(&opts).
+ Do(ctx).
+ Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *customRuns) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
+ var timeout time.Duration
+ if listOpts.TimeoutSeconds != nil {
+ timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
+ }
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("customruns").
+ VersionedParams(&listOpts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Body(&opts).
+ Do(ctx).
+ Error()
+}
+
+// Patch applies the patch and returns the patched customRun.
+func (c *customRuns) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomRun, err error) {
+ result = &v1beta1.CustomRun{}
+ err = c.client.Patch(pt).
+ Namespace(c.ns).
+ Resource("customruns").
+ Name(name).
+ SubResource(subresources...).
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(data).
+ Do(ctx).
+ Into(result)
+ return
+}
diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_customrun.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_customrun.go
new file mode 100644
index 00000000000..f80f4a1785e
--- /dev/null
+++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_customrun.go
@@ -0,0 +1,142 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ "context"
+
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ testing "k8s.io/client-go/testing"
+)
+
+// FakeCustomRuns implements CustomRunInterface
+type FakeCustomRuns struct {
+ Fake *FakeTektonV1beta1
+ ns string
+}
+
+var customrunsResource = schema.GroupVersionResource{Group: "tekton.dev", Version: "v1beta1", Resource: "customruns"}
+
+var customrunsKind = schema.GroupVersionKind{Group: "tekton.dev", Version: "v1beta1", Kind: "CustomRun"}
+
+// Get takes name of the customRun, and returns the corresponding customRun object, and an error if there is any.
+func (c *FakeCustomRuns) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CustomRun, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewGetAction(customrunsResource, c.ns, name), &v1beta1.CustomRun{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1beta1.CustomRun), err
+}
+
+// List takes label and field selectors, and returns the list of CustomRuns that match those selectors.
+func (c *FakeCustomRuns) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CustomRunList, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewListAction(customrunsResource, customrunsKind, c.ns, opts), &v1beta1.CustomRunList{})
+
+ if obj == nil {
+ return nil, err
+ }
+
+ label, _, _ := testing.ExtractFromListOptions(opts)
+ if label == nil {
+ label = labels.Everything()
+ }
+ list := &v1beta1.CustomRunList{ListMeta: obj.(*v1beta1.CustomRunList).ListMeta}
+ for _, item := range obj.(*v1beta1.CustomRunList).Items {
+ if label.Matches(labels.Set(item.Labels)) {
+ list.Items = append(list.Items, item)
+ }
+ }
+ return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested customRuns.
+func (c *FakeCustomRuns) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
+ return c.Fake.
+ InvokesWatch(testing.NewWatchAction(customrunsResource, c.ns, opts))
+
+}
+
+// Create takes the representation of a customRun and creates it. Returns the server's representation of the customRun, and an error, if there is any.
+func (c *FakeCustomRuns) Create(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.CreateOptions) (result *v1beta1.CustomRun, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewCreateAction(customrunsResource, c.ns, customRun), &v1beta1.CustomRun{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1beta1.CustomRun), err
+}
+
+// Update takes the representation of a customRun and updates it. Returns the server's representation of the customRun, and an error, if there is any.
+func (c *FakeCustomRuns) Update(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (result *v1beta1.CustomRun, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateAction(customrunsResource, c.ns, customRun), &v1beta1.CustomRun{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1beta1.CustomRun), err
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *FakeCustomRuns) UpdateStatus(ctx context.Context, customRun *v1beta1.CustomRun, opts v1.UpdateOptions) (*v1beta1.CustomRun, error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateSubresourceAction(customrunsResource, "status", c.ns, customRun), &v1beta1.CustomRun{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1beta1.CustomRun), err
+}
+
+// Delete takes name of the customRun and deletes it. Returns an error if one occurs.
+func (c *FakeCustomRuns) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
+ _, err := c.Fake.
+ Invokes(testing.NewDeleteActionWithOptions(customrunsResource, c.ns, name, opts), &v1beta1.CustomRun{})
+
+ return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeCustomRuns) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
+ action := testing.NewDeleteCollectionAction(customrunsResource, c.ns, listOpts)
+
+ _, err := c.Fake.Invokes(action, &v1beta1.CustomRunList{})
+ return err
+}
+
+// Patch applies the patch and returns the patched customRun.
+func (c *FakeCustomRuns) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomRun, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewPatchSubresourceAction(customrunsResource, c.ns, name, pt, data, subresources...), &v1beta1.CustomRun{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1beta1.CustomRun), err
+}
diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go
index 55c4c40d3f0..a142026b2ba 100644
--- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go
+++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go
@@ -32,6 +32,10 @@ func (c *FakeTektonV1beta1) ClusterTasks() v1beta1.ClusterTaskInterface {
return &FakeClusterTasks{c}
}
+func (c *FakeTektonV1beta1) CustomRuns(namespace string) v1beta1.CustomRunInterface {
+ return &FakeCustomRuns{c, namespace}
+}
+
func (c *FakeTektonV1beta1) Pipelines(namespace string) v1beta1.PipelineInterface {
return &FakePipelines{c, namespace}
}
diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go
index 83951f9851f..b9f3554be3e 100644
--- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go
+++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go
@@ -20,6 +20,8 @@ package v1beta1
type ClusterTaskExpansion interface{}
+type CustomRunExpansion interface{}
+
type PipelineExpansion interface{}
type PipelineRunExpansion interface{}
diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go
index bec6312585d..0974d31771a 100644
--- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go
+++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go
@@ -29,6 +29,7 @@ import (
type TektonV1beta1Interface interface {
RESTClient() rest.Interface
ClusterTasksGetter
+ CustomRunsGetter
PipelinesGetter
PipelineRunsGetter
TasksGetter
@@ -44,6 +45,10 @@ func (c *TektonV1beta1Client) ClusterTasks() ClusterTaskInterface {
return newClusterTasks(c)
}
+func (c *TektonV1beta1Client) CustomRuns(namespace string) CustomRunInterface {
+ return newCustomRuns(c, namespace)
+}
+
func (c *TektonV1beta1Client) Pipelines(namespace string) PipelineInterface {
return newPipelines(c, namespace)
}
diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go
index ee587d9440d..3f3c58d271c 100644
--- a/pkg/client/informers/externalversions/generic.go
+++ b/pkg/client/informers/externalversions/generic.go
@@ -71,6 +71,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
// Group=tekton.dev, Version=v1beta1
case v1beta1.SchemeGroupVersion.WithResource("clustertasks"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().ClusterTasks().Informer()}, nil
+ case v1beta1.SchemeGroupVersion.WithResource("customruns"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().CustomRuns().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("pipelines"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().Pipelines().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("pipelineruns"):
diff --git a/pkg/client/informers/externalversions/pipeline/v1beta1/customrun.go b/pkg/client/informers/externalversions/pipeline/v1beta1/customrun.go
new file mode 100644
index 00000000000..532a61c8b61
--- /dev/null
+++ b/pkg/client/informers/externalversions/pipeline/v1beta1/customrun.go
@@ -0,0 +1,90 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ "context"
+ time "time"
+
+ pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
+ internalinterfaces "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/internalinterfaces"
+ v1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// CustomRunInformer provides access to a shared informer and lister for
+// CustomRuns.
+type CustomRunInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1beta1.CustomRunLister
+}
+
+type customRunInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+ namespace string
+}
+
+// NewCustomRunInformer constructs a new informer for CustomRun type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewCustomRunInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredCustomRunInformer(client, namespace, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredCustomRunInformer constructs a new informer for CustomRun type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredCustomRunInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.TektonV1beta1().CustomRuns(namespace).List(context.TODO(), options)
+ },
+ WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.TektonV1beta1().CustomRuns(namespace).Watch(context.TODO(), options)
+ },
+ },
+ &pipelinev1beta1.CustomRun{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func (f *customRunInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredCustomRunInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *customRunInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&pipelinev1beta1.CustomRun{}, f.defaultInformer)
+}
+
+func (f *customRunInformer) Lister() v1beta1.CustomRunLister {
+ return v1beta1.NewCustomRunLister(f.Informer().GetIndexer())
+}
diff --git a/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go b/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go
index 37b4f5364c7..307843a8014 100644
--- a/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go
+++ b/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go
@@ -26,6 +26,8 @@ import (
type Interface interface {
// ClusterTasks returns a ClusterTaskInformer.
ClusterTasks() ClusterTaskInformer
+ // CustomRuns returns a CustomRunInformer.
+ CustomRuns() CustomRunInformer
// Pipelines returns a PipelineInformer.
Pipelines() PipelineInformer
// PipelineRuns returns a PipelineRunInformer.
@@ -52,6 +54,11 @@ func (v *version) ClusterTasks() ClusterTaskInformer {
return &clusterTaskInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}
+// CustomRuns returns a CustomRunInformer.
+func (v *version) CustomRuns() CustomRunInformer {
+ return &customRunInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
+
// Pipelines returns a PipelineInformer.
func (v *version) Pipelines() PipelineInformer {
return &pipelineInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
diff --git a/pkg/client/injection/client/client.go b/pkg/client/injection/client/client.go
index ec93708a498..3104910cf66 100644
--- a/pkg/client/injection/client/client.go
+++ b/pkg/client/injection/client/client.go
@@ -388,6 +388,137 @@ func (w *wrapTektonV1beta1ClusterTaskImpl) Watch(ctx context.Context, opts v1.Li
return nil, errors.New("NYI: Watch")
}
+func (w *wrapTektonV1beta1) CustomRuns(namespace string) typedtektonv1beta1.CustomRunInterface {
+ return &wrapTektonV1beta1CustomRunImpl{
+ dyn: w.dyn.Resource(schema.GroupVersionResource{
+ Group: "tekton.dev",
+ Version: "v1beta1",
+ Resource: "customruns",
+ }),
+
+ namespace: namespace,
+ }
+}
+
+type wrapTektonV1beta1CustomRunImpl struct {
+ dyn dynamic.NamespaceableResourceInterface
+
+ namespace string
+}
+
+var _ typedtektonv1beta1.CustomRunInterface = (*wrapTektonV1beta1CustomRunImpl)(nil)
+
+func (w *wrapTektonV1beta1CustomRunImpl) Create(ctx context.Context, in *v1beta1.CustomRun, opts v1.CreateOptions) (*v1beta1.CustomRun, error) {
+ in.SetGroupVersionKind(schema.GroupVersionKind{
+ Group: "tekton.dev",
+ Version: "v1beta1",
+ Kind: "CustomRun",
+ })
+ uo := &unstructured.Unstructured{}
+ if err := convert(in, uo); err != nil {
+ return nil, err
+ }
+ uo, err := w.dyn.Namespace(w.namespace).Create(ctx, uo, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRun{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
+ return w.dyn.Namespace(w.namespace).Delete(ctx, name, opts)
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
+ return w.dyn.Namespace(w.namespace).DeleteCollection(ctx, opts, listOpts)
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.CustomRun, error) {
+ uo, err := w.dyn.Namespace(w.namespace).Get(ctx, name, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRun{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) List(ctx context.Context, opts v1.ListOptions) (*v1beta1.CustomRunList, error) {
+ uo, err := w.dyn.Namespace(w.namespace).List(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRunList{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomRun, err error) {
+ uo, err := w.dyn.Namespace(w.namespace).Patch(ctx, name, pt, data, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRun{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) Update(ctx context.Context, in *v1beta1.CustomRun, opts v1.UpdateOptions) (*v1beta1.CustomRun, error) {
+ in.SetGroupVersionKind(schema.GroupVersionKind{
+ Group: "tekton.dev",
+ Version: "v1beta1",
+ Kind: "CustomRun",
+ })
+ uo := &unstructured.Unstructured{}
+ if err := convert(in, uo); err != nil {
+ return nil, err
+ }
+ uo, err := w.dyn.Namespace(w.namespace).Update(ctx, uo, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRun{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) UpdateStatus(ctx context.Context, in *v1beta1.CustomRun, opts v1.UpdateOptions) (*v1beta1.CustomRun, error) {
+ in.SetGroupVersionKind(schema.GroupVersionKind{
+ Group: "tekton.dev",
+ Version: "v1beta1",
+ Kind: "CustomRun",
+ })
+ uo := &unstructured.Unstructured{}
+ if err := convert(in, uo); err != nil {
+ return nil, err
+ }
+ uo, err := w.dyn.Namespace(w.namespace).UpdateStatus(ctx, uo, opts)
+ if err != nil {
+ return nil, err
+ }
+ out := &v1beta1.CustomRun{}
+ if err := convert(uo, out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (w *wrapTektonV1beta1CustomRunImpl) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
+ return nil, errors.New("NYI: Watch")
+}
+
func (w *wrapTektonV1beta1) Pipelines(namespace string) typedtektonv1beta1.PipelineInterface {
return &wrapTektonV1beta1PipelineImpl{
dyn: w.dyn.Resource(schema.GroupVersionResource{
diff --git a/pkg/client/injection/informers/pipeline/v1beta1/customrun/customrun.go b/pkg/client/injection/informers/pipeline/v1beta1/customrun/customrun.go
new file mode 100644
index 00000000000..5f97b83c0a9
--- /dev/null
+++ b/pkg/client/injection/informers/pipeline/v1beta1/customrun/customrun.go
@@ -0,0 +1,116 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package customrun
+
+import (
+ context "context"
+
+ apispipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
+ v1beta1 "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1"
+ client "github.com/tektoncd/pipeline/pkg/client/injection/client"
+ factory "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory"
+ pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ cache "k8s.io/client-go/tools/cache"
+ controller "knative.dev/pkg/controller"
+ injection "knative.dev/pkg/injection"
+ logging "knative.dev/pkg/logging"
+)
+
+func init() {
+ injection.Default.RegisterInformer(withInformer)
+ injection.Dynamic.RegisterDynamicInformer(withDynamicInformer)
+}
+
+// Key is used for associating the Informer inside the context.Context.
+type Key struct{}
+
+func withInformer(ctx context.Context) (context.Context, controller.Informer) {
+ f := factory.Get(ctx)
+ inf := f.Tekton().V1beta1().CustomRuns()
+ return context.WithValue(ctx, Key{}, inf), inf.Informer()
+}
+
+func withDynamicInformer(ctx context.Context) context.Context {
+ inf := &wrapper{client: client.Get(ctx), resourceVersion: injection.GetResourceVersion(ctx)}
+ return context.WithValue(ctx, Key{}, inf)
+}
+
+// Get extracts the typed informer from the context.
+func Get(ctx context.Context) v1beta1.CustomRunInformer {
+ untyped := ctx.Value(Key{})
+ if untyped == nil {
+ logging.FromContext(ctx).Panic(
+ "Unable to fetch github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1.CustomRunInformer from context.")
+ }
+ return untyped.(v1beta1.CustomRunInformer)
+}
+
+type wrapper struct {
+ client versioned.Interface
+
+ namespace string
+
+ resourceVersion string
+}
+
+var _ v1beta1.CustomRunInformer = (*wrapper)(nil)
+var _ pipelinev1beta1.CustomRunLister = (*wrapper)(nil)
+
+func (w *wrapper) Informer() cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(nil, &apispipelinev1beta1.CustomRun{}, 0, nil)
+}
+
+func (w *wrapper) Lister() pipelinev1beta1.CustomRunLister {
+ return w
+}
+
+func (w *wrapper) CustomRuns(namespace string) pipelinev1beta1.CustomRunNamespaceLister {
+ return &wrapper{client: w.client, namespace: namespace, resourceVersion: w.resourceVersion}
+}
+
+// SetResourceVersion allows consumers to adjust the minimum resourceVersion
+// used by the underlying client. It is not accessible via the standard
+// lister interface, but can be accessed through a user-defined interface and
+// an implementation check e.g. rvs, ok := foo.(ResourceVersionSetter)
+func (w *wrapper) SetResourceVersion(resourceVersion string) {
+ w.resourceVersion = resourceVersion
+}
+
+func (w *wrapper) List(selector labels.Selector) (ret []*apispipelinev1beta1.CustomRun, err error) {
+ lo, err := w.client.TektonV1beta1().CustomRuns(w.namespace).List(context.TODO(), v1.ListOptions{
+ LabelSelector: selector.String(),
+ ResourceVersion: w.resourceVersion,
+ })
+ if err != nil {
+ return nil, err
+ }
+ for idx := range lo.Items {
+ ret = append(ret, &lo.Items[idx])
+ }
+ return ret, nil
+}
+
+func (w *wrapper) Get(name string) (*apispipelinev1beta1.CustomRun, error) {
+ return w.client.TektonV1beta1().CustomRuns(w.namespace).Get(context.TODO(), name, v1.GetOptions{
+ ResourceVersion: w.resourceVersion,
+ })
+}
diff --git a/pkg/client/injection/informers/pipeline/v1beta1/customrun/fake/fake.go b/pkg/client/injection/informers/pipeline/v1beta1/customrun/fake/fake.go
new file mode 100644
index 00000000000..0c8e5b0bde6
--- /dev/null
+++ b/pkg/client/injection/informers/pipeline/v1beta1/customrun/fake/fake.go
@@ -0,0 +1,40 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ context "context"
+
+ fake "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/fake"
+ customrun "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/customrun"
+ controller "knative.dev/pkg/controller"
+ injection "knative.dev/pkg/injection"
+)
+
+var Get = customrun.Get
+
+func init() {
+ injection.Fake.RegisterInformer(withInformer)
+}
+
+func withInformer(ctx context.Context) (context.Context, controller.Informer) {
+ f := fake.Get(ctx)
+ inf := f.Tekton().V1beta1().CustomRuns()
+ return context.WithValue(ctx, customrun.Key{}, inf), inf.Informer()
+}
diff --git a/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/customrun.go b/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/customrun.go
new file mode 100644
index 00000000000..712aca5b185
--- /dev/null
+++ b/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/customrun.go
@@ -0,0 +1,136 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package filtered
+
+import (
+ context "context"
+
+ apispipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
+ v1beta1 "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1"
+ client "github.com/tektoncd/pipeline/pkg/client/injection/client"
+ filtered "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/filtered"
+ pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ cache "k8s.io/client-go/tools/cache"
+ controller "knative.dev/pkg/controller"
+ injection "knative.dev/pkg/injection"
+ logging "knative.dev/pkg/logging"
+)
+
+func init() {
+ injection.Default.RegisterFilteredInformers(withInformer)
+ injection.Dynamic.RegisterDynamicInformer(withDynamicInformer)
+}
+
+// Key is used for associating the Informer inside the context.Context.
+type Key struct {
+ Selector string
+}
+
+func withInformer(ctx context.Context) (context.Context, []controller.Informer) {
+ untyped := ctx.Value(filtered.LabelKey{})
+ if untyped == nil {
+ logging.FromContext(ctx).Panic(
+ "Unable to fetch labelkey from context.")
+ }
+ labelSelectors := untyped.([]string)
+ infs := []controller.Informer{}
+ for _, selector := range labelSelectors {
+ f := filtered.Get(ctx, selector)
+ inf := f.Tekton().V1beta1().CustomRuns()
+ ctx = context.WithValue(ctx, Key{Selector: selector}, inf)
+ infs = append(infs, inf.Informer())
+ }
+ return ctx, infs
+}
+
+func withDynamicInformer(ctx context.Context) context.Context {
+ untyped := ctx.Value(filtered.LabelKey{})
+ if untyped == nil {
+ logging.FromContext(ctx).Panic(
+ "Unable to fetch labelkey from context.")
+ }
+ labelSelectors := untyped.([]string)
+ for _, selector := range labelSelectors {
+ inf := &wrapper{client: client.Get(ctx), selector: selector}
+ ctx = context.WithValue(ctx, Key{Selector: selector}, inf)
+ }
+ return ctx
+}
+
+// Get extracts the typed informer from the context.
+func Get(ctx context.Context, selector string) v1beta1.CustomRunInformer {
+ untyped := ctx.Value(Key{Selector: selector})
+ if untyped == nil {
+ logging.FromContext(ctx).Panicf(
+ "Unable to fetch github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1.CustomRunInformer with selector %s from context.", selector)
+ }
+ return untyped.(v1beta1.CustomRunInformer)
+}
+
+type wrapper struct {
+ client versioned.Interface
+
+ namespace string
+
+ selector string
+}
+
+var _ v1beta1.CustomRunInformer = (*wrapper)(nil)
+var _ pipelinev1beta1.CustomRunLister = (*wrapper)(nil)
+
+func (w *wrapper) Informer() cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(nil, &apispipelinev1beta1.CustomRun{}, 0, nil)
+}
+
+func (w *wrapper) Lister() pipelinev1beta1.CustomRunLister {
+ return w
+}
+
+func (w *wrapper) CustomRuns(namespace string) pipelinev1beta1.CustomRunNamespaceLister {
+ return &wrapper{client: w.client, namespace: namespace, selector: w.selector}
+}
+
+func (w *wrapper) List(selector labels.Selector) (ret []*apispipelinev1beta1.CustomRun, err error) {
+ reqs, err := labels.ParseToRequirements(w.selector)
+ if err != nil {
+ return nil, err
+ }
+ selector = selector.Add(reqs...)
+ lo, err := w.client.TektonV1beta1().CustomRuns(w.namespace).List(context.TODO(), v1.ListOptions{
+ LabelSelector: selector.String(),
+ // TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
+ })
+ if err != nil {
+ return nil, err
+ }
+ for idx := range lo.Items {
+ ret = append(ret, &lo.Items[idx])
+ }
+ return ret, nil
+}
+
+func (w *wrapper) Get(name string) (*apispipelinev1beta1.CustomRun, error) {
+ // TODO(mattmoor): Check that the fetched object matches the selector.
+ return w.client.TektonV1beta1().CustomRuns(w.namespace).Get(context.TODO(), name, v1.GetOptions{
+ // TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
+ })
+}
diff --git a/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/fake/fake.go b/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/fake/fake.go
new file mode 100644
index 00000000000..f44d2100186
--- /dev/null
+++ b/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered/fake/fake.go
@@ -0,0 +1,52 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ context "context"
+
+ factoryfiltered "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/filtered"
+ filtered "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/customrun/filtered"
+ controller "knative.dev/pkg/controller"
+ injection "knative.dev/pkg/injection"
+ logging "knative.dev/pkg/logging"
+)
+
+var Get = filtered.Get
+
+func init() {
+ injection.Fake.RegisterFilteredInformers(withInformer)
+}
+
+func withInformer(ctx context.Context) (context.Context, []controller.Informer) {
+ untyped := ctx.Value(factoryfiltered.LabelKey{})
+ if untyped == nil {
+ logging.FromContext(ctx).Panic(
+ "Unable to fetch labelkey from context.")
+ }
+ labelSelectors := untyped.([]string)
+ infs := []controller.Informer{}
+ for _, selector := range labelSelectors {
+ f := factoryfiltered.Get(ctx, selector)
+ inf := f.Tekton().V1beta1().CustomRuns()
+ ctx = context.WithValue(ctx, filtered.Key{Selector: selector}, inf)
+ infs = append(infs, inf.Informer())
+ }
+ return ctx, infs
+}
diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/controller.go b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/controller.go
new file mode 100644
index 00000000000..a82283dd4f1
--- /dev/null
+++ b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/controller.go
@@ -0,0 +1,162 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package customrun
+
+import (
+ context "context"
+ fmt "fmt"
+ reflect "reflect"
+ strings "strings"
+
+ versionedscheme "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/scheme"
+ client "github.com/tektoncd/pipeline/pkg/client/injection/client"
+ customrun "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/customrun"
+ zap "go.uber.org/zap"
+ corev1 "k8s.io/api/core/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ scheme "k8s.io/client-go/kubernetes/scheme"
+ v1 "k8s.io/client-go/kubernetes/typed/core/v1"
+ record "k8s.io/client-go/tools/record"
+ kubeclient "knative.dev/pkg/client/injection/kube/client"
+ controller "knative.dev/pkg/controller"
+ logging "knative.dev/pkg/logging"
+ logkey "knative.dev/pkg/logging/logkey"
+ reconciler "knative.dev/pkg/reconciler"
+)
+
+const (
+ defaultControllerAgentName = "customrun-controller"
+ defaultFinalizerName = "customruns.tekton.dev"
+)
+
+// NewImpl returns a controller.Impl that handles queuing and feeding work from
+// the queue through an implementation of controller.Reconciler, delegating to
+// the provided Interface and optional Finalizer methods. OptionsFn is used to return
+// controller.ControllerOptions to be used by the internal reconciler.
+func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl {
+ logger := logging.FromContext(ctx)
+
+ // Check the options function input. It should be 0 or 1.
+ if len(optionsFns) > 1 {
+ logger.Fatal("Up to one options function is supported, found: ", len(optionsFns))
+ }
+
+ customrunInformer := customrun.Get(ctx)
+
+ lister := customrunInformer.Lister()
+
+ var promoteFilterFunc func(obj interface{}) bool
+
+ rec := &reconcilerImpl{
+ LeaderAwareFuncs: reconciler.LeaderAwareFuncs{
+ PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error {
+ all, err := lister.List(labels.Everything())
+ if err != nil {
+ return err
+ }
+ for _, elt := range all {
+ if promoteFilterFunc != nil {
+ if ok := promoteFilterFunc(elt); !ok {
+ continue
+ }
+ }
+ enq(bkt, types.NamespacedName{
+ Namespace: elt.GetNamespace(),
+ Name: elt.GetName(),
+ })
+ }
+ return nil
+ },
+ },
+ Client: client.Get(ctx),
+ Lister: lister,
+ reconciler: r,
+ finalizerName: defaultFinalizerName,
+ }
+
+ ctrType := reflect.TypeOf(r).Elem()
+ ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name())
+ ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".")
+
+ logger = logger.With(
+ zap.String(logkey.ControllerType, ctrTypeName),
+ zap.String(logkey.Kind, "tekton.dev.CustomRun"),
+ )
+
+ impl := controller.NewContext(ctx, rec, controller.ControllerOptions{WorkQueueName: ctrTypeName, Logger: logger})
+ agentName := defaultControllerAgentName
+
+ // Pass impl to the options. Save any optional results.
+ for _, fn := range optionsFns {
+ opts := fn(impl)
+ if opts.ConfigStore != nil {
+ rec.configStore = opts.ConfigStore
+ }
+ if opts.FinalizerName != "" {
+ rec.finalizerName = opts.FinalizerName
+ }
+ if opts.AgentName != "" {
+ agentName = opts.AgentName
+ }
+ if opts.SkipStatusUpdates {
+ rec.skipStatusUpdates = true
+ }
+ if opts.DemoteFunc != nil {
+ rec.DemoteFunc = opts.DemoteFunc
+ }
+ if opts.PromoteFilterFunc != nil {
+ promoteFilterFunc = opts.PromoteFilterFunc
+ }
+ }
+
+ rec.Recorder = createRecorder(ctx, agentName)
+
+ return impl
+}
+
+func createRecorder(ctx context.Context, agentName string) record.EventRecorder {
+ logger := logging.FromContext(ctx)
+
+ recorder := controller.GetEventRecorder(ctx)
+ if recorder == nil {
+ // Create event broadcaster
+ logger.Debug("Creating event broadcaster")
+ eventBroadcaster := record.NewBroadcaster()
+ watches := []watch.Interface{
+ eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof),
+ eventBroadcaster.StartRecordingToSink(
+ &v1.EventSinkImpl{Interface: kubeclient.Get(ctx).CoreV1().Events("")}),
+ }
+ recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName})
+ go func() {
+ <-ctx.Done()
+ for _, w := range watches {
+ w.Stop()
+ }
+ }()
+ }
+
+ return recorder
+}
+
+func init() {
+ versionedscheme.AddToScheme(scheme.Scheme)
+}
diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/reconciler.go b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/reconciler.go
new file mode 100644
index 00000000000..6873dda2b64
--- /dev/null
+++ b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/reconciler.go
@@ -0,0 +1,450 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package customrun
+
+import (
+ context "context"
+ json "encoding/json"
+ fmt "fmt"
+
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
+ pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1"
+ zap "go.uber.org/zap"
+ v1 "k8s.io/api/core/v1"
+ equality "k8s.io/apimachinery/pkg/api/equality"
+ errors "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ types "k8s.io/apimachinery/pkg/types"
+ sets "k8s.io/apimachinery/pkg/util/sets"
+ record "k8s.io/client-go/tools/record"
+ controller "knative.dev/pkg/controller"
+ kmp "knative.dev/pkg/kmp"
+ logging "knative.dev/pkg/logging"
+ reconciler "knative.dev/pkg/reconciler"
+)
+
+// Interface defines the strongly typed interfaces to be implemented by a
+// controller reconciling v1beta1.CustomRun.
+type Interface interface {
+ // ReconcileKind implements custom logic to reconcile v1beta1.CustomRun. Any changes
+ // to the objects .Status or .Finalizers will be propagated to the stored
+ // object. It is recommended that implementors do not call any update calls
+ // for the Kind inside of ReconcileKind, it is the responsibility of the calling
+ // controller to propagate those properties. The resource passed to ReconcileKind
+ // will always have an empty deletion timestamp.
+ ReconcileKind(ctx context.Context, o *v1beta1.CustomRun) reconciler.Event
+}
+
+// Finalizer defines the strongly typed interfaces to be implemented by a
+// controller finalizing v1beta1.CustomRun.
+type Finalizer interface {
+ // FinalizeKind implements custom logic to finalize v1beta1.CustomRun. Any changes
+ // to the objects .Status or .Finalizers will be ignored. Returning a nil or
+ // Normal type reconciler.Event will allow the finalizer to be deleted on
+ // the resource. The resource passed to FinalizeKind will always have a set
+ // deletion timestamp.
+ FinalizeKind(ctx context.Context, o *v1beta1.CustomRun) reconciler.Event
+}
+
+// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a
+// controller reconciling v1beta1.CustomRun if they want to process resources for which
+// they are not the leader.
+type ReadOnlyInterface interface {
+ // ObserveKind implements logic to observe v1beta1.CustomRun.
+ // This method should not write to the API.
+ ObserveKind(ctx context.Context, o *v1beta1.CustomRun) reconciler.Event
+}
+
+type doReconcile func(ctx context.Context, o *v1beta1.CustomRun) reconciler.Event
+
+// reconcilerImpl implements controller.Reconciler for v1beta1.CustomRun resources.
+type reconcilerImpl struct {
+ // LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware.
+ reconciler.LeaderAwareFuncs
+
+ // Client is used to write back status updates.
+ Client versioned.Interface
+
+ // Listers index properties about resources.
+ Lister pipelinev1beta1.CustomRunLister
+
+ // Recorder is an event recorder for recording Event resources to the
+ // Kubernetes API.
+ Recorder record.EventRecorder
+
+ // configStore allows for decorating a context with config maps.
+ // +optional
+ configStore reconciler.ConfigStore
+
+ // reconciler is the implementation of the business logic of the resource.
+ reconciler Interface
+
+ // finalizerName is the name of the finalizer to reconcile.
+ finalizerName string
+
+ // skipStatusUpdates configures whether or not this reconciler automatically updates
+ // the status of the reconciled resource.
+ skipStatusUpdates bool
+}
+
+// Check that our Reconciler implements controller.Reconciler.
+var _ controller.Reconciler = (*reconcilerImpl)(nil)
+
+// Check that our generated Reconciler is always LeaderAware.
+var _ reconciler.LeaderAware = (*reconcilerImpl)(nil)
+
+func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client versioned.Interface, lister pipelinev1beta1.CustomRunLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler {
+ // Check the options function input. It should be 0 or 1.
+ if len(options) > 1 {
+ logger.Fatal("Up to one options struct is supported, found: ", len(options))
+ }
+
+ // Fail fast when users inadvertently implement the other LeaderAware interface.
+ // For the typed reconcilers, Promote shouldn't take any arguments.
+ if _, ok := r.(reconciler.LeaderAware); ok {
+ logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r)
+ }
+
+ rec := &reconcilerImpl{
+ LeaderAwareFuncs: reconciler.LeaderAwareFuncs{
+ PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error {
+ all, err := lister.List(labels.Everything())
+ if err != nil {
+ return err
+ }
+ for _, elt := range all {
+ // TODO: Consider letting users specify a filter in options.
+ enq(bkt, types.NamespacedName{
+ Namespace: elt.GetNamespace(),
+ Name: elt.GetName(),
+ })
+ }
+ return nil
+ },
+ },
+ Client: client,
+ Lister: lister,
+ Recorder: recorder,
+ reconciler: r,
+ finalizerName: defaultFinalizerName,
+ }
+
+ for _, opts := range options {
+ if opts.ConfigStore != nil {
+ rec.configStore = opts.ConfigStore
+ }
+ if opts.FinalizerName != "" {
+ rec.finalizerName = opts.FinalizerName
+ }
+ if opts.SkipStatusUpdates {
+ rec.skipStatusUpdates = true
+ }
+ if opts.DemoteFunc != nil {
+ rec.DemoteFunc = opts.DemoteFunc
+ }
+ }
+
+ return rec
+}
+
+// Reconcile implements controller.Reconciler
+func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
+ logger := logging.FromContext(ctx)
+
+ // Initialize the reconciler state. This will convert the namespace/name
+ // string into a distinct namespace and name, determine if this instance of
+ // the reconciler is the leader, and any additional interfaces implemented
+ // by the reconciler. Returns an error is the resource key is invalid.
+ s, err := newState(key, r)
+ if err != nil {
+ logger.Error("Invalid resource key: ", key)
+ return nil
+ }
+
+ // If we are not the leader, and we don't implement either ReadOnly
+ // observer interfaces, then take a fast-path out.
+ if s.isNotLeaderNorObserver() {
+ return controller.NewSkipKey(key)
+ }
+
+ // If configStore is set, attach the frozen configuration to the context.
+ if r.configStore != nil {
+ ctx = r.configStore.ToContext(ctx)
+ }
+
+ // Add the recorder to context.
+ ctx = controller.WithEventRecorder(ctx, r.Recorder)
+
+ // Get the resource with this namespace/name.
+
+ getter := r.Lister.CustomRuns(s.namespace)
+
+ original, err := getter.Get(s.name)
+
+ if errors.IsNotFound(err) {
+ // The resource may no longer exist, in which case we stop processing and call
+ // the ObserveDeletion handler if appropriate.
+ logger.Debugf("Resource %q no longer exists", key)
+ if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok {
+ return del.ObserveDeletion(ctx, types.NamespacedName{
+ Namespace: s.namespace,
+ Name: s.name,
+ })
+ }
+ return nil
+ } else if err != nil {
+ return err
+ }
+
+ // Don't modify the informers copy.
+ resource := original.DeepCopy()
+
+ var reconcileEvent reconciler.Event
+
+ name, do := s.reconcileMethodFor(resource)
+ // Append the target method to the logger.
+ logger = logger.With(zap.String("targetMethod", name))
+ switch name {
+ case reconciler.DoReconcileKind:
+ // Set and update the finalizer on resource if r.reconciler
+ // implements Finalizer.
+ if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil {
+ return fmt.Errorf("failed to set finalizers: %w", err)
+ }
+
+ if !r.skipStatusUpdates {
+ reconciler.PreProcessReconcile(ctx, resource)
+ }
+
+ // Reconcile this copy of the resource and then write back any status
+ // updates regardless of whether the reconciliation errored out.
+ reconcileEvent = do(ctx, resource)
+
+ if !r.skipStatusUpdates {
+ reconciler.PostProcessReconcile(ctx, resource, original)
+ }
+
+ case reconciler.DoFinalizeKind:
+ // For finalizing reconcilers, if this resource being marked for deletion
+ // and reconciled cleanly (nil or normal event), remove the finalizer.
+ reconcileEvent = do(ctx, resource)
+
+ if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil {
+ return fmt.Errorf("failed to clear finalizers: %w", err)
+ }
+
+ case reconciler.DoObserveKind:
+ // Observe any changes to this resource, since we are not the leader.
+ reconcileEvent = do(ctx, resource)
+
+ }
+
+ // Synchronize the status.
+ switch {
+ case r.skipStatusUpdates:
+ // This reconciler implementation is configured to skip resource updates.
+ // This may mean this reconciler does not observe spec, but reconciles external changes.
+ case equality.Semantic.DeepEqual(original.Status, resource.Status):
+ // If we didn't change anything then don't call updateStatus.
+ // This is important because the copy we loaded from the injectionInformer's
+ // cache may be stale and we don't want to overwrite a prior update
+ // to status with this stale state.
+ case !s.isLeader:
+ // High-availability reconcilers may have many replicas watching the resource, but only
+ // the elected leader is expected to write modifications.
+ logger.Warn("Saw status changes when we aren't the leader!")
+ default:
+ if err = r.updateStatus(ctx, original, resource); err != nil {
+ logger.Warnw("Failed to update resource status", zap.Error(err))
+ r.Recorder.Eventf(resource, v1.EventTypeWarning, "UpdateFailed",
+ "Failed to update status for %q: %v", resource.Name, err)
+ return err
+ }
+ }
+
+ // Report the reconciler event, if any.
+ if reconcileEvent != nil {
+ var event *reconciler.ReconcilerEvent
+ if reconciler.EventAs(reconcileEvent, &event) {
+ logger.Infow("Returned an event", zap.Any("event", reconcileEvent))
+ r.Recorder.Event(resource, event.EventType, event.Reason, event.Error())
+
+ // the event was wrapped inside an error, consider the reconciliation as failed
+ if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent {
+ return reconcileEvent
+ }
+ return nil
+ }
+
+ if controller.IsSkipKey(reconcileEvent) {
+ // This is a wrapped error, don't emit an event.
+ } else if ok, _ := controller.IsRequeueKey(reconcileEvent); ok {
+ // This is a wrapped error, don't emit an event.
+ } else {
+ logger.Errorw("Returned an error", zap.Error(reconcileEvent))
+ r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error())
+ }
+ return reconcileEvent
+ }
+
+ return nil
+}
+
+func (r *reconcilerImpl) updateStatus(ctx context.Context, existing *v1beta1.CustomRun, desired *v1beta1.CustomRun) error {
+ existing = existing.DeepCopy()
+ return reconciler.RetryUpdateConflicts(func(attempts int) (err error) {
+ // The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API.
+ if attempts > 0 {
+
+ getter := r.Client.TektonV1beta1().CustomRuns(desired.Namespace)
+
+ existing, err = getter.Get(ctx, desired.Name, metav1.GetOptions{})
+ if err != nil {
+ return err
+ }
+ }
+
+ // If there's nothing to update, just return.
+ if equality.Semantic.DeepEqual(existing.Status, desired.Status) {
+ return nil
+ }
+
+ if diff, err := kmp.SafeDiff(existing.Status, desired.Status); err == nil && diff != "" {
+ logging.FromContext(ctx).Debug("Updating status with: ", diff)
+ }
+
+ existing.Status = desired.Status
+
+ updater := r.Client.TektonV1beta1().CustomRuns(existing.Namespace)
+
+ _, err = updater.UpdateStatus(ctx, existing, metav1.UpdateOptions{})
+ return err
+ })
+}
+
+// updateFinalizersFiltered will update the Finalizers of the resource.
+// TODO: this method could be generic and sync all finalizers. For now it only
+// updates defaultFinalizerName or its override.
+func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1beta1.CustomRun) (*v1beta1.CustomRun, error) {
+
+ getter := r.Lister.CustomRuns(resource.Namespace)
+
+ actual, err := getter.Get(resource.Name)
+ if err != nil {
+ return resource, err
+ }
+
+ // Don't modify the informers copy.
+ existing := actual.DeepCopy()
+
+ var finalizers []string
+
+ // If there's nothing to update, just return.
+ existingFinalizers := sets.NewString(existing.Finalizers...)
+ desiredFinalizers := sets.NewString(resource.Finalizers...)
+
+ if desiredFinalizers.Has(r.finalizerName) {
+ if existingFinalizers.Has(r.finalizerName) {
+ // Nothing to do.
+ return resource, nil
+ }
+ // Add the finalizer.
+ finalizers = append(existing.Finalizers, r.finalizerName)
+ } else {
+ if !existingFinalizers.Has(r.finalizerName) {
+ // Nothing to do.
+ return resource, nil
+ }
+ // Remove the finalizer.
+ existingFinalizers.Delete(r.finalizerName)
+ finalizers = existingFinalizers.List()
+ }
+
+ mergePatch := map[string]interface{}{
+ "metadata": map[string]interface{}{
+ "finalizers": finalizers,
+ "resourceVersion": existing.ResourceVersion,
+ },
+ }
+
+ patch, err := json.Marshal(mergePatch)
+ if err != nil {
+ return resource, err
+ }
+
+ patcher := r.Client.TektonV1beta1().CustomRuns(resource.Namespace)
+
+ resourceName := resource.Name
+ updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{})
+ if err != nil {
+ r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed",
+ "Failed to update finalizers for %q: %v", resourceName, err)
+ } else {
+ r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate",
+ "Updated %q finalizers", resource.GetName())
+ }
+ return updated, err
+}
+
+func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1beta1.CustomRun) (*v1beta1.CustomRun, error) {
+ if _, ok := r.reconciler.(Finalizer); !ok {
+ return resource, nil
+ }
+
+ finalizers := sets.NewString(resource.Finalizers...)
+
+ // If this resource is not being deleted, mark the finalizer.
+ if resource.GetDeletionTimestamp().IsZero() {
+ finalizers.Insert(r.finalizerName)
+ }
+
+ resource.Finalizers = finalizers.List()
+
+ // Synchronize the finalizers filtered by r.finalizerName.
+ return r.updateFinalizersFiltered(ctx, resource)
+}
+
+func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1beta1.CustomRun, reconcileEvent reconciler.Event) (*v1beta1.CustomRun, error) {
+ if _, ok := r.reconciler.(Finalizer); !ok {
+ return resource, nil
+ }
+ if resource.GetDeletionTimestamp().IsZero() {
+ return resource, nil
+ }
+
+ finalizers := sets.NewString(resource.Finalizers...)
+
+ if reconcileEvent != nil {
+ var event *reconciler.ReconcilerEvent
+ if reconciler.EventAs(reconcileEvent, &event) {
+ if event.EventType == v1.EventTypeNormal {
+ finalizers.Delete(r.finalizerName)
+ }
+ }
+ } else {
+ finalizers.Delete(r.finalizerName)
+ }
+
+ resource.Finalizers = finalizers.List()
+
+ // Synchronize the finalizers filtered by r.finalizerName.
+ return r.updateFinalizersFiltered(ctx, resource)
+}
diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/state.go b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/state.go
new file mode 100644
index 00000000000..70711d05a53
--- /dev/null
+++ b/pkg/client/injection/reconciler/pipeline/v1beta1/customrun/state.go
@@ -0,0 +1,97 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by injection-gen. DO NOT EDIT.
+
+package customrun
+
+import (
+ fmt "fmt"
+
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ types "k8s.io/apimachinery/pkg/types"
+ cache "k8s.io/client-go/tools/cache"
+ reconciler "knative.dev/pkg/reconciler"
+)
+
+// state is used to track the state of a reconciler in a single run.
+type state struct {
+ // key is the original reconciliation key from the queue.
+ key string
+ // namespace is the namespace split from the reconciliation key.
+ namespace string
+ // name is the name split from the reconciliation key.
+ name string
+ // reconciler is the reconciler.
+ reconciler Interface
+ // roi is the read only interface cast of the reconciler.
+ roi ReadOnlyInterface
+ // isROI (Read Only Interface) the reconciler only observes reconciliation.
+ isROI bool
+ // isLeader the instance of the reconciler is the elected leader.
+ isLeader bool
+}
+
+func newState(key string, r *reconcilerImpl) (*state, error) {
+ // Convert the namespace/name string into a distinct namespace and name.
+ namespace, name, err := cache.SplitMetaNamespaceKey(key)
+ if err != nil {
+ return nil, fmt.Errorf("invalid resource key: %s", key)
+ }
+
+ roi, isROI := r.reconciler.(ReadOnlyInterface)
+
+ isLeader := r.IsLeaderFor(types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ })
+
+ return &state{
+ key: key,
+ namespace: namespace,
+ name: name,
+ reconciler: r.reconciler,
+ roi: roi,
+ isROI: isROI,
+ isLeader: isLeader,
+ }, nil
+}
+
+// isNotLeaderNorObserver checks to see if this reconciler with the current
+// state is enabled to do any work or not.
+// isNotLeaderNorObserver returns true when there is no work possible for the
+// reconciler.
+func (s *state) isNotLeaderNorObserver() bool {
+ if !s.isLeader && !s.isROI {
+ // If we are not the leader, and we don't implement the ReadOnly
+ // interface, then take a fast-path out.
+ return true
+ }
+ return false
+}
+
+func (s *state) reconcileMethodFor(o *v1beta1.CustomRun) (string, doReconcile) {
+ if o.GetDeletionTimestamp().IsZero() {
+ if s.isLeader {
+ return reconciler.DoReconcileKind, s.reconciler.ReconcileKind
+ } else if s.isROI {
+ return reconciler.DoObserveKind, s.roi.ObserveKind
+ }
+ } else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok {
+ return reconciler.DoFinalizeKind, fin.FinalizeKind
+ }
+ return "unknown", nil
+}
diff --git a/pkg/client/listers/pipeline/v1beta1/customrun.go b/pkg/client/listers/pipeline/v1beta1/customrun.go
new file mode 100644
index 00000000000..546668a17ea
--- /dev/null
+++ b/pkg/client/listers/pipeline/v1beta1/customrun.go
@@ -0,0 +1,99 @@
+/*
+Copyright 2020 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.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+)
+
+// CustomRunLister helps list CustomRuns.
+// All objects returned here must be treated as read-only.
+type CustomRunLister interface {
+ // List lists all CustomRuns in the indexer.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1beta1.CustomRun, err error)
+ // CustomRuns returns an object that can list and get CustomRuns.
+ CustomRuns(namespace string) CustomRunNamespaceLister
+ CustomRunListerExpansion
+}
+
+// customRunLister implements the CustomRunLister interface.
+type customRunLister struct {
+ indexer cache.Indexer
+}
+
+// NewCustomRunLister returns a new CustomRunLister.
+func NewCustomRunLister(indexer cache.Indexer) CustomRunLister {
+ return &customRunLister{indexer: indexer}
+}
+
+// List lists all CustomRuns in the indexer.
+func (s *customRunLister) List(selector labels.Selector) (ret []*v1beta1.CustomRun, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1beta1.CustomRun))
+ })
+ return ret, err
+}
+
+// CustomRuns returns an object that can list and get CustomRuns.
+func (s *customRunLister) CustomRuns(namespace string) CustomRunNamespaceLister {
+ return customRunNamespaceLister{indexer: s.indexer, namespace: namespace}
+}
+
+// CustomRunNamespaceLister helps list and get CustomRuns.
+// All objects returned here must be treated as read-only.
+type CustomRunNamespaceLister interface {
+ // List lists all CustomRuns in the indexer for a given namespace.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1beta1.CustomRun, err error)
+ // Get retrieves the CustomRun from the indexer for a given namespace and name.
+ // Objects returned here must be treated as read-only.
+ Get(name string) (*v1beta1.CustomRun, error)
+ CustomRunNamespaceListerExpansion
+}
+
+// customRunNamespaceLister implements the CustomRunNamespaceLister
+// interface.
+type customRunNamespaceLister struct {
+ indexer cache.Indexer
+ namespace string
+}
+
+// List lists all CustomRuns in the indexer for a given namespace.
+func (s customRunNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.CustomRun, err error) {
+ err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1beta1.CustomRun))
+ })
+ return ret, err
+}
+
+// Get retrieves the CustomRun from the indexer for a given namespace and name.
+func (s customRunNamespaceLister) Get(name string) (*v1beta1.CustomRun, error) {
+ obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1beta1.Resource("customrun"), name)
+ }
+ return obj.(*v1beta1.CustomRun), nil
+}
diff --git a/pkg/client/listers/pipeline/v1beta1/expansion_generated.go b/pkg/client/listers/pipeline/v1beta1/expansion_generated.go
index 3da70592c54..db5d996e615 100644
--- a/pkg/client/listers/pipeline/v1beta1/expansion_generated.go
+++ b/pkg/client/listers/pipeline/v1beta1/expansion_generated.go
@@ -22,6 +22,14 @@ package v1beta1
// ClusterTaskLister.
type ClusterTaskListerExpansion interface{}
+// CustomRunListerExpansion allows custom methods to be added to
+// CustomRunLister.
+type CustomRunListerExpansion interface{}
+
+// CustomRunNamespaceListerExpansion allows custom methods to be added to
+// CustomRunNamespaceLister.
+type CustomRunNamespaceListerExpansion interface{}
+
// PipelineListerExpansion allows custom methods to be added to
// PipelineLister.
type PipelineListerExpansion interface{}