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)

 
问题描述:

  1. 如果你的Ansible报类似上面这种错误,
  2. 或者你的脚本里没有显式指明 rsync 的路径,
  3. 那么你就要考虑执行这一解决方法,看错误会不会消失。  

解决方法:

  1. 受控主机(remote)上找到 rsync 的可执行文件路径
whereis rsync

 在我的受控主机上,它的路径为:/usr/bin/rsync

synchronize ansible synchronize ansible copy link_Ansible

2. 在 Ansible脚本 中 synchronize 模块下添加一行 rsync_path: /usr/bin/rsync

synchronize ansible synchronize ansible copy link_解决方法_02

至此,这个问题应该就解决了,如果没有解决就去找其他 Solution 吧… 

2. 没有权限

failed: Operation not permitted 
failed: Permission denied

 
问题描述:
 在一大段报错信息里,如果出现了如上有关权限的报错,就应该是这个问题。
 问题原理:
Synchronize模块是Ansible的模块里比较特殊的一个。
假设你在对 受控主机目录A 进行操作:

  1. 目录A 的所有者为 root
  2. 而你在 Ansible 脚本里的登录用户是一个 有sudo权限的非root用户

在如上情况下,即使你在脚本中写了 become 也无济于事:

become: yes
become_user: root

 因为 synchronize 这个模块是工作在本地主机上的(运行 Ansible 脚本的主机),它不会受到 become 相关字段的影响。

 因此你以为你 become 成了 root,可以任意地对 root 的目录进行 rsync 操作;然而实际上你在 synchronize 模块的眼里依然是普通用户。 

解决方法:
 在 Ansible 脚本中对目录权限进行控制,具体内容如下:
 
图片版:

synchronize ansible synchronize ansible copy link_Ansible_03

文字版:

- 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