web-dev-qa-db-ja.com

受信後のフック中にGitクライアントがハングするのを防ぐ方法

設定ファイルとpythonスクリプトのコレクションを含むGitリポジトリがあります。

サーバーリポジトリには、次のような受信後のフックがあります。

  • マスターブランチをチェックアウトし、
  • セットアップa python virtualenv、
  • ピップ要件をインストールし、
  • いくつかのスクリプトを実行します

このような:

#!/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ログに表示するのではなく、個別にログに記録する必要があります。

  1. gitクライアントがハングする原因は何ですか?
  2. クライアントをハングさせずに、gitクライアントでスクリプト実行のステータスを監視するにはどうすればよいですか?

直接電話する

受信後のフックを手動で呼び出してプッシュをシミュレートすると、フックは正常に完了します。

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"

この行をフックから削除し、更新をプッシュする前に仮想環境を手動でセットアップすると、プッシュは正常に完了します。

3
Marvin

python source/some_script.py --param=valueまたはpip installのいずれかが、ハングした子プロセスを残すと思います。

私の実験から、gitにはpost-receiveスクリプトによって残されたすべての子プロセスを待機するサーバー側ロジックがあると思います。ぶら下がっている子供を永遠に待ちます。

受信後のスクリプトが常に完全に終了するという予測を確認してください。シェルで手動でpost-receiveを実行してから、psで子を検索します。

2
kubanczyk