scriptコマンドが動いているとansibleがAnsiballZ_hogeの実行でフリーズする
tl;dr
/etc/profile.d/*.sh
は非ログインシェルでも(/etc/bashrc
から)呼ばれる- scriptコマンドが動いていると,ansibleがタイムアウトせずにフリーズする
/etc/profile
でscriptコマンドを実行するようにすることで,ansibleの実行でscriptコマンドが動かず問題が起きなくなった
環境
- コントロールノード
- macOS 12.3
- ansible 2.13
- マネージドノード
- CentOS 7.9
- bash 3.2
- script 2.23
背景
マネージドノードにsshで入って作業した記録するために,/etc/profile.d/record.sh
に以下のようなスクリプトを書いていました.
/etc/profile.d/record.sh
tty -s
if [ $? == 0 ]; then
if [ "x$session_record" = "x" ]
then
timestamp=`date "+%Y%m%d%H%M"`
output=/var/log/session/session.$USER.$$.$timestamp
session_record=started
export session_record
script -t -f -q 2>${output}.timing $output
exit
fi
fi
スクリプトはこちらを参考にしました.
cf. How to Automatically Record the Terminal Session Activity of All Users on Linux | 2DayGeek
ターミナルの有無を評価しているのは,scp等の場合は操作が記録されないようにしたかったからです.
しかし,scpの場合は/etc/profile
が読み込まれないようなので,これは必要ありませんでした(後述).
問題
この状態でマネージドノードに対してansibleを実行すると,AnsiballZ_hoge
(実行するモジュールによってAnsiballZ_ping
だったりAnsiballZ_setup
だったり)がフリーズする現象が起きました(タイムアウトもしない).
$ ansible -vvv -i hosts -m ping target
ansible [core 2.13.1]
config file = None
configured module search path = ['/Users/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/Cellar/ansible/6.0.0/libexec/lib/python3.10/site-packages/ansible
ansible collection location = /Users/username/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.10.5 (main, Jun 23 2022, 17:15:25) [Clang 13.1.6 (clang-1316.0.21.2.5)]
jinja version = 3.1.2
libyaml = True
No config file found; using defaults
host_list declined parsing /Users/username/Downloads/ansigle-script/hosts as it did not pass its verify_file() method
script declined parsing /Users/username/Downloads/ansigle-script/hosts as it did not pass its verify_file() method
auto declined parsing /Users/username/Downloads/ansigle-script/hosts as it did not pass its verify_file() method
Parsed /Users/username/Downloads/ansigle-script/hosts inventory source with ini plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
META: ran handlers
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' target '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<target> (0, b'/home/vagrant\n', b'')
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' target '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /home/vagrant/.ansible/tmp `"&& mkdir "` echo /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000 `" && echo ansible-tmp-1657341680.9266748-42824-188038444489000="` echo /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000 `" ) && sleep 0'"'"''
<target> (0, b'ansible-tmp-1657341680.9266748-42824-188038444489000=/home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000\n', b'')
<target> Attempting python interpreter discovery
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' target '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'python3.10'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.9'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.8'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.5'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/libexec/platform-python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<target> (0, b'PLATFORM\nLinux\nFOUND\n/usr/libexec/platform-python\n/usr/bin/python2.7\n/usr/bin/python\n/usr/bin/python\nENDFOUND\n', b'')
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' target '/bin/sh -c '"'"'/usr/libexec/platform-python && sleep 0'"'"''
<target> (0, b'{"osrelease_content": "NAME=\\"CentOS Linux\\"\\nVERSION=\\"7 (Core)\\"\\nID=\\"centos\\"\\nID_LIKE=\\"rhel fedora\\"\\nVERSION_ID=\\"7\\"\\nPRETTY_NAME=\\"CentOS Linux 7 (Core)\\"\\nANSI_COLOR=\\"0;31\\"\\nCPE_NAME=\\"cpe:/o:centos:centos:7\\"\\nHOME_URL=\\"https://www.centos.org/\\"\\nBUG_REPORT_URL=\\"https://bugs.centos.org/\\"\\n\\nCENTOS_MANTISBT_PROJECT=\\"CentOS-7\\"\\nCENTOS_MANTISBT_PROJECT_VERSION=\\"7\\"\\nREDHAT_SUPPORT_PRODUCT=\\"centos\\"\\nREDHAT_SUPPORT_PRODUCT_VERSION=\\"7\\"\\n\\n", "platform_dist_result": ["centos", "7.8.2003", "Core"]}\n', b'')
Using module file /usr/local/Cellar/ansible/6.0.0/libexec/lib/python3.10/site-packages/ansible/modules/ping.py
<target> PUT /Users/username/.ansible/tmp/ansible-local-42822e1dxayu5/tmpyb2fl1hk TO /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000/AnsiballZ_ping.py
<target> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' '[target]'
<target> (0, b'sftp> put /Users/username/.ansible/tmp/ansible-local-42822e1dxayu5/tmpyb2fl1hk /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000/AnsiballZ_ping.py\n', b'')
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' target '/bin/sh -c '"'"'chmod u+x /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000/ /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000/AnsiballZ_ping.py && sleep 0'"'"''
<target> (0, b'', b'')
<target> ESTABLISH SSH CONNECTION FOR USER: None
<target> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/Users/username/.ansible/cp/ecebe3fde6"' -tt target '/bin/sh -c '"'"'/usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1657341680.9266748-42824-188038444489000/AnsiballZ_ping.py && sleep 0'"'"''
最後の行が出力されたところでフリーズします.
原因
- ansible実行時(非ログインシェル)にロードされないと思っていた
/etc/profile.d/record.sh
がロードされていた(/etc/bashrc
から呼ばれていた・・・). - scriptコマンドを実行していると,ansibleが上記のようにフリーズしてしまう(なぜそうなるのかは不明).
解決方法
ansibleによる操作を記録する必要はそもそもなかったので,scriptコマンドの実行は/etc/profile.d/record.sh
ではなく,/etc/profile
に書くように変更しました.
/etc/profileがロードされるパターン
下記のとおりだったので,/etc/profile
でターミナルの有無を評価してscriptコマンドの実行を制御する必要はないと思います.
パターン | ロード |
---|---|
ssh | される |
ssh(コマンドパラメタあり) | されない |
scp | されない |
sftp | されない |
ansible | されない |