如何使用ansible有条件地复制文件?
How to conditionally copy files using ansible?
请参考下面的配置,想法是,如果找到配置文件,请部署配置
我尝试了很多表达这个想法的变体,尤其是在最后 3 行中,但我无法全神贯注将 stat 循环的结果与我的部署循环结合起来 以一种有意义的方式
我的结构列表如下:
config_vars:
- war_name: TestNode_app1.war
standalone_name: jboss_standalone.xml
jboss_service_name: jboss_app1
jboss_folder: jboss_app1
- war_name: TestNode_app2.war
standalone_name: jboss_app2_standalone.xml
jboss_service_name: jboss_app2
jboss_folder: jboss_app2
我有剧本
...
...
tasks:
- name: check if war exists
stat:
path: files/wars/{{ item.war_name }}
register: war_file
loop: "{{ config_vars }}"
- name: Deploy config file
copy: src=files/wars/{{ item.war_name }} dest=/opt/{{ item.jboss_folder }}/standalone/deployments/{{ item.war_name }}
when: item.stat.exists
loop: "{{ config_vars }}"
with_items: war_file.results
预期结果:对于存在的 war 文件,部署循环应该选取它并进行复制。如果不存在,则不采取任何行动
实际结果:多种多样。对于上面的配置,我有:
ERROR! duplicate loop in task: items
The offending line appears to be:
- name: deploy WAR file
^ here
这可以通过 loop
和 zip
实现(替换旧的 with_together
循环)。
- name: Deploy config file
copy: src=files/wars/{{ item.0.war_name }} dest=/opt/{{ item.0.jboss_folder }}/standalone/deployments/{{ item.0.war_name }}
when: item.1.stat.exists
loop: "{{ config_vars | zip(war_file.results) | list }}"
这将产生相当冗长的输出,因此如果您想将其最小化,请添加如下内容:
loop_control:
label: "Copy {{ item.0.war_name }}"
确实,您确实有 duplicate loop in task
:loop
和 with_items
都是循环结构。
这里有一个简单的剧本来演示如何实现这一点。您甚至不需要使用 Matt P 提供的 with_together
结构,但是为了可读性,您可能需要使用。
- hosts: localhost
connection: local
gather_facts: false
vars:
config_vars:
- filepath: ./f1.txt
other: 'here'
- filepath: ./f2.txt
other: 'also here'
tasks:
- name: check if war exists
stat:
path: "{{ item.filepath }}"
register: war_file
loop: "{{ config_vars }}"
- debug:
msg: "Copying {{ item.item }}"
when: item.stat.exists
loop: "{{ war_file.results }}"
结果(仅给出 f2.txt 存在):
PLAY [localhost] *****************************************************************************************************************************************************************
TASK [check if war exists] *******************************************************************************************************************************************************
ok: [localhost] => (item={'filepath': './f1.txt', 'other': 'here'})
ok: [localhost] => (item={'filepath': './f2.txt', 'other': 'also here'})
TASK [debug] *********************************************************************************************************************************************************************
skipping: [localhost] => (item={'changed': False, 'stat': {'exists': False}, 'invocation': {'module_args': {'path': './f1.txt', 'follow': False, 'get_checksum': True, 'get_mime': True, 'get_attributes': True, 'checksum_algorithm': 'sha1', 'get_md5': None}}, 'failed': False, 'item': {'filepath': './f1.txt', 'other': 'here'}, 'ansible_loop_var': 'item'})
ok: [localhost] => (item={'changed': False, 'stat': {'exists': True, 'path': './f2.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 501, 'gid': 20, 'size': 0, 'inode': 8626896681, 'dev': 16777220, 'nlink': 1, 'atime': 1572930945.6961422, 'mtime': 1572930850.452235, 'ctime': 1572930850.452235, 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False, 'blocks': 0, 'block_size': 4096, 'device_type': 0, 'flags': 0, 'generation': 0, 'birthtime': 1572930850.452235, 'readable': True, 'writeable': True, 'executable': False, 'pw_name': 'pwd', 'gr_name': 'staff', 'checksum': 'da39a3ee5e6b4b0d3255bfef95601890afd80709', 'mimetype': 'unknown', 'charset': 'unknown', 'version': None, 'attributes': [], 'attr_flags': ''}, 'invocation': {'module_args': {'path': './f2.txt', 'follow': False, 'get_checksum': True, 'get_mime': True, 'get_attributes': True, 'checksum_algorithm': 'sha1', 'get_md5': None}}, 'failed': False, 'item': {'filepath': './f2.txt', 'other': 'also here'}, 'ansible_loop_var': 'item'}) => {
"msg": "Copying {'filepath': './f2.txt', 'other': 'also here'}"
}
PLAY RECAP ***********************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
请注意,war_file.results
的每个元素中都提供了 item
字典元素。此 item
包含 stat
循环中使用的项目。
这里是关于循环的更多信息:https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
谢谢你们。以下现在运行良好:
tasks:
- name: check if war exists
local_action: stat path=files/wars/{{ item.war_name }}
register: war_file
loop: "{{ config_vars }}"
- name: deploy war file
become: yes
become_user: jboss-as
copy: |
src=files/wars/{{ item.item.war_name }}
dest=/opt/{{ item.item.jboss_folder }}/standalone/deployments/{{ item.item.war_name }}
when: item.stat.exists
loop: "{{ war_file.results }}"
请参考下面的配置,想法是,如果找到配置文件,请部署配置
我尝试了很多表达这个想法的变体,尤其是在最后 3 行中,但我无法全神贯注将 stat 循环的结果与我的部署循环结合起来 以一种有意义的方式
我的结构列表如下:
config_vars:
- war_name: TestNode_app1.war
standalone_name: jboss_standalone.xml
jboss_service_name: jboss_app1
jboss_folder: jboss_app1
- war_name: TestNode_app2.war
standalone_name: jboss_app2_standalone.xml
jboss_service_name: jboss_app2
jboss_folder: jboss_app2
我有剧本
...
...
tasks:
- name: check if war exists
stat:
path: files/wars/{{ item.war_name }}
register: war_file
loop: "{{ config_vars }}"
- name: Deploy config file
copy: src=files/wars/{{ item.war_name }} dest=/opt/{{ item.jboss_folder }}/standalone/deployments/{{ item.war_name }}
when: item.stat.exists
loop: "{{ config_vars }}"
with_items: war_file.results
预期结果:对于存在的 war 文件,部署循环应该选取它并进行复制。如果不存在,则不采取任何行动 实际结果:多种多样。对于上面的配置,我有:
ERROR! duplicate loop in task: items
The offending line appears to be:
- name: deploy WAR file
^ here
这可以通过 loop
和 zip
实现(替换旧的 with_together
循环)。
- name: Deploy config file
copy: src=files/wars/{{ item.0.war_name }} dest=/opt/{{ item.0.jboss_folder }}/standalone/deployments/{{ item.0.war_name }}
when: item.1.stat.exists
loop: "{{ config_vars | zip(war_file.results) | list }}"
这将产生相当冗长的输出,因此如果您想将其最小化,请添加如下内容:
loop_control:
label: "Copy {{ item.0.war_name }}"
确实,您确实有 duplicate loop in task
:loop
和 with_items
都是循环结构。
这里有一个简单的剧本来演示如何实现这一点。您甚至不需要使用 Matt P 提供的 with_together
结构,但是为了可读性,您可能需要使用。
- hosts: localhost
connection: local
gather_facts: false
vars:
config_vars:
- filepath: ./f1.txt
other: 'here'
- filepath: ./f2.txt
other: 'also here'
tasks:
- name: check if war exists
stat:
path: "{{ item.filepath }}"
register: war_file
loop: "{{ config_vars }}"
- debug:
msg: "Copying {{ item.item }}"
when: item.stat.exists
loop: "{{ war_file.results }}"
结果(仅给出 f2.txt 存在):
PLAY [localhost] *****************************************************************************************************************************************************************
TASK [check if war exists] *******************************************************************************************************************************************************
ok: [localhost] => (item={'filepath': './f1.txt', 'other': 'here'})
ok: [localhost] => (item={'filepath': './f2.txt', 'other': 'also here'})
TASK [debug] *********************************************************************************************************************************************************************
skipping: [localhost] => (item={'changed': False, 'stat': {'exists': False}, 'invocation': {'module_args': {'path': './f1.txt', 'follow': False, 'get_checksum': True, 'get_mime': True, 'get_attributes': True, 'checksum_algorithm': 'sha1', 'get_md5': None}}, 'failed': False, 'item': {'filepath': './f1.txt', 'other': 'here'}, 'ansible_loop_var': 'item'})
ok: [localhost] => (item={'changed': False, 'stat': {'exists': True, 'path': './f2.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 501, 'gid': 20, 'size': 0, 'inode': 8626896681, 'dev': 16777220, 'nlink': 1, 'atime': 1572930945.6961422, 'mtime': 1572930850.452235, 'ctime': 1572930850.452235, 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False, 'blocks': 0, 'block_size': 4096, 'device_type': 0, 'flags': 0, 'generation': 0, 'birthtime': 1572930850.452235, 'readable': True, 'writeable': True, 'executable': False, 'pw_name': 'pwd', 'gr_name': 'staff', 'checksum': 'da39a3ee5e6b4b0d3255bfef95601890afd80709', 'mimetype': 'unknown', 'charset': 'unknown', 'version': None, 'attributes': [], 'attr_flags': ''}, 'invocation': {'module_args': {'path': './f2.txt', 'follow': False, 'get_checksum': True, 'get_mime': True, 'get_attributes': True, 'checksum_algorithm': 'sha1', 'get_md5': None}}, 'failed': False, 'item': {'filepath': './f2.txt', 'other': 'also here'}, 'ansible_loop_var': 'item'}) => {
"msg": "Copying {'filepath': './f2.txt', 'other': 'also here'}"
}
PLAY RECAP ***********************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
请注意,war_file.results
的每个元素中都提供了 item
字典元素。此 item
包含 stat
循环中使用的项目。
这里是关于循环的更多信息:https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
谢谢你们。以下现在运行良好:
tasks:
- name: check if war exists
local_action: stat path=files/wars/{{ item.war_name }}
register: war_file
loop: "{{ config_vars }}"
- name: deploy war file
become: yes
become_user: jboss-as
copy: |
src=files/wars/{{ item.item.war_name }}
dest=/opt/{{ item.item.jboss_folder }}/standalone/deployments/{{ item.item.war_name }}
when: item.stat.exists
loop: "{{ war_file.results }}"