Ansible学习笔记——错误控制介绍及练习

ignore_errors:忽略错误failed

我们使用一下yml文件来做测试,使用yum模块安装一个不存在的软件包。

---
- name: test ignore handler
  hosts: servera
  tasks:
    - name: 1)test ignore handler
      yum:
        name: notpackage
        state: latest
      #ignore_errors: yes
    - name: 2)test debug
      debug:
        msg: this is debug output

正常情况下,一个playbook中如果某个tasks出现错误,则后面的tasks将不再继续执行。

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

TASK [1)test ignore handler] *********************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "failures": ["No package notpackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

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

在一些特殊场景中,我们需要忽略当前task的异常,继续执行。
此时在task后面加上ignore_errors: yes 可控制忽略当前错误,继续执行。

添加以下代码:

     ignore_errors: yes    

可以忽略yum模块的错误,继续执行debug模块,运行结果为:


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

TASK [1)test ignore handler] *********************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "failures": ["No package notpackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring

TASK [2)test debug] ******************************************************************************************************************
ok: [servera] => {
    "msg": "this is debug output"
}

force_handlers:handler错误控制

示例代码:

---
- name: test ignore handler
  hosts: servera
  tasks:
    - name:
      command: /bin/true
      notify: test notify
    
    - name: 1)test force_handlers
      yum:
        name: notpackage
        state: latest
    
    - name: 2)test debug
      debug:
        msg: this is debug output

  handlers:
    - name: test notify
      debug:
        msg: this is notify output

正常情况下,如果后续的task执行失败,notify中的handler是不会执行的。

TASK [command] ***********************************************************************************************************************
changed: [servera]

TASK [1)test force_handlers] *********************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "failures": ["No package notpackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

RUNNING HANDLER [test notify] ********************************************************************************************************

使用forece_handlers可以强制执行当后续task返回为failed时,无论如何都执行handler

- name: test ignore handler
  hosts: servera
  force_handlers: yes
  tasks:
    - name:

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

TASK [command] ***********************************************************************************************************************
changed: [servera]

TASK [1)test force_handlers] *********************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "failures": ["No package notpackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

RUNNING HANDLER [test notify] ********************************************************************************************************
ok: [servera] => {
    "msg": "this is notify output"
}

failed_when:指定失败条件

示例代码:

[student@workstation wangxc]$ cat failed.yml 
---
- name: 
  hosts: servera
  tasks:
    - name: run server creation script
      command: /etc/hosts123 
      register: command_result
      #failed_when: "'No such' in command_result"
      #ignore_errors: yes
    - name: 
      debug:
        msg: "{{ command_result }}"

在正常情况下,改yml执行会直接输出result并终止。

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

TASK [run server creation script] ****************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "cmd": "/etc/hosts123", "msg": "[Errno 2] No such file or directory: '/etc/hosts123': '/etc/hosts123'", "rc": 2}

此时,failed_when有两种用法:

1. 指定条件,当判断条件为真时,则失败。在代码中加入下面这行:

failed_when: "'No such' in command_result"

则可以正常运行后面的debug模块

TASK [run server creation script] ****************************************************************************************************
ok: [servera]

TASK [debug] *************************************************************************************************************************
ok: [servera] => {
    "msg": {
        "changed": false,
        "cmd": "/etc/hosts123",
        "failed": false,
        "failed_when_result": false,
        "msg": "[Errno 2] No such file or directory: '/etc/hosts123': '/etc/hosts123'",
        "rc": 2
    }
}

2. 条件判断,当失败的时候,输出自定义的失败信息。

上面的模块可以拆分为两部分,使用fail模块进行错误信息输出。

---
- name: 
  hosts: servera
  tasks:
    - name: run server creation script
      command: /etc/hosts123 
      register: command_result
      ignore_errors: yes
      # failed_when: "'No such' in command_result"
    - name:
      fail:
        msg: " No such file or directory"
      when: "'No such' in command_result"

    - name: 
      debug:
        msg: "{{ command_result }}"

changed_when:控制changed返回

示例代码:

---
- name:
  hosts: servera
  tasks:
    - name:
      copy:
        src: inventory
        dest: /home/student
      register: copy_res
      # changed_when: "{{ copy_res['changed'] }}"
      # changed_when: false
      notify: debug output
    - name:
      debug:
        msg: "{{ copy_res['changed'] }}"

  handlers:
     - name: debug output
       debug:
         msg: this is debug output

