希望在使用 Ansible 时,也能够在日语环境的服务器上进行 su 操作
失败的案例
我认为 Ansible 的一个优点是即使没有 sudo 设置,也可以通过 su 开始管理。但是有些登录的服务器可能无法使用 su。
$ ansible -vvv -k -a id test01
SSH password:
<test01> ESTABLISH CONNECTION FOR USER: hoge on PORT 22 TO test01
<test01> REMOTE_MODULE command id
<test01> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081 && echo $HOME/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081'
<test01> PUT /tmp/tmphT3M68 TO /home/hoge/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081/command
<test01> EXEC /bin/sh -c 'LANG=C LC_CTYPE=C /usr/bin/python /home/hoge/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081/command; rm -rf /home/hoge/.ansible/tmp/ansible-tmp-1413805795.69-176729273645081/ >/dev/null 2>&1'
test01 | success | rc=0 >>
uid=500(hoge) gid=500(hoge) groups=500(hoge)
}
$ ansible -vvv -k --ask-su-pass -S -a id test01
SSH password:
su password:
<test01> ESTABLISH CONNECTION FOR USER: hoge on PORT 22 TO test01
<test01> REMOTE_MODULE command id
<test01> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113 && echo $HOME/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113'
<test01> PUT /tmp/tmpjkkti2 TO /home/hoge/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113/command
<test01> EXEC /bin/sh -c 'su root -c "/bin/sh -c '"'"'echo SUDO-SUCCESS-xmanncgpffykbigatwdldkkdgmmbhtce; LANG=C LC_CTYPE=C /usr/bin/python /home/hoge/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113/command; rm -rf /home/hoge/.ansible/tmp/ansible-tmp-1413805925.95-157880462545113/ >/dev/null 2>&1'"'"'"'
解决方案
似乎在 1.8 版本中修复了关于 UTF-8 的问题。
https://github.com/ansible/ansible/issues/8681
只要安装开发版就可以解决。
$ git clone git://github.com/ansible/ansible.git
$ cd ./ansible
$ git submodule update --init --recursive
$ make rpm
$ su
# rpm -Uvh rpm-build/ansible-*.noarch.rpm
最新的时候又发现了一个令人沉迷的东西,于是我调查了一下,结果发现这次是EUC-JP编码,所以我暂时解决了它。也许将来会遇到类似的情况,使用不同的字符编码。
--- su_prompts.py.org 2014-10-20 20:15:09.000000000 +0900
+++ su_prompts.py 2014-10-20 20:59:43.249570364 +0900
@@ -23,6 +23,7 @@
'Password',
'??',
'パスワード',
+ '\xa5\xd1\xa5\xb9\xa5\xef\xa1\xbc\xa5\xc9',
'Adgangskode',
'Contrasena',
'Contrasenya',
$ ansible -vvv -k --ask-su-pass -S -a id test01
SSH password:
su password:
<test01> ESTABLISH CONNECTION FOR USER: hoge on PORT 22 TO test01
<test01> REMOTE_MODULE command id
<test01> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100 && echo $HOME/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100'
<test01> PUT /tmp/tmpjHv_x2 TO /home/hoge/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100/command
<test01> EXEC /bin/sh -c 'su root -c "/bin/sh -c '"'"'echo SUDO-SUCCESS-xtytjbmmmvotdxchaexagwjhciuxdiaq; LANG=C LC_CTYPE=C /usr/bin/python /home/hoge/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100/command; rm -rf /home/hoge/.ansible/tmp/ansible-tmp-1413806497.99-216453360801100/ >/dev/null 2>&1'"'"'"'
test01 | success | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
非语言难题之外的痴迷点
不管区域设置如何,当su的用户的主目录不存在时,出现了多余的字符串而导致困扰。
(Pdb) s
> /usr/lib/python2.6/site-packages/ansible/runner/connection_plugins/paramiko_ssh.py(243)exec_command()
-> (self.runner.su_pass and utils.su_prompts.check_su_prompt(sudo_output)):
(Pdb) list
238
239 while True:
240
241 if success_key in sudo_output or \
242 (self.runner.sudo_pass and sudo_output.endswith(prompt)) or \
243 -> (self.runner.su_pass and utils.su_prompts.check_su_prompt(sudo_output)):
244 break
245 chunk = chan.recv(bufsize)
246
247 if not chunk:
248 if 'unknown user' in sudo_output:
(Pdb) print repr(sudo_output)
'Could not chdir to home directory /home/hoge: No such file or directory\r\nPassword: '
如果添加正则表达式等以使得check_su_prompt的结果变为True,这个问题就可以避免。但这个方法有点棘手,所以我选择安静地创建一个主目录。