ansible的handlers、任务失败和文件管理

1.实施notify处理程序

2.1 ansible处理程序

​ 使用notify语句来调用一个任务的触发,只有当任务的结果为change时,才会调用任务

​ 在下列代码片段中,只有配置文件更新并且通知了该任务,restart apache处理程序才会重启Apache服务:

---
- name: test
  hosts: all
  tasks:
    - name: change config
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: "^Listen 80"
        line: "Listen 8080"
      notify:
        - restart apache
          
  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted

​ 在上面这个例子中,我们修改了apache的配置文件,所以它的结果为change,就触发了notify的调用,调用了handlers里名为restart apache的任务

​ 一个任务可以在其notify部分中调用多个处理程序。Ansible将notify语句视为数组,并且迭代处理程序名称:

---
- name: test
  hosts: all
  tasks:
    - name: change config
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: "^Listen 80"
        line: "Listen 8080"
      notify:
        - restart apache
        - restart mysql
          
  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted
        
    - name: restart mysql
      service:
        name: mariadb
        state: restarted

2.2 调用使用notify的好处

使用处理程序时需要牢记几个重要事项:

  • 处理程序始终按照playhandlers部分指定的顺序运行。它们不按在任务中由notify语句列出的顺序运行,或按任务通知它们的顺序运行。
  • 处理程序通常在相关play中的所有其他任务完成后运行。playbooktasks部分中某一任务调用的处理程序,将等到tasks下的所有任务都已处理后才会运行。
  • 处理程序名称存在于各play命名空间中。如果两个处理程序被错误地给予相同的名称,则仅会运行一个。
  • 即使有多个任务通知处理程序,该处理程序依然仅运行一次。如果没有任务通知处理程序,它就不会运行。
  • 如果包含notify语句的任务没有报告changed结果(例如,软件包已安装并且任务报告ok),则处理程序不会获得通知。处理程序将被跳过,直到有其他任务通知它。只有相关任务报告了changed状态,Ansible才会通知处理程序。

处理程序用于在任务对受管主机进行更改时执行额外操作。它们不应用作正常任务的替代。

2. 处理任务结果

2.1 忽略任务失败

​ 在默认情况下,当我们的playbook中有任务失败时,ansible就会自动终止后面的任务

​ 但是我们可以通过忽略失败来继续执行后面的任务,可以在任务中使用ignore_errors关键字来实现此目的。

​ 下列代码片段演示了如何在任务中使用ignore_errors,以便在任务失败时也继续在主机上执行playbook。例如,如果notapkg软件包不存在,则yum模块将失败,但若将ignore_errors设为yes,则执行将继续。

[root@ansible ansible]# vim playbook/test.yml
---
- name: test
  hosts: all
  tasks:
    - name: nopackage
      yum:
        name: nopackage
        state: present
      ignore_errors: yes
[root@ansible ansible]# ansible-playbook playbook/test.yml

PLAY [test] ************************************************************************************************
TASK [Gathering Facts] *************************************************************************************ok: [192.168.10.201]

