はじめに
このエントリーに気がついたあなたは我々の仲間です!!(フィッシングメールみたいな書き出しだな…) 簡単に言うと、UnityアプリをMacでJenkinsで自動ビルドする際に引っかかるポイントの一つがこれです。
なぜ実行ユーザーを変更するのか?
そもそもなぜJenkinsの実行ユーザーを変更する必要があるのかというと、
- インストーラでJenkinsをインストールすると、jenkinsという名前のユーザーでLaunchDaemonsとして実行される。
- Unityはビルド時にEnlightenのためにGPUを使用するので、LaunchDaemonsとしては実行できない。
- ユーザーがログイン中の状態でLaunchAgentsとして実行すればGPUが使用できる。
- でも、jenkinsユーザーでログインするのはいろいろ不備があって問題がある。
- それに、いつも使っているユーザーでないと、コードサインのための各種証明書類の扱いがなんか面倒くさい。
からです。ちなみにWindowsではサービスとして「ローカルシステムユーザー」という特権ユーザーで普通に実行して普通にビルドできます。ずるい。
前提
前提条件として、Jenkinsを.jarファイルやHomebrewではなく、インストーラ(.pkg)でインストールされた方を対象とします。たぶん、インストーラを使わなかった方は問題なかったはずです。(なんとなくHomebrew嫌いなので…)
念のため、確認したときの関連ツールのバージョンを記しておきます。
OS: OS X El Capitan v10.11, macOS Sierra v10.12
Java: 1.8.0_112, 1.8.0_121
Jenkins: 2.19.3, 2.32.2
Unity: 5.4.1f1, 5.5.1f1
※基本的にはOSとJenkinsのインストーラの問題です。
LaunchDaemonsとLaunchAgents
インストーラでJenkinsをインストールした場合、インストーラが作ったjenkinsという名前のユーザーでLaunchDaemonsを使ってJenkinsが実行されることになっています。しかし、LaunchDaemonsではGPUが使用できないため、LaunchAgentsへ変更する必要があります。
で、こちらにも書きましたが、
launchdが言うことを聞かない場合に見直すべきこと
http://qiita.com/MARQUE/items/42446bbca65bbce27a43
こんな感じで、
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
mkdir ~/Library/LaunchAgents
sudo mv /Library/LaunchDaemons/org.jenkins-ci.plist ~/Library/LaunchAgents/
sudo chown -R hoge /var/log/jenkins/
sudo chown -R hoge /Users/Shared/Jenkins/
launchctl load ~/Library/LaunchAgents/org.jenkins-ci.plist
※chmodじゃなくてchownしています。
一旦実行中のJenkinsを停止して、インストーラで追加されたLaunchDaemonsの設定ファイルをLaunchAgentsとして起動するためにムーブして(おそらくユーザーのLaunchAgentsフォルダがないのでついでに生成)、すでに一度jenkinsユーザーで動いてしまっているのでログファイルフォルダとワークフォルダの所有権をJenkinsを実行させたいユーザーに変更して、LaunchAgentsとして再起動しています。あ、そのユーザーでログインした状態で実行してくださいね。
注意点として、OSをアップデートするとなぜか/var/log/jenkins/の所有権がrootに戻ってしまうっぽいので(SierraとHighSierraで経験)、OSアップデート後にJenkinsが動かなくなった場合は確認してみてください。
これで基本的には問題ないんですが、実はこれだけだと、次の日以降にMacを再起動すると動かなくなります。
newsyslog
問題はログファイルでした。/var/log/jenkins/
にJenkinsのログファイルがあるんですが、この所有権がいつの間にかjenkinsユーザーに戻ってしまい、Jenkins再起動時にログファイルにアクセスできなくなり、コンソールに
2017/02/04 11:11:47.894 com.apple.xpc.launchd[1]: (org.jenkins-ci[1437]) Service exited with abnormal code: 1
2017/02/04 11:11:47.894 com.apple.xpc.launchd[1]: (org.jenkins-ci) Service only ran for 0 seconds. Pushing respawn out by 10 seconds.
というエラーを吐き続けて起動しなくなります。
で、いろいろ調べたんですが、実は、Jenkinsのインストーラはnewsyslogにも痕跡を残していたのです!!
そもそもnewsyslogとは何かというと、ログファイルをログローテート、ざっくり言うと、古いログファイルを定期的に圧縮してコピーするツールで、Jenkinsとは別個に動くものなのです。それをインストーラがいつの間にか設定していたのですねー。
そのJenkins用の設定ファイルがこんな感じ。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
# Rotate Jenkins log at midnight, and preserve old logs in 3 days
/var/log/jenkins/jenkins.log jenkins:jenkins 644 3 * $D0 J
この書式だと、jenkinsグループのjenkinsユーザーで、毎日午前0時付近にbz圧縮してコピーし、過去3日間のログファイルを保存するという設定になっています。これを、例えば以下のようにして任意のエディタで編集して、
sudo nano /etc/newsyslog.d/jenkins.conf
ユーザー名とグループ名がjenkins:jenkins
となっているところをhoge:staff
などの任意のユーザーに変更すれば解決です。
おわりに
インストーラが何をしているのかというのはなかなか分からないものですが、やっぱり便利なので基本的にはインストーラを使いたいと思いつつ、もうちょっとJenkinsのインストーラ頑張れ、と言ったところでしょうか。