StackStorm分析(四)Mistral说明

StackStorm介绍

       StackStorm是一个强大的自动化平台,结合DevOpsChatOps,提供可扩展、灵活和健壮的工具链用于应用、服务和工作流的自动化能力。

 



Mistral

       Mistral是Mirantis公司为Openstack开发的工作流组件,提供Workflow as aService。Stackstorm集成了Mistral,提供更加灵活和强大的Workflow支持。

Mistral的一些概念,需要和StackStrom的概念区分开来:

  • Workbook:工作簿。可以理解为工作流任务的文档,纪录了工作流,任务以及任务的执行顺序,依赖关系,以及每个任务的输入输出等。从开发者的角度看,可以认为它是一种工作流任务的文档组织形式,或者命名空间。
  • Workflow:工作流。比Workbook小的单元。描述了任务,动作的执行顺序,依赖关系。一个Workbook可以有多条Workflow,也可以只有一条Workflow。
  • Task:描述Workflow中包含的工作步骤。
  • Action:Mistral中最小的单位,描述了某一个具体的动作,比如执行一个http请求,或者发一个e-mail等等。

 

 

YAQL & Jinja

Mistral中支持的模板解析语法有YAQLJinja,这提供了强大的流程控制和语法支持。下面对比下YAQLJinja:

 

YAQL:

version: '2.0'

 

examples.mistral-branching:

    description: >

        A sample workflow that demonstrates how to use conditions

        to determine which path in the workflow to take.

    type: direct

    input:

        - which

    tasks:

        t1:

            action: core.local

            input:

                cmd: "printf <% $.which %>"

            publish:

                path: <% task(t1).result.stdout %>

            on-success:

                - a: <% $.path = 'a' %>

                - b: <% $.path = 'b' %>

                - c: <% not $.path in list(a, b) %>

        a:

            action: core.local

            input:

                cmd: "echo 'Took path A.'"

            publish:

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

        b:

            action: core.local

            input:

                cmd: "echo 'Took path B.'"

            publish:

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

        c:

            action: core.local

            input:

                cmd: "echo 'Took path C.'"

            publish:

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

 

Jinja

version: '2.0'

 

examples.mistral-jinja-branching:

    description: >

        A sample workflow that demonstrates how to use conditions

        to determine which path in the workflow to take.

    type: direct

    input:

        - which

    tasks:

        t1:

            action: core.local

            input:

                cmd: "echo {{ _.which }}"

            publish:

                path: "{{ task('t1').result.stdout }}"

            on-success:

                - a: "{{ _.path == 'a' }}"

                - b: "{{ _.path == 'b' }}"

                - c: "{{ not _.path in ['a', 'b'] }}"

        a:

            action: core.local

            input:

                cmd: "echo 'Took path A.'"

        b:

            action: core.local

            input:

                cmd: "echo 'Took path B.'"

        c:

            action: core.local

            input:

                cmd: "echo 'Took path C.'"


 

Mistral示例

       StackStorm的examples下面提供了关于Mistral的示例,我们接下来通过一系列的示例来说明Mistral。

examples.mistral-basic

同样的MistralWorkflow跟ActionChainWorkflow一样都需要提供元数据文件和规格文件,

Pack examples的元数据文件是在/opt/stackstorm/packs/examples/actions目录下,规格文件是在/opt/stackstorm/packs/examples/actions/workflows目录下.

/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

 

规格文件/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 %>

 

         根据定义examples.mistral-basic需要提供参数cmd(必选)和timeout(可选),然后在task1中调用core.local执行,并且打印执行结果。执行如下:

$ st2 run examples.mistral-basic cmd="date"

.

id: 5afba6ed2b2556015687cdda

action.ref: examples.mistral-basic

parameters:

  cmd: date

status: succeeded

result_task: task1

result:

  failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 03:35:10 UTC 2018

  succeeded: true

start_timestamp: Wed, 16 May 2018 03:35:09 UTC

end_timestamp: Wed, 16 May 2018 03:35:11 UTC

+--------------------------+------------------------+-------+------------+-------------------------------+

