stackstorm 6. 工作流之Mistral

  • Post author:
  • Post category:其他


1 Mistral


Mistral是一个用于管理和执行动作流的Openstack项目。Mistral是可以作为一个单独的

mistral服务在StackStorm中安装。一个Mistral工作流可以通过

https://docs.openstack.org/mistral/latest/user/wf_lang_v2.html

被定义为一个StackStorm动作。

表达式语言,例如YAQL被用于格式化变量和条件验证。从StackStorm2.2版本开始,

Jinja2也开始支持YAQL表达式。同样工作簿和工作流定义也是支持的。

在一个动作执行的时候,StackStorm编写Mistral定义并执行工作流。

一个工作流可以调用其他的StackStorm动作作为子任务。StackStorm处理

转化和在Mistral中显式调用并向Mistral轮询来获取执行结果。StackStorm

在工作流中的动作可以被追溯到原始的父动作,即调用工作的动作。

Essential Mistral Links:

Mistral workflow definition language, aka v2 WorkFlow Language

YAQL documentation and YAQL online evaluator

Jinja2 template engine documentation and Jinja2 online evaluator

2 基本工作流


与ActionChains相似,Mistral工作流在/opt/stackstorm/packs/<mypack>/actions

有一个动作元数据文件,工作流定义本身是在/opt/stackstorm/packs/<mypack>/actions/workflows。

让我们用一个非常基本的工作流调用一个StackStorm动作和在工作流完成时通知StackStorm的例子作为开始。

这个文件时在examples中,在/usr/share/doc/st2/examples的位置。

第一个任务叫做run-cmd。它在StackStorm安装的地方,在一个servier上执行了一个shell命令。

一个任务可以直接引用任何注册的StackStorm的动作。在例子中,这个run-cmd任务调用core.local,并传入

cmd作为输入。core.local是一个StackStorm安装时携带的动作。当工作流被调用时,StackStorm将会

在发送工作流给Mistral之前对工作流定定义进行合适地转换。让我们把它存储StackStorm的

/opt/stackstorm/packs/examples/actions/workflows/mistral-basic.yaml


version: ‘2.0’

examples.mistral-basic:

description: A basic workflow that runs an arbitrary linux command.

type: direct

input:

– cmd

– timeout

output:

stdout: <% $.stdout %>

tasks:

task1:

action: core.local cmd=<% $.cmd %> timeout=<% $.timeout %>

publish:

stdout: <% task(task1).result.stdout %>

stderr: <% task(task1).result.stderr %>


这是一个与StackStorm动作元数据相对应的例子。用于工作流动作的StackStorm的包叫做examples。

注意工作流在上述定义中以<pack>.<action>命名是完全合格的。StackStorm动作运行器是mistral-v2.

StackStorm的entry point指向工作流定义的YAML文件。我们将元数据保存为:

/opt/stackstorm/packs/examples/actions/mistral-basic.yaml



description: Run a local linux command

enabled: true

runner_type: mistral-v2

entry_point: workflows/mistral-basic.yaml

name: mistral-basic

pack: examples

parameters:

cmd:

required: true

type: string

timeout:

type: integer

default: 60

下面的可选参数列表可以被定义在工作流动作中。在例子中,这些可选参数被设置为

不可修改的。设置它们为不可修改的是一种良好的实践,即使它们为空。

options    description

workflow    如果定义是一个包含了许多工作流的workbook,这个参数指定了要执行的主工作流。

task        如果工作流是逆序的,这个参数指定了要调用的任务。

context    一个包含额外工作流启动参数的字典。

下一步,运行 st2 action create /opt/stackstorm/packs/examples/actions/mistral-basic.yaml

来创建工作流动作。这将会注册动作流以examples.mistral-basic的形式到StackStorm中。

为了执行工作流,运行:

st2 run examples.mistral-basic cmd=date -a

而 -a告诉命令无需等待工作流完成即可返回。

如果工作流成功完成,工作流examples.mistral-basic和动作core.local

在StackStorm的动作执行列表中应该有一个succeeded状态。

