[本文基于Ansible 2.7]
设置切换用户执行后,某任务报出以下错误:
Failed to change ownership of the temporary files Ansible needs to create despite connecting as a privileged user. Unprivileged become user would be unable to read the file.
看起来是说无法修改远程临时目录的属主。直接在源码中搜索错误信息,找到如下代码:
ansible/plugins/action/__init__.py: 447~451
res = self._remote_chown(remote_paths, self._play_context.become_user)
if res['rc'] != 0 and remote_user in self._get_admin_users():
# chown failed even if remote_user is administrator/root
raise AnsibleError('Failed to change ownership of the temporary files Ansible needs to create despite connecting as a privileged user. '
'Unprivileged become user would be unable to read the file.')
所以_remote_chown的返回码为非零值。
ansible/plugins/action/__init__.py: 484~490
def _remote_chown(self, paths, user, sudoable=False):
'''
Issue a remote chown command
'''
cmd = self._connection._shell.chown(paths, user)
res = self._low_level_execute_command(cmd, sudoable=sudoable)
return res
远程执行命令的内容是由self._connection._shell.chown拼出来的。chown实现于ShellBase:
ansible/plugins/shell/__init__.py:100~105
def chown(self, paths, user):
cmd = ['chown', user]
cmd.extend(paths)
cmd = [shlex_quote(c) for c in cmd]
return ' '.join(cmd)
其实就简单拼接了一下,shlex_quote就等于shlex.quote(有兴趣可阅读ansible/module_utils/six/__init__.py, 里面关于MovedAttribute的定义)。
总之这个操作是为了将由登录用户创建的目录/文件(默认属主为登录用户)的属主修改为用于执行远程任务的用户(become_user),这样become_user就必定可以读取临时目录(以及其他在特定情况下需要的目录)下以及临时文件/其他必要的文件中的内容。
然而这条chown命令却执行失败了。
一般来说常见的造成chown错误的原因无非是:
- 目录或文件不存在
- 没有权限修改属主
- 目标用户不存在
临时目录是由登录用户创建的,按道理说前两点可以排除了,所以先检查一下become_user是不是存在,是不是写错了。如果不存在become_user错误,那就只好将生成的cmd(即上文chown的返回值)打印出来,到目标服务器上去看看报错的具体原因了。