diff --git a/docs/taskruns.md b/docs/taskruns.md index aa64088ef02..7becc13965e 100644 --- a/docs/taskruns.md +++ b/docs/taskruns.md @@ -303,6 +303,8 @@ For each step we also include the fully-qualified image used, with the digest. If any pods have been [`OOMKilled`](https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/) by Kubernetes, the `Taskrun` will be marked as failed even if the exit code is 0. +The exact Task Spec used to instantiate the TaskRun is also included in the Status for full auditability. + ### Steps If multiple `steps` are defined in the `Task` invoked by the `TaskRun`, we will see the diff --git a/pkg/apis/pipeline/v1beta1/taskrun_types.go b/pkg/apis/pipeline/v1beta1/taskrun_types.go index 08cefb8d195..79b08c498d6 100644 --- a/pkg/apis/pipeline/v1beta1/taskrun_types.go +++ b/pkg/apis/pipeline/v1beta1/taskrun_types.go @@ -177,6 +177,9 @@ type TaskRunStatusFields struct { // The list has one entry per sidecar in the manifest. Each entry is // represents the imageid of the corresponding sidecar. Sidecars []SidecarState `json:"sidecars,omitempty"` + + // TaskSpec contains the Spec from the dereferenced Task definition used to instantiate this TaskRun. + TaskSpec *TaskSpec `json:"taskSpec,omitempty"` } // TaskRunResult used to describe the results of a task diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 1d53fb0f78e..1d92712e04a 100644 --- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1481,6 +1481,11 @@ func (in *TaskRunStatusFields) DeepCopyInto(out *TaskRunStatusFields) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.TaskSpec != nil { + in, out := &in.TaskSpec, &out.TaskSpec + *out = new(TaskSpec) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/pod/status.go b/pkg/pod/status.go index e7ed666030d..dddeafc01b8 100644 --- a/pkg/pod/status.go +++ b/pkg/pod/status.go @@ -17,6 +17,7 @@ limitations under the License. package pod import ( + "context" "encoding/json" "fmt" "sort" @@ -24,6 +25,7 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/names" "github.com/tektoncd/pipeline/pkg/termination" "go.uber.org/zap" @@ -116,6 +118,12 @@ func MakeTaskRunStatus(logger *zap.SugaredLogger, tr v1alpha1.TaskRun, pod *core trs.Steps = []v1alpha1.StepState{} trs.Sidecars = []v1alpha1.SidecarState{} + ts := v1beta1.TaskSpec{} + if err := taskSpec.ConvertTo(context.Background(), &ts); err != nil { + logger.Errorf("error setting taskrun.Status.taskSpec in taskrun %s: %w", tr.Name, err) + } + trs.TaskSpec = &ts + for _, s := range pod.Status.ContainerStatuses { if IsContainerStep(s.Name) { if s.State.Terminated != nil && len(s.State.Terminated.Message) != 0 { diff --git a/pkg/pod/status_test.go b/pkg/pod/status_test.go index d8b4cd6bde0..1344d1358a6 100644 --- a/pkg/pod/status_test.go +++ b/pkg/pod/status_test.go @@ -17,6 +17,7 @@ limitations under the License. package pod import ( + "context" "testing" "time" @@ -721,6 +722,11 @@ func TestMakeTaskRunStatus(t *testing.T) { // Common traits, set for test case brevity. c.want.PodName = "pod" c.want.StartTime = &metav1.Time{Time: startTime} + ts := v1beta1.TaskSpec{} + if err := c.taskSpec.ConvertTo(context.Background(), &ts); err != nil { + t.Errorf("error converting ts: %w", err) + } + c.want.TaskSpec = &ts ensureTimeNotNil := cmp.Comparer(func(x, y *metav1.Time) bool { if x == nil {