以上代码,正常情况下会输出changed并处调用handlers模块。


TASK [copy] **************************************************************************************************************************
changed: [servera]

TASK [debug] *************************************************************************************************************************
ok: [servera] => {
    "msg": true
}

RUNNING HANDLER [debug output] *******************************************************************************************************
ok: [servera] => {
    "msg": "this is debug output"
}

有些时候只是为了获取信息,而非真正做出了改变,我们并不想让task输出changed结果。
此时需要添加changed_when: false,即可将结果改变为ok

changed_when: false

输出结果:此时不再出发handler


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

TASK [copy] **************************************************************************************************************************
ok: [servera]

TASK [debug] *************************************************************************************************************************
ok: [servera] => {
    "msg": false
}

还可以根据register的结果,来决定是否展示changed状态。

changed_when: "{{ copy_res['changed'] }}"

此时输出结果:

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

TASK [copy] **************************************************************************************************************************
 [WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{
copy_res['changed'] }}

changed: [servera]

TASK [debug] *************************************************************************************************************************
ok: [servera] => {
    "msg": true
}

RUNNING HANDLER [debug output] *******************************************************************************************************
ok: [servera] => {
    "msg": "this is debug output"
}

block、rescue、always:块运行控制

  • block:运行的主要任务块
  • rescue:在block中定义的任务失败时,需要运行的任务
  • always:始终都会运行的任务,无论block和rescue中的任务是成功还是失败

示例:
非常简单的例子,安装一个不存在的软件包,当出现错误时,执行rescue,然后执行always。
这个语法和逻辑有点类似java的try catch finally

---
- name:
  hosts: servera
  tasks:
    - name:
      block:
        - name: block
          yum:
            name: nopackage
            state: latest
      rescue:
        - name: rescue
          debug:
            msg: this is rescue

      always:
        - name: always
          debug:
            msg: this is always

运行结果

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

TASK [block] *************************************************************************************************************************
fatal: [servera]: FAILED! => {"changed": false, "failures": ["No package nopackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

TASK [rescue] ************************************************************************************************************************
ok: [servera] => {
    "msg": "this is rescue"
}

TASK [always] ************************************************************************************************************************
ok: [servera] => {
    "msg": "this is always"
}

当我们尝试修改yum安装的软件包为正常的包时,可以看到不再运行rescue了。

block:
        - name: block
          yum:
            name: httpd
            state: latest

结果为:

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

TASK [block] *************************************************************************************************************************
ok: [servera]

TASK [always] ************************************************************************************************************************
ok: [servera] => {
    "msg": "this is always"
}

综合实验:处理失败的任务

  1. 故意安装错误的软件包,练习忽略失败ignore_errors
  2. 使用block等块控制语句,练习块控制
  3. 添加时间输出tasks,查看被管理主机的时间。由于此项并未作出改变,练习changed_when使task的结果为ok
  4. 练习failed_when,当安装软件包满足条件时,结果为failed
---
- name:
  hosts: databases
  vars:
    web_package: httpd
    db_package: mariadb-server
    db_service: mariadb

  tasks:
    - name: chekc local time
      command: date
      register: cmd_res
      #changed_when: false

    - name: print local time
      debug:
        var: cmd_res.stdout
       
    - name:
      block:
        - name: install {{ web_package }}
          yum:
            name: "{{ web_package }}"
            state: present
            #failed_when: web_package == "httpd"
            #ignore_errors: yes
      rescue:
        - name: install {{ db_package }}
          yum:
            name: "{{ db_package }}"
            state: present
      always:
        - name: start {{ db_service }} service
          service:
            name: "{{ db_service }}"
            state: started

运行结果:这里只展示了最后一次,可以通过不同的语句来做控制

TASK [Gathering Facts] ***************************************************************************************************************
ok: [servera.lab.example.com]

TASK [chekc local time] **************************************************************************************************************
changed: [servera.lab.example.com]

TASK [print local time] **************************************************************************************************************
ok: [servera.lab.example.com] => {
    "cmd_res.stdout": "Wed Mar 24 13:58:10 CST 2021"
}

TASK [install httpd] *****************************************************************************************************************
ok: [servera.lab.example.com]

TASK [start mariadb service] *********************************************************************************************************
ok: [servera.lab.example.com]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值