カスタム実行者

GitLab Runner 12.1 で導入されました

GitLab RunnerはPodmanやLibvirtのようなネイティブでサポートしていない環境のためにCustom executorを提供します。

これは、GitLab Runnerが環境のプロビジョニング、実行、クリーンアップを行う実行ファイルを使うように設定することで、独自のexecutorを作成できるようにするものです。

カスタムexecutor用に設定したスクリプトは、Driversと呼ばれます。例えば、Podmanドライバ、LXDドライバLibvirtドライバを作成することができます。

制限事項

以下はCustom executorを使用する際の現在の制限です:

設定

選択できる設定キーがいくつかあります。 そのうちのいくつかはオプションです。

以下は、使用可能な全てのコンフィギュレーション・キーを使用したCustom executorのコンフィギュレーション例です:

[[runners]]
  name = "custom"
  url = "https://gitlab.com"
  token = "TOKEN"
  executor = "custom"
  builds_dir = "/builds"
  cache_dir = "/cache"
  [runners.custom]
    config_exec = "/path/to/config.sh"
    config_args = [ "SomeArg" ]
    config_exec_timeout = 200

    prepare_exec = "/path/to/script.sh"
    prepare_args = [ "SomeArg" ]
    prepare_exec_timeout = 200

    run_exec = "/path/to/binary"
    run_args = [ "SomeArg" ]

    cleanup_exec = "/path/to/executable"
    cleanup_args = [ "SomeArg" ]
    cleanup_exec_timeout = 200

    graceful_kill_timeout = 200
    force_kill_timeout = 200

フィールドの定義と、どのフィールドが必須であるかについては、[runners.custom]セクションの設定を参照してください。

また、[[runners]]の内部には、builds_dircache_dir の両方が必須フィールドです。

ジョブ実行に必要なソフトウェア

ユーザーは、PATHに存在しなければならない以下を含む環境をセットアップする必要があります:

  • git: リポジトリのクローンに使用します。
  • gitLFS: リポジトリにある LFS オブジェクトをすべて取り出します。
  • GitLabRunner: アーティファクトとキャッシュのダウンロード/アップデートに使用します。

ステージ

Custom executorはジョブの詳細を設定し、環境を準備し、クリーンアップし、その中でジョブスクリプトを実行するためのステージを提供します。 各ステージは特定のことを担当し、注意すべきことが異なります。

Custom executorによって実行される各ステージは、組み込みのGitLab Runner executorが実行する時間に実行されます。

実行される各ステップについて、実行ファイルに特定の環境変数が公開され、実行中の特定のジョブについての情報を得るために使用できます。 すべてのステージは以下の環境変数を利用できます:

  • 定義済み変数を含む標準的なCI/CD環境変数
  • Custom Runnerホストシステムによって提供されるすべての環境変数。

CI/CD環境変数と定義済み変数の両方は、システム環境変数との競合を防ぐために、CUSTOM_ENV_ が先頭に付きます。 例えば、CI_BUILDS_DIR は、CUSTOM_ENV_CI_BUILDS_DIRとして利用できます。

ステージは以下の順番で進行します:

  1. config_exec
  2. prepare_exec
  3. run_exec
  4. cleanup_exec

コンフィグ

コンフィグステージはconfig_execによって実行されます。

例えば、プロジェクトIDに応じたビルドディレクトリの設定などです。config_exec 、STDOUTから読み込み、特定のキーを持つ有効なJSON文字列を期待します。

使用例:

#!/usr/bin/env bash

cat << EOS
{
  "builds_dir": "/builds/${CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID}/${CUSTOM_ENV_CI_PROJECT_PATH_SLUG}",
  "cache_dir": "/cache/${CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID}/${CUSTOM_ENV_CI_PROJECT_PATH_SLUG}",
  "builds_dir_is_shared": true,
  "hostname": "custom-hostname",
  "driver": {
    "name": "test driver",
    "version": "v0.0.1"
  }
}
EOS

JSON文字列の中に追加のキーがあっても無視されます。 有効なJSON文字列でない場合、ステージは失敗し、さらに2回再試行されます。

パラメータ タイプ 必須 説明
builds_dir ジョブの作業ディレクトリが作成されるベースディレクトリ。
cache_dir ローカルキャッシュが保存されるベースディレクトリ。
builds_dir_is_shared ブール 該当なし 同時実行ジョブ間で環境を共有するかどうかを定義します。
hostname Runnerによって保存されたジョブの “メタデータ “に関連付けるホスト名。 未定義の場合、ホスト名は設定されません。
driver.name ドライバのユーザー定義名。Using custom executor... 行とともに表示されます。 未定義の場合、ドライバに関する情報は表示されません。
driver.version ドライブのユーザー定義バージョン。Using custom executor... 行とともに印刷されます。未定義の場合は、名前情報のみが印刷されます。

実行ファイルのSTDERR がジョブログに出力されます。

GitLab Runnerが処理を終了する前にJSON文字列を返すまでの期限を設定したい場合は、config_exec_timeout

