【備忘】Jenkinsビルド実行時に権限不足で実行失敗した件
背景
業務でJenkinsを使用してECSへアプリケーションをビルドしようとした際に、ECSのタスク初回実行時に下記ログが出力されて異常終了しました。
+ ./jenkins/slave_run_maven_build.sh
ファイルパス: 行 1:./jenkins/slave_run_maven_build.sh: 許可がありません
洗い出し
許可がないとのことでしたので、Jenkins実行シェルの権限を確認しました。
$ ls -l
total ○○
-rwxr-wr-w 1 user ○○ ○○ Month Day Time slave_run_maven_build.sh*
ログを見る限り、実行権限があるように見えます。
権限不足の正体
調査したところ、git ls-files
コマンドで実行権限の有無を確認しないといけませんでした。
ここで、lsコマンドとgit ls-filesコマンドの違いについてまとめました。
ls コマンド(Linux/Unixの基本コマンド)
- 目的:ファイルシステム上のディレクトリやファイルを一覧表示する
- 対象:現在のディレクトリや指定したパスに存在する実際のファイル・フォルダ
ls
ls -l /home/user/projects
- 特徴:
- Gitとは無関係
- ファイルの存在や属性(サイズ、更新日時など)を確認するのに使う
git ls-files コマンド(Gitのサブコマンド)
- 目的:Gitのインデックス(ステージングエリア)に登録されているファイルを一覧表示する
- 対象:Gitリポジトリ内でGitが管理しているファイル
git ls-files
オプション | 説明 |
---|---|
オプションなし または –c | インデックスされているファイルの一覧を表示する |
-d | working-directory(作業ディレクトリ)で削除したファイルが表示される |
-m | working-directory(作業ディレクトリ)で更新したファイルが表示される |
-o | インデックスに追加していない(追跡されていない)ファイルの一覧を表示する |
-s | リポジトリ格納されたblobのhash値とファイル名の一覧を表示する |
- 特徴:
- ワーキングディレクトリに存在していても、Gitに追加(git add)されていないファイルは表示されない
- .gitignore で無視されているファイルも表示されない
- オプションでステージ情報や変更状態を確認できる
再確認
git ls-files コマンドで確認できることがわかりましたので、改めて確認しようと思います。
git ls-files -s
100644 hfahfeoegkaga 0 slave_run_maven_build.sh
コマンドの出力結果については、下記の通りです。
※出力結果左から
フィールド | 説明 |
---|---|
mode | ファイルのパーミッション(例:100644 は通常のファイル、100755 は実行可能ファイル、120000 はシンボリックリンク) |
object | GitオブジェクトのSHA-1(またはSHA-256)ハッシュ。ファイルの内容を一意に識別するID |
stage | ステージ番号(通常は 0。マージ中の競合があると 1, 2, 3 などが表示される) |
file | ファイル名(パス) |
git ls-files コマンドで確認しましたところ、
実行権限が無い
ことがわかりました。
権限付与対応
git update-index --add --chmod=+x slave_run_maven_build.sh
git update-indexコマンドの各種オプションは以下の通りです。
今回の事例でいうと、
Jenkinsの実行シェルに対して実行権限を追加する
処理を行いました。
オプション | 説明 |
---|---|
--add | インデックスに存在しないファイルを追加 |
--remove | インデックスにあるが、作業ツリーに存在しないファイルを削除 |
--force-remove | 作業ツリーに存在していてもインデックスから強制的に削除 |
--refresh | 作業ツリーとインデックスの差分をチェックして更新 |
--really-refresh | assume-unchanged フラグを無視して強制的に更新 |
--ignore-missing | --refresh 実行時に存在しないファイルを無視 |
--unmerged | マージ中の未解決ファイルがあってもエラーにせず続行 |
--cacheinfo <mode>,<object>,<path> | 指定した情報を直接インデックスに挿入 |
--index-info | 標準入力からインデックス情報を読み込む |
--chmod=+ | 実行権限を持たせる |
--[no-]assume-unchanged | Gitに「このファイルは変更されない」と仮定させる |
--[no-]skip-worktree | Gitに「このファイルは作業ツリーで変更されない」と仮定させる |
--info-only | オブジェクトを作成せず、インデックスにIDだけ挿入 |
--unresolve | 誤ってクリアされたマージ状態を復元 |
--verbose | 詳細な出力を表示 |
--index-version <n> | インデックスのバージョンを設定 |
--show-index-version | 現在のインデックスバージョンを表示 |
参考:
権限追加後の確認
git ls-files -s
100755 hfahfeoegkaga 0 slave_run_maven_build.sh
無事にJenkinsの実行シェルに実行権限が付与されました!
備考
Jenkinsと他CI/CDの違い
項目 | Jenkins | CircleCI | GitHub Actions |
---|---|---|---|
実行形式 | シェルスクリプトを直接実行 | run ステップでコマンド実行 | run ステップでコマンド実行 |
実行権限の扱い | Gitの実行権限が影響する | 明示的に chmod +x が必要 | 明示的に chmod +x が必要 |
実行環境 | Jenkinsエージェント | Docker executor など | GitHubホストランナー or 自前 |
Jenkins の「実行シェル」
- Jenkins では、「ビルドステップ」や「シェルスクリプト」 として .sh ファイルを直接実行することが多い
- そのため、実行権限(chmod +x) が必要になるケースが多く、今回のような「Git上の実行権限」が問題になることがある
- 実行環境は基本的に Jenkinsエージェント(slave)上のOS環境
CircleCI の場合
- CircleCI では .circleci/config.yml に定義されたジョブ内で、
run ステップ
を使ってコマンドを実行する - ここでも .sh ファイルを実行することは可能だが、実行権限が必要な場合は chmod +x を明示的に書くことが多い
- ただし、CircleCI の場合は Docker イメージや executor の中で動作するため、Gitのインデックス上の実行権限が直接影響するケースは少ない
- run:
name: 実行スクリプト
command: |
chmod +x ./scripts/deploy.sh
./scripts/deploy.sh
GitHub Actions の場合
- GitHub Actions も
.github/workflows/*.yml
に定義されたジョブ内でrun ステップ
を使用する - .sh ファイルを実行する場合、実行権限が必要な場合は chmod +x を明示的に記述する
- GitHub Actions では、Gitのインデックス上の実行権限は無視されることが多く、ワークフロー内で明示的に権限を付与するのが一般的
- name: 実行スクリプト
run: |
chmod +x ./scripts/build.sh
./scripts/build.sh
.gitattributes
や .gitignore
の影響について
補足:今回の事象には直接関係しませんが、Gitの挙動に影響する設定ファイルとして .gitattributes
や .gitignore
の存在も知っておくと便利です。
-
.gitignore
Gitが追跡しないファイルを指定するための設定ファイル
例えば、ビルド成果物や一時ファイルなどを除外する際に使用
→.sh
ファイルが.gitignore
に含まれていると、git ls-files
では表示されない -
.gitattributes
Gitがファイルを扱う際の属性(改行コード、マージ戦略、フィルタなど)を制御する設定ファイル
例えば、WindowsとUnix間で改行コードの違いを吸収するためにtext=auto
を指定することがある
→ 実行権限には直接影響しないが、CI環境でのファイルの整合性に関係することがある
なぜ Git の実行権限が Jenkins に影響するのか?
⇒JenkinsがGitからチェックアウトしたファイルをそのまま使うため、Gitのインデックスにある実行権限が反映される
最後に
今回はJenkinsの実行シェルについての実行権限の有無確認、権限付与についてまとめてみました。
この解決法が何かしらのお役に立てられたら幸いです。
Discussion