-
Notifications
You must be signed in to change notification settings - Fork 35
/
result.go
159 lines (128 loc) · 4.21 KB
/
result.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package claim
import (
"fmt"
"strconv"
"time"
"github.com/pkg/errors"
)
// Result tracks the result of an operation on a CNAB installation
type Result struct {
// Id of the result.
ID string `json:"id"`
// ClaimId associated with the claim that generated the result.
ClaimID string `json:"claimId"`
// Claim associated with the Result.
// This is not stored in the Result document but is loaded onto
// the Result to build an in-memory hierarchy.
// This may not always be set depending on how the Result was constructed.
claim *Claim
// Created timestamp of the result.
Created time.Time `json:"created"`
// Message communicates the outcome of the operation.
Message string `json:"message,omitempty"`
// Status of the operation, for example StatusSucceeded.
Status string `json:"status"`
// OutputMetadata generated by the operation, mapping from the output names to
// metadata about the output.
OutputMetadata OutputMetadata `json:"outputs,omitempty"`
// Custom extension data applicable to a given runtime.
Custom interface{} `json:"custom,omitempty"`
}
// NewResult creates a Result document with all required values set.
func NewResult(c Claim, status string) (Result, error) {
id, err := NewULID()
if err != nil {
return Result{}, err
}
return Result{
ID: id,
ClaimID: c.ID,
claim: &c,
Created: time.Now(),
Status: status,
OutputMetadata: OutputMetadata{},
}, nil
}
// Validate the Result
func (r Result) Validate() error {
if r.ID == "" {
return errors.New("the result id must be set")
}
if r.ClaimID == "" {
return errors.New("the claimID must be set")
}
switch r.Status {
case StatusCanceled, StatusFailed, StatusPending, StatusRunning, StatusSucceeded, StatusUnknown:
return nil
}
return fmt.Errorf("invalid status: %s", r.Status)
}
// HasLogs indicates if logs were persisted for the result.
func (r Result) HasLogs() bool {
if r.OutputMetadata == nil {
return false
}
_, ok := r.OutputMetadata[OutputInvocationImageLogs]
return ok
}
// Results is a sortable list of Result documents.
type Results []Result
func (r Results) Len() int {
return len(r)
}
func (r Results) Less(i, j int) bool {
return r[i].ID < r[j].ID
}
func (r Results) Swap(i, j int) {
r[i], r[j] = r[j], r[i]
}
// OutputMetadata is the output metadata from an operation.
// Any metadata can be stored, however this provides methods
// for safely querying and retrieving well-known metadata.
type OutputMetadata map[string]map[string]string
// GetMetadata for the specified output and key.
func (o OutputMetadata) GetMetadata(outputName string, metadataKey string) (string, bool) {
if output, ok := o[outputName]; ok {
if value, ok := output[metadataKey]; ok {
return value, true
}
}
return "", false
}
// SetMetadata for the specified output and key.
func (o *OutputMetadata) SetMetadata(outputName string, metadataKey string, value string) error {
if *o == nil { // If the receiver is nil, initialize it to an empty map
*o = OutputMetadata{}
}
metadata := *o
outputMetadata, ok := metadata[outputName]
if !ok {
outputMetadata = map[string]string{
metadataKey: value,
}
metadata[outputName] = outputMetadata
return nil
}
outputMetadata[metadataKey] = value
return nil
}
// GetGeneratedByBundle flag for the specified output.
func (o *OutputMetadata) GetGeneratedByBundle(outputName string) (bool, bool) {
if generatedByBundleS, ok := o.GetMetadata(outputName, OutputGeneratedByBundle); ok {
generatedByBundle, err := strconv.ParseBool(generatedByBundleS)
return generatedByBundle, err == nil
}
return false, false
}
// SetGeneratedByBundle for the specified output.
func (o *OutputMetadata) SetGeneratedByBundle(outputName string, generatedByBundle bool) error {
return o.SetMetadata(outputName, OutputGeneratedByBundle, strconv.FormatBool(generatedByBundle))
}
// GetContentDigest for the specified output.
func (o *OutputMetadata) GetContentDigest(outputName string) (string, bool) {
return o.GetMetadata(outputName, OutputContentDigest)
}
// SetContentDigest for the specified output.
func (o *OutputMetadata) SetContentDigest(outputName string, contentDigest string) error {
return o.SetMetadata(outputName, OutputContentDigest, contentDigest)
}