config_exec_argsのいずれかが定義されている場合、これらはconfig_execで定義されている実行ファイルに順番に追加されます。 例えば、以下のconfig.toml の内容があります:

...
[runners.custom]
  ...
  config_exec = "/path/to/config"
  config_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runner は/path/to/config Arg1 Arg2として実行します。

準備

準備ステージはprepare_execによって実行されます。

この時点で、GitLab Runnerはジョブに関するすべてのこと(どこで、どのように実行されるのか)を知っています。 あとは、ジョブが実行できるように環境を設定するだけです。 GitLab Runnerは、prepare_execで指定された実行ファイルを実行します。

これは環境のセットアップを担当します (たとえば、仮想マシンやコンテナの作成など)。 これが完了すると、ジョブを実行する環境が整うことになります。

このステージはジョブ実行の中で一度だけ実行されます。

ユーザは、GitLab Runnerがプロセスを終了する前に環境を準備するために待機する時間の期限を設定したい場合、prepare_exec_timeout

この実行ファイルから返されるSTDOUTSTDERR は、ジョブ・ログに出力されます。

prepare_exec_argsのいずれかが定義されている場合、これらはprepare_execで定義されている実行ファイルに順番に追加されます。 例えば、以下のconfig.toml の内容があります:

...
[runners.custom]
  ...
  prepare_exec = "/path/to/bin"
  prepare_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runner は/path/to/bin Arg1 Arg2として実行します。

走る

実行ステージはrun_execによって実行されます。

この実行ファイルから返されるSTDOUTSTDERR は、ジョブ・ログに出力されます。

他のステージとは異なり、run_exec ステージは複数回実行されます。これは、以下のサブステージに順次分割されるためです:

  1. prepare_script
  2. get_sources
  3. restore_cache
  4. download_artifacts
  5. step_*
  6. build_script
  7. step_*
  8. after_script
  9. archive_cache
  10. upload_artifacts_on_success またはupload_artifacts_on_failure
Note:GitLab Runner 14.0 以降では、build_scriptstep_scriptに置き換えられます。 詳しくはイシューをご覧ください。

上記の各ステージで、run_exec の実行ファイルが実行されます:

  • 通常の環境変数。
  • 論拠は2つ:
    • GitLab RunnerがCustom executorを実行するために作成するスクリプトへのパス。
    • ステージの名前。

使用例:

/path/to/run_exec.sh /path/to/tmp/script1 prepare_executor
/path/to/run_exec.sh /path/to/tmp/script1 prepare_script
/path/to/run_exec.sh /path/to/tmp/script1 get_sources

run_args が定義されている場合、それらはrun_exec 実行ファイルに渡される最初の引数のセットとなり、その後 GitLab Runner が他の引数を追加します。例えば、次のようにconfig.tomlを定義したとします:

...
[runners.custom]
  ...
  run_exec = "/path/to/run_exec.sh"
  run_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runnerは以下の引数で実行ファイルを実行します:

/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 prepare_executor
/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 prepare_script
/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 get_sources

この実行ファイルは、最初の引数で指定されたスクリプトの実行を担当します。 このスクリプトには、GitLab Runner の executor が通常実行する、クローン、アーティファクトのダウンロード、ユーザースクリプトの実行、そして以下で説明するその他のすべてのステップを実行するためのすべてのスクリプトがコンテナとして含まれています。 スクリプトには以下のシェルを指定できます:

  • Bash
  • PowerShellデスクトップ
  • PowerShellコア
  • バッチ(非推奨)

[[runners]]の内部でshell によって設定されたシェルを使用してスクリプトを生成します。 何も指定されていない場合は、OS プラットフォームのデフォルトが使用されます。

下の表は、それぞれのスクリプトが何をするのか、そのスクリプトの主な目的は何なのかを詳しく説明したものです。

スクリプト名 スクリプトの内容
prepare_script ジョブがどのマシンで実行されているかの簡単なデバッグ情報です。
get_sources Gitの設定を準備し、リポジトリをクローン/フェッチします。 GitLabが提供するGit戦略の利点をすべて得られるので、このままにしておくことをお勧めします。
restore_cache キャッシュが定義されている場合は、それを取り出します。これは、gitlab-runner のバイナリが$PATHで利用可能であることを想定しています。
download_artifacts gitlab-runner アーティファクトが定義されている場合は、ダウンロードします。 このバイナリは$PATHで利用可能です。
step_* GitLabによって生成されます。 実行するスクリプトのセットです。 カスタムexecutorには送られないかもしれません。step_releasestep_accessibilityのように複数のステップを持つかもしれません。.gitlab-ci.yml ファイルからの機能かもしれません。
build_script before_scriptscriptの組み合わせです。 GitLab Runner 14.0 以降では、build_scriptstep_scriptに置き換えられます。詳しくはこのイシューをご覧ください。
after_script これはジョブから定義されたafter_script 。 前のステップのどれかが失敗した場合でも、これは常に呼び出されます。
archive_cache キャッシュが定義されている場合、すべてのキャッシュのアーカイブを作成します。
upload_artifacts_on_success 定義されているアーティファクトをアップロードします。build_script が成功した場合のみ実行されます。
upload_artifacts_on_failure 定義されているアーティファクトをアップロードします。build_script が失敗した場合のみ実行されます。

