我正在编写一个用于创建仅在我办公室内使用的Docker镜像的剧本。我的一个要求是允许其他开发人员在构建docker镜像之前轻松运行自己的代码。为此,我允许他们添加自己的yml文件,并在变量设置为False时运行它。我要求他们将文件称为{{account}}。yml其中account是另一个必须设置的变量。
对于在构建图片之前不想运行自定义播放的用户,将不会有{{account}}。yml文件。我认为通过添加条件,错误不会发生,因为我不会尝试导入文件,但即使应该忽略包含,我仍然会收到一个错误,告诉我文件没有'存在。
- name: Custom provisioning
include: '{{account}}.yml'
when: default_prebuild_provision == 'False' or generic == 'False'
我知道我的条件有效,因为我将其改为
- name: Custom provisioning
shell: echo Hello World
when: default_prebuild_provision == 'False' or generic == 'False'
由于条件失败,我无法获得任何输出。
有没有人有办法解决这个问题?我也应该为此打开一张票,因为它似乎是一个错误吗?
答案 0 :(得分:3)
正如Leito所描述的那样,由于include
的处理方式,这不可能直接实现。作为一个自定义模块,如果可能的话,这也很难实现。
丑陋解决方法可能是,为开发人员提供提供自定义剧本的选项,然后运行shell
操作,检查该playbook文件的存在,然后运行另一个ansible-playbook
进程。这当然有许多缺点,最令人担忧的是你不会在主剧中看到第二部剧本的输出。但它是我现在能想象的唯一选择,你可以在其中包含自定义任务。
- name: Custom provisioning
shell: [ -f {{account}}.yml ] && ansible-playbook ... {{account}}.yml
如果您希望开发人员运行的任务以某种方式预定义且仅在配置上有所不同,您可以允许他们提供自定义变量文件,然后根据定义的变量触发角色中的操作。在include_vars
任务中,您可以忽略错误:
- include_vars: {{account}}.yml
failed_when: false
failed_when: false
恕我直言比ignore_errors: yes
更好,因为它不会将任务标记为失败。 ignore_errors
仍然会抛出错误,但继续玩游戏。
或者,您可以执行类似的操作并返回默认或空的vars文件:
- include_vars: "{{ item }}"
with_first_found:
- "{{ account }}.yml"
- "empty.yml"
然后根据可能定义的变量运行您的任务:
- some_other_action:
details: some_var_from_account
when: some_var_from_account is defined
答案 1 :(得分:1)
这不是错误,请在发布的问题中详细了解:Ansible include task only if file exists
简短回答:when: False
不会使包含短路。 when子句只适用于' {{account}}内的所有任务.yml'当它存在或失败时,它没有。
解决这个问题的方法:我不确定,但是探索编写自己的包含(作为模块)的可能性