設定ファイルとpythonスクリプトのコレクションを含むGitリポジトリがあります。
サーバーリポジトリには、次のような受信後のフックがあります。
このような:
#!/bin/bash
while read oldrev newrev ref; do
branch=$(git rev-parse --symbolic --abbrev-ref $ref)
if [[ $branch == "master" ]];
then
echo "Ref $ref received in branch $branch"
echo "setup..."
cd /srv/repo.git
git --work-tree=/opt/work-dir checkout master -f
cd /opt/work-dir
echo "install virtual environment..." > "setup.log"
python3 -m virtualenv venv >> "setup.log"
echo "activate virtual environment..." >> "setup.log"
source venv/bin/activate >> "setup.log"
echo "install requirements..." >> "setup.log"
pip install -r requirements.txt >> "setup.log"
echo "done." >> "setup.log"
echo "run scripts..."
python source/some_script.py --param=value
else
echo "Ref $ref received, in branch $branch"
echo "no action needed."
fi
done
これはすべて正常に機能しますが、フックの実行中にGitクライアントがハングし、手動でキャンセルするまでその状態が続きます。明確にするために、サーバー側フックは正常に完了しますが、クライアントは途中でロギングを停止します。
pythonセットアップと実行を別のbashファイルに移動し、Nohup
またはdisown
を使用して、ハングの問題を修正できることを認識しています。ターミナルが閉じたら実行を継続します。ただし、これには、スクリプトの実行結果をgit Pushログに表示するのではなく、個別にログに記録する必要があります。
受信後のフックを手動で呼び出してプッシュをシミュレートすると、フックは正常に完了します。
hooks/post-receive <<MARK
09998130e13827a097797ff2fd3a973e91665960 fcb0b23a62f47bb73d6ccf2e6bfce324a04eeace master
MARK
フックの子プロセスを調べて、何かが適切に終了していないかどうかを確認しました。私の知る限り、親スクリプトが続行する前に、すべての子プロセスが完全に終了します。
私は呼びました ps auxf
受信後フックのすべてのコマンドの後で、プロセスツリーがどのように見えるかを確認し、常に次を返します。
root 711 0.0 0.3 95184 6812 ? Ss Feb16 0:00 sshd: username [priv]
username 720 0.0 0.2 95184 4660 ? S Feb16 0:04 \_ sshd: username @pts/1,pts/0,pts/2
username 725 0.0 0.1 19892 3712 pts/0 Ss Feb16 0:00 \_ -bash
root 842 0.0 0.1 49484 3676 pts/0 S 02:49 0:00 | \_ Sudo -i
root 843 0.0 0.1 19940 3768 pts/0 S 02:49 0:00 | \_ -bash
root 4616 0.0 0.1 50892 3428 pts/0 S 13:59 0:00 | \_ su - git
git 4617 0.0 0.1 19920 3752 pts/0 S 13:59 0:00 | \_ -su
git 5108 0.0 0.1 11256 3016 pts/0 S+ 17:26 0:00 | \_ /bin/bash hooks/post-receive
git 5130 0.0 0.1 38456 3328 pts/0 R+ 17:27 0:00 | \_ ps auxf
Ssh経由でログインし、Sudoを実行してからgitユーザーに送信するため、ネストは大きくなります...しかし、重要な部分は最後の2行にあります。
ハングの原因となる行を特定しました。
python3 -m virtualenv venv >> "setup.log"
この行をフックから削除し、更新をプッシュする前に仮想環境を手動でセットアップすると、プッシュは正常に完了します。
python source/some_script.py --param=value
またはpip install
のいずれかが、ハングした子プロセスを残すと思います。
私の実験から、gitにはpost-receive
スクリプトによって残されたすべての子プロセスを待機するサーバー側ロジックがあると思います。ぶら下がっている子供を永遠に待ちます。
受信後のスクリプトが常に完全に終了するという予測を確認してください。シェルで手動でpost-receive
を実行してから、ps
で子を検索します。