遠き君へ

〜インターネットの最果てで自分語りを垂れ流したり垂れ流さなかったりするブログ〜

DockerのJenkinsのジョブでGroovy使おうとしたらめちゃくちゃハマった話

Dockerコンテナって便利だけど、ハマったら切り分けとか、使ってる技術が多くて大変ですね……


目次


ハマりその1:Docker Desktopが起動しない

こちらは前回の記事(MacでDocker Desktopが起動しない - 遠き君へ)で書いた通りです。

ハマりその2:自動インストールの設定が反映されない

Dockerは起動するようになったので、気を取り直して、以下のJenkinsコンテナを立ち上げます。
GitHub - jenkinsci/docker: Docker official jenkins repo

docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

で、いつも通りウィザードに従って設定を完了させて、今回の目的のGroovy plugin - Jenkins - Jenkins Wikiをインストールします。

プラグインの説明通り、
Jenkinsの管理(/manage) > Global Tool Configuration(/configureTools/) > Groovy
で実行に使うGroovyの設定をして、テスト用のジョブを作成して実行したのですが……

FATAL: command execution failed
java.io.IOException: Cannot run program "groovy" (in directory "/var/jenkins_home/workspace/test1"): error=2, No such file or directory

あれーー?

ハマりその3:直接コンテナにgroovyをインストールしようとしたら、zipコマンドがないしapt-getもできない

調べてみてもイマイチよくわからないので、自動インストールに頼らず直接コンテナにgroovyインストールしちゃおうと思いました。

参考にしたのはこの辺りです。
インストールと実行(プログラミング入門 with Groovy) - Qiita
Installation - SDKMAN! the Software Development Kit Manager

SDKMANを入れる以下のコマンドをコンテナ内で叩いたところ……

curl -s "https://get.sdkman.io" | bash

こんな結果に。

Looking for a previous installation of SDKMAN...
Looking for unzip...
Looking for zip...
Not found.
======================================================================================================
 Please install zip on your system using your favourite package manager.

 Restart after installing zip.
======================================================================================================

「zipコマンドが入ってないからインストールしてからやり直してくれよな!」って感じのことを言われました。

そもそも使ってるコンテナのディストリビューションがわからないのでまず確認。
【3分理解】Linuxディストリビューションの確認方法

cat /etc/issue

 ↓

Debian GNU/Linux 9 \n \l

どうやらDebianのようです。ってことでapt-getしてみます。

apt-get install zip

 ↓

E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

「今rootユーザーじゃないからダメよ」ってことらしいです。

現在のユーザーを確認してみたところ、jenkinsでした。(まぁ妥当ですよね)

whoami

 ↓

jenkins

「root権限ならsudoだ〜」と何も考えず実行した結果

sudo apt-get install zip

 ↓

bash: sudo: command not found

sudoがない……だと!?
じゃぁsuか?!

su

 ↓

Password: 

って自分このコンテナのパスワード知らんやん/(^o^)\

このあたりでよくわからなくなっていろいろ別の試行錯誤しつつ、やっぱり戻ってきて以下の記事に辿り着く。

意外と忘れがち?コンテナのrootユーザのパスワードを知らなくてもrootユーザで実行する方法 - Qiita

なるほどね!コンテナの外から実行すればいいのね!!!
(自PCのDocker Desktop壊れてたことから伺えるように、たまにしかコンテナ触らないからさ……)

ということで一旦コンテナの外に出て、以下を実行。

sudo docker exec -u root -it {コンテナID} /bin/bash

(外からひとつひとつ実行してもいいけど、試行錯誤するにあたってはrootとして入っちゃった方が楽かなと)

ハマりその4:rootでapt-getしてもzipが入らない

さっきので「もーこれはゴール見えたっしょ」と思ったのもつかの間、
root権限でapt-get実行してもコノザマ

apt install -y zip

 ↓

Package zip is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'zip' has no installation candidate

ん???????
「まだなんかいかんのか…………」と思ってまた調べると以下の記事が。
DockerのUbuntuイメージでapt-getするには - Qiita

