当前位置: 首页 > article >正文

Ansible playbook的block

环境

  • 控制节点:Ubuntu 22.04
  • Ansible 2.10.8
  • 管理节点:CentOS 8

block

顾名思义,通过block可以把task按逻辑划分到不同的“块”里面,实现“块操作”。此外,block还提供了错误处理功能。

task分组

下面的例子,把3个task放到一个block里面。

创建文件 testBlock1.yml 如下:

---
- name: testBlock1
  hosts: all
  tasks:
  - name: My task 1
    block:
    - name: Part1
      debug:
        msg: "Hello Zhang San"

    - name: Part2
      debug:
        msg: "Hello Li Si"

    - name: Part3
      debug:
        msg: "Hello Wang Wu"
    when: 2 > 1

运行结果如下:

➜  temp ansible-playbook testBlock1.yml

PLAY [testBlock1] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Zhang San"
}

TASK [Part2] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Li Si"
}

TASK [Part3] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Wang Wu"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

如果把block的判断条件 when: 2 > 1 改为 when: 2 == 1 ,则运行结果如下:

➜  temp ansible-playbook testBlock1.yml

PLAY [testBlock1] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
skipping: [192.168.1.55]

TASK [Part2] ***************************************************************************************
skipping: [192.168.1.55]

TASK [Part3] ***************************************************************************************
skipping: [192.168.1.55]

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=1    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0 

可见,由于条件不满足,block里的3个task都没有执行。

错误处理

如果block里的某个task出错了,则后面的task不再运行。

创建文件 testBlock2.yml 如下:

---
- name: testBlock2
  hosts: all
  tasks:
  - name: My task 1
    block:
    - name: Part1
      debug:
        msg: "Hello Zhang San"

    - name: Part2
      command: /bin/false # will trigger an error

    - name: Part3
      debug:
        msg: "Hello Li Si"

运行结果如下:

➜  temp ansible-playbook testBlock2.yml

PLAY [testBlock2] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Zhang San"
}

TASK [Part2] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001904", "end": "2023-10-26 08:50:36.850526", "msg": "non-zero return code", "rc": 1, "start": "2023-10-26 08:50:36.848622", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  

可见,由于Part2出错,Part3并没有运行。

Ansible的错误处理有两个关键字:

  • rescue :类似于 catch
  • always :类似于 finally

先加上 always 看看效果:

---
- name: testBlock2
  hosts: all
  tasks:
  - name: My task 1
    block:
    - name: Part1
      debug:
        msg: "Hello Zhang San"

    - name: Part2
      command: /bin/false # will trigger an error

    - name: Part3
      debug:
        msg: "Hello Li Si"
    always:
    - name: Always do this
      debug:
        msg: "End End End"
➜  temp ansible-playbook testBlock2.yml

PLAY [testBlock2] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Zhang San"
}

TASK [Part2] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002734", "end": "2023-10-26 08:52:19.329781", "msg": "non-zero return code", "rc": 1, "start": "2023-10-26 08:52:19.327047", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

TASK [Always do this] ******************************************************************************
ok: [192.168.1.55] => {
    "msg": "End End End"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=3    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

可见,Part2出错, always 也会运行(当然,Part3不会运行)。

注意:加上 always ,failed仍然是1。

现在来试一下 rescue

---
- name: testBlock2
  hosts: all
  tasks:
  - name: My task 1
    block:
    - name: Part1
      debug:
        msg: "Hello Zhang San"

    - name: Part2
      command: /bin/false # will trigger an error

    - name: Part3
      debug:
        msg: "Hello Li Si"
    always:
    - name: Always do this
      debug:
        msg: "End End End"
    rescue:
    - name: Rescue tasks
      debug:
        msg: "Something is wrong!"

运行结果如下:

➜  temp ansible-playbook testBlock2.yml

PLAY [testBlock2] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "Hello Zhang San"
}

TASK [Part2] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001726", "end": "2023-10-26 09:00:01.785445", "msg": "non-zero return code", "rc": 1, "start": "2023-10-26 09:00:01.783719", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

