技術ネタはQiitaに移りました。壁もどこぞに。

TeamCity の BuildAgent をデーモン化

以前の記事で、TeamCity、および BuildAgent のインストールをおこなった。 ところが、この状態だとサーバー再起動時などに再び手動で BuildAgent を起動しなければならないため、 今回は BuildAgent のデーモン化をおこなってみようと思う。 また、TeamCity、BuildAgent のインストールについてまだの場合は以下を確認しつつ進める。

TeamCity JavaEE:war 版のインストール - 作業ノート
TeamCity JavaEE:war 版に BuildAgent インストール - 作業ノート

CentOS7 以降ではシステム管理の方法が、systemctl にまとめられ 初見でこそ少々面食らってしまうが、いろいろと見通しが良くなり、 わかりやすくなった部分も多い。

今回は CentOS7 で環境を立てているため、 このあたらしい方法でデーモン化を行ってみたいと思う。 なお、デーモン化についてのより詳細な情報については、別途以下を確認してほしい。

systemd (日本語) - ArchWiki

BuildAgent の起動確認

TeamCity の BuildAgent をインストールしたあとは、 エージェントディレクトリ内の bin ディレクトリに配置されている、 agent.sh を使用してプロセスを起動することになる。

なお、スクリプトの内容を見ると分かる通り、 agent.sh には引数を与えて動作指示を出すことができ、 以下4つのオプションが用意されている。

  • start
    • バックグラウンドでエージェントを起動する。
  • stop
    • 現在おこなっているビルドがあれば、それが完了した後に、エージェントを停止する。
  • run
    • フォアグラウンドでエージェントを起動する。
  • stop force
    • 現在おこなっているビルドがあってもそれを中止して、エージェントを停止する。

起動を確認する。今回は、/opt/teamcity/buildAgent-1 にエージェントがインストールされているものとする。

$ cd /opt/teamcity/buildAgent-1/bin
$ sudo ./agent.sh start
Starting TeamCity build agent...
Java executable is found in '/bin/..'.
Starting TeamCity Build Agent Launcher...
Agent home directory is /opt/teamcity/buildAgent-1
Current Java runtime version is 1.7
Lock file: /opt/teamcity/buildAgent-1/logs/buildAgent.properties.lock
Using no lock
$ ls ../logs/
buildAgent.pid  buildAgent.xmlRpcPort  error.log  launcher.log  output.log  teamcity-agent.log  teamcity-vcs.log  upgrade.log

エージェントが起動すると、log ディレクトリに pid ファイルが作成される。この pid ファイルはデーモン化で使用することになるので、生成パスを覚えておくと良い。

また、同様にスクリプト内のコメントから、いくつかの環境変数が使用されることも分かる。エージェントがうまく起動しなかった場合は、以下の設定も確認しておく。

  • JAVA_HOME、または JRE_HOME
    • エージェントの使用す bin/java の配置されているディレクトリを指定する。
  • TEAMCITY_AGENT_MEM_OPTS
    • (任意)エージェントの使用するメモリーを、JVM オプションで指定する。
  • TEAMCITY_AGENT_OPTS
    • (任意)追加の JVM オプションを指定する。
  • TEAMCITY_LAUNCHER_OPTS
    • (任意)エージェントランチャーの JVM オプション。
  • TEAMCITY_AGENT_PREPARE_SCRIPT
    • (任意)エージェントの、起動および停止前に実行するスクリプトの名前を指定する。

BuildAgent のデーモン化

エージェントの起動を確認できたら、一度 agent.sh stop でエージェントは停止しておく。つづいて、デーモン化できるように service ファイルの作成をしていく。

デーモン起動に必要なファイルは以下のいずれかのディレクトリに配置する。なお、同名のスクリプトが両方に存在する場合は、/usr/lib/systemd/system に存在するほうが優先され、ユーザー定義の起動ファイルもこちらに配置する。

  1. /etc/systemd/system
  2. /usr/lib/systemd/system

ここまでで動きを確認した agent.sh と、buildAgent.pid を使用して起動設定ファイルを作成する。

$ sudo vi /usr/lib/systemd/system/teamcity-agent-1.service
[Unit]
Description=TeamCity Build Agent 1
After=network.target

[Service]
Type=forking
PIDFile=/opt/teamcity/buildAgent-1/logs/buildAgent.pid
ExecStart=/opt/teamcity/buildAgent-1/bin/agent.sh start
ExecStop=/opt/teamcity/buildAgent-1/bin/agent.sh stop

[Install]
WantedBy=multi-user.target

保存をして、デーモンの再起動と起動設定ファイルの適用を確認する。

$ sudo systemctl daemon-reload

$ sudo systemctl start teamcity-agent-1

$ systemctl status teamcity-agent-1
teamcity-agent-1.service - TeamCity Build Agent 1
   Loaded: loaded (/usr/lib/systemd/system/teamcity-agent-1.service; disabled)
   Active: active (running) since 土 2015-01-17 03:22:39 JST; 20h ago
  Process: 7008 ExecStart=/opt/teamcity/buildAgent-1/bin/agent.sh start (code=exited, status=0/SUCCESS)
 Main PID: 7031 (java)
   CGroup: /system.slice/teamcity-agent-1.service
           ├─7031 java -ea -cp ../launcher/lib/launcher.jar jetbrains.buildServer.agent.Launcher -ea -Xmx384m -Dteam...
           └─7042 java -ea -Xmx384m -Dteamcity_logs=../logs/ -Dlog4j.configuration=file:../conf/teamcity-agent-log4j...

うまく動いた。TeamCity 側でのエージェント認識までには、1分〜3分程度要する場合があるので、こちらは慌てずに待とう。これでサーバー再起動時にも、自動起動させたりできるようになる。