无法使用 ansible 将多个文件归档到单个 tar 中

问题描述 投票:0回答:1

我希望将变量

{{ sourcefiles }}
中的逗号分隔文件压缩到目标
HELLO.tar
上的
source_host
中,并使用
fetch
模块将其带到 Ansible 控制器并取消存档(同时保留其绝对路径 <- this is optional).

不幸的是,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}

目的是在不同的主机上重新创建相同的文件文件夹结构。

一种解决方案可能是将所有文件复制到一个目录,然后压缩该目录,但我希望在保留其绝对路径的同时进行存档。

ansible overriding archive absolute-path
1个回答
0
投票

您当前的方法可以修复(请参阅@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

inventory.yml
将针对该 docker 测试容器:

---
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

现在我们运行剧本:

$ 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)

我将让您再次运行剧本以检查它是否完全幂等,并使用远程文件来检查任何更改是否按要求传输回控制器。完成后只需清理测试容器:

$ docker stop testans_container
© www.soinside.com 2019 - 2024. All rights reserved.