默认,st2 execution list只返回顶级的执行。这意味着自任务并不会被展现。

+————————–+————–+————–+———–+—————–+—————+

| id                       | action.ref   | context.user | status    | start_timestamp | end_timestamp |

+————————–+————–+————–+———–+—————–+—————+

| 54ee54c61e2e24152b769a47 | examples     | stanley      | succeeded | Wed, 25 Feb     | Wed, 25 Feb   |

|                          | .mistral-    |              |           | 2015 23:03:34   | 2015 23:03:34 |

|                          | basic        |              |           | UTC             | UTC           |

+————————–+————–+————–+———–+—————–+—————+

为了展示子任务,运行:

st2 execution get <execution-id> –show-tasks

+————————–+————+————–+———–+——————————+——————————+

| id                       | action.ref | context.user | status    | start_timestamp              | end_timestamp                |

+————————–+————+————–+———–+——————————+——————————+

| 54ee54c91e2e24152b769a49 | core.local | stanley      | succeeded | Wed, 25 Feb 2015 23:03:37    | Wed, 25 Feb 2015 23:03:37    |

|                          |            |              |           | UTC                          | UTC                          |

+————————–+————+————–+———–+——————————+——————————+

下面是基于先前工作流定义的简单扩展。在这个例子中,我们已经有第二个叫做”task2″的任务。

很自然地可以想到,按照顺序task2将会在task1后面执行。然而,当没有任务属性例如:

on-complete, on-success和on-error是被定义地,任务将会并行。这在Mistral中是可能地,

因为它提供了一个工作流加入控制,这允许我们同步多个并行地工作流分支,并可以巨基它们地数据。

version: ‘2.0’

examples.mistral-basic-two-tasks-with-notifications:

description: A basic workflow that runs two Linux commands (one in each task).

type: direct

output:

stdout: <% $.stdout %>

tasks:

task1:

action: core.local cmd=”echo task1″

publish:

stdout: <% task(task1).result.stdout %>

stderr: <% task(task1).result.stderr %>

task2:

action: core.local cmd=”echo task2″

publish:

stdout: <% task(task2).result.stdout %>

stderr: <% task(task2).result.stderr %>

3 发布变量


一个Mistral任务可以产生结果,并将一个任务以变量的形式在其他任务中使用:

tasks:

get_hostname:

action: core.local

input:

cmd: “hostname”

publish:

hostname: <% task(get_hostname).result.stdout %>

在上述的例子中,get_hostname是一个core.local动作,该动作运行命令 hostname。

这个 core.local动作产生了的输出由stdout, stderr, exit_code等字段构成。

我们仅仅将变量stdout发布,以供剩余的任务使用。为了在任务中引用结果,使用

task功能,该功能呢个返回一个包含任务属性的字典,例如: id, state, result

和其他信息。

另一个例子显示如下:

tasks:

create_new_node:

action: rackspace.create_vm

input:

name: <% $.hostname %>

flavor_id: <% $.vm_size_id %>

image_id: <% $.vm_image_id %>

key_material: <% $.ssh_pub_key %>

metadata:

asg: <% $.asg %>

publish:

ipv4_address: ‘<% task(create_new_node).result.result.public_ips[1] %>’

ipv6_address: ‘<% task(create_new_node).result.result.public_ips[0] %>’


在上述例子中,动作rackspace.create_vm是一个Python动作,该动作长生了一个result对象。

我们仅仅想要从result对象的public_ips的列表字段中将IP地址发布出去。

请注意result.result不是一个打印错误。这个Python动作提交了一个叫做result的key,用于st2

动作执行和Mistral 任务函数将Python动作的结果存储到输出字典的result中。

这样发布的变量是可以作为输入参数被工作流中其他任务获取的。在下面的其他任务中使用ipv3_address的例子如下:

tasks:

# … <snap>

setup_ipv4_dns:

action: rackspace.create_dns_record

wait-before: 1 # delay, in seconds

input:

name: ‘<% $.hostname %>.<% $.asg %>.<% $.domain %>’

