2015-07-27

藉由 JNLP 設置 Mac OS X 的 Jenkins Slave

近來凍仁用 Jenkins CI 幫公司整合了些工作流程 (例如網站的 codebase 升版降版、私有 GitBook 文件網站 …),在前公司時更拿它來編 Android ROM。

接下來凍仁想用它來編 iOS Apps 或進行些自動化測試工作;但在這之前還需先把 Mac OS X (以下簡稱為 OSX) 納入版圖才行!

▲ 凍仁目前是拿 Mac mini 當 Mac OSX 的 Jenkins Slave。 (圖片來源: CNET)

0. 環境介紹

  • Master: Ubuntu 14.04 (Server)
  • Slave: Mac OS X 10.10.4 (Desktop)

1. 於 Master 新增 JNLP 節點

1.1. 若您對 Jenkins 不熟,還請參考 Jenkins – 如何透過 Java Web Start 建立 slave | 科科和測試 一文來新增 JNLP 節點。

1.2. 新增節點流程 (Jenkins → 管理 Jenkins → 管理節點 → 新增節點) 的最後一個畫面應與下圖雷同。

啟動模式請選擇「透過 Java Web Start 啟動 Slave 代理程式」。

2. 於 Slave 安裝 Java

請至 Java SE 官網下載 jdk-8u51-macosx-x64.dmg,建議直接上 JDK 已利建置編譯環境。

3. 於 Slave 執行 JNLP agent

3.1. 在設置好 Slave 節點後,可以直接點擊 Launch 或使用命令列執行 (需自行下載 slave.jar)。

▲ 凍仁在實作時有遇過 Launch 無法正常執行的情形。

3.2. 檢查執行狀態,若與下方結果雷同則成功。
[ jonny@yosemite ~ ]
$ ps aux | grep jenkins | grep EXAMPLE.TW [Enter]
/usr/bin/java -Djava.awt.headless=true -jar /Users/jenkins/bin/slave.jar -jnlpUrl http://JENKINS.EXAMPLE.TW/computer/NODE_NAME/slave-agent.jnlp -secret SECRET_KEY 

4. 於 Slave 註冊 slave agent 系統服務 (Daemon)

4.1. 在 OSX 裡我們需藉由 plist 設定檔將 agent 變成系統服務 (Daemon) 或常駐程式,底下為 plist 範例:
[ jonny@yosemite ~ ]
$ sudo vim /Library/LaunchDaemons/com.jenkins.ci.plist [Enter]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.jenkins.ci</string>
    <key>UserName</key>
    <string>jenkins</string>
    <key>SessionCreate</key>
    <true/>
    <key>ProgramArguments</key>
    <array>
      <string>java</string>
      <string>-Djava.awt.headless=true</string>
      <string>-jar</string>
      <string>/Users/jenkins/bin/slave.jar</string>
      <string>-jnlpUrl</string>
      <string>http://JENKINS.EXAMPLE.TW/computer/NODE_NAME/slave-agent.jnlp</string>
      <string>-secret</string>
      <string>SECRET_KEY</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/Users/jenkins/workspace/stdout.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/jenkins/workspace/error.log</string>
  </dict>
</plist> 

每人的設定檔將因人而異,例如:
  1. 擺放 slave.jar 的路徑。
  2. Jenkisn Master 的網址。
  3. 節點名稱。
  4. 私鑰代碼。
  5. 記錄檔 (log) 存放位置。

4.2. 撰寫完 plist 後,若不想重新開機則可以手動使用 launchctl 指令讀取。
[ jonny@yosemite ~ ]
$ launchctl load -w /Library/LaunchDaemons/com.jenkins.ci.plist [Enter]

4.3. 若 plist 有問題,我們可以使用 launchctl 手動卸除。
[ jonny@yosemite ~ ]
$ launchctl unload /Library/LaunchDaemons/com.jenkins.ci.plist [Enter]

4.4. 若嫌上述兩點過於複雜,重新開機後系統即會自行載入此 plist。

5. 檢查 Slave agent 狀態

以上都完成後,就可以到 Master 上查看結果;若失敗則圖示會多個紅字叉叉。
▲ 成功使用 JNLP agent 建立連線。

在完成 Jenkins 的版圖擴張後,還得撰寫些 Apple Script 來操控 OSX 才行。相信這對剛踏入 OSX 世界不到 5 個月的凍仁而言會是個不錯挑戰!

加油吧!邁向 DevOps 之路的 IT 工程師!

相關連結:
mac使用launchctl定时运行程序 | IT 男
Installing Jenkins as a Windows service | Jenkins Wiki

資料來源:
Setup a Mac Slave for Jenkins
Continuous Integration for iOS with Jenkins - savvy apps blog
mac osx - How to start/stop/restart launchd services from the command line? - Server Fault