28

我目前正在编写一个遵循这种通用格式并通过 cron 作业运行的 Ansible 游戏:

pre_tasks:
  -Configuration / package installation

tasks:
  -Work with installed packages

post_tasks:
  -Cleanup / uninstall packages

上面的问题是,有时节中的命令tasks失败,当它失败时,post_tasks节不运行,使系统处于混乱状态。post_tasks即使发生故障或致命错误,是否可以强制命令运行?

我目前的方法是应用于ignore_errors: yes该部分下的所有tasks内容,然后when:对每个任务应用条件以单独检查先前的命令是否成功。

这个解决方案似乎是一个 hack,但它变得更糟,因为即使使用ignore_errors: yesset,如果一个任务遇到致命错误,整个游戏仍然会立即失败,所以我还必须运行一个 cron'd bash 脚本来手动检查事情达到播放执行后。

我想要的只是保证即使tasks失败,post_tasks仍然会运行。我确信有一种方法可以做到这一点,而无需求助于 bash 脚本包装器。

4

4 回答 4

54

此功能在 Ansible 2.0 中可用:

这是新节标记blockrescue和的文档always

于 2015-08-02T04:34:01.647 回答
3

您应该使用处理程序(http://docs.ansible.com/ansible/playbooks_intro.html)并设置:

force_handlers: 真

请看一下 KubeNow 的集成测试(https://github.com/kubenow/KubeNow/blob/master/test/integration-test.yml)。

于 2017-01-19T09:44:19.050 回答
0

@MarkTamsky 是对的,但这里也有一个快速解释。

您可以将多个任务分组到blocks 中,然后任务指令将更深一层(如大多数 OO 语言中的“try”块中的代码),并且在更高级别,您可以控制如果其中一个或多个块会发生什么任务失败(rescue如“try”块之后的“catch”es)。

此外,如果您需要在块任务执行结束时运行一些任务(即,无论这些块任务是否失败),您都可以使用always(如 Python 的“finally”)。

示例(直接从文档中复制):

- name: Attempt and graceful roll back demo

  block: # <--- a block of tasks
    - name: Print a message
      ansible.builtin.debug:
        msg: 'I execute normally'

    - name: Force a failure
      ansible.builtin.command: /bin/false

    - name: Never print this
      ansible.builtin.debug:
        msg: 'I never execute, due to the above task failing, :-('

  rescue: # <--- a rescue
    - name: Print when errors
      ansible.builtin.debug:
        msg: 'I caught an error'

    - name: Force a failure in middle of recovery! >:-)
      ansible.builtin.command: /bin/false

    - name: Never print this
      ansible.builtin.debug:
        msg: 'I also never execute :-('

  always: # <--- an always
    - name: Always do this
      ansible.builtin.debug:
        msg: "This always executes"

注意1:每个块必须在一个“任务”中,即:

 tasks:
   - name: some name
     block:
       - name: some name
         <module>

注意 2:块级别的每个指令(例如whenbecome等)都将应用于“块中的每个任务”而不是块本身。

于 2021-11-23T10:42:11.140 回答
-14

不要使用post_tasks块,而是将您的清理过程作为常规的一部分tasks

于 2014-05-27T07:03:52.040 回答