Posted at

JenkinsのJNLPスレーブを簡単に gradlew 一発で立てたい

More than 1 year has passed since last update.


Jenkinsスレーブの立ち上げは無策でやると面倒くさい

Jenkinsではビルドする際、Jenkinsスレーブを立てることになるのですが、下記の理由により面倒です。


  • スレーブの登録が面倒
    image.png


    • というか、Jenkinsに設定をあまり持たせたくない。



  • Jenkinsからスレーブをつなぎに行く方式(SSHとか)だと、Firewall設定が厄介。


    • クラウド上にたっているJenkinsは実質ムリ。



  • WindowsとLinux、macOSやらで違う手順・プロトコルが必要になってくる。


面倒くささを克服する

そういうことで、下記方針でJenkinsスレーブ立てをやっていくことになります。



  • スレーブの登録が面倒



    • Swarm Plugin を使います。


      • このプラグインを使えば、スレーブ側からJenkins上に直接自分自身のスレーブ登録をオンデマンドかつ自動で行うことができます。

      • 設定画面上は "Self-Organizing Swarm Plug-in Modules" という名前になっているので注意。

      • 実際動かす際は Swarm Plugin のクライアントJARをダウンロードして下記のように引数付きで起動することになります。

        $ java -jar swarm-client.jar \
      
      -master "http://JenkinsのURL" \
      -name "スレーブの名前のプレフィックス" \
      -uname "JenkinsにログインするID" \
      -password "上記IDのパスワード" \
      -fsroot "スレーブのワークスペースルートパス" \
      -executors "エグゼキュータの数" \
      -deleteExistingClients \
      -label "スレーブノードのラベル1 ラベル2 ラベル3 ..." \
      -mode "exclusive"

      # あらかじめJenkinsのJNLPポートをあけておくこと / あらかじめ Swarm Plugin をインストールしておくこと





  • Jenkinsからスレーブをつなぎに行く方式(SSHとか)だと、Firewall設定が厄介。


    • → JNLPプロトコルを利用する。


      • 特定のポートにたっているJNLPポートにスレーブ側からシェイクハンドして以後TCP接続をするという方式です。

      • Swarm Pluginを使う時点でこれしか選択肢は無いです。






  • WindowsとLinux、macOSやらで違う手順・プロトコルが必要になってくる。


    • → JNLPは特にSSH非依存なので大丈夫。どの環境からでもいけます。




でもSwarm PluginのJARを置いたりするのが面倒くさい → Gradle化すればいい

上記のやり方でやるとしても、 Swarm Plugin のクライアントJAR をダウンロード・設置するのが非常に面倒です。クライアントJARのバージョンアップもやってられません。

そういうことで、 Gradle ビルドスクリプトを使ってスレーブのJARのダウンロードと立ち上げすべてをやってもらいます。


build.gradle

repositories { mavenCentral(); maven { url "https://repo.jenkins-ci.org/releases/" } }

configurations { tool }
dependencies { tool "org.jenkins-ci.plugins:swarm-client:3.12" }

task start(type: JavaExec) {
classpath = configurations.tool
main = "hudson.plugins.swarm.Client"
args([
"-master", "http://JenkinsのURL",
"-name", "スレーブの名前のプレフィックス",
"-username", "JenkinsにログインするID",
"-password", "上記IDのパスワード",
"-fsroot", "スレーブのワークスペースルートパス ",
"-executors", "エグゼキュータの数",
"-deleteExistingClients",
"-labels", ["スレーブノードのラベル1","ラベル2","ラベル3","..."].join(" "),
"-mode", "exclusive", // 排他モード
])
}
defaultTasks "start"


上記ファイルを用意して、下記コマンドを流せばスレーブが繋がります。

$ gradle

とはいえ、こうなるとGradleのインストールも面倒なので、Gradle wrapperも用意すればGradleのインストールも不要になります。

# JDKのインストールはさすがに必要

$ ./gradlew


スレーブを立ち上げ・維持するのが面倒

こうなると、スレーブを立ち上げ・維持するのが面倒になってきます。

Jenkinsスレーブを立ち上げるホストOSのデーモンサービス的な機能を使ってプロセスを維持させましょう。


  • macOS: launchd

  • 最近のLinux: systemd。systemdでデーモンのユニットを作る方法で調べましょう。

  • Windows: タスクスケジューラとか使えばできる。(詳しくない)

macOSなど、要するに証明書やらで特定ユーザの環境込みのXcodeでビルドしたいのだと思いますが、誰かのユーザプロセスとして立ち上げるようにデーモンを構成することをおすすめします。(場合によってはスレーブを立ち上げるためだけに、電源ONの後、ユーザログインという手順が必要になるでしょうね。)


ここまでやってきたことはこのリポジトリにあります

https://github.com/knjname/JenkinsSwarmPluginLauncherScript

そのうちLinuxデーモンの登録用スクリプト足すかも…