前言
新到公司的時候發現公司還在使用傳統的手動打包測試方式,所以利用自己的閑暇時間開發了一個 iOS 打包平臺,經過不斷改良,現在公司在使用新一款的打包平臺,測試人員可以輕松完成打包工作。我目前也在重新構建平臺,發布開源版本。
本系列文章記錄完整的 iOS 打包平臺搭建過程,文章列表記錄如下:
iOS自動打包平臺搭建:一 概述
iOS自動打包平臺搭建:二 模塊(組件)化開發
[iOS自動打包平臺搭建:三 Master/Slave架構
iOS自動打包平臺搭建:四 打包腳本(待完成)
iOS自動打包平臺搭建:五 內網OTA(待完成)
iOS自動打包平臺搭建:附 安卓打包(待完成)
什么是Master/Slave架構
Master/Slave相當于Server和agent的概念。Master提供web接口讓用戶來管理job和slave,job可以運行在master本機或者被分配到slave上運行。一個master可以關聯多個slave用來為不同的job或相同的job的不同配置來服務。[摘自網絡]
為什么用到Master/Slave架構
其實之前對這種架構并不是很熟,但因為公司沒有閑置Mac可以用來搭建服務器,打包平臺的服務只能在Linux系統的一臺服務器運行,而眾所周知 iOS 的打包只能在 Mac 上進行,所以要實現 iOS 的打包功能只能在服務器發布命令后,將打包指令傳遞給 Mac 去執行,在這個過程中服務器就是一個 Master,而執行打包操作的 Mac 就是 Slave,其關系如下圖所示。
怎么實現
關于 Master/Slave 架構的實現,我選擇使用 ssh,因為這是一種很簡單的方式,并且在 Mac 、 Linux 系統中都是默認安裝的,后來才注意到 Jenkins 也是 Master/Slave 架構,它有提供幾種方案,展示如下
對其他的方式有興趣的朋友可以研究下,我們繼續說 ssh 方式。
我在本地(localhost)新建一個用戶 ipack,在終端輸入 ssh ipack@localhost
:
$ ssh ipack@localhost
Password:
系統會提示輸入密碼,輸入對應的密碼 123456 ,提示成功后就已經算是可以搭建 Master/Slave 的橋梁了。
因為我們是要在 Master ssh 遠程登錄到 Slave,并不是同一臺主機的兩個用戶,另外我們是不希望 Master 在登錄到 Slave 的時候輸入密碼的,所以接下來將面對兩個問題:
- 能否登錄到其他主機?
- 能否免密登錄?
能否登錄到其他主機?
答案是肯定的,但是因為 Mac 系統的安全設置,需要開啟共享設置,如下
注意:要設置允許所用用戶訪問。
能否免密登錄?
免密登錄也是可以實現的,在 Master 生成公鑰和私鑰,然后將公鑰保存在 Slave 即可完成。具體如下:
在 Master 執行 ssh-keygen -t rsa
,默認會在 /Users/<User Name>/.ssh/
目錄下生成兩個文件,一個是私鑰(id_rsa
) ,一個是公鑰(id_rsa.pub
)。將公鑰文件上傳到 Slave 的 ~/.ssh/ 目錄,然后重命名為 authorized_keys
。
至此,對于普通發行版的 Linux 已經可以正常免密碼登錄了,但是在 Mac 上是不行的, Mac 上 sshd 一般默認是沒有打開免密登錄選項的,需要手動開啟。
在 Slave 上編輯文件 /etc/ssh_config
(需要 root 權限),如果沒有就新建一個,在行尾添加一行
PubkeyAuthentication yes
如果不出意外,現在是可以免密連接到 Slave 的。
執行命令
現在已經可以從 Master 登錄到 Slave ,并且已經可以執行操作,但也僅限于在終端中輸入命令,而我們需要的是能登錄能執行操作的一條命令,查閱很多資料找到一條線索,ssh 的 -t
參數。
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
就是可以提供一個遠程服務器的虛擬tty終端,加上這個參數我們就可以在遠程服務器的虛擬終端上輸入自己的提權密碼了,示例如下:
ssh -t -p $port $user@$ip 'cmd'
可以發現它的后面可以拼接 cmd
,也就是說可以預先在 Slave 上配置好腳本文件,然后在上述命令中執行這個腳本文件就可以達到我們的目的。
具體實現
根據以上的信息,要實現在 Slave 執行 iOS 打包操作有兩種實現方案:
- 提前部署好打包腳本文件,然后通過 ssh 執行
- 腳本部署在 Master,每次打包從 Mater 下拉,
sh -c "$(curl -fsSL <URL>.sh)"
這里對我采用提前部署好,部署腳本部分展示如下:
# 授權
if [ ! -d ${USER_DIR}/.ssh ];
then
mkdir -p ${USER_DIR}/.ssh
fi
cat << EOF > ${USER_DIR}/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB....
EOF
# 生成plist文件
cat << EOF > ${BASE_DIR}/Plist/options.plist
<?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>compileBitcode</key>
<false/>
<key>method</key>
<string>ad-hoc</string>
</dict>
</plist>
EOF
# 獲取iOS打包腳本
cd ${BASE_DIR}/Scripts
curl -o archive.sh ${URL}'/scripts/archive-ios.sh'
chmod +x archive.sh
# 獲取iOS模塊升級腳本
curl -o update-component.sh ${URL}'/scripts/update-component-ios.sh'
chmod +x update-component.sh
從腳本中可以看到獲取打包和升級模塊的部分,是從服務端下拉腳本到本地,并修改執行權限。有了這兩個腳本文件,在 Master 收到打包命令的時候就可以調用 Slave 的這個腳本執行打包操作了。
總結
本文主要針對用到的 Master/Slave 進行說明,因為相對簡單,所以很多地方并未展開說明,如發現錯誤或有任何疑問歡迎留言交流。
更多內容請訪問 http://blog.makaiwen.com