TASK [nopackage] *******************************************************************************************fatal: [192.168.10.201]: FAILED! => {"changed": false, "failures": ["No package nopackage available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring			##此处显示为忽略错误

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

2.2 任务失败后强制执行处理程序

​ 通常而言,如果任务失败并且play在该主机上中止,则收到play中早前任务通知的处理程序将不会运行。如果在play中设置force_handlers: yes关键字,则即使play因为后续任务失败而中止也会调用被通知的处理程序。

​ 下列代码片段演示了如何在play中使用force_handlers关键字,以便在任务失败时也强制执行相应的处理程序:

[root@ansible ansible]# vim playbook/test.yml
---
- name: test
  hosts: all
  tasks:
    - name: test
      command: /bin/bash
      notify: restart apache

    - name: test2
      yum:
        name: nopackage
        state: present

  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted
[root@ansible ansible]# ansible-playbook playbook/test.yml

PLAY [test] ************************************************************************************************
TASK [Gathering Facts] *************************************************************************************ok: [192.168.10.201]

TASK [test] ************************************************************************************************changed: [192.168.10.201]

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

RUNNING HANDLER [restart apache]   ##尽管前面有任务失败,但还是执行了handlers ***************************************************************************
PLAY RECAP ********************************************************************************192.168.10.201             : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

2.3 指定任务失败条件

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

​ 例如,可以运行输出错误消息的脚本,并使用该消息定义任务的失败状态。下列代码片段演示了如何在任务中使用failed_when关键字:

---
- name: test
  hosts: all
  tasks:
    - name: test
      shell: /root/user.sh
      register: result
      failed_when: "'Password missing' in result.stdout"

​ 我们可以使用fail模块为任务提供明确的失败消息。

---
- name: test
  hosts: all
  tasks:
    - name: test
      shell: /root/user.sh
      register: result
      ignore_errors: yes
  - name: stdout
    fail:
      msg:"密码丢失"
    when: "'Password missing' in result.stdout"

2.4 指定何时任务报告“change”结果

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

changed_when关键字可用于控制任务在何时报告它已进行了更改。下面这个例子中,我们修改了用户的uid,使用changed_when: false以后,它的结果变成了ok

---
- name: test
  hosts: all
  tasks:
    - name: test
      user:
        name: tom
        uid: 2001
      changed_when: false
[root@ansible ansible]# ansible-playbook playbook/test.yml

PLAY [test] ************************************************************************************************
TASK [Gathering Facts] *************************************************************************************ok: [192.168.10.201]

TASK [test] ************************************************************************************************ok: [192.168.10.201]

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

[root@ansible ansible]#

2.5 ansible的任务块和错误处理

​ 在playbook中,块是对任务进行逻辑分组的子句,可用于控制任务的执行方式。例如,任务块可以含有when关键字,以将某一条件应用到多个任务:

[root@ansible ansible]# vim playbook/test.yml
---
- name: test
  hosts: all
  tasks:
    - name: block
      block:
      - name: install package
        yum:
          name: httpd
          state: latest
      - name: config
        lineinfile:
          path: /etc/httpd/conf/httpd.conf
          regexp: "^Listen 80"
          line: "Listen 8080"
      when: ansible_distribution == "Redhat"
[root@ansible ansible]# ansible-playbook playbook/test.yml

PLAY [test] ********************************************************************************

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

TASK [install package] ********************************************************************************skipping: [192.168.10.201]

TASK [config] ********************************************************************************skipping: [192.168.10.201]

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

​ 通过块,也可结合rescuealways语句来处理错误。如果块中的任何任务失败,则执行其rescue块中的任务来进行恢复。在block子句中的任务以及rescue子句中的任务(如果出现故障)运行之后,always子句中的任务运行。总结:

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

​ 以下示例演示了如何在playbook中实施块。即使block子句中定义的任务失败,rescue和always子句中定义的任务也会执行。

---
- name: test
  hosts: all
  tasks:
    - name: block
      block:
        - name: test
          shell: "/usr/local/lib/upgrade-database"
      rescue:
        - name: test2
          shell: "/usr/local/lib/revert-database"
      always:
        - name: restart database
          service:
            name: mariadb
            state: restarted

在block中的when条件也会应用到rescue和always里面

3. 文件的管理

3.1 描述文件的模块

Files模块库包含的模块允许用户完成与Linux文件管理相关的大多数任务,如创建、复制、编辑和修改文件的权限和其他属性。下表提供了常用文件管理模块的列表:

常用文件模块

模块名称模块说明
blockinfile插入、更新或删除由可自定义标记线包围的多行文本块
copy将文件从本地或远程计算机复制到受管主机上的某个位置。 类似于file模块,copy模块还可以设置文件属性,包括SELinux上下文件。
fetch此模块的作用和copy模块类似,但以相反方式工作。此模块用于从远程计算机获取文件到控制节点, 并将它们存储在按主机名组织的文件树中。
file设置权限、所有权、SELinux上下文以及常规文件、符号链接、硬链接和目录的时间戳等属性。 此模块还可以创建或删除常规文件、符号链接、硬链接和目录。其他多个与文件相关的 模块支持与file模块相同的属性设置选项,包括copy模块。
lineinfile确保特定行位于某文件中,或使用反向引用正则表达式来替换现有行。 此模块主要在用户想要更改文件的某一行时使用。
stat检索文件的状态信息,类似于Linux中的stat命令。
synchronize围绕rsync命令的一个打包程序,可加快和简化常见任务。 synchronize模块无法提供对rsync命令的完整功能的访问权限,但确实最常见的调用更容易实施。 用户可能仍需通过run command模块直接调用rsync命令。

3.2 文件模块的使用

3.2.1 创建文件或文件夹

​ 使用file模块处理受管主机上的文件。其工作方式与touch命令类似,如果不存在则创建一个空文件,如果存在,则更新其修改时间。在本例中,除了处理文件之外,Ansible还确保将文件的所有者、组和权限设置为特定值。

---
- name: test
  hosts: all
  tasks:
    - name: test
      file:
        path: /root/file
        owner: tom
        group: tom
        mode: 0755
        state: touch
3.2.2 修改文件属性

​ 使用file模块还可以确保新的或现有的文件具有正确的权限和SELinux类型。

​ 以下任务确保了anaconda-ks.cfg文件的SELinux上下文件类型属性是所需的samba_share_t类型。此行为与Linux中的chcon命令类似。

---
- name: test
  hosts: all
  tasks:
    - name: test
      file:
        path: /path/to/samba_file
        setype: samba_share_t
3.2.3 使SELinux文件上下文更改具有持久性

​ 设置文件上下文时,file模块的行为与chcon类似。通过运行restorecon,可能会意外地撤消使用该模块所做的更改。使用file设置上下文后,用户可以使用system模块集合中的sefcontext来更新SELinux策略,如semanage fcontext

---
- name: test
  hosts: all
  tasks:
    - name: test
      sefcontext:
        target: /path/to/samba_file
        setype: samba_share_t
        state: present

注意:sefcontext模块更新SELinux策略中目标的默认上下文,但不更改现有文件的上下文。

3.2.4 在受管主机上复制和编辑文件

在此示例中,copy模块用于将位于控制节点上的Ansible工作目录中的文件复制到选定的受管主机。

默认情况下,此模块假定设置了force: yes。这会强制该模块覆盖远程文件(如果存在但包含与正在复制的文件不同的内容)。如果设置force: no,则它仅会将该文件复制到受管主机(如果该文件尚不存在)。

---
- name: test
  hosts: all
  tasks:
    - name: test
      copy:
        src: file
        dest: /path/to/file

要从受管主机传输文件到ansible主机,可使用fetch模块。

---
- name: test
  hosts: all
  tasks:
    - name: test
      fetch:
        src: /client/path/to/file
        dest: /ansible/path/to/file

要确保现有文件中存在特定的单行文本,可使用lineinfile模块:

---
- name: test
  hosts: all
  tasks:
    - name: test
      lineinfile:
        path: /path/to/file
        line: "add this line in the file"
        state: present

要将文本块添加到现有文件,可使用blockinfile模块:

---
- name: test
  hosts: all
  tasks:
    - name: test
      blockinfile:
        path: /path/to/file
        block: |
          one line
          two line
        state: present
3.2.5 从受管主机删除文件

​ 删除受管主机上的文件,可以使用file模块:

---
- name: test
  hosts: all
  tasks:
    - name: test
      file:
        path: /path/to/file
        state: absent
3.2.6 检索受管主机上的文件状态

stat模块检索文件的事实,类似于Linux中的stat命令。参数提供检索文件属性、确定文件检验和等功能。

stat模块返回一个包含文件状态数据的值的散列字典,允许用户使用单独的变量引用各条信息。

​ 以下示例注册stat模块的结果,然后显示它检查的文件的MD5检验和。

---
- name: test
  hosts: all
  tasks:
    - name: test
      stat:
        path: /path/to/file
        checksum_algorithm: md5
      register: result
      
    - debug:
      msg: "The checksum of the file is {{ result.stat.checksum }}"
3.2.7 同步控制节点和受管主机之间的文件

synchronize模块是一个围绕rsync工具的打包程序,它简化了playbook中的常见文件管理任务。rsync工具必须同时安装在本机和远程主机上。默认情况下,在使用synchronize模块时,“本地主机”是同步任务所源自的主机(通常是控制节点),而“目标主机”是synchronize连接到的主机。

以下示例将位于Ansible工作目录中的文件同步到受管主机:

---
- name: test
  hosts: all
  tasks:
    - name: test
      synchronize:
        src: file
        dest: /path/to/file

有很多种方法可以使用synchronize模块及其许多参数,包括同步目录。运行ansible-doc synchronize命令查看其他参数和playbook示例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值