JenkinsのスレーブをWindowsサービスとして動作させるためにやったこと

JenkinsのジョブをWindowsマシンでビルドするために、スレーブの設定を行おうとした場合に、手っ取り早くやるならbat経由でフォアグラウンドでスレーブを起動する感じになるかと思います

ただ、この運用方法ですと、

1. batを叩いてスレーブを起動
2. いつの間にかエラーが出て、スレーブがオフラインになる
3. 定期実行によってジョブがビルドされる
4. ビルド先のスレーブがオフラインなので、ビルドキューに溜まっていく。。。
5. 1に戻る

という負のループが出来上がりました
しかも、このエラーの原因がよく分からず。。。

毎回、手動でスレーブを再起動するのがシンドイため、どうにかならないものかと悩んでいたところ、
「Windowsサービスとしてスレーブを動かせば、エラーで落ちても自動的に再起動してくれる」
との情報を得て、調べてみました

調べてみると、レジストリーを弄る系の記事ばかり出てきて、
流石にそこら辺を弄るのはなぁ。。。と思っていたら、ドンピシャの記事を見つけまして、
実際に試したところ、ちゃんと想定した通りの動作が実現出来たため、こちらでご紹介させて頂きます

同じような悩みをお持ちの方がいましたら、ご参考になれば幸いです

ちなみに、下記が参考にした記事となります
https://hayato-iriumi.net/2019/05/23/how-to-install-jenkins-slave-as-windows-service/

## 事前準備

下記に関しては、記事内では触れないため、事前に行っておいて下さい

* Jenkinsの構築
* スレーブとして使用するWindowsマシンにjavaをインストール


## ノードを作成する

下記の設定でノードを作成します

ポイントとしては、**リモートFSルート** には、何も入力せず、（必須ですと書いてありますが無視で良いみたいです、、）
起動方法のプルダウンを **Launch agent by connecting it to the master** に設定し、
**Custom WorkDir path** に 任意のディレクトリのパスを指定します


:::note info
「Custom WorkDir path」 に指定したディレクトリ内に実行ファイルや設定ファイル等、もろもろ配置することになりますので、ドライブ直下に 「jenkins」ディレクトリを作成して、指定するのがオススメです
:::


設定が出来たら、**保存** をクリックします

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/e339ce85-770e-580c-4b34-c911622c9221.png" width=60%>


## ノードの状態画面でスレーブの起動オプションをコピーする


画像を参考にして **-jnlpURL** から末尾までコピーします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/51560c22-5b47-2f40-5733-7ef7c7128774.png)


## jenkins-slave.xmlを作成する
D:\jenkins の中に **jenkins-slave.xml** ファイルを作成します

:::note info
「D:\jenkins」は、ノード作成時に指定して頂いた 「Custom WorkDir path」 のパスのディレクトリです
:::

jenkins-slave.xmlをエディタで開いて頂いて、
下記のコードをコピー＆ペーストします


``` xml:jenkins-slave.xml
<service>
  <id>JenkinsSlave</id>
  <name>Jenkins agent</name>
  <description>This service runs an agent for Jenkins automation server.</description>
  <executable>{java.exeまでのフルパス}</executable>
  <arguments>-Xrs -jar "%BASE%\slave.jar" {前ステップでコピーした内容をここにそのままペースト}</arguments>
  <logmode>rotate</logmode>
  <onfailure action="restart" />
  <download from="https://{Jenkinsのドメイン名を入力}/jnlpJars/agent.jar" to="%BASE%\slave.jar" />
 <extensions>
    <extension enabled="true" className="winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension" id="killOnStartup">
      <pidfile>%BASE%\jenkins_agent.pid</pidfile>
      <stopTimeout>5000</stopTimeout>
      <stopParentFirst>false</stopParentFirst>
    </extension>
  </extensions>
</service>
```

次に、 **{}** で表記されている箇所を埋めていきます
ご自分の環境に合わせて埋めて頂ければと思います

1. `<executable>{java.exeまでのフルパス}</executable>`
    * 事前にインストールして頂いたjavaのexeまでのフルパスを入力します
    * 例: `<executable>C:\Program Files\Java\jdk-11.0.11\bin\java.exe</executable>`
2. `<arguments>-Xrs -jar "%BASE%\slave.jar" {前ステップでコピーした内容をここにそのままペースト}</arguments>`
    * **ノードの状態画面でスレーブの起動オプションをコピーする** のステップでコピーしたオプションをここにペーストします
3.  `<download from="https://{Jenkinsのドメイン名を入力}/jnlpJars/agent.jar" to="%BASE%\slave.jar" />`
    * 事前に構築済みのJenkinsのドメイン名を入力します

ここまで出来ましたら、ファイルを保存します

## jenkins-slave.exe.configを作成する

下記の内容で D:\jenkins にファイルを作成します

```
<configuration>
	<startup>
		<supportedruntime version="v4.0"/>
	</startup>
</configuration>
```

## 最新バージョンの winsw-2.x.x-net4.exe をダウンロード

下記サイトから最新バージョンの winsw-2.x.x-net4.exe をダウンロードします
https://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/

:::note info
この時の最新バージョンは、2.9.0でした
恐らく、最新バージョンであれば大丈夫かとおもいます
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/b843ffa2-cb87-2bc1-75ec-708b4916b556.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/011783c2-7c55-7192-3536-811e913ff2a7.png)

ダウンロードした winsw-2.x.x-net4.exe を **jenkins-slave.exe** にリネームして、D:\jenkins に配置します

## コマンドプロンプトからサービスをインストールする

管理者権限でコマンドプロンプトを起動します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/5db0ff90-417f-2f2d-f593-c95000fbc50a.png)

カレントディレクトリを変更して、**jenkins-slave.exe install** を実行します

```
cd /d D:\jenkins
jenkins-slave.exe install
```

下記のようなメッセージが表示されればインストール成功です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/15add392-0080-2371-94b6-a602bf6cf227.png)

## サービスを開始する

タスクマネージャーを起動して、サービスタブを開きます
インストールされていれば、**JenkinsSlave** というサービスが見つかります
この段階では、まだ状態が **停止** になっているため、右クリックメニューから **開始** をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/6b2dfc70-3b67-0a40-364e-2d82d0100492.png)

サービスが開始されると、状態が **実行中** に変わります

![2021-10-08_18h13_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/01b70e60-a3ad-e040-26d7-d7f9bca9e944.png)

## ビルド出来る状態か確認する

Jenkinsを開いて、ノードの状態が **Agent is conneced** になっていて、ビルド実行状態が **待機中** になっていればスレーブが正常に動作しているため、Windowsマシンでジョブを回すことが出来るかと思います
![31ba5754f621abba4f13de719b152e72.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969354/b2474e12-1e8a-2c2f-5d26-e042710b3066.png)

## あとがき

以上の手順で、JenkinsのスレーブをWindowsサービスとして動作させることが出来たかと思います
これでスレーブがエラーでオフラインになった場合でも、自動的に再起動されるため、負のループから脱出出来て、きっと幸せになれることでしょう。。（遠い目）

実は、サービスで動かした場合は、権限がSYSTEMユーザーになってしまうので、フォアグラウンドで動かしていた場合と色々と挙動が異なる部分もあるかと思いますが、そこはヨシナニお願いします。。

では、今回はこの辺で！