Skip to content

Commit 7443e91

Browse files
committed
feat: surface artifacts through termination message
1 parent 9a089d7 commit 7443e91

File tree

6 files changed

+158
-0
lines changed

6 files changed

+158
-0
lines changed

pkg/apis/pipeline/v1/artifact_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ type ArtifactValue struct {
1919
// TaskRunStepArtifact represents an artifact produced or used by a step within a task run.
2020
// It directly uses the Artifact type for its structure.
2121
type TaskRunStepArtifact = Artifact
22+
23+
type Artifacts struct {
24+
Inputs []Artifact `json:"inputs"`
25+
Outputs []Artifact `json:"outputs"`
26+
}

pkg/apis/pipeline/v1beta1/artifact_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ type ArtifactValue struct {
1919
// TaskRunStepArtifact represents an artifact produced or used by a step within a task run.
2020
// It directly uses the Artifact type for its structure.
2121
type TaskRunStepArtifact = Artifact
22+
23+
type Artifacts struct {
24+
Inputs []Artifact `json:"inputs"`
25+
Outputs []Artifact `json:"outputs"`
26+
}

pkg/entrypoint/entrypointer.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,28 @@ func (e Entrypointer) Go() error {
269269
}
270270
}
271271

272+
artifacts, err := e.readArtifacts()
273+
if err != nil {
274+
logger.Fatalf("Error while handling artifacts: %s", err)
275+
}
276+
output = append(output, artifacts...)
277+
272278
return err
273279
}
274280

281+
func (e Entrypointer) readArtifacts() ([]result.RunResult, error) {
282+
fp := filepath.Join(e.StepMetadataDir, "artifacts", "provenance.json")
283+
284+
file, err := os.ReadFile(fp)
285+
if os.IsNotExist(err) {
286+
return []result.RunResult{}, nil
287+
}
288+
if err != nil {
289+
return nil, err
290+
}
291+
return []result.RunResult{{Key: fp, Value: string(file), ResultType: result.ArtifactsResultType}}, nil
292+
}
293+
275294
func (e Entrypointer) readResultsFromDisk(ctx context.Context, resultDir string, resultType result.ResultType) error {
276295
output := []result.RunResult{}
277296
results := e.Results

pkg/pod/status.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL
273273

274274
// Parse termination messages
275275
terminationReason := ""
276+
var as v1.Artifacts
276277
if state.Terminated != nil && len(state.Terminated.Message) != 0 {
277278
msg := state.Terminated.Message
278279

@@ -281,6 +282,15 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL
281282
logger.Errorf("termination message could not be parsed as JSON: %v", err)
282283
merr = multierror.Append(merr, err)
283284
} else {
285+
for _, r := range results {
286+
if r.ResultType == result.ArtifactsResultType {
287+
if err := json.Unmarshal([]byte(r.Value), &as); err != nil {
288+
merr = multierror.Append(merr, err)
289+
}
290+
// there should be only one ArtifactsResult
291+
break
292+
}
293+
}
284294
time, err := extractStartedAtTimeFromResults(results)
285295
if err != nil {
286296
logger.Errorf("error setting the start time of step %q in taskrun %q: %v", s.Name, tr.Name, err)
@@ -324,6 +334,8 @@ func setTaskRunStatusBasedOnStepStatus(ctx context.Context, logger *zap.SugaredL
324334
ImageID: s.ImageID,
325335
Results: taskRunStepResults,
326336
TerminationReason: terminationReason,
337+
Inputs: as.Inputs,
338+
Outputs: as.Outputs,
327339
})
328340
}
329341

pkg/pod/status_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,118 @@ func TestMakeTaskRunStatus_StepResults(t *testing.T) {
433433
}
434434
}
435435