TASK [Rescue tasks] ********************************************************************************
ok: [192.168.1.55] => {
    "msg": "Something is wrong!"
}

TASK [Always do this] ******************************************************************************
ok: [192.168.1.55] => {
    "msg": "End End End"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0  

注意,always是在rescue之后运行的(Part3仍然不会运行)。

注:如果task没有出错, rescue 不会被触发。

rescue与handler

我们知道,当task运行成功,状态改变时,可以用 notify 来触发handler。但如果后续的task出错了,则当前task的handler并不会触发。如果有 rescue ,则handler仍然会被触发(在 always 之后)。在 rescue 中可以通过 meta: flush_handlers 来立即触发handler(在 always 之前)。

---
- name: testBlock2
  hosts: all
  tasks:
  - name: My task 1
    block:
    - name: Part1
      debug:
        msg: "Hello Zhang San"
      changed_when: true
      notify: Run me even after an error

    - name: Part2
      command: /bin/false # will trigger an error

    - name: Part3
      debug:
        msg: "Hello Li Si"
    always:
    - name: Always do this
      debug:
        msg: "End End End"
    rescue:
    - name: Rescue tasks
      #debug:
      #  msg: "Something is wrong!"
      meta: flush_handlers
  handlers:
  - name: Run me even after an error
    debug:
      msg: 'This handler runs even on error'

运行结果如下:

➜  temp ansible-playbook testBlock2.yml

PLAY [testBlock2] **********************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]

TASK [Part1] ***************************************************************************************
changed: [192.168.1.55] => {
    "msg": "Hello Zhang San"
}

TASK [Part2] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002172", "end": "2023-10-26 09:11:26.530609", "msg": "non-zero return code", "rc": 1, "start": "2023-10-26 09:11:26.528437", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

RUNNING HANDLER [Run me even after an error] *******************************************************
ok: [192.168.1.55] => {
    "msg": "This handler runs even on error"
}

TASK [Always do this] ******************************************************************************
ok: [192.168.1.55] => {
    "msg": "End End End"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0 

本例中,Part1运行成功,且改变了状态,所以触发了handler Run me even after an error 。但由于Part2出错,如果没有 rescue ,则Part1的handler不会触发。加上 rescue 之后,就会触发Part1的handler。本例中加上了 meta: flush_handlers ,所以会立即触发handler。

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_blocks.html

http://www.kler.cn/a/106354.html

相关文章:

  • Excel超级处理器:高效实现2种批量生成二维码方式
  • 网络安全之WINDOWS端口及病毒编写
  • springboot004基于springboot004网页时装购物系统(源码+包运行+LW+技术指导)
  • Spring Batch :高效处理海量数据的利器
  • Nginx 上安装 SSL 证书并启用 HTTPS 访问
  • 使用Python实现深度学习模型:智能食品配送优化
  • 229. 多数元素 II
  • 【HarmonyOS】元服务卡片router实现跳转到指定页面并传动态参数
  • 【Python 千题 —— 基础篇】列表排序
  • Kafka To HBase To Hive
  • NReco.LambdaParser使用案例
  • docker、docker-compose安装教程,很详细
  • 【wvp】wvp设备上可以开启tcp被动模式
  • 人工智能和机器学习:走向智能未来的关键
  • 数字化转型系列主题:数据中台知识体系
  • vue中报 TypeError: Assignment to constant variable.
  • oracle统计信息
  • 万能鼠标设置 SteerMouse v5.6.8
  • 【高效开发工具系列】Postman
  • 交换机基础(四):MSTP负载均衡配置案例
  • 1-多媒体通信概述
  • 『力扣刷题本』:合并两个有序链表(递归解法)
  • Microsoft.Extensions 简介
  • golang 工程组件:grpc-gateway 环境安装+默认网关测试
  • LeetCode--3.无重复字符的最长子串
  • 【APP VTable】和市面上的 Table 组件一样,都是接收表格[] 以及数据源[]