Skip to content

Commit

Permalink
feat: surface artifacts through termination message
Browse files Browse the repository at this point in the history
  • Loading branch information
ericzzzzzzz committed Mar 11, 2024
1 parent 9a089d7 commit 7443e91
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pkg/apis/pipeline/v1/artifact_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ type ArtifactValue struct {
// TaskRunStepArtifact represents an artifact produced or used by a step within a task run.
// It directly uses the Artifact type for its structure.
type TaskRunStepArtifact = Artifact

type Artifacts struct {
Inputs []Artifact `json:"inputs"`
Outputs []Artifact `json:"outputs"`
}
5 changes: 5 additions & 0 deletions pkg/apis/pipeline/v1beta1/artifact_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ type ArtifactValue struct {
// TaskRunStepArtifact represents an artifact produced or used by a step within a task run.
// It directly uses the Artifact type for its structure.
type TaskRunStepArtifact = Artifact

type Artifacts struct {
Inputs []Artifact `json:"inputs"`
Outputs []Artifact `json:"outputs"`
}
19 changes: 19 additions & 0 deletions pkg/entrypoint/entrypointer.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,28 @@ func (e Entrypointer) Go() error {
}
}

artifacts, err := e.readArtifacts()
if err != nil {
logger.Fatalf("Error while handling artifacts: %s", err)
}
output = append(output, artifacts...)

return err
}

func (e Entrypointer) readArtifacts() ([]result.RunResult, error) {
fp := filepath.Join(e.StepMetadataDir, "artifacts", "provenance.json")

file, err := os.ReadFile(fp)
if os.IsNotExist(err) {
return []result.RunResult{}, nil
}
if err != nil {
return nil, err
}
return []result.RunResult{{Key: fp, Value: string(file), ResultType: result.ArtifactsResultType}}, nil
}

func (e Entrypointer) readResultsFromDisk(ctx context.Context, resultDir string, resultType result.ResultType) error {
output := []result.RunResult{}
results := e.Results
Expand Down
12 changes: 12 additions & 0 deletions pkg/pod/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL

// Parse termination messages
terminationReason := ""
var as v1.Artifacts
if state.Terminated != nil && len(state.Terminated.Message) != 0 {
msg := state.Terminated.Message

Expand All @@ -281,6 +282,15 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL
logger.Errorf("termination message could not be parsed as JSON: %v", err)
merr = multierror.Append(merr, err)
} else {
for _, r := range results {
if r.ResultType == result.ArtifactsResultType {
if err := json.Unmarshal([]byte(r.Value), &as); err != nil {
merr = multierror.Append(merr, err)
}
// there should be only one ArtifactsResult
break
}
}
time, err := extractStartedAtTimeFromResults(results)
if err != nil {
logger.Errorf("error setting the start time of step %q in taskrun %q: %v", s.Name, tr.Name, err)
Expand Down Expand Up @@ -324,6 +334,8 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL
ImageID: s.ImageID,
Results: taskRunStepResults,
TerminationReason: terminationReason,
Inputs: as.Inputs,
Outputs: as.Outputs,
})
}

Expand Down
112 changes: 112 additions & 0 deletions pkg/pod/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,118 @@ func TestMakeTaskRunStatus_StepResults(t *testing.T) {
}
}