zone_id: <% $.dns_zone_id %>

type: ‘A’

data: <% $.ipv4_address %>

# …. </snap>


4 一起构造一个复杂的工作流


下面是一个复杂工作流的仿制。在这个仿制中运行了简单的printf和sleep命令,

工作流展示了内迁的工作流,fork和join:

version: “2.0”

name: examples.mistral-workbook-complex

description: A sample workflow that demonstrates nested workflows, forks, and join.

workflows:

main:

type: direct

input:

– vm_name

– cpu_cores

– memory_mb

output:

vm_id: <% $.vm_id %>

ip: <% $.ip %>

tasks:

register_dns:

action: core.local

input:

cmd: “sleep 1; printf ‘Registering <% $.vm_name %>…'”

publish:

ip: “10.1.23.99”

status_message: “DNS for <% $.vm_name %> is registered.”

on-success:

– configure_vm

– notify

create_vm:

wait-before: 1

workflow: create_vm

input:

name: <% $.vm_name %>

cpu_cores: <% $.cpu_cores %>

memory_mb: <% $.memory_mb %>

publish:

vm_id: <% task(create_vm).result.vm_id %>

status_message: “VM <% $.vm_name %> is created.”

on-success:

– configure_vm

– notify

configure_vm:

join: all

workflow: configure_vm

input:

vm_id: <% $.vm_id %>

ip: <% $.ip %>

publish:

status_message: “VM <% $.vm_name %> is reconfigured.”

on-success:

– close_request

– notify

close_request:

action: std.noop

publish:

status_message: “VM request is fulfilled.”

on-success:

– notify

notify:

action: core.local

input:

cmd: “printf ‘<% $.status_message %>'”

create_vm:

type: direct

input:

– name

– cpu_cores

– memory_mb

output:

vm_id: <% $.vm_id %>

tasks:

create:

action: core.local

input:

cmd: “printf ‘vm1234’; sleep 5”

publish:

vm_id: <% task(create).result.stdout %>

configure_vm:

type: direct

input:

– vm_id

– ip

tasks:

add_disks:

action: core.local

input:

cmd: “sleep 1; printf ‘disks created'”

add_nics:

action: core.local

input:

cmd: “sleep 1; printf ‘nics created'”

install_apps:

action: core.local

input:

cmd: “sleep 1; printf ‘apps installed'”

在这个工作簿中有多个工作流被定义,工作流作者必须在元数据中指定要执行的工作流:



description: Run a series of simulated actions.

enabled: true

entry_point: workflows/mistral-workbook-complex.yaml

name: mistral-workbook-complex

pack: examples

parameters:

cpu_cores:

default: 1

type: integer

memory_mb:

default: 1024

type: integer

vm_name:

required: true

type: string

workflow:

default: examples.mistral-workbook-complex.main

immutable: true

type: string

runner_type: mistral-v2

为了测试工作流的输出,将元数据文件存储在

/opt/stackstorm/packs/examples/actions/

而工作流文件存储在

/opt/stackstorm/packs/examples/actions/workflows



运行

st2 action create /opt/stackstorm/packs/examples/actions/mistral-workbook-complex.yaml

来创建动作并执行

st2 run examples.mistral-workbook-complex vm_name=”vmtest1″ -a

用于测试。

5 验证


Mistral 命令行包含了用于执行逻辑高度清晰的工作流YAML文件工作:

# 验证一个工作流

mistral workflow-validate /path/to/workflow.yaml

# 验证一个工作簿

mistral workbook-validate /path/to/workbook.yaml


6 更多的例子


更多工作流的例子在

/usr/share/doc/st2/examples

。这些例子包含了错误处理,重复和重试。

一步一步的实验来在StackStorm重创建工作流请参见:

https://stackstorm.com/2015/07/08/automating-with-mistral-workflow/

更多关于Mistral的细节可以在下面找到:

https://docs.openstack.org/mistral/latest/


以上翻译自:

https://docs.stackstorm.com/mistral.html