リポジトリ情報の更新が必要らしいので、それをやってからリトライ。

apt-get update
apt install zip

 ↓

Unpacking zip (3.0-11+b1) ...
Setting up zip (3.0-11+b1) ...

入ったっぽい!!!

ハマりその5:rootでgroovyを入れたらjenkinsユーザーで使えなさそう

これでよーやくgroovyをインストールする手順に戻れます😭

curl -s "https://get.sdkman.io" | bash
source "/root/.sdkman/bin/sdkman-init.sh"
sdk install groovy

 ↓

Installing: groovy 2.5.7
Done installing!


Setting groovy 2.5.7 as default.

場所を確認

which groovy

 ↓

/root/.sdkman/candidates/groovy/current/bin/groovy

PATHにも入ってますね。

echo $PATH

 ↓

/root/.sdkman/candidates/groovy/current/bin:/usr/local/openjdk-8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ってことで再び「Global Tool Configuration」を開き、GROOVY_HOMEにこいつのbinの親ディレクトリを設定します。

エラーメッセージが表示される

/root/.sdkman/candidates/groovy/current is not a directory on the Jenkins master (but perhaps it exists on some agents)

怒られた\(^o^)/

「まるでディレクトリが存在しないかのようなメッセージだけど、こういう時は大抵権限の問題だぞ……
それに確かにいかにもrootなディレクトリだし、jenkinsユーザーで入れ直そう!」

ということで再びjenkinsユーザーでコンテナに入って以下を実行

curl -s "https://get.sdkman.io" | bash
source "/var/jenkins_home/.sdkman/bin/sdkman-init.sh"
sdk install groovy
which groovy

 ↓

/var/jenkins_home/.sdkman/candidates/groovy/current/bin/groovy

「今度はいかにもJenkinsっぽい場所に入ったしいけそう!」
ってことでみたび「Global Tool Configuration」を開きGROOVY_HOMEを設定。

今度は成功

エラー出ませんでした🎉

ハマりその6:Groovy Versionが(Default)だとダメ

あとは引き続きGroovy plugin - Jenkins - Jenkins Wikiの説明の通りにジョブを設定し、
「Execute Groovy script」でprintln "Hello World"を設定し、実行。

FATAL: command execution failed
java.io.IOException: Cannot run program "groovy" (in directory "/var/jenkins_home/workspace/test1"): error=2, No such file or directory

あっっっるぇーーー???

Groovy plugin - Jenkins - Jenkins Wikiにこんな記述が。

If you don't configure any Groovy installation and select (Default) option in a job, the plugin will fallback into calling just the groovy command, assuming you have groovy binary on the default path on given machine.

「「Global Tool Configuration」のGroovyの設定がない場合に、(Default)を選択してると、マシンのローカルのPATHから探しちゃうよ」
って感じでしょうか。

今はちゃんと「Global Tool Configuration」のGroovyの設定をしているので該当しない気がしますが、
ジョブの設定中のGroovy Versionをちゃんと選択してみます。

ジョブの実行も成功

無事「Hello World」できました!!!

ハマり番外編:Jenkins上で実行するシェルスクリプトPATHが通らない

これはおまけです。

最後の成功した画像にgroovy --versionの結果も出てますが、これは確認用に「シェルの実行」の方に書いたやつです。
ここでgroovyコマンドを認識させるのもまたてこずりまして、
結果としては、コンテナ内のjenkinsユーザーのPATH環境変数をいじっても無駄のようで、
Jenkinsの管理(/manage) > システムの設定(/configure) > グローバル プロパティ
の方で環境変数PATHの設定をしてあげないとダメのようです。

jenkins で /usr/local/bin にあるコマンドファイルを実行できない。 | 晴れときどきPython

最後に

あーこんなにハマると思わなかった………

そして明らかになる真実。

「自分が使いたいのは「Execute Groovy script」ではなく「Execute system Groovy script」の方だ(Jenkins固有の操作がしたかった)から、これまでの過程がほぼ全部無駄だった」

半日分の努力の供養として、この記事を残します………

background image is created by Niellyn & bhsav.