我正在尝试编写一个从多个主机获取文件的脚本,每个远程主机的路径以及从每个主机获取的文件数量都不同。
我的问题是,当
with_items
块内的文件长度不固定时,如何循环/迭代每个文件列表?
由于文件和路径的数量各不相同,我已按如下方式声明了我的库存文件,以使我的剧本更加灵活。来自远程主机的每个 fetch_path 对应于本地主机上的 land_path:
[hosts]
host1 fetch_paths='["path/to/file1", "path/to/file2"]' land_paths='["path/to/file1", "path/to/file2"]'
host2 fetch_paths='["path/to/file1"]' land_paths='["path/to/file1"]'
host3 fetch_paths='["path/to/file1", "path/to/file2", "path/to/file3"]' land_paths='["path/to/file1", "path/to/file2", "path/to/file3"]'
我当前的剧本如下,但我不确定如何在我的
loop
语句中嵌套 with_items
语句,并使其将 fetch_path 与 land_path 相关联。我假设我需要某种基于每个列表的长度的索引迭代器,但我不确定应该如何以及在哪里实现这个逻辑。
---
- name: fetch files from remote host then execute batch scripts on the localhost
hosts: hosts
tasks:
- name: fetch files from remote host to local
fetch:
src: "{{ item.fetch_paths }}"
dest: "{{ item.land_paths }}"
flat: yes
fail_on_missing: yes
validate_certs: no
with_items: "{{ groups['hosts'] }}"
我对 Ansible 非常陌生(这是我的第一本剧本),因此非常感谢任何正确方向的指导,提前致谢!
zip 列表。比如下面这个剧
shell> cat pb.yml
- hosts: all
tasks:
- fetch:
src: "{{ item.0 }}"
dest: "{{ item.1 }}"
flat: true
loop: "{{ fetch_paths|zip(land_paths) }}"
鉴于库存
shell> cat hosts
host1
host2
和 host_vars
shell> cat host_vars/host1
fetch_paths: [/etc/passwd, /etc/services]
land_paths: [/tmp/host1/etc/passwd, /tmp/host1/etc/services]
shell> cat host_vars/host2
fetch_paths: [/etc/passwd]
land_paths: [/tmp/host2/etc/passwd]
将按预期获取文件
shell> ansible-playbook pb.yml
PLAY [all] ************************************************************************************
TASK [fetch] **********************************************************************************
changed: [host2] => (item=['/etc/passwd', '/tmp/host2/etc/passwd'])
changed: [host1] => (item=['/etc/passwd', '/tmp/host1/etc/passwd'])
changed: [host1] => (item=['/etc/services', '/tmp/host1/etc/services'])
PLAY RECAP ************************************************************************************
host1: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host2: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
shell> tree /tmp/host1
/tmp/host1
└── etc
├── passwd
└── services
1 directory, 2 files
shell> tree /tmp/host2
/tmp/host2
└── etc
└── passwd
1 directory, 1 file
注1
没有记录参数dest可以是一个文件
dest:保存文件的目录。例如,如果目标目录是
,则主机/backup
上名为/etc/profile
的 src 文件将保存到host.example.com
中。主机名基于清单名称。/backup/host.example.com/etc/profile
参见:参数 flat
注2
如果不更改所获取文件的路径名,则可以简化工作流程。默认情况下,模块 fetch 将主机名添加到路径中。引用dest:
保存文件的目录。例如,如果主机
/backup/host.example.com/etc/profile' 上的dest' directory is
/backup' 为src' file named
/etc/profile'。主机名基于清单名称。host.example.com', would be saved into
以下播放
- hosts: all
tasks:
- fetch:
src: "{{ item }}"
dest: /tmp/ansible_fetch
loop: "{{ fetch_paths }}"
将获取的文件放入控制器上的目录 /tmp/ansible_fetch(如果需要,请将其更改为 /tmp)
shell> tree /tmp/ansible_fetch/
/tmp/ansible_fetch/
├── host1
│ └── etc
│ ├── passwd
│ └── services
└── host2
└── etc
└── passwd
因此,您不再需要列表 land_paths 了
shell> cat host_vars/host1
fetch_paths: [/etc/passwd, /etc/services]
shell> cat host_vars/host2
fetch_paths: [/etc/passwd]