@@ -17,7 +17,6 @@ limitations under the License.
17
17
package pod
18
18
19
19
import (
20
- "encoding/json"
21
20
"fmt"
22
21
"sort"
23
22
"strings"
@@ -97,27 +96,51 @@ func SidecarsReady(podStatus corev1.PodStatus) bool {
97
96
}
98
97
99
98
// MakeTaskRunStatus returns a TaskRunStatus based on the Pod's status.
100
- func MakeTaskRunStatus (logger * zap.SugaredLogger , tr v1beta1.TaskRun , pod * corev1.Pod , taskSpec v1beta1.TaskSpec ) v1beta1.TaskRunStatus {
99
+ func MakeTaskRunStatus (logger * zap.SugaredLogger , tr v1beta1.TaskRun , pod * corev1.Pod , taskSpec v1beta1.TaskSpec ) ( v1beta1.TaskRunStatus , error ) {
101
100
trs := & tr .Status
102
101
if trs .GetCondition (apis .ConditionSucceeded ) == nil || trs .GetCondition (apis .ConditionSucceeded ).Status == corev1 .ConditionUnknown {
103
102
// If the taskRunStatus doesn't exist yet, it's because we just started running
104
103
MarkStatusRunning (trs , v1beta1 .TaskRunReasonRunning .String (), "Not all Steps in the Task have finished executing" )
105
104
}
106
105
106
+ // Complete if we did not find a step that is not complete, or the pod is in a definitely complete phase
107
+ complete := areStepsComplete (pod ) || pod .Status .Phase == corev1 .PodSucceeded || pod .Status .Phase == corev1 .PodFailed
108
+
109
+ if complete {
110
+ updateCompletedTaskRun (trs , pod )
111
+ } else {
112
+ updateIncompleteTaskRun (trs , pod )
113
+ }
114
+
107
115
trs .PodName = pod .Name
108
116
trs .Steps = []v1beta1.StepState {}
109
117
trs .Sidecars = []v1beta1.SidecarState {}
110
118
119
+ var err error
120
+
111
121
for _ , s := range pod .Status .ContainerStatuses {
112
122
if IsContainerStep (s .Name ) {
113
123
if s .State .Terminated != nil && len (s .State .Terminated .Message ) != 0 {
114
- message , time , err := removeStartInfoFromTerminationMessage (s )
124
+
125
+ var results []v1beta1.PipelineResourceResult
126
+ results , err = termination .ParseMessage (s .State .Terminated .Message )
115
127
if err != nil {
116
- logger .Errorf ("error setting the start time of step %q in taskrun %q: %w" , s .Name , tr .Name , err )
117
- }
118
- if time != nil {
119
- s .State .Terminated .StartedAt = * time
120
- s .State .Terminated .Message = message
128
+ logger .Errorf ("termination message could not be parsed as JSON: %v" , err )
129
+ } else {
130
+ //Further processing if the termination message is JSON formatted
131
+ var time * metav1.Time
132
+ time , err = extractStartedAtTimeFromResults (results )
133
+ if err != nil {
134
+ logger .Errorf ("error setting the start time of step %q in taskrun %q: %v" , s .Name , tr .Name , err )
135
+ }
136
+ if time != nil {
137
+ s .State .Terminated .StartedAt = * time
138
+ }
139
+ if tr .IsSuccessful () {
140
+ taskResults , pipelineResourceResults := filterResultsAndResources (results )
141
+ trs .TaskRunResults = append (trs .TaskRunResults , taskResults ... )
142
+ trs .ResourcesResult = append (trs .ResourcesResult , pipelineResourceResults ... )
143
+ }
121
144
}
122
145
}
123
146
trs .Steps = append (trs .Steps , v1beta1.StepState {
@@ -135,51 +158,70 @@ func MakeTaskRunStatus(logger *zap.SugaredLogger, tr v1beta1.TaskRun, pod *corev
135
158
})
136
159
}
137
160
}
138
-
139
- // Complete if we did not find a step that is not complete, or the pod is in a definitely complete phase
140
- complete := areStepsComplete (pod ) || pod .Status .Phase == corev1 .PodSucceeded || pod .Status .Phase == corev1 .PodFailed
141
-
142
- if complete {
143
- updateCompletedTaskRun (trs , pod )
144
- } else {
145
- updateIncompleteTaskRun (trs , pod )
146
- }
161
+ trs .TaskRunResults = removeDuplicateResults (trs .TaskRunResults )
147
162
148
163
// Sort step states according to the order specified in the TaskRun spec's steps.
149
164
trs .Steps = sortTaskRunStepOrder (trs .Steps , taskSpec .Steps )
150
165
151
- return * trs
166
+ return * trs , err
167
+ }
168
+
169
+ func filterResultsAndResources (results []v1beta1.PipelineResourceResult ) ([]v1beta1.TaskRunResult , []v1beta1.PipelineResourceResult ) {
170
+ var taskResults []v1beta1.TaskRunResult
171
+ var pipelineResourceResults []v1beta1.PipelineResourceResult
172
+ for _ , r := range results {
173
+ switch r .ResultType {
174
+ case v1beta1 .TaskRunResultType :
175
+ taskRunResult := v1beta1.TaskRunResult {
176
+ Name : r .Key ,
177
+ Value : r .Value ,
178
+ }
179
+ taskResults = append (taskResults , taskRunResult )
180
+ case v1beta1 .InternalTektonResultType :
181
+ // Internal messages are ignored because they're not used as external result
182
+ continue
183
+ case v1beta1 .PipelineResourceResultType :
184
+ fallthrough
185
+ default :
186
+ pipelineResourceResults = append (pipelineResourceResults , r )
187
+ }
188
+ }
189
+
190
+ return taskResults , pipelineResourceResults
152
191
}
153
192
154
- // removeStartInfoFromTerminationMessage searches for a result called "StartedAt" in the JSON-formatted
155
- // termination message of a step and returns the values to use for sets State.Terminated if it's
156
- // found. The "StartedAt" result is also removed from the list of results in the container status.
157
- func removeStartInfoFromTerminationMessage (s corev1.ContainerStatus ) (string , * metav1.Time , error ) {
158
- r , err := termination .ParseMessage (s .State .Terminated .Message )
159
- if err != nil {
160
- return "" , nil , fmt .Errorf ("termination message could not be parsed as JSON: %w" , err )
193
+ func removeDuplicateResults (taskRunResult []v1beta1.TaskRunResult ) []v1beta1.TaskRunResult {
194
+ if len (taskRunResult ) == 0 {
195
+ return nil
196
+ }
197
+
198
+ uniq := make ([]v1beta1.TaskRunResult , 0 )
199
+ latest := make (map [string ]v1beta1.TaskRunResult , 0 )
200
+ for _ , res := range taskRunResult {
201
+ if _ , seen := latest [res .Name ]; ! seen {
202
+ uniq = append (uniq , res )
203
+ }
204
+ latest [res .Name ] = res
205
+ }
206
+ for i , res := range uniq {
207
+ uniq [i ] = latest [res .Name ]
161
208
}
162
- for index , result := range r {
209
+ return uniq
210
+ }
211
+
212
+ func extractStartedAtTimeFromResults (results []v1beta1.PipelineResourceResult ) (* metav1.Time , error ) {
213
+
214
+ for _ , result := range results {
163
215
if result .Key == "StartedAt" {
164
216
t , err := time .Parse (timeFormat , result .Value )
165
217
if err != nil {
166
- return "" , nil , fmt .Errorf ("could not parse time value %q in StartedAt field: %w" , result .Value , err )
218
+ return nil , fmt .Errorf ("could not parse time value %q in StartedAt field: %w" , result .Value , err )
167
219
}
168
- message := ""
169
220
startedAt := metav1 .NewTime (t )
170
- // remove the entry for the starting time
171
- r = append (r [:index ], r [index + 1 :]... )
172
- if len (r ) == 0 {
173
- message = ""
174
- } else if bytes , err := json .Marshal (r ); err != nil {
175
- return "" , nil , fmt .Errorf ("error marshalling remaining results back into termination message: %w" , err )
176
- } else {
177
- message = string (bytes )
178
- }
179
- return message , & startedAt , nil
221
+ return & startedAt , nil
180
222
}
181
223
}
182
- return "" , nil , nil
224
+ return nil , nil
183
225
}
184
226
185
227
func updateCompletedTaskRun (trs * v1beta1.TaskRunStatus , pod * corev1.Pod ) {
0 commit comments