| id                       | status                 | task  | action     | start_timestamp               |

+--------------------------+------------------------+-------+------------+-------------------------------+

| 5afba6ee2b2556015687cddd | succeeded (0s elapsed) | task1 | core.local | Wed, 16 May 2018 03:35:10 UTC |

+--------------------------+------------------------+-------+------------+-------------------------------+

 

examples. mistral-workbook-basic

Mistral中有个WorkBook的概念,是Workflow的组合,也就是说可以同时定义多个Workflow

 

/opt/stackstorm/packs/examples/actions/workflows/mistral-workbook-multiple-subflows.yaml

version: "2.0"

name: "examples.mistral-workbook-multiple-subflows"

 

workflows:

 

    main:

        type: direct

        output:

            report: <% $.report %>

            state: <% $.state %>

        tasks:

            call_internal_workflow:

                workflow: wf1

                input:

                    v1: ok

                publish:

                    report: <% task(call_internal_workflow).result.report %>

                on-success:

                    - call_internal_workflow_multiple_tasks

            call_internal_workflow_multiple_tasks:

                workflow: wf2

                input:

                    v1: good

                    v2: excellent

                on-success:

                    - call_external_workflow

            call_external_workflow:

                action: examples.mistral-basic

                input:

                    cmd: "echo 'external workflow ok'"

                publish:

                    state: <% task(call_external_workflow).result.stdout %>

                on-success:

                    - call_action_chain

            call_action_chain:

                action: examples.echochain

 

    wf1:

        type: direct

        input:

            - v1

        output:

            report: <% $.report %>

        tasks:

            t1:

                action: core.local

                input:

                    cmd: "echo 'task1 <% $.v1 %>'; sleep 1"

                publish:

                    report: <% task(t1).result.stdout %>

 

    wf2:

        type: direct

        input:

            - v1

            - v2

        tasks:

            t1:

                action: core.local

                input:

                    cmd: "echo 'task2 <% $.v1 %>'; sleep 1"

            t2:

                action: core.local

                input:

                    cmd: "echo 'task3 <% $.v2 %>'; sleep 2"

 

examples.mistral-handle-error

Mistral Workflow通过可以设置子任务成功失败后的执行顺序,

/opt/stackstorm/packs/examples/actions/workflows/mistral-handle-error.yaml:

version: '2.0'

 

examples.mistral-handle-error:

    description: >

        A workflow example that illustrates error handling. By default when any task fails,

        the notify_on_error task will be executed and the workflow will transition to the

        failed state.

    type: direct

    input:

        - cmd

    vars:

        error_handled: False

    tasks:

        task1:

            action: core.local cmd="echo 1 && exit 0"

            publish:

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

            on-success:

                - task2

            on-error:

                - handle_error

        task2:

            action: core.local cmd="echo 2 && exit 1"

            publish:

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

            on-error:

                - handle_error

        handle_error:

            action: core.local

            input:

                cmd: "printf '<% task(task1).result.stderr %>'"

            publish:

                error_handled: True

            on-complete:

                - fail

 

examples.mistral-handle-error定义了task1和task2,task1成功后执行task2,task2失败后执行handle_error。

$ st2 run examples.mistral-handle-error

..

id: 5afbca362b2556015687cddf

action.ref: examples.mistral-handle-error

parameters: None

status: failed

start_timestamp: Wed, 16 May 2018 06:05:42 UTC

end_timestamp: Wed, 16 May 2018 06:05:45 UTC

+--------------------------+------------------------+--------------+------------+-------------------------------+

| id                       | status                 | task         | action     | start_timestamp               |

+--------------------------+------------------------+--------------+------------+-------------------------------+

| 5afbca372b2556015687cde2 | succeeded (0s elapsed) | task1        | core.local | Wed, 16 May 2018 06:05:43 UTC |

| 5afbca372b2556015687cde4 | failed (1s elapsed)    | task2        | core.local | Wed, 16 May 2018 06:05:43 UTC |