清掃

クリーンアップステージはcleanup_execによって実行されます。

この最終ステージは、前のステージのいずれかが失敗した場合でも実行されます。 このステージの主な目的は、セットアップされている可能性のある環境をクリーンアップすることです。 たとえば、VMをオフにしたり、コンテナを削除したりします。

cleanup_exec の結果はジョブのステータスに影響しません。例えば、以下のような場合でも、ジョブは成功としてマークされます:

  • prepare_execrun_exec も成功。
  • cleanup_exec 失敗しました。

GitLab Runnerが環境をクリーンアップしてからプロセスを終了するまでの期限を設定したい場合は、cleanup_exec_timeout

この実行ファイルのSTDOUT は GitLab Runner のログに DEBUG レベルで出力されます。STDERR はログに WARN レベルで出力されます。

cleanup_exec_argsのいずれかが定義されている場合、これらはcleanup_execで定義されている実行ファイルに順番に追加されます。 例えば、以下のconfig.toml の内容があります:

...
[runners.custom]
  ...
  cleanup_exec = "/path/to/bin"
  cleanup_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runner は/path/to/bin Arg1 Arg2として実行します。

実行可能ファイルの終了とキル

GitLab Runnerは、以下のいずれかの条件下で実行可能ファイルを優雅に終了させようとします:

  • config_exec_timeoutprepare_exec_timeout または を満たしています。cleanup_exec_timeout
  • ジョブがタイムアウトしました。
  • ジョブはキャンセルされました。

タイムアウトに達すると、SIGTERM が実行ファイルに送られ、exec_terminate_timeoutのカウントダウンが始まります。実行ファイルはこのシグナルをリッスンして、リソースのクリーンアップを行う必要があります。exec_terminate_timeout が過ぎてプロセスがまだ実行中であれば、SIGKILL が送られてプロセスが kill され、exec_force_kill_timeoutが開始されます。exec_force_kill_timeout が終わった後もプロセスがまだ実行中であれば、GitLab Runner はプロセスを放棄し、それ以上停止/kill しようとしません。config_execprepare_exec またはrun_exec の間にこれらのタイムアウトの両方に達した場合、ビルドは失敗とマークされます。

GitLab13.1では、ドライバによって生成された子プロセスも、UNIXベースのシステムでは上で説明したグレースフル・ターミネーション処理を受けます。 これは、メインプロセスをプロセスグループとして設定し、すべての子プロセスがそれに属するようにすることで実現します。

エラー処理

GitLab Runnerが扱えるエラーには2種類あり、config_execprepare_execrun_execcleanup_exec の内部で実行ファイルがこれらのコードで終了した場合にのみ扱われます。 ユーザーが0以外の終了コードで終了した場合、以下のエラーコードの1つとして伝搬されるはずです。

ユーザースクリプトがこれらのコードの1つで終了する場合、それは実行可能な終了コードに伝搬されなければなりません。

ビルドの失敗

GitLab Runnerは、BUILD_FAILURE_EXIT_CODE GitLab RunnerにユーザーのBUILD_FAILURE_EXIT_CODEジョBUILD_FAILURE_EXIT_CODE ブに失敗があったことを通知するための終了コードとして、実行可能ファイルによって使用されるべきBUILD_FAILURE_EXIT_CODE環境変数を提供します。BUILD_FAILURE_EXIT_CODE もし実行可能ファイルが , のコードで終了したBUILD_FAILURE_EXIT_CODE場合、ビルドはGitLab CIで適切に失敗としてマークされます。

ユーザーが.gitlab-ci.yml ファイル内部で定義したスクリプトがゼロ以外のコードで終了する場合、run_execBUILD_FAILURE_EXIT_CODE の値で終了する必要があります。

注意:** を使って終了することを強くお勧めします。

システム障害

SYSTEM_FAILURE_EXIT_CODEで指定されたエラーコードでプロセスを終了することで、GitLab Runner にシステムエラーを送信することができます。 このエラーコードが返された場合、特定のステージで GitLab Runner はステージを再試行し、再試行がどれも成功しなかった場合、ジョブは失敗としてマークされます。

以下は、どのステージが何回再試行されるかの表です。

ステージ名 試行回数 各再試行間の待機時間
prepare_exec 3 3秒
get_sources GET_SOURCES_ATTEMPTS 変数の値(デフォルト 1)。 0秒
restore_cache RESTORE_CACHE_ATTEMPTS 変数の値(デフォルト 1)。 0秒
download_artifacts ARTIFACT_DOWNLOAD_ATTEMPTS 変数の値(デフォルト 1)。 0秒
注意:SYSTEM_FAILURE_EXIT_CODE を使って終了することを強くお勧めします。

ドライバーの例

Custom executorを使用したドライバーのサンプルはexamplesページにあります。