diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go index facce409cb9e..ad3af1257cf0 100644 --- a/workflow/controller/operator.go +++ b/workflow/controller/operator.go @@ -1920,6 +1920,14 @@ func (woc *wfOperationCtx) executeScript(nodeName string, templateScope string, // buildLocalScope adds all of a nodes outputs to the local scope with the given prefix, as well // as the global scope, if specified with a globalName func (woc *wfOperationCtx) buildLocalScope(scope *wfScope, prefix string, node *wfv1.NodeStatus) { + // It may be that the node is a retry node, in which case we want to get the outputs of the last node + // in the retry group instead of the retry node itself. + if node.Type == wfv1.NodeTypeRetry { + if lastNode, err := woc.getLastChildNode(node); err == nil { + node = lastNode + } + } + if node.PodIP != "" { key := fmt.Sprintf("%s.ip", prefix) scope.addParamToScope(key, node.PodIP) diff --git a/workflow/controller/operator_test.go b/workflow/controller/operator_test.go index eda10eaf738f..fbe94b6f3c71 100644 --- a/workflow/controller/operator_test.go +++ b/workflow/controller/operator_test.go @@ -2566,5 +2566,119 @@ func TestPodSpecLogForAllPods(t *testing.T) { for _, node := range woc.wf.Status.Nodes { assert.True(t, woc.shouldPrintPodSpec(node)) } +} +var retryNodeOutputs = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: daemon-step-dvbnn +spec: + arguments: {} + entrypoint: daemon-example + templates: + - arguments: {} + inputs: {} + metadata: {} + name: daemon-example + outputs: {} + steps: + - - arguments: {} + name: influx + template: influxdb + - arguments: {} + container: + image: influxdb:1.2 + name: "" + readinessProbe: + httpGet: + path: /ping + port: 8086 + resources: {} + daemon: true + inputs: {} + metadata: {} + name: influxdb + outputs: {} + retryStrategy: + limit: 10 +status: + finishedAt: null + nodes: + daemon-step-dvbnn: + children: + - daemon-step-dvbnn-1159996203 + displayName: daemon-step-dvbnn + finishedAt: "2020-04-02T16:29:24Z" + id: daemon-step-dvbnn + name: daemon-step-dvbnn + outboundNodes: + - daemon-step-dvbnn-2254877734 + phase: Succeeded + startedAt: "2020-04-02T16:29:18Z" + templateName: daemon-example + type: Steps + daemon-step-dvbnn-1159996203: + boundaryID: daemon-step-dvbnn + children: + - daemon-step-dvbnn-3639466923 + displayName: '[0]' + finishedAt: "2020-04-02T16:29:24Z" + id: daemon-step-dvbnn-1159996203 + name: daemon-step-dvbnn[0] + phase: Succeeded + startedAt: "2020-04-02T16:29:18Z" + templateName: daemon-example + type: StepGroup + daemon-step-dvbnn-2254877734: + boundaryID: daemon-step-dvbnn + daemoned: true + displayName: influx(0) + finishedAt: "2020-04-02T16:29:24Z" + id: daemon-step-dvbnn-2254877734 + name: daemon-step-dvbnn[0].influx(0) + phase: Running + podIP: 172.17.0.8 + resourcesDuration: + cpu: 10 + memory: 0 + startedAt: "2020-04-02T16:29:18Z" + templateName: influxdb + type: Pod + daemon-step-dvbnn-3639466923: + boundaryID: daemon-step-dvbnn + children: + - daemon-step-dvbnn-2254877734 + displayName: influx + finishedAt: "2020-04-02T16:29:24Z" + id: daemon-step-dvbnn-3639466923 + name: daemon-step-dvbnn[0].influx + phase: Succeeded + startedAt: "2020-04-02T16:29:18Z" + templateName: influxdb + type: Retry + phase: Succeeded + startedAt: "2020-04-02T16:29:18Z" + +` + +// This tests to see if the outputs of the last child node of a retry node are added correctly to the scope +func TestRetryNodeOutputs(t *testing.T) { + controller := newController() + wfcset := controller.wfclientset.ArgoprojV1alpha1().Workflows("") + wf := unmarshalWF(retryNodeOutputs) + wf, err := wfcset.Create(wf) + assert.NoError(t, err) + wf, err = wfcset.Get(wf.ObjectMeta.Name, metav1.GetOptions{}) + assert.NoError(t, err) + woc := newWorkflowOperationCtx(wf, controller) + + retryNode := woc.getNodeByName("daemon-step-dvbnn[0].influx") + assert.NotNil(t, retryNode) + fmt.Println(retryNode) + scope := &wfScope{ + scope: make(map[string]interface{}), + } + woc.buildLocalScope(scope, "steps.influx", retryNode) + assert.Contains(t, scope.scope, "steps.influx.ip") }