我想使用ansible 2.5.2来执行一些升级任务,如果失败则回滚到之前的安装。我对所有配置更改使用notify,以防止在没有更改的情况下进行升级。我最初想在该通知的处理程序中使用block:
和rescue:
语句。
然而,由于尚未支持(https://github.com/ansible/ansible/issues/14270),我采用了建议的解决方法,在通知块中包含另一个任务,最终得到与以下内容等效的内容:
upgrade
|-handlers
main.yml
- name: upgrade task
include: upgrade.yml
|-tasks
main.yml
- name: Update configuration 1
template: src=conf.j2 dest={{ conf_dir }}/conf.conf
notify: upgrade task
- name: Update configuration 2
template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
notify: upgrade task
upgrade.yml
- block:
- debug: msg="Starting upgrade"
- name: Simulate failure of first of many upgrade tasks
command: /bin/false
rescue:
- debug: msg="Upgrade failed, rolling back now"
- name: Rollback deploy
include: rollback.yml
always:
- debug: msg="Upgrade complete"
rollback.yml
....
正如预期的那样,失败了:
RUNNING HANDLER [upgrade : Simulate failure of first of many upgrade tasks]
fatal: [hostname]: FAILED!
但不会打印Upgrade failed
或Upgrade complete
,并且不会执行rollback.yml
。
可能性似乎是:
任何人都可以发现问题或者以支持的方式给我一些关于构建此问题的指示吗?我能想到的唯一选择是使用listen
对处理程序进行分组,将它们标记为已更改但在失败时不会失败,并让它们通知回滚任务,但乍一看这似乎是非常的脆弱。
答案 0 :(得分:1)
答案似乎是2和3.如果示例块被移动到main.yml中,它将完美地运行,排除1。
在我在问题中链接的功能请求的评论中,另一个人在2016年提到了相同的问题,所以我现在提出了一个新的错误:https://github.com/ansible/ansible/issues/40130
要回答关于我建议的解决方法的更好替代方法的问题,可以使用register:
作为条件允许将块移动到tasks/main.yml
:< / p>
- name: Update configuration 1
template: src=conf.j2 dest={{ conf_dir }}/conf.conf
register: update1
- name: Update configuration 2
template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
register: update2
- block:
- debug: msg="Starting upgrade"
when: update1.changed or update2.changed
- name: Simulate failure of first of many upgrade tasks
command: /bin/false
when: update1.changed or update2.changed
rescue:
- debug: msg="Upgrade failed, rolling back now"
- name: Rollback deploy
include: rollback.yml
always:
- debug: msg="Upgrade complete"
这仍然很脆弱,因为每次添加配置任务时都需要记住更新块中的所有内容。如果您可以手动刷新处理程序,则以下方法可以消除此问题,并且有点清洁恕我直言:
- name: Update configuration 1
template: src=conf.j2 dest={{ conf_dir }}/conf.conf
notify: trigger upgrade
- name: Update configuration 2
template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
notify: trigger upgrade
- meta: flush_handlers
- block:
- debug: msg="Starting upgrade"
when: upgrade is defined and upgrade.changed
...
其中trigger upgrade
是handlers/main.yml
中的一个虚拟更改的处理程序,即:
- name: trigger upgrade
shell: echo "Upgrading"
register: upgrade
我认为在修复错误或处理程序允许阻止之前,这是最好的。