Ansible 'synchronize' 覆盖文件夹,即使 delete=no
Ansible 'synchronize' overwrites folder even though delete=no
在我的 Ansible 角色 "xen" 中,我有这个任务:
---
- name: Install Xen
synchronize: src=install/
dest=/
archive=yes
delete=no
我想将以下结构复制到目标位置,而不覆盖 /boot
和 /lib64
等现有文件夹中的文件:
root@node51 [~]# tree -L 1 /etc/ansible/xenhost/xen/files/install
/etc/ansible/xenhost/xen/files/install
├── boot
├── etc
├── lib64
├── usr
└── var
5 directories, 0 files
任务成功,但它替换了/lib64
中的所有文件。那杀死了我的服务器:
[root@localhost ~]# ls /lib64/
-bash: /usr/bin/ls: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
这是详细的任务输出,为简洁起见被截断了:
TASK: [xen | Install Xen] *****************************************************
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676 && echo $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676']
<127.0.0.1> PUT /tmp/tmpb7EusD TO /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize
<127.0.0.1> EXEC ['/bin/sh', '-c', u'LANG=C LC_CTYPE=C /usr/bin/python /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize; rm -rf /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/ >/dev/null 2>&1']
changed: [192.168.0.123] => {"changed": true, "cmd": "rsync --delay-updates -FF --compress --archive --rsh 'ssh -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"/etc/ansible/xenhost/xen/files/install/\" \"root@192.168.0.123:/\"", "msg": "…truncated…"}
奇怪的是,任务并没有删除 /boot
中的现有文件。
我确保明确指定 delete=no
,以防万一,所以它应该 而不是 "Delete files that don't exist (after transfer, not before) in the src
path."
为什么 Ansible 'synchronize' 模块替换了 /lib64
但按预期复制到 /boot
?
问题是 /lib64
不是目录。它是一个符号 link:
[root@localhost ~]# file /lib64
/lib64: symbolic link to `usr/lib64'
通过让 Ansible 'synchronize' rsync
您的 lib64
目录,它 删除符号 link 并在其位置放置一个实际文件夹.
因此,无法再从 /lib64
访问 /usr/lib64
中的库,这就是为什么依赖于在 /lib64
中查找库的所有操作都失败了:
[root@localhost ~]# ldd /usr/bin/ls
linux-vdso.so.1 => (0x00007fffa9118000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe4b9630000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007fe4b9428000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007fe4b9218000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe4b8e50000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fe4b8be8000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fe4b89c0000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe4b87b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4b9860000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007fe4b85b0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe4b8390000)
补救措施
改为复制到 /usr/lib64
。将要复制的库放在 /etc/ansible/xenhost/xen/files/install/usr/lib64
而不是 /etc/ansible/xenhost/xen/files/install/lib64
中,并确保后一个路径不存在。
在我的 Ansible 角色 "xen" 中,我有这个任务:
---
- name: Install Xen
synchronize: src=install/
dest=/
archive=yes
delete=no
我想将以下结构复制到目标位置,而不覆盖 /boot
和 /lib64
等现有文件夹中的文件:
root@node51 [~]# tree -L 1 /etc/ansible/xenhost/xen/files/install
/etc/ansible/xenhost/xen/files/install
├── boot
├── etc
├── lib64
├── usr
└── var
5 directories, 0 files
任务成功,但它替换了/lib64
中的所有文件。那杀死了我的服务器:
[root@localhost ~]# ls /lib64/
-bash: /usr/bin/ls: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
这是详细的任务输出,为简洁起见被截断了:
TASK: [xen | Install Xen] *****************************************************
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676 && echo $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676']
<127.0.0.1> PUT /tmp/tmpb7EusD TO /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize
<127.0.0.1> EXEC ['/bin/sh', '-c', u'LANG=C LC_CTYPE=C /usr/bin/python /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize; rm -rf /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/ >/dev/null 2>&1']
changed: [192.168.0.123] => {"changed": true, "cmd": "rsync --delay-updates -FF --compress --archive --rsh 'ssh -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"/etc/ansible/xenhost/xen/files/install/\" \"root@192.168.0.123:/\"", "msg": "…truncated…"}
奇怪的是,任务并没有删除 /boot
中的现有文件。
我确保明确指定 delete=no
,以防万一,所以它应该 而不是 "Delete files that don't exist (after transfer, not before) in the src
path."
为什么 Ansible 'synchronize' 模块替换了 /lib64
但按预期复制到 /boot
?
问题是 /lib64
不是目录。它是一个符号 link:
[root@localhost ~]# file /lib64
/lib64: symbolic link to `usr/lib64'
通过让 Ansible 'synchronize' rsync
您的 lib64
目录,它 删除符号 link 并在其位置放置一个实际文件夹.
因此,无法再从 /lib64
访问 /usr/lib64
中的库,这就是为什么依赖于在 /lib64
中查找库的所有操作都失败了:
[root@localhost ~]# ldd /usr/bin/ls
linux-vdso.so.1 => (0x00007fffa9118000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe4b9630000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007fe4b9428000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007fe4b9218000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe4b8e50000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fe4b8be8000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fe4b89c0000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe4b87b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4b9860000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007fe4b85b0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe4b8390000)
补救措施
改为复制到 /usr/lib64
。将要复制的库放在 /etc/ansible/xenhost/xen/files/install/usr/lib64
而不是 /etc/ansible/xenhost/xen/files/install/lib64
中,并确保后一个路径不存在。