0. 前言
在使用Synchronize模块的途中遇到了一些问题,并且很难在网上找到相应的解决方法。
1. 未显式指明 rsync 路径
sudo: no tty present and no askpass program specified
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(235)
问题描述:
- 如果你的Ansible报类似上面这种错误,
- 或者你的脚本里没有显式指明 rsync 的路径,
- 那么你就要考虑执行这一解决方法,看错误会不会消失。
解决方法:
- 在受控主机(remote)上找到 rsync 的可执行文件路径
whereis rsync
在我的受控主机上,它的路径为:/usr/bin/rsync
2. 在 Ansible脚本 中 synchronize 模块下添加一行 rsync_path: /usr/bin/rsync
至此,这个问题应该就解决了,如果没有解决就去找其他 Solution 吧…
2. 没有权限
failed: Operation not permitted
failed: Permission denied
问题描述:
在一大段报错信息里,如果出现了如上有关权限的报错,就应该是这个问题。
问题原理:
Synchronize模块是Ansible的模块里比较特殊的一个。
假设你在对 受控主机 的 目录A 进行操作:
- 目录A 的所有者为 root
- 而你在 Ansible 脚本里的登录用户是一个 有sudo权限的非root用户。
在如上情况下,即使你在脚本中写了 become 也无济于事:
become: yes
become_user: root
因为 synchronize 这个模块是工作在本地主机上的(运行 Ansible 脚本的主机),它不会受到 become 相关字段的影响。
因此你以为你 become 成了 root,可以任意地对 root 的目录进行 rsync 操作;然而实际上你在 synchronize 模块的眼里依然是普通用户。
解决方法:
在 Ansible 脚本中对目录权限进行控制,具体内容如下:
图片版:
文字版:
- name: 示例操作
block:
- name: chown dir to evo
args:
warn: False # 添加该参数来屏蔽直接使用shell产生的warning
# 把你在受控主机(remote)上要操作的目录(例如/usr/local)的owner和group
# 都改成脚本里的登录用户(例如user1用户)
shell: chown -R user1:user1 /usr/local/; chown user1:user1 /usr/local
# 进行synchronize操作
- name: sync copy qcap sdk
synchronize:
src: "{{ qcap.sdk_dir }}/"
dest: /usr/local/
recursive: yes
rsync_path: /usr/bin/rsync # 这个在问题一里说了
# 把目录权限改回去(别忘了)!
- name: chown dir to root
args:
warn: False
shell: chown -R root:root /usr/local/; chown root:root /usr/local