Ansible 仅当文件存在时才允许包含任务
我试图仅在文件存在时才包含该文件。如果我的角色的用户需要,这允许在现有“任务/角色”之间自定义“任务/角色”。我发现:Ansible 仅当文件存在时才允许包含任务,ansible,Ansible,我试图仅在文件存在时才包含该文件。如果我的角色的用户需要,这允许在现有“任务/角色”之间自定义“任务/角色”。我发现: - include: ... when: condition 但Ansible文件指出: “所有任务都得到评估,但条件应用于每个任务”—— 所以 如果包含的文件不存在,则将失败。我想可能还有另一种机制允许用户向现有配方中添加任务。我不能让用户在我的角色之后添加角色,因为他们无法控制顺序:他们的角色将在我的角色之后执行。如果我没有错,你想继续剧本,即使when语句为fals
- include: ...
when: condition
但Ansible文件指出:
“所有任务都得到评估,但条件应用于每个任务”——
所以
如果包含的文件不存在,则将失败。我想可能还有另一种机制允许用户向现有配方中添加任务。我不能让用户在我的角色之后添加角色,因为他们无法控制顺序:他们的角色将在我的角色之后执行。如果我没有错,你想继续剧本,即使when语句为false 如果是,请在:
ignore_errors: True
因此,您的任务将如下所示:
- stat: path=/home/user/optional/file.yml
register: optional_file
- include: /home/user/optional/file.yml
when: optional_file.stat.exists
ignore_errors: True
请让我知道,如果我理解正确您的问题,或可以进一步帮助。谢谢到目前为止,我想到的最好的选择是:
- include: "{{ hook_variable | default(lookup('pipe', 'pwd') ~ '/hooks/empty.yml') }}"
它并不完全是一个“如果存在”,但它会给角色的用户相同的结果。在您的角色中创建一些变量和默认的空文件。Jinja过滤器“default”和“lookup”负责在未设置变量的情况下返回空文件
为方便起见,用户可以使用{{playbook\u dir}}
变量设置路径:
hook_variable: "{{ playbook_dir }}/hooks/tasks-file.yml"
我可以在这里花些时间来抨击ansible的错误处理规定,但简而言之,您是对的,由于声明的原因,您不能为此目的使用
stat
模块
对于大多数ansible问题,最简单的解决方案是在ansible之外进行。例如
- shell: test -f /home/user/optional/file.yml # or use -r if you're too particular.
register: optional_file
failed_when: False
- include: /home/user/optional/file.yml
when: optional_file.rc == 0
- debug: msg="/home/user/optional/file.yml did not exist and was not included"
when: optional_file.rc != 0
*
失败\u当添加
以避免主机在文件不存在时被排除在进一步的任务之外时。我使用了类似的方法,但对于文件模块,我的诀窍是检查变量定义,请尝试以下操作:
when: optional_file.stat.exists is defined and optional_file.stat.exists
只有当变量存在时,任务才会运行。谢谢大家的帮助!在今天的Ansible:Ansible 2.0.1.0 我的原始代码现在似乎可以工作了,除了我在本地机器中查找的可选文件外,所以我必须通过本地_操作运行stat,并为特定任务设置
been:no
,这样ansible就不会尝试在本地机器中执行sudo,并出现错误:“sudo:需要密码\n”
找到第一个_的条件可以在不使用统计或本地_操作的情况下完成此操作。此条件将遍历本地文件列表并执行任务,将
项设置为存在的第一个文件的路径。
如果在中包含skip:true
,并首先找到
选项,则可以防止文件不存在时失败
例如:
- hosts: localhost
connection: local
gather_facts: false
tasks:
- include: "{{ item }}"
with_first_found:
- files:
- /home/user/optional/file.yml
skip: true
使用ansible-2.1.0,我可以在我的剧本中使用这样的片段:
- hosts: all
gather_facts: false
tasks:
- name: Determine if local playbook exists
local_action: stat path=local.yml
register: st
- include: local.yml
when: st.stat.exists
当local.yml
不存在并且playbook被执行时(作为playbook,意味着它以主机:
行开始,等等),我没有收到任何错误/失败
您可以在任务级别使用类似的代码执行相同的操作。
使用stat
似乎可以正常工作。也可以选择使用Jinja2过滤器:
- set_fact: optional_file="/home/user/optional/file.yml"
- include: ....
when: optional_file|exists
在Ansible 2.5及以上版本中,可以使用以下测试进行:
- stat: path=/home/user/optional/file.yml
register: optional_file
- include: /home/user/optional/file.yml
when: optional_file.stat.exists
ignore_errors: True
-包括:/home/user/optional/file.yml
当:“'/home/user/optional/file.yml”为文件时
更多详细信息:我花了一点时间研究这个问题,看起来您是正确的,即使条件为false,它也肯定会失败。谢谢,您似乎理解这个问题,但这不起作用。忽略\u错误不会忽略文件丢失的事实。当它说:“请注意,上面的系统只控制特定任务的失败,因此如果使用了未定义的变量,它仍然会引发用户需要解决的错误。”这个错误是会阻止用户的错误之一。这只适用于Ansible v1.9及以下版本。Ansible v2.0及更高版本应在@olluchThank建议定义:include\u file\u变量时使用!我在我的真实代码中使用了{{playbook\u dir}}
,为了简单起见,我只是将其排除在示例之外。谢谢,似乎没有定义可选的\u file.stat.exists时,when将起作用。我仍在试图确定什么样的更改允许这样做。是否可以对角色执行类似的操作:仅当角色存在时才“包括”角色?我尝试使用pre_tast检查主文件中是否存在角色,保存一个变量,然后在角色包含中使用该变量,但ansible失败,因为找不到角色“debian_stock_config”
。谢谢你,这超出了这个问题的范围,你可能想开始你自己的,在你的具体问题上获得更多的关注。尝试这个,我看到了这个:错误with_first_found'不是PlaybookInclude的有效属性我将include
语句作为任务,而不是playbook级别的任务。它以这种方式作为一项任务工作。但包含的文件仅包含任务。如果您需要包含单独的以主机为目标的剧本,那么您必须在本地统计该文件,然后将该结果作为条件使用。这是Ansible的一个隐藏良好的功能,但非常棒,谢谢!请注意,Ansible的较新版本已切换到使用lookup
和first\u found
过滤器。看,这是一个惊人的方法。谢谢我使用test-d检查目录,后来意识到failed_when标志的值。再次感谢Ansible 2.9.1,我得到没有名为“exists”的筛选器
您是否尝试使用is exists
而不是| exists
?刚才我尝试了您的建议,但无法使其工作。您的意思是使用local\u action:stat…
,如
- set_fact: optional_file="/home/user/optional/file.yml"
- include: ....
when: optional_file|exists