提问人:Ashar 提问时间:11/8/2023 最后编辑:ZeitounatorAshar 更新时间:11/10/2023 访问量:40
无法使用 ansible 将多个文件存档在单个 tar 中
Unable to archive mutiple files in a single tar using ansible
问:
我希望将变量中的逗号分隔文件压缩到目标上,并使用模块和 unarchive 将其带到 Ansible 控制器(同时保留它们的绝对路径< - 这是可选的)。{{ sourcefiles }}
HELLO.tar
source_host
fetch
不幸的是,tar 文件只提供了文件列表中的最后一个文件(具有绝对路径),即 ./tmp/4192.txt
- name: Archive the files
archive:
path: "{{ item }}"
dest: "~/HELLO.tar"
format: tar
with_items: "{{ sourcefiles.split(',') }}"
- name: Fetch directories from remote hosts
fetch:
src: "~/HELLO.tar"
dest: "{{ playbook_dir }}/tmpfiles/{{ Latest_Build_Number_rec }}/"
flat: yes
fail_on_missing: no
ansible 运行:
ansible-playbook passvar.yml -e "Latest_Build_Number_rec=200" -e "sourcefiles=/tmp/419.txt,/tmp/4191.txt,/tmp/4192.txt,/tmp/moht,/tmp/4192.txt" -vv
输出:
[wladmin@ansiblehost 200]$ tar -tvf HELLO.tar
-rw-r--r-- wladmin/aces 0 2023-11-08 04:02 tmp/4192.txt
如您所见,我只获取循环中的最后一个文件,而不是所有文件。
输出:
TASK [debug] ******************************************************************************************************************
task path: /home/wladmin/passvar.yml:56
Wednesday 08 November 2023 05:32:19 -0600 (0:00:00.214) 0:00:01.089 ****
ok: [remotesourcehost] => (item=/tmp/419.txt) => {
"msg": "/tmp/419.txt"
}
ok: [remotesourcehost] => (item=/tmp/4191.txt) => {
"msg": "/tmp/4191.txt"
}
ok: [remotesourcehost] => (item=/tmp/4192.txt) => {
"msg": "/tmp/4192.txt"
}
ok: [remotesourcehost] => (item=/tmp/moht) => {
"msg": "/tmp/moht"
}
ok: [remotesourcehost] => (item=/tmp/4192.txt) => {
"msg": "/tmp/4192.txt"
}
TASK [Archive the files] ******************************************************************************************************
task path: /home/wladmin/passvar.yml:61
Wednesday 08 November 2023 05:32:19 -0600 (0:00:00.046) 0:00:01.136 ****
ok: [remotesourcehost] => (item=/tmp/419.txt) => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_loop_var": "item", "archived": ["/tmp/419.txt"], "arcroot": "/tmp/", "changed": false, "dest": "/home/wladmin/HELLO.tar", "expanded_exclude_paths": [], "expanded_paths": ["/tmp/419.txt"], "gid": 64395, "group": "aces", "item": "/tmp/419.txt", "missing": [], "mode": "0644", "owner": "wladmin", "size": 10240, "state": "file", "uid": 600000008, "warnings": ["Platform linux on host remotesourcehost is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.8/reference_appendices/interpreter_discovery.html for more information."]}
ok: [remotesourcehost] => (item=/tmp/4191.txt) => {"ansible_loop_var": "item", "archived": ["/tmp/4191.txt"], "arcroot": "/tmp/", "changed": false, "dest": "/home/wladmin/HELLO.tar", "expanded_exclude_paths": [], "expanded_paths": ["/tmp/4191.txt"], "gid": 64395, "group": "aces", "item": "/tmp/4191.txt", "missing": [], "mode": "0644", "owner": "wladmin", "size": 10240, "state": "file", "uid": 600000008}
ok: [remotesourcehost] => (item=/tmp/4192.txt) => {"ansible_loop_var": "item", "archived": ["/tmp/4192.txt"], "arcroot": "/tmp/", "changed": false, "dest": "/home/wladmin/HELLO.tar", "expanded_exclude_paths": [], "expanded_paths": ["/tmp/4192.txt"], "gid": 64395, "group": "aces", "item": "/tmp/4192.txt", "missing": [], "mode": "0644", "owner": "wladmin", "size": 10240, "state": "file", "uid": 600000008}
ok: [remotesourcehost] => (item=/tmp/moht) => {"ansible_loop_var": "item", "archived": [], "arcroot": "/tmp/", "changed": false, "dest": "/home/wladmin/HELLO.tar", "expanded_exclude_paths": [], "expanded_paths": ["/tmp/moht"], "gid": 64395, "group": "aces", "item": "/tmp/moht", "missing": [], "mode": "0644", "owner": "wladmin", "size": 10240, "state": "file", "uid": 600000008}
ok: [remotesourcehost] => (item=/tmp/4192.txt) => {"ansible_loop_var": "item", "archived": ["/tmp/4192.txt"], "arcroot": "/tmp/", "changed": false, "dest": "/home/wladmin/HELLO.tar", "expanded_exclude_paths": [], "expanded_paths": ["/tmp/4192.txt"], "gid": 64395, "group": "aces", "item": "/tmp/4192.txt", "missing": [], "mode": "0644", "owner": "wladmin", "size": 10240, "state": "file", "uid": 600000008}
TASK [Fetch directories from remote hosts] ************************************************************************************
task path: /home/wladmin/passvar.yml:75
Wednesday 08 November 2023 05:32:21 -0600 (0:00:01.914) 0:00:03.051 ****
changed: [remotesourcehost] => {"changed": true, "checksum": "c44a7a35626075a29c6af395c096faada0fd1758", "dest": "/home/wladmin/tmpfiles/200/HELLO.tar", "md5sum": "72e76072ca2022b4d912b5108858fd53", "remote_checksum": "c44a7a35626075a29c6af395c096faada0fd1758", "remote_md5sum": null}
目的是在不同的主机上重新创建相同的文件夹结构。
一种解决方案可能是将所有文件复制到一个目录,然后压缩该目录,但我希望在保留其绝对路径的同时进行存档。
答:
您当前的方法可以修复(请参阅@U880D的评论),但是使用ansible.posix.synchronize
模块可以实现目标的更有效的方法。只需将文件列表直接从目标获取到容器,而无需通过存档。唯一的先决条件是在目标和控制器上都可用。rsync
下面是一个使用 docker 容器作为目标的完整示例。
测试项目结构:
$ tree
.
├── Dockerfile
├── filelist.txt
├── inventory.yml
├── playbook.yml
└── sync_dir
1 directory, 4 files
这是用于测试的 Dockerfile:
FROM python:alpine
WORKDIR /work
RUN \
apk update && apk add rsync && \
for i in `seq 1 9`; do \
touch demofile$i.txt; \
done
CMD tail -f /dev/null
我们可以构建映像并启动测试容器:
$ docker build -t testans:local .
$ docker run -d --rm --name testans_container testans:local
我们可以检查在默认容器工作目录中是否准备好了一些测试文件:
$ docker exec testans_container pwd
/work
$ docker exec testans_container ls -l
total 9
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile1.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile2.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile3.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile4.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile5.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile6.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile7.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile8.txt
-rw-r--r-- 1 root root 0 Nov 8 17:51 demofile9.txt
将针对该 docker 测试容器:inventory.yml
---
all:
hosts:
testans_container:
ansible_connection: docker
ansible_python_interpreter: /usr/local/bin/python
我们在要传输的文件中列出:filelist.txt
demofile1.txt
demofile4.txt
demofile9.txt
我们现在创建将所有这些放在一起:playbook.yml
---
- name: partial synchronize demo
hosts: testans_container
gather_facts: false
vars:
remote_dir: /work
local_dir: sync_dir
file_list: filelist.txt
tasks:
- name: Copy selected file listed in filelist.txt from target to controller
ansible.posix.synchronize:
mode: pull
src: "{{ remote_dir }}"
dest: "{{ local_dir }}"
rsync_opts:
- "--files-from={{ file_list }}"
在尝试之前,让我们检查一下目标目录是否为空:
$ ls -l sync_dir/
total 0
现在我们运行 playbook:
$ ansible-playbook -i inventory.yml playbook.yml
PLAY [partial synchronize demo] ******************************************************************************************************************************************************************************************************
TASK [Copy selected file listed in filelist.txt from target to controller] ***********************************************************************************************************************************************************
changed: [testans_container]
PLAY RECAP ***************************************************************************************************************************************************************************************************************************
testans_container : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我们可以看到所需的文件已到达目的地:
$ ls -l sync_dir/
total 3
-rw-r--r-- 1 user users 0 nov 8 18:51 demofile1.txt
-rw-r--r-- 1 user users 0 nov 8 18:51 demofile4.txt
-rw-r--r-- 1 user users 0 nov 8 18:51 demofile9.txt
注意:容器和控制器之间的文件时移是正常的,因为容器中的默认时区是 UTC,而我的本地计算机配置了 CET(即 UTC+1)
我将让您再次运行 playbook 以检查它是否完全幂等,并播放远程文件以检查任何更改是否按要求传输回控制器。完成后,只需清理测试容器:
$ docker stop testans_container
评论
loop
path: "{{ sourcefiles.split(',') }}"