前言
新到公司的时候发现公司还在使用传统的手动打包测试方式,所以利用自己的闲暇时间开发了一个 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