436+
func TestMakeTaskRunStatus_StepArtifacts(t *testing.T) {
437+
for _, c := range []struct {
438+
desc string
439+
podStatus corev1.PodStatus
440+
pod corev1.Pod
441+
tr v1.TaskRun
442+
want v1.TaskRunStatus
443+
}{
444+
{
445+
desc: "step artifacts result type",
446+
podStatus: corev1.PodStatus{
447+
Phase: corev1.PodSucceeded,
448+
ContainerStatuses: []corev1.ContainerStatus{{
449+
Name: "step-one",
450+
State: corev1.ContainerState{
451+
Terminated: &corev1.ContainerStateTerminated{
452+
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}]`,
453+
},
454+
},
455+
}},
456+
},
457+
tr: v1.TaskRun{
458+
ObjectMeta: metav1.ObjectMeta{
459+
Name: "task-run",
460+
Namespace: "foo",
461+
},
462+
Spec: v1.TaskRunSpec{
463+
TaskSpec: &v1.TaskSpec{
464+
Steps: []v1.Step{{
465+
Name: "one",
466+
}},
467+
},
468+
},
469+
},
470+
want: v1.TaskRunStatus{
471+
Status: statusSuccess(),
472+
TaskRunStatusFields: v1.TaskRunStatusFields{
473+
Steps: []v1.StepState{{
474+
ContainerState: corev1.ContainerState{
475+
Terminated: &corev1.ContainerStateTerminated{
476+
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}]`,
477+
}},
478+
Name: "one",
479+
Container: "step-one",
480+
Inputs: []v1.Artifact{
481+
{
482+
Name: "input-artifacts",
483+
Values: []v1.ArtifactValue{{
484+
Digest: map[string]string{"sha256": "b35cacccfdb1e24dc497d15d553891345fd155713ffe647c281c583269eaaae0"},
485+
Uri: "git:jjjsss",
486+
},
487+
},
488+
},
489+
},
490+
Outputs: []v1.Artifact{
491+
{
492+
Name: "build-results",
493+
Values: []v1.ArtifactValue{{
494+
Digest: map[string]string{
495+
"sha1": "95588b8f34c31eb7d62c92aaa4e6506639b06ef2",
496+
"sha256": "df85b9e3983fe2ce20ef76ad675ecf435cc99fc9350adc54fa230bae8c32ce48",
497+
},
498+
Uri: "pkg:balba",
499+
},
500+
},
501+
},
502+
},
503+
Results: []v1.TaskRunResult{},
504+
}},
505+
Sidecars: []v1.SidecarState{},
506+
// We don't actually care about the time, just that it's not nil
507+
CompletionTime: &metav1.Time{Time: time.Now()},
508+
},
509+
},
510+
},
511+
} {
512+
t.Run(c.desc, func(t *testing.T) {
513+
now := metav1.Now()
514+
if cmp.Diff(c.pod, corev1.Pod{}) == "" {
515+
c.pod = corev1.Pod{
516+
ObjectMeta: metav1.ObjectMeta{
517+
Name: "pod",
518+
Namespace: "foo",
519+
CreationTimestamp: now,
520+
},
521+
Status: c.podStatus,
522+
}
523+
}
524+
525+
logger, _ := logging.NewLogger("", "status")
526+
kubeclient := fakek8s.NewSimpleClientset()
527+
got, err := MakeTaskRunStatus(context.Background(), logger, c.tr, &c.pod, kubeclient, c.tr.Spec.TaskSpec)
528+
if err != nil {
529+
t.Errorf("MakeTaskRunResult: %s", err)
530+
}
531+
532+
// Common traits, set for test case brevity.
533+
c.want.PodName = "pod"
534+
535+
ensureTimeNotNil := cmp.Comparer(func(x, y *metav1.Time) bool {
536+
if x == nil {
537+
return y == nil
538+
}
539+
return y != nil
540+
})
541+
if d := cmp.Diff(c.want, got, ignoreVolatileTime, ensureTimeNotNil); d != "" {
542+
t.Errorf("Diff %s", diff.PrintWantGot(d))
543+
}
544+
})
545+
}
546+
}
547+
436548
func TestMakeTaskRunStatus(t *testing.T) {
437549
for _, c := range []struct {
438550
desc string

pkg/result/result.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const (
3535
UnknownResultType = 10
3636
// StepResultType default step result value
3737
StepResultType ResultType = 4
38+
39+
// ArtifactsResultType default artifacts result value
40+
ArtifactsResultType ResultType = 5
3841
)
3942

4043
// RunResult is used to write key/value pairs to TaskRun pod termination messages.
@@ -88,6 +91,8 @@ func (r *ResultType) UnmarshalJSON(data []byte) error {
8891
*r = TaskRunResultType
8992
case "InternalTektonResult":
9093
*r = InternalTektonResultType
94+
case "ArtifactsResult":
95+
*r = ArtifactsResultType
9196
default:
9297
*r = UnknownResultType
9398
}

0 commit comments

Comments
 (0)