forked from argoproj/argo-workflows
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix issue where daemoned steps were not terminated properly in DAG te…
…mplates (resolves argoproj#832)
- Loading branch information
Showing
6 changed files
with
175 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# This example demonstrates daemoned steps when used in in DAG templates. It is is equivalent to the | ||
# daemon-step.yaml example, but written in DAG format. The IP address of the daemoned step can be | ||
# referenced using the '{{tasks.taskname.ip}}' variable. | ||
apiVersion: argoproj.io/v1alpha1 | ||
kind: Workflow | ||
metadata: | ||
generateName: dag-daemon-task- | ||
spec: | ||
entrypoint: daemon-example | ||
templates: | ||
- name: daemon-example | ||
dag: | ||
tasks: | ||
- name: influx | ||
template: influxdb | ||
|
||
- name: init-database | ||
template: influxdb-client | ||
dependencies: [influx] | ||
arguments: | ||
parameters: | ||
- name: cmd | ||
value: curl -XPOST 'http:https://{{tasks.influx.ip}}:8086/query' --data-urlencode "q=CREATE DATABASE mydb" | ||
|
||
- name: producer-1 | ||
template: influxdb-client | ||
dependencies: [init-database] | ||
arguments: | ||
parameters: | ||
- name: cmd | ||
value: for i in $(seq 1 20); do curl -XPOST 'http:https://{{tasks.influx.ip}}:8086/write?db=mydb' -d "cpu,host=server01,region=uswest load=$i" ; sleep .5 ; done | ||
- name: producer-2 | ||
template: influxdb-client | ||
dependencies: [init-database] | ||
arguments: | ||
parameters: | ||
- name: cmd | ||
value: for i in $(seq 1 20); do curl -XPOST 'http:https://{{tasks.influx.ip}}:8086/write?db=mydb' -d "cpu,host=server02,region=uswest load=$((RANDOM % 100))" ; sleep .5 ; done | ||
- name: producer-3 | ||
template: influxdb-client | ||
dependencies: [init-database] | ||
arguments: | ||
parameters: | ||
- name: cmd | ||
value: curl -XPOST 'http:https://{{tasks.influx.ip}}:8086/write?db=mydb' -d 'cpu,host=server03,region=useast load=15.4' | ||
|
||
- name: consumer | ||
template: influxdb-client | ||
dependencies: [producer-1, producer-2, producer-3] | ||
arguments: | ||
parameters: | ||
- name: cmd | ||
value: curl --silent -G http:https://{{tasks.influx.ip}}:8086/query?pretty=true --data-urlencode "db=mydb" --data-urlencode "q=SELECT * FROM cpu" | ||
|
||
- name: influxdb | ||
daemon: true | ||
container: | ||
image: influxdb:1.2 | ||
restartPolicy: Always | ||
readinessProbe: | ||
httpGet: | ||
path: /ping | ||
port: 8086 | ||
initialDelaySeconds: 5 | ||
timeoutSeconds: 1 | ||
|
||
- name: influxdb-client | ||
inputs: | ||
parameters: | ||
- name: cmd | ||
container: | ||
image: appropriate/curl:latest | ||
command: ["sh", "-c"] | ||
args: ["{{inputs.parameters.cmd}}"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../examples/dag-daemon-task.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package controller | ||
|
||
import ( | ||
"encoding/json" | ||
"time" | ||
|
||
"github.com/argoproj/argo/errors" | ||
"github.com/argoproj/argo/workflow/common" | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// killDeamonedChildren kill any daemoned pods of a steps or DAG template node. | ||
func (woc *wfOperationCtx) killDeamonedChildren(nodeID string) error { | ||
woc.log.Infof("Checking deamoned children of %s", nodeID) | ||
var firstErr error | ||
execCtl := common.ExecutionControl{ | ||
Deadline: &time.Time{}, | ||
} | ||
for _, childNode := range woc.wf.Status.Nodes { | ||
if childNode.BoundaryID != nodeID { | ||
continue | ||
} | ||
if childNode.Daemoned == nil || !*childNode.Daemoned { | ||
continue | ||
} | ||
err := woc.updateExecutionControl(childNode.ID, execCtl) | ||
if err != nil { | ||
woc.log.Errorf("Failed to update execution control of %s: %+v", childNode, err) | ||
if firstErr == nil { | ||
firstErr = err | ||
} | ||
} | ||
} | ||
return firstErr | ||
} | ||
|
||
// updateExecutionControl updates the execution control parameters | ||
func (woc *wfOperationCtx) updateExecutionControl(podName string, execCtl common.ExecutionControl) error { | ||
execCtlBytes, err := json.Marshal(execCtl) | ||
if err != nil { | ||
return errors.InternalWrapError(err) | ||
} | ||
|
||
woc.log.Infof("Updating execution control of %s: %s", podName, execCtlBytes) | ||
err = common.AddPodAnnotation( | ||
woc.controller.kubeclientset, | ||
podName, | ||
woc.wf.ObjectMeta.Namespace, | ||
common.AnnotationKeyExecutionControl, | ||
string(execCtlBytes), | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Ideally we would simply annotate the pod with the updates and be done with it, allowing | ||
// the executor to notice the updates naturally via the Downward API annotations volume | ||
// mounted file. However, updates to the Downward API volumes take a very long time to | ||
// propagate (minutes). The following code fast-tracks this by signaling the executor | ||
// using SIGUSR2 that something changed. | ||
woc.log.Infof("Signalling %s of updates", podName) | ||
exec, err := common.ExecPodContainer( | ||
woc.controller.restConfig, woc.wf.ObjectMeta.Namespace, podName, | ||
common.WaitContainerName, true, true, "sh", "-c", "kill -s USR2 1", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
go func() { | ||
// This call is necessary to actually send the exec. Since signalling is best effort, | ||
// it is launched as a goroutine and the error is discarded | ||
_, _, err = common.GetExecutorOutput(exec) | ||
if err != nil { | ||
log.Warnf("Signal command failed: %v", err) | ||
return | ||
} | ||
log.Infof("Signal of %s (%s) successfully issued", podName, common.WaitContainerName) | ||
}() | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters