一、Ansible处理任务失败

1、管理play中任务错误

1️⃣:Ansible评估任务的返回代码,从而确定任务是成功还是失败

2️⃣:通常而言,当任务失败时,Ansible将立即在该主机上中止play的其余部分并且跳过所有后续任务,但有些时候,可能希望即使在任务失败时也继续执行play

2、忽略任务失败

1️⃣:默认情况下,任务失败时play会中止。不过,可以通过忽略失败的任务来覆盖此行为。可以在任务中使用ignore_errors关键字来实现此目的

  • 演示实例:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: install httpd
    yum:
    name: packages //没有这个包
    state: present
    ignore_errors: yes //可选{yes、no} - name: shoe some massage
    debug:
    msg: "hello word" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [install httpd] ******************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false, "failures": ["No package packages available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
    ...ignoring //已经忽略这个任务出错 TASK [shoe some massage] **************************************************************************************************************************************************
    ok: [client.example.com] => {
    "msg": "hello word"
    } PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1   

3、任务失败也强制执行处理程序(handlers)

1️⃣:在play中设置force_handlers: yes关键字,则即使play因为后续任务失败而中止也会调用被通知的处理程序(force:促使,推动)

  • 演示实例:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    force_handlers: yes //可选{yes、no}
    tasks:
    - name: install httpd
    shell: ls //这条命令一定会执行成功,从而保证handlers处理程序一定会被触发
    notify:
    - massage - name: install httpd
    yum:
    name: packages //没有这个包,肯定会出错
    state: present handlers:
    - name: massage
    debug:
    msg: "hello word" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [install httpd] ******************************************************************************************************************************************************
    changed: [client.example.com] TASK [install httpd] *****************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"changed": false, "failures": ["No package packages available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []} RUNNING HANDLER [massage] *************************************************************************************************************************************************
    ok: [client.example.com] => {
    "msg": "hello word"
    } PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=3 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

2️⃣:处理程序会在任务报告changed结果时获得通知,而在任务报告okfailed结果时不会获得通知

4、指定任务失败的条件

1️⃣:在任务中使用failed_when关键字来指定表示任务已失败的条件;通常与命令模块搭配使用,这些模块可能成功执行了某一命令,但命令的输出可能指示了失败

  • 演示实例一:使用failed_when关键字

     //查看使用的脚本
    [root@localhost project]# cat files/test.sh
    #!/bin/bash
    cat /root //这句肯定会出错
    echo "hello word"
    //注意:在playbook中执行脚本会以最后一个命令作为错误判断标准,中间错误命令不会影响整体的出错,同样也不会因为中间出错而报错 //查看playbook,执行一次看是否成功
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    script:
    files/test.sh
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    changed: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    //这样无法判断是否都执行成功 //添加任务失败判断语句
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    script:
    files/test.sh
    register: result
    failed_when: "'Is a directory' in result['stdout']"
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"changed": true, "failed_when_result": true, "rc": 0, "stderr": "Shared connection to client.example.com closed.\r\n", "stderr_lines": ["Shared connection to client.example.com closed."], "stdout": "cat: /root: Is a directory\r\nhello word\r\n", "stdout_lines": ["cat: /root: Is a directory", "hello word"]} PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

2️⃣:fail模块也可用于强制任务失败(主要是将杂乱的提示信息通过自己设置提示方式,达到简单、明了的目的)

  • 演示实例二:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    script:
    files/test.sh
    register: result - fail:
    msg: "There have a failed"
    when: "'Is a directory' in result['stdout']" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    changed: [client.example.com] TASK [fail] ***************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"changed": false, "msg": "There have a failed"} PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

5、指定何时任务报告“changed”结果

1️⃣:当任务对托管主机进行了更改时,会报告 changed 状态并通知处理程序;如果任务不需要进行更改,则会报告ok并且不通知处理程序

2️⃣:使用changed_when关键字可用于控制任务在何时报告它已进行了更改

  • 演示实例一:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    shell: echo "hello word" //执行后发现,每次都是changed
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    changed: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 //添加changed_when关键字,以便报告OK
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    shell: echo "hello word"
    changed_when: false //可选{true、false}
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    ok: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0  

3️⃣:根据通过已注册变量收集的模块的输出来报告changed

  • 演示实例二:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    tasks:
    - name: test
    command: echo "hello word"
    register: result
    changed_when: "'hello word' in result['stdout']" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com] TASK [test] ***************************************************************************************************************************************************************
    changed: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    //因为在result['stdout']中有hello word ,所以被认定为是true,所以就显示changed

6、Ansible块和错误处理

1️⃣:在playbook中,块是对任务进行逻辑分组的子句,可用于控制任务的执行方式

2️⃣:通过块,也可结合rescuealways语句来处理错误。如果块中的任何任务失败,则执行其rescue块中的任务来进行恢复

3️⃣:在block子句中的任务以及rescue子句中的任务(如果出现故障)运行之后,always子句中的任务运行

4️⃣:总结:

  • block:定义要运行的主要任务
  • rescue:定义要在block子句中定义的任务失败时运行的任务
  • always:定义始终都独立运行的任务,不论blockrescue子句中定义的任务是成功还是失败

5️⃣:演示:

  • 演示实例一:当只有block和rescue,且block语句执行成功时,只执行block语句而不执行rescue语句(rescue:营救、救援)

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    shell: echo "hello word" rescue:
    - name: rescue
    shell: ls /root //执行play
    [root@localhost project]# ansible-playbook --syntax-check playbook.yaml playbook: playbook.yaml
    [root@localhost project]# an
    anacron ansible-config ansible-console ansible-galaxy ansible-playbook ansible-test
    ansible ansible-connection ansible-doc ansible-inventory ansible-pull ansible-vault
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    changed: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    //可以发现,只执行了block语句,并没有执行rescue语句
  • 演示实例二:当只有block和rescue,且block语句执行失败时,不执行block语句而执行rescue语句

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    command: cat / //这句肯定会失败 rescue:
    - name: rescue
    shell: ls /root //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["cat", "/"], "delta": "0:00:00.005350", "end": "2020-09-08 10:59:18.381699", "msg": "non-zero return code", "rc": 1, "start": "2020-09-08 10:59:18.376349", "stderr": "cat: /: Is a directory", "stderr_lines": ["cat: /: Is a directory"], "stdout": "", "stdout_lines": []} TASK [rescue] *************************************************************************************************************************************************************
    changed: [client.example.com] PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
    //可以看出,block语句执行失败而执行了rescue语句
  • 演示实例三:当block语句、rescue语句和always语句都有时,无论block语句是否失败,always语句总是执行

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    command: cat / rescue:
    - name: rescue
    shell: ls /root always:
    - name: always
    debug:
    msg: "This is my test" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["cat", "/"], "delta": "0:00:00.008993", "end": "2020-09-08 11:05:47.816489", "msg": "non-zero return code", "rc": 1, "start": "2020-09-08 11:05:47.807496", "stderr": "cat: /: Is a directory", "stderr_lines": ["cat: /: Is a directory"], "stdout": "", "stdout_lines": []} TASK [rescue] *************************************************************************************************************************************************************
    changed: [client.example.com] TASK [always] *************************************************************************************************************************************************************
    ok: [client.example.com] => {
    "msg": "This is my test"
    } PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0

6️⃣:block中的when条件也会应用到其rescuealways子句(若存在)

  • 演示实例一:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    command: echo "hello word" //该语句没有错误
    when: ansible_facts['distribution'] == "CentOS" //条件判断出错会导致block语句不会执行 rescue:
    - name: rescue
    shell: ls /root always:
    - name: always
    debug:
    msg: "This is my test" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"msg": "The conditional check 'ansible_facts['distribution'] == \"CentOS\"' failed. The error was: error while evaluating conditional (ansible_facts['distribution'] == \"CentOS\"): 'dict object' has no attribute 'distribution'\n\nThe error appears to be in '/root/project/playbook.yaml': line 7, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n block:\n - name: block\n ^ here\n"} TASK [rescue] *************************************************************************************************************************************************************
    changed: [client.example.com] TASK [always] *************************************************************************************************************************************************************
    ok: [client.example.com] => {
    "msg": "This is my test"
    } PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0  
  • 演示实例二:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    command: echo "hello word"
    when: ansible_facts['distribution'] == "CentOS" rescue:
    - name: rescue
    shell: ls /root
    when: ansible_facts['distribution_major_version'] == "7" //这句when语句会执行失败,导致rescue语句不会执行 always:
    - name: always
    debug:
    msg: "This is my test" //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"msg": "The conditional check 'ansible_facts['distribution'] == \"CentOS\"' failed. The error was: error while evaluating conditional (ansible_facts['distribution'] == \"CentOS\"): 'dict object' has no attribute 'distribution'\n\nThe error appears to be in '/root/project/playbook.yaml': line 7, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n block:\n - name: block\n ^ here\n"} TASK [rescue] *************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"msg": "The conditional check 'ansible_facts['distribution_major_version'] == \"7\"' failed. The error was: error while evaluating conditional (ansible_facts['distribution_major_version'] == \"7\"): 'dict object' has no attribute 'distribution_major_version'\n\nThe error appears to be in '/root/project/playbook.yaml': line 12, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n rescue:\n - name: rescue\n ^ here\n"} TASK [always] *************************************************************************************************************************************************************
    ok: [client.example.com] => {
    "msg": "This is my test"
    } PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=1 ignored=0
    //可以看出,block语句和rescue语句都没执行

    实例二

  • 演示实例三:

     //查看playbook
    [root@localhost project]# cat playbook.yaml
    ---
    - hosts: all
    gather_facts: no
    tasks:
    - name: test
    block:
    - name: block
    command: echo "hello word" rescue:
    - name: rescue
    shell: ls /root always:
    - name: always
    debug:
    msg: "This is my test"
    when: ansible_facts['distribution_version'] == "8" //when条件储出错没回导致always语句执行失败 //执行play
    [root@localhost project]# ansible-playbook playbook.yaml PLAY [all] **************************************************************************************************************************************************************** TASK [block] **************************************************************************************************************************************************************
    changed: [client.example.com] TASK [always] *************************************************************************************************************************************************************
    fatal: [client.example.com]: FAILED! => {"msg": "The conditional check 'ansible_facts['distribution_version'] == \"8\"' failed. The error was: error while evaluating conditional (ansible_facts['distribution_version'] == \"8\"): 'dict object' has no attribute 'distribution_version'\n\nThe error appears to be in '/root/project/playbook.yaml': line 15, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n always:\n - name: always\n ^ here\n"} PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com : ok=1 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

    实例三

  • 注意:block执行会成功的话,如果用when条件判断,即使判断条件会成功,但block语句任然会失败,而去执行rescue语句

Ansible_处理失败的任务的更多相关文章

  1. 网络原因导致 npm 软件包 node-sass / gulp-sass 安装失败的处理办法

    如果你正在构建一个基于 gulp 的前端自动化开发环境,那么极有可能会用到 gulp-sass ,由于网络原因你可能会安装失败,因为安装过程中部分细节会到亚马逊云服务器上获取文件.本文主要讨论在不变更 ...

  2. Jenkins的一个bug-同时build一个项目两次导致失败

    我们有一个job A, A只是配置了一些参数,它会去触发模板job B. 我一开始点击构建A, 马上发现参数配置不对,于是撤消了构建,但是我没有发现B已经被触发,我重新配置参数,然后再次构建A,这个时 ...

  3. HTML5 摇一摇加强版之一次失败的探索

    最近在看设备传感器的API,当然也少不了研究一下让微信称神的“摇一摇”了.关于“摇一摇”的实现,网上很多资料所以不详细说了,但总是有布局.效果不全等各种问题,所以作为一名资深copypaster,代码 ...

  4. Fedora 21 安装 Nvidia 驱动以及失败后的补救方法

    在 Linux 桌面系统下玩了这么久,大部分时间都是使用 Ubuntu,偶尔使用一下 Fedora.我的电脑中安装有多个 Linux 发行版,见这里<在同一个硬盘上安装多个Linux发行版及Fe ...

  5. 如何修复VUM在客户端启用之后报数据库连接失败的问题

    在上一篇随笔中介绍了关于重新注册VMware Update Manager(VUM)至vCenter Server中的方法,最近有朋友反应,原本切换过去好好的更新服务为什么某次使用一下就不灵了? 当时 ...

  6. 5.C#WinForm基础登陆失败三次退出系统

    目标: 登陆界面,登陆错误三次退出程序.假设用户名密码是admin.888888,不区分大小写,(易错点:局部变量与类变量) 局部变量每次运行完毕变量的值都会被销毁,下次再运行,会重新初始化.     ...

  7. Win10 连接L2TP VPN 失败解决方法

    Win10 连接L2TP VPN 失败解决方法 iOS系统不知道在什么时候,已经不支持PPTP VPN.偶尔的机会刚好看到github上的一键式VPN服务器部署脚本setup-ipsec-vpn,就在 ...

  8. "检索COM类工厂中 CLSID为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005" 问题的解决

    一.故障环境 Windows 2008 .net 3.0 二.故障描述 ​ 调用excel组件生成excel文档时页面报错.报错内容一大串,核心是"检索COM类工厂中 CLSID为 {000 ...

  9. 创建虚拟目录失败,必须为服务器名称指定“localhost”?看进来!!

    没废话,直接讲! 关于微信开发过程,远程调试后,再次打开vs出现项目加载失败的解决办法! 上图: 这图应该不陌生,你肯定打开iis把绑定的域名给干掉了.这个提示很坑人,简直就是坑爹!!!fck!! 来 ...

随机推荐

  1. EFCore3.1+编写自定义的EF.Functions扩展方法

    前言 本文主要是讲解EF Core3.0+ 如何实现自定义的数据库扩展函数 虽然EF.Functions 提供了很多数据库函数,但是并不全面.比如加密解密.. 这样的话 我们就需要自己扩展这些数据库函 ...

  2. 尝试做一个.NET模板填充导出Excel工具

    园友好,最近晚辈延续上篇后尝试进阶做成Excel模板填充数据生成工具 MiniExcel Template. 主要特点 同样以Stream流.延迟查询避免全部数据载入内存情况,做到1GB内存降低到只需 ...

  3. ClickHouse源码笔记5:聚合函数的源码再梳理

    笔者在源码笔记1之中分析过ClickHouse的聚合函数的实现,但是对于各个接口函数的实际如何共同工作的源码,回头看并没有那么明晰,主要原因是没有结合Aggregator的类来一起分析聚合函数的是如果 ...

  4. Go-06-数据类型、常量、运算符

    数据类型转换 Go语言采用数据类型前置加括号的方式进行类型转换,格式如:T(表达式).T表示要转换的类型:表达式包括变量.数值.函数返回值等. var a int =100 b := float(a) ...

  5. Flutter 状态管理- 使用 MobX

    文 / Paul Halliday, developer.school 创始人 众所周知,状态管理是每个软件项目都需要持续迭代更新的方向.它并不是一个「一次性」的工作, 而需要不断确保你遵循的最佳实践 ...

  6. H5 hybrid开发-前端资源本地化方案纪要

    H5 hybrid-前端资源本地化方案纪要 就整个行业来说,大前端是趋势,现阶段,native方面除了一些偏CPU密集型工作与操作系统底层API方面的工作外,H5基本都可以满足需要. 目前的工作更偏向 ...

  7. Flowable中的Service

    前言 在学习博客[(https://blog.csdn.net/puhaiyang/article/details/79845248)]时,注意到Flowable中的各种Service(如下),进而在 ...

  8. docker搭建简单mysql主从

    关于MySQL主从模式,如果我们直接在本机上搭建的话,是没法搭建的,只能借助于虚拟机,但有的时候我们又需要搭建一个主从集群,以便于进行一些功能性的测试.这个时候我们就可以尝试使用docker,借助于d ...

  9. k8s deployment

    案例01 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabe ...

  10. 一台window服务器部署多个tomcat(超简单配置)!!!

    1.首先准备好已经安装好的jdk环境,点击查看JDK安装. 2.准备好一个全新的tomcat,我这里使用的是tomcat-7.0.109.rar绿色版. 3.解压文件,并复制成三份.我这里是放在F:\ ...