func TestMakeTaskRunStatus_StepArtifacts(t *testing.T) {
for _, c := range []struct {
desc string
podStatus corev1.PodStatus
pod corev1.Pod
tr v1.TaskRun
want v1.TaskRunStatus
}{
{
desc: "step artifacts result type",
podStatus: corev1.PodStatus{
Phase: corev1.PodSucceeded,
ContainerStatuses: []corev1.ContainerStatus{{
Name: "step-one",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"/tekton/run/0/status/artifacts/provenance.json","value":"{\n \"inputs\":[\n {\n \"name\":\"input-artifacts\",\n \"values\":[\n {\n \"uri\":\"git:jjjsss\",\n \"digest\":{\n \"sha256\":\"b35cacccfdb1e24dc497d15d553891345fd155713ffe647c281c583269eaaae0\"\n }\n }\n ]\n }\n ],\n \"outputs\":[\n {\n \"name\":\"build-results\",\n \"values\":[\n {\n \"uri\":\"pkg:balba\",\n \"digest\":{\n \"sha256\":\"df85b9e3983fe2ce20ef76ad675ecf435cc99fc9350adc54fa230bae8c32ce48\",\n \"sha1\":\"95588b8f34c31eb7d62c92aaa4e6506639b06ef2\"\n }\n }\n ]\n }\n ]\n}\n","type":5}]`,
},
},
}},
},
tr: v1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: "task-run",
Namespace: "foo",
},
Spec: v1.TaskRunSpec{
TaskSpec: &v1.TaskSpec{
Steps: []v1.Step{{
Name: "one",
}},
},
},
},
want: v1.TaskRunStatus{
Status: statusSuccess(),
TaskRunStatusFields: v1.TaskRunStatusFields{
Steps: []v1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"/tekton/run/0/status/artifacts/provenance.json","value":"{\n \"inputs\":[\n {\n \"name\":\"input-artifacts\",\n \"values\":[\n {\n \"uri\":\"git:jjjsss\",\n \"digest\":{\n \"sha256\":\"b35cacccfdb1e24dc497d15d553891345fd155713ffe647c281c583269eaaae0\"\n }\n }\n ]\n }\n ],\n \"outputs\":[\n {\n \"name\":\"build-results\",\n \"values\":[\n {\n \"uri\":\"pkg:balba\",\n \"digest\":{\n \"sha256\":\"df85b9e3983fe2ce20ef76ad675ecf435cc99fc9350adc54fa230bae8c32ce48\",\n \"sha1\":\"95588b8f34c31eb7d62c92aaa4e6506639b06ef2\"\n }\n }\n ]\n }\n ]\n}\n","type":5}]`,
}},
Name: "one",
Container: "step-one",
Inputs: []v1.Artifact{
{
Name: "input-artifacts",
Values: []v1.ArtifactValue{{
Digest: map[string]string{"sha256": "b35cacccfdb1e24dc497d15d553891345fd155713ffe647c281c583269eaaae0"},
Uri: "git:jjjsss",
},
},
},
},
Outputs: []v1.Artifact{
{
Name: "build-results",
Values: []v1.ArtifactValue{{
Digest: map[string]string{
"sha1": "95588b8f34c31eb7d62c92aaa4e6506639b06ef2",
"sha256": "df85b9e3983fe2ce20ef76ad675ecf435cc99fc9350adc54fa230bae8c32ce48",
},
Uri: "pkg:balba",
},
},
},
},
Results: []v1.TaskRunResult{},
}},
Sidecars: []v1.SidecarState{},
// We don't actually care about the time, just that it's not nil
CompletionTime: &metav1.Time{Time: time.Now()},
},
},
},
} {
t.Run(c.desc, func(t *testing.T) {
now := metav1.Now()
if cmp.Diff(c.pod, corev1.Pod{}) == "" {
c.pod = corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod",
Namespace: "foo",
CreationTimestamp: now,
},
Status: c.podStatus,
}
}

logger, _ := logging.NewLogger("", "status")
kubeclient := fakek8s.NewSimpleClientset()
got, err := MakeTaskRunStatus(context.Background(), logger, c.tr, &c.pod, kubeclient, c.tr.Spec.TaskSpec)
if err != nil {
t.Errorf("MakeTaskRunResult: %s", err)
}

// Common traits, set for test case brevity.
c.want.PodName = "pod"

ensureTimeNotNil := cmp.Comparer(func(x, y *metav1.Time) bool {
if x == nil {
return y == nil
}
return y != nil
})
if d := cmp.Diff(c.want, got, ignoreVolatileTime, ensureTimeNotNil); d != "" {
t.Errorf("Diff %s", diff.PrintWantGot(d))
}
})
}
}

func TestMakeTaskRunStatus(t *testing.T) {
for _, c := range []struct {
desc string
Expand Down
5 changes: 5 additions & 0 deletions pkg/result/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const (
UnknownResultType = 10
// StepResultType default step result value
StepResultType ResultType = 4

// ArtifactsResultType default artifacts result value
ArtifactsResultType ResultType = 5
)

// RunResult is used to write key/value pairs to TaskRun pod termination messages.
Expand Down Expand Up @@ -88,6 +91,8 @@ func (r *ResultType) UnmarshalJSON(data []byte) error {
*r = TaskRunResultType
case "InternalTektonResult":
*r = InternalTektonResultType
case "ArtifactsResult":
*r = ArtifactsResultType
default:
*r = UnknownResultType
}
Expand Down

0 comments on commit 7443e91

Please sign in to comment.