ActionChain是一个不加修饰的线性工作流。它是动作调用的简单串联。每个动作的结果(
成功或失败)会被检查并用于确定下一次动作的执行。它提供了简单的分支逻辑,基于成功或失败。
数据可以在各个动作只见传递,并且结果可以发布给每个动作。
从StackStorm的观点来看,一个动作链是一个动作。因此,它有相同的操作和特性。
例如从命令行的定义,注册,执行,规则的使用,等等。一个动作链可以像一个动作一样被另一个
动作链调用,或者被一个Mistral工作流调用。
动作链被定义在包中,在 /opt/stackstorm/packs/
一个动作链需要两个文件: 一个YAML元数据文件,和用于简单动作相同的作用,
和一个ActionChain定义文件。元数据文件在
而ActionChain定义被放在
动作链元数据对于其他动作来说是简单的。最关键的不同之处在于它制定了act8ion-chain作为runner_type,
并且entry_point指向了工作流定义文件。
下面是一个例子,显示了为动作链echochain.yaml定义的元数据echochain.meta.yaml
---
# Action definition metadata
name: "echochain"
description: "Simple Action Chain workflow"
# `runner_type` has value `action-chain` to identify that action is an ActionChain.
runner_type: "action-chain"
# `entry_point` path to the ActionChain definition file, relative to the pack's action directory.
entry_point: "chains/echochain.yaml"
enabled: true
parameters:
skip_notify:
default:
- c2
notify:
on-complete:
message: "\"@channel: Action succeeded.\""
routes:
- "slack"
echochain.yaml是对应动作链工作流的定义:
---
chain:
-
name: "c1"
ref: "core.local"
parameters:
cmd: "echo c1"
on-success: "c2"
on-failure: "c4"
-
name: "c2"
ref: "core.local"
parameters:
cmd: "echo \"c2: parent exec is {{action_context.parent.execution_id}}.\""
on-success: "c3"
on-failure: "c4"
-
name: "c3"
ref: "core.local"
parameters:
cmd: "echo c3"
on-failure: "c4"
-
name: "c4"
ref: "core.local"
parameters:
cmd: "echo fail c4"
default: "c1"
chain:是包含动作的数组属性,封装了动作调用
Tasks: 被命名为动作的的执行,并以列表形式指定。名字
是在动作链中指定的,并被用于执行一个task。
ref:该属性是一个注册到StackStorm的任务点,这可以在任何pack中。
on-success:是当动作成功执行的时候链接到的任务,如果没有提供,
动作链键会以success状态来终止。
on-failuer:是一个可选的链接,可用于当动作执行失败的时候链接到的任务。、
如果没有提供,动作链将会以error状态来终止。
default: 是一个可选的定义属性,该属性值点明了动作链的起始任务。如果default
没有被显示指定,ActionChain会从第一个动作开始指定。
一旦动作定义文件和元数据文件被创建了,加载动作:
#注册动作
st2 action create /opt/stackstorm/packs/examples/actions/echochain.meta.yaml
#检查它是否可用
st2 action list --pack=examples
#运行它
st2 run examples.echochain
任何在ActionChain工作流定义中的动作会被自动串联。然而,如果你改变了动作的元数据
(例如: 重命名或者添加参数),你需要通过
st2 action update
通过 st2ctl reload --register-all 将会所所有改变进行再一次加载。
为了提供输入到一个动作链中,输入参数必须定义在动作的元数据中:
---
# Action definition metadata
name: "echochain-param"
description: "Action Chain workflow passing variables"
# `runner_type` identifies the runner
runner_type: "action-chain"
# `entry_point` path to the ActionChain definition file, relative to the pack's action directory.
entry_point: "chains/echochain_param.yaml"
enabled: true
parameters:
input1:
type: "string"
required: true
description: "Any string to pass down"
输入参数input1可以在一个任务的参数中被引用,
---
# ...
chain:
-
name: "action1"
ref: "core.local"
parameters:
action1_input: "{{input1}}"
# ...
action1_input有值 {{input1}}.这个语法是Jinja模板支持的变量渲染。
相似的狗在也可以在Rule criteria和action的字段中被使用
ActionChain提供了命名参数的简便性。全部变量被vars关键词定义在顶部。
Tasks任务通过publish关键字发布新的变量。 Variables are handy when you need to mash up a reusable value from the input, globals, datastore values, and results of multiple action executions.
所有的变量都被Jinja语法引用。累计的已发布变量都可以在一个
ActionChian执行结果的publisher属性中被获得,如果display_published属性支持ActionChain Runner。
---
vars:
domain: "{{ st2kv.system.domain }}" # Global Var
port: 9101
chain:
-
name: get_service_data
ref: my_pack.get_services
publish:
url_1: http://"{{ get_service_data.result[0].host.name }}.{{ domain }}:{{ port }}"
这个publish_data.yaml工作流在examples包中,它通过使用vars和publish显示了一个复杂的例子:
---
vars:
domain: "{{ st2kv.system.domain }}" # `system` references DataStore key-values. Null if not set.
api_port: 9101
webui_port: 8080
chain:
-
name: "get_host"
ref: "core.local"
parameters:
cmd: hostname | tr -d ' \n'
publish:
# Publish a variable to shortcut a long expression
api_url: "http://{{ get_host.stdout }}:{{ api_port }}"
webui_url: "http://{{ get_host.stdout }}:{{ webui_port }}"
host: "{{ get_host.stdout }}"
# Jinja woodoo used for basic logic
fqdn: "{{ get_host.stdout }}{% if domain %}.{{ domain }}{% endif %}"
# A complex object can be published
paths:
api: [ "v1/actions", "v1/triggers"]
webui: "/"
auth_port: "{{ api_port + 1 }}"
# This variable references "system_info_path" variable which is an action parameter
system_info: "{{ system_info_path }}"
on-success: say_the_names
-
name: say_the_names
先前的任务的输出可以通过类似的方式作为一个动作链的输入。
在例子 echochain_param.yaml中展示了输入和数据在工作流中如何传递。
---
chain:
-
name: "c1"
ref: "core.local"
parameters:
cmd: "echo c1, input {{input1}}" # Refers to action's input parameter
on-success: "c2"
on-failure: "c4"
-
name: "c2"
ref: "core.local"
parameters:
cmd: "echo c2 {{c1.stdout}}" # refers to previous action's output
on-success: "c3"
on-failure: "c4"
-
name: "c3"
ref: "core.local"
parameters:
cmd: "echo c3 {{c2.stdout}}"
on-failure: "c4"
-
name: "c4"
ref: "core.local"
parameters:
cmd: "echo fail c4"
default: "c1"
细节:
1) 一个任务的输出总是以该任务的名称作为前缀,例如:
在{"cmd":"echo c2 {{c1.stdout}}"}中,c1.stdout执行了'c1'的输出,
并且挖掘到输出的属性列表中。这个引用的关键就是action_execution对象的result
字段。
2) 一个特殊的__results 的键提供了对整个链执行结果的访问。
在stackstorm中,一个工作流仅仅是一个动作。这意味着你可以将一个工作流的数据传递
给另一个,正如你可以讲述传递到一个动作中,你可以使用action参数。
在下面的例子中,我们有两个工作流-workflow1和workflow2。在饥饿和任务被命名为
在workflow1中task2调用workflow2并传递变量date给它作为一个动作参数。
workflow2接着可以使用这个值并将它打印到便准输出。
workflow1.yaml
---
chain:
-
name: "task1"
ref: "core.local"
parameters:
cmd: "date"
on-success: "task2"
-
name: "task2"
ref: "mypack.workflow2"
parameters:
date: "{{ task1.stdout }}" # Here we pass result from "task1" as a "date" action parameter to the action "workflow2"
workflow2.meta.yaml
---
name: "workflow2"
description: "..."
runner_type: "action-chain"
entry_point: "workflow2.yaml"
enabled: true
parameters:
date:
type: "string"
description: "Date which show be printed to stdout"
required: True
workflow2.yaml
---
chain:
-
name: "task1"
ref: "core.local"
parameters:
cmd: "echo {{ date }}" # Here we echo the variable "date" which was passed to the workflow as an action parameter
上述例子可以应用在当你有两个相关的工作流,并且一个调用了另一个的场景。
If you have two independent workflows
如果你拥有两个独立的工作流,并且你希望在它们之间传递数据或者
在另一个工作流中使用一个工作流的数据,最常见的方法就是使用内置的键值对datastore。
在第一个工作流中,你可以在datastore中存储数据,并在第二个工作流中在datastore中查询数据。
这个方法创建了严密的链接。
使用action参数意味着第二种工作流可以被服用并且运行独立于第一个-仅仅需要传递需要的参数给它。
可以通过运行 st2 execution pause
一个执行必须是处于运行中状态才能被成功暂停。这次执行最初进入到pausing状态,如果没有更多的
任务处于激活状态(例如: running, pausing,或者canceling)接着
会进入到paused状态。当一个动作链暂停了,它可以通过运行
st2 execution resume
已经发布的变量会在暂停的时候被存储在执行的上下文中,恢复的时候会再次被存储。
pause和resume操作会级联下降到子工作流中,无论它的另一个StackSTorm的动作是一个Mistral工作流或者动作链。
如果pause操作被自工作流或者子链执行了,这个pause将会级联上升到父工作流或者父链。
这允许用户恢复并充当故障检测员。
使用YAML和Jinja应用到一些限制中,如何命名和渲染变量:
1) 变量名可以使用字母,下划线和数字。没有横线。这对所有变量生效:
全剧变量,输入参数,DataStore的键,和已经发布的变量。
2)同样的命名规则应用到task名称中: this-task-name-is-wrong! 使用
task_names_with_underscores
3)通常引用变量渲染 "{{ my_variable.or.expression }}"
(记住{} 是一个YAML字典)。类型个子在Jinja模板中,但是but converted to strings outside: "{{ 1 + 2 }} + 3" resolves to "3 + 3".
ActionChain错误被分类为:
1) 错误是由链中指定的任务报告出来的。在这种情况下,任务中每个特定的动作行为都会
被报告。
样例输出:
{
"result": {
"tasks": [
{
"created_at": "2015-02-27T19:29:02.057885+00:00",
"execution_id": "54f0c57e0640fd177f278052",
"id": "c1",
"name": "c1",
"result": {
"failed": true,
"return_code": 127,
"stderr": "bash: borg: command not found\n",
"stdout": "",
"succeeded": false
},
"state": "failed",
"updated_at": "2015-02-27T19:29:03.149547+00:00",
"workflow": null
}
]
}
}
2)错误是由动作链运行时决定流的时候发生的。
样例输出:
{
"result": {
"error": "Failed to run task \"c2\". Parameter rendering failed: 's1' is undefined",
"traceback": "Traceback (most recent call last):...",
"tasks": [
{
"created_at": "2015-02-27T19:19:34.536558+00:00",
"execution_id": "54f0c3460640fd15a843957d",
"id": "c1",
"name": "c1",
"result": {
"failed": false,
"return_code": 0,
"stderr": "",
"stdout": "Fri Feb 27 19:19:34 UTC 2015\n",
"succeeded": true
},
"state": "succeeded",
"updated_at": "2015-02-27T19:19:35.591297+00:00",
"workflow": null
}
]
}
}
以上翻译自:
https://docs.stackstorm.com/actionchain.html