英文:
How to copy first file to first host, second file to second host and so on via ansible?
问题
我有10台主机和10个文件。我想将这10个文件中的一个复制到相应的主机上:
1_file.txt -> 1_host
2_file.txt -> 2_host
...
10_file.txt -> 10_host
我尝试使用zip过滤器来实现,类似于:
- name: 将分割的文件复制到实例
copy:
src: "{{ item.0 }}"
dest: "{{ remote_ips_file }}"
delegate_to: "{{ item.1 }}"
loop: "{{ splitted_files.files | zip(instances) | list }}"
但是出现了错误:
{"msg": "模块执行期间发生意外故障。", "stdout": ""}
另一种方法(来自ChatGPT)是:
- name: 复制文件到主机
hosts: "{{ hosts }}"
tasks:
- name: 复制文件到主机
copy:
src: "{{ item.0 }}"
dest: "/tmp/{{ item.1 }}"
loop: "{{ zip(files, hosts) }}"
vars:
files: ['/path/to/file1', '/path/to/file2']
hosts: ['host1', 'host2']
但是也出现了错误:
zip未定义
有没有正确的方法来实现这个功能呢?
编辑
我找到了一种解决方法,但是它不是并行执行的:
- name: 将分割的文件复制到实例
copy:
src: "{{ item.0.path }}"
dest: "{{ remote_ips_file }}"
delegate_to: "{{ item.1 }}"
with_together:
- "{{ splitted_files.files }}"
- "{{groups['all']}}"
英文:
I have 10 hosts and 10 files. I want to copy one of 10 files to corresponding host:
> 1_file.txt -> 1_host
>
> 2_file.txt -> 2_host
>
> ...
>
> 10_file.txt -> 10_host
I've tried to do it with zip filter, like
- name: Copy splitted files to instances
copy:
src: "{{ item.0 }}"
dest: "{{ remote_ips_file }}"
delegate_to: "{{ item.1 }}"
loop: "{{ splitted_files.files | zip(instances) | list }}"
but got an error:
{"msg": "Unexpected failure during module execution.", "stdout": ""}
Another way (from ChatGPT) was:
- name: Copy files to hosts
hosts: "{{ hosts }}"
tasks:
- name: Copy file to host
copy:
src: "{{ item.0 }}"
dest: "/tmp/{{ item.1 }}"
loop: "{{ zip(files, hosts) }}"
vars:
files: ['/path/to/file1', '/path/to/file2']
hosts: ['host1', 'host2']
But also got an error:
zip is undefined
How to do it with proper way?
Edit
I've found workaround, but it works not in parallel:
- name: Copy splitted files to instances
copy:
src: "{{ item.0.path }}"
dest: "{{ remote_ips_file }}"
delegate_to: "{{ item.1 }}"
with_together:
- "{{ splitted_files.files }}"
- "{{groups['all']}}"
答案1
得分: 1
给定以下列表:
```yaml
my_files: [file1, file2]
my_hosts: [host1, host2]
创建字典:
hosts_files: "{{ dict(my_hosts|zip(my_files)) }}"
得到:
hosts_files:
host1: file1
host2: file2
在任务中使用该字典:
- copy:
src: "{{ hosts_files[inventory_hostname] }}"
dest: /tmp
用于测试的完整项目示例
shell> tree .
.
├── ansible.cfg
├── files
│ ├── file1
│ └── file2
├── hosts
└── pb.yml
1 directory, 5 files
shell> cat ansible.cfg
[defaults]
gathering = explicit
collections_path = $HOME/.local/lib/python3.9/site-packages/
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml
shell> cat hosts
[test]
host1 ansible_host=10.1.0.61
host2 ansible_host=10.1.0.63
[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
shell> cat pb.yml
- hosts: host1,host2
vars:
my_files: [file1, file2]
my_hosts: [host1, host2]
hosts_files: "{{ dict(my_hosts|zip(my_files)) }}"
tasks:
- debug:
var: hosts_files
run_once: true
- copy:
src: "{{ hosts_files[inventory_hostname] }}"
dest: /tmp
shell> ansible-playbook pb.yml
PLAY [host1,host2] ***************************************************************************
TASK [debug] *********************************************************************************
ok: [host1] =>
hosts_files:
host1: file1
host2: file2
TASK 点击复制 **********************************************************************************
changed: [host1]
changed: [host2]
PLAY RECAP ***********************************************************************************
host1: ok=2 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> ssh admin@10.1.0.61 ls -1 /tmp/file1
/tmp/file1
shell> ssh admin@10.1.0.63 ls -1 /tmp/file2
/tmp/file2
```
英文:
Given the lists
my_files: [file1, file2]
my_hosts: [host1, host2]
Create the dictionary
hosts_files: "{{ dict(my_hosts|zip(my_files)) }}"
gives
hosts_files:
host1: file1
host2: file2
Use the dictionary in the task
- copy:
src: "{{ hosts_files[inventory_hostname] }}"
dest: /tmp
<hr>
<sup>
Example of a complete project for testing
shell> tree .
.
├── ansible.cfg
├── files
│   ├── file1
│   └── file2
├── hosts
└── pb.yml
1 directory, 5 files
shell> cat ansible.cfg
[defaults]
gathering = explicit
collections_path = $HOME/.local/lib/python3.9/site-packages/
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml
shell> cat hosts
[test]
host1 ansible_host=10.1.0.61
host2 ansible_host=10.1.0.63
[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
shell> cat pb.yml
- hosts: host1,host2
vars:
my_files: [file1, file2]
my_hosts: [host1, host2]
hosts_files: "{{ dict(my_hosts|zip(my_files)) }}"
tasks:
- debug:
var: hosts_files
run_once: true
- copy:
src: "{{ hosts_files[inventory_hostname] }}"
dest: /tmp
shell> ansible-playbook pb.yml
PLAY [host1,host2] ***************************************************************************
TASK [debug] *********************************************************************************
ok: [host1] =>
hosts_files:
host1: file1
host2: file2
TASK 点击复制 **********************************************************************************
changed: [host1]
changed: [host2]
PLAY RECAP ***********************************************************************************
host1: ok=2 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> ssh admin@10.1.0.61 ls -1 /tmp/file1
/tmp/file1
shell> ssh admin@10.1.0.63 ls -1 /tmp/file2
/tmp/file2
</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论