| 5afbca382b2556015687cde6 | succeeded (0s elapsed) | handle_error | core.local | Wed, 16 May 2018 06:05:44 UTC |

 

 

Mistral Workflow可以针对失败的子任务进行重跑(StackStorm2.7版本的ActionChain不支持从失败的子任务继续重跑):

$ st2 execution re-run 5afbca362b2556015687cddf --tasks task2

.

id: 5afbcadc2b2556015687cde8

action.ref: examples.mistral-handle-error

parameters: None

status: failed

result_task: task2

result:

  failed: true

  return_code: 1

  stderr: ''

  stdout: 2

  succeeded: false

start_timestamp: Wed, 16 May 2018 06:08:28 UTC

end_timestamp: Wed, 16 May 2018 06:08:30 UTC

+--------------------------+------------------------+--------------+------------+-------------------------------+

| id                       | status                 | task         | action     | start_timestamp               |

+--------------------------+------------------------+--------------+------------+-------------------------------+

| 5afbcadc2b2556015687cdea | failed (1s elapsed)    | task2        | core.local | Wed, 16 May 2018 06:08:28 UTC |

| 5afbcadd2b2556015687cdec | succeeded (0s elapsed) | handle_error | core.local | Wed, 16 May 2018 06:08:29 UTC |

+--------------------------+------------------------+--------------+------------+-------------------------------+

 

examples.mistral-repeat

Mistral Workflow支持循环语法:

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

version: '2.0'

 

examples.mistral-repeat:

    description: >

        A sample workflow that demonstrates how to repeat a task

        x number of times with the same inputs.

    type: direct

    input:

        - cmd

        - count

    tasks:

        repeat:

            with-items: i in <% list(range(0, $.count)) %>

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

            publish:

                result: <% task(repeat).result.select($.stdout) %>

 

循环5次执行命令:

st2 run examples.mistral-repeat cmd=date count=5

..

id: 5afbdab82b2556015687ce19

action.ref: examples.mistral-repeat

parameters:

  cmd: date

  count: 5

status: succeeded

result_task: repeat

result: - failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 07:16:09 UTC 2018

  succeeded: true

- failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 07:16:09 UTC 2018

  succeeded: true

- failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 07:16:09 UTC 2018

  succeeded: true

- failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 07:16:09 UTC 2018

  succeeded: true

- failed: false

  return_code: 0

  stderr: ''

  stdout: Wed May 16 07:16:09 UTC 2018

  succeeded: true

start_timestamp: Wed, 16 May 2018 07:16:08 UTC

end_timestamp: Wed, 16 May 2018 07:16:11 UTC

+--------------------------+------------------------+--------+------------+-------------------------------+

| id                       | status                 | task   | action     | start_timestamp               |

+--------------------------+------------------------+--------+------------+-------------------------------+

| 5afbdab82b2556015687ce20 | succeeded (1s elapsed) | repeat | core.local | Wed, 16 May 2018 07:16:08 UTC |

| 5afbdab82b2556015687ce22 | succeeded (1s elapsed) | repeat | core.local | Wed, 16 May 2018 07:16:08 UTC |

| 5afbdab82b2556015687ce23 | succeeded (1s elapsed) | repeat | core.local | Wed, 16 May 2018 07:16:08 UTC |

| 5afbdab82b2556015687ce21 | succeeded (1s elapsed) | repeat | core.local | Wed, 16 May 2018 07:16:08 UTC |

| 5afbdab82b2556015687ce24 | succeeded (1s elapsed) | repeat | core.local | Wed, 16 May 2018 07:16:08 UTC |

+--------------------------+------------------------+--------+------------+-------------------------------+

 

 

 

 

参考

  • https://yaql.readthedocs.io/en/latest/
  • http://jinja.pocoo.org/
  • http://jinja.pocoo.org/



作者简介

吴龙辉,现任网宿科技云计算架构师,致力于云计算PaaS的研究和实践,《Kubernetes实战》作者,活跃于CloudFoundry,Docker,Kubernetes等开源社区,贡献代码和撰写技术文档。 
邮箱:[email protected]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章