ansible - 仅在需要时使用处理程序执行 Ansible 重启

标签 ansible ansible-role ansible-handlers

我有以下文件结构:

$ tree roles/os
roles/os
├── handlers
│   └── main.yaml
└── tasks
    └── main.yaml

tasks/main.yaml:

---
- name: Upgrade all packages
  ansible.builtin.apt:
    update_cache: true
    upgrade: dist

- name: Update bootloader firmware
  ansible.builtin.command: rpi-eeprom-update -ad
  changed_when: eeprom_update.stdout.find('updates pending') != -1
  notify: Perform reboot
  register: eeprom_update

- name: Check reboot status
  ansible.builtin.stat:
    path: /var/run/reboot-required
    get_checksum: false
  changed_when: reboot.stat.exists
  notify: Perform reboot
  register: reboot

handlers/main.yaml:

---
- name: Perform reboot
  ansible.builtin.reboot:
    post_reboot_delay: 30
  when: >
    eeprom_update.stdout.find('updates pending') != -1 or
    reboot.stat.exists

使用上述配置,仅当发生更改时才会执行重新启动。

这是使用处理程序执行有条件重新启动的正确方法吗?

最佳答案

您不必在处理程序中重复条件。这些条件用于通知任务中的处理程序。

  when: >
    eeprom_update.stdout.find('updates pending') != -1 or
    reboot.stat.exists

从处理程序中删除条件

- name: Perform reboot
  ansible.builtin.reboot:
    post_reboot_delay: 30

注释:

  • 在处理程序中,条件的语法错误。表达式的结果是一个字符串。测试一下
    - name: Test the syntax of the condition
      block:
        - name: Wrong. The result of the expression is string.
          debug:
            msg: >
              eeprom_update.stdout.find('updates pending') != -1 or
              reboot.stat.exists
        - name: Correct. The result of the expression is boolean.
          debug:
            msg: "{{ eeprom_update.stdout.find('updates pending') != -1 or
                     reboot.stat.exists }}"

        - name: Do not use braces "{{ '{{' }}" in the conditions. Variables are
                expanded automatically in a condition.
          debug:
            msg: Correct. The result of the expression is boolean
          when: eeprom_update.stdout.find('updates pending') != -1 or
                reboot.stat.exists

给出

TASK [Wrong. The result of the expression is string.] ****************************************
ok: [localhost] => 
  msg: |-
    eeprom_update.stdout.find('updates pending') != -1 or reboot.stat.exists

TASK [Correct. The result of the expression is boolean.] *************************************
ok: [localhost] => 
  msg: true

TASK [Do not use braces "{{" in the conditions. Variables are expanded automatically in a condition.] ***
ok: [localhost] => 
  msg: Correct. The result of the expression is boolean
shell> tree .
.
├── ansible.cfg
├── hosts
└── pb.yml

0 directories, 3 files
shell> cat ansible.cfg 
[defaults]
gathering = explicit
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml
shell> cat hosts 
localhost

重启文件存在

shell> ls -1 /tmp/reboot-required 
/tmp/reboot-required

剧本

shell> cat pb.yml 
- hosts: localhost

  tasks:

    - name: Update bootloader firmware
      ansible.builtin.command: echo 'updates pending'
      register: eeprom_update
      changed_when: eeprom_update.stdout.find('updates pending') != -1
      notify: Perform reboot
    - debug:
        var: eeprom_update.stdout

    - name: Check reboot status
      ansible.builtin.stat:
        path: /tmp/reboot-required
        get_checksum: false
      register: reboot
      changed_when: reboot.stat.exists
      notify: Perform reboot
    - debug:
        var: reboot.stat.exists

    - name: Test the syntax of the condition
      block:
        - name: Wrong. The result of the expression is string.
          debug:
            msg: >
              eeprom_update.stdout.find('updates pending') != -1 or
              reboot.stat.exists
        - name: Correct. The result of the expression is boolean.
          debug:
            msg: "{{ eeprom_update.stdout.find('updates pending') != -1 or
                     reboot.stat.exists }}"

        - name: Do not use braces '{{' '}}' in the conditions. Variables are
                expanded automatically in a condition.
          debug:
            msg: Correct. The result of the expression is boolean
          when: eeprom_update.stdout.find('updates pending') != -1 or
                reboot.stat.exists
        
  handlers:

    - name: Perform reboot
      debug:
        msg: Perform reboot

给出

shell> ansible-playbook pb.yml 

PLAY [localhost] *****************************************************************************

TASK [Update bootloader firmware] ************************************************************
changed: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  eeprom_update.stdout: updates pending

TASK [Check reboot status] *******************************************************************
changed: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  reboot.stat.exists: true

TASK [Wrong. The result of the expression is string.] ****************************************
ok: [localhost] => 
  msg: |-
    eeprom_update.stdout.find('updates pending') != -1 or reboot.stat.exists

TASK [Correct. The result of the expression is boolean.] *************************************
ok: [localhost] => 
  msg: true

TASK [Do not use braces "{{" in the conditions. Variables are expanded automatically in a condition.] ***
ok: [localhost] => 
  msg: Correct. The result of the expression is boolean

RUNNING HANDLER [Perform reboot] *************************************************************
ok: [localhost] => 
  msg: Perform reboot

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

关于ansible - 仅在需要时使用处理程序执行 Ansible 重启,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75272769/

相关文章:

docker - ansible即使安装了也找不到python包

Ansible:仅对某些主机执行角色

使用 if 语句的 Ansible 处理程序

Ansible 处理程序 - 未从救援 block 中调用

Ansible 在其处理程序中未检测到角色默认变量

variables - Ansible 2.8 角色 - 使用 vars/main 目录

docker - 在Ansible中全局设置TMPDIR以将Docker与/tmp上的noexec标志一起使用

Ansible:我可以从命令行执行角色吗?

linux - 未找到 Ansible 内部脚本命令

shell - 是否可以从ansible角色/文件目录运行shell脚本?