jenkins使用简记
一、安装
jenkins有多种安装方式,可以使用内嵌的Servlet容器运行,也可以基于Apache运行,也可以安装成Linux或Windows服务。
macOS 下可以简单的使用 brew install jenkins 来安装,默认安装在 /usr/local/Cellar/jenkins 目录下,然后找到该目录下的 homebrew.mxcl.jenkins.plist 文件,修改其中的 httpListenAddress=127.0.0.1 为
0.0.0.0(否则就只能本机访问),然后拷贝到 ~/Library/LaunchAgents/ 目录下,就可以开机自动启动 jenkins 了。如果没有找到该文件,也可以自己手动新建:
<?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>homebrew.mxcl.jenkins</string> <key>ProgramArguments</key> <array> <string>/usr/bin/java</string> <string>-Dmail.smtp.starttls.enable=true</string> <string>-jar</string> <string>/usr/local/opt/jenkins/libexec/jenkins.war</string> <string>--httpListenAddress=0.0.0.0</string> <string>--httpPort=8080</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
1、使用 Servlet 容器运行
从官网下载 jenkins 的 .war 包,然后使用 java -jar jenkins.war 即可运行,当然前提是系统中已经安装好了Java环境,这种方式最便捷,可以放到 screen 里或者后台任务运行。
2、注册成 Linux 服务
以 CentOS 为例,从官网下载处选择 RedHat/CentOS 项进行 https://pkg.jenkins.io/redhat-stable/ ,根据提示添加 jenkins 源并安装即可:
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins
安装完毕后,就已经成功注册成了服务,通过 service jenkins start 启动即可。默认的配置文件路径是 /etc/sysconfig/jenkins ,默认的 jenkins 家目录是 /var/lib/jenkins
3、通过apache访问
其实是通过代理,使用类似 http://domain.com/jenkins 的形式访问 http://domain.com:8080 ,而将 8080 端口使用防火墙屏蔽禁止外部访问,使用的是 Apache 的 mod_proxy 和 proxy_ajp 模块,启动 Servlet 时只需要通过下面命令即可:
java -jar jenkins.war --httpPort=8080 --ajp13Port=80 --prefix=jenkins //--prefix=jenkins 指定通过 Apache 代理时URL访问的路径名字
二、权限管理
为什么这么早提到权限管理呢?因为 jenkins 默认的权限是比较开放的,如果不设置一下,可能会带来严重的安全隐患。
通过系统设置中 Configure Global Security 项,勾选 "开启安全" 项,帐户系统可以使用 jenkins 自有数据库,也可以使用 Unix 帐户系统,看个人习惯和实际使用需求,授权策略如果没有特殊的要求,一般推荐使用 “登录用户可以做任何事” 且取消 "允许任何人匿名读取" 勾选项。
注意点:
1、使用 Unix 帐户系统时,请务必点击下面的 "测试" 看有无提示问题,有可能会提示需要修改用户组等,但如果你没根据提示操作,直接点击保存,就会直接进入登录界面,导致登录不上。
2、如果修改权限出现问题或者遗忘密码不能登录,可以修改 jenkins 家目录下的 config.xml 文件,将
<useSecurity>true</useSecurity>
中的 true 修改成 false 并重启 jenkins 服务即可匿名登录,重新修改权限。
3、当在构建任务里需要对系统环境进行一些操作,如复制、改名等等,可能会因为权限不够而失败。原因在于 jenkins 是以某一个用户权限来运行的,默认是 jenkins 用户(在安装 jenkins时产生),所以解决问题的办法是要么提升 jenkins 的权限,要么修改所属用户如 root。仍然是修改 jenkins 启动配置文件,如果是使用 Linux 系统服务方式安装,则默认路径是 /etc/sysconfig/jenkins (可以通过 /etc/init.d/jenkins 查看)
三、参数化构建
在新建构建任务时,可以选择是否使用参数化构建,可用的参数类型有字符串、布尔、下拉列表、文件等多种形式。变量名可以在构建过程中通过 $ 前缀来获取它的值,其中下拉列表参数配置时,第一行是默认参数,而文件参数会让你设置一个存储目录,实现在构建过程中上传文件的功能。
参数化构建可以使你的构建任务更加灵活,但有一点需要注意,在普通构建中的 "构建后操作" 中使用 "Build other projects" 调用其它构建时,是不能调用参数化构建的。需要安装插件 "Parameterized Trigger plugin" ,这样就能在 "构建操作" 中(注意跟上面的位置不同)选择 "Trigger a remote parameterized job" 来调用参数化构建。
四、远程构建
我们常常需要在代码版本库更新时,去进行编译或部署操作,通常的做法是在构建任务中设置定时检查一次版本库,如果版本库更新则执行构建操作。但有时我们需要更及时的响应,或者更灵活的调用构建行为。
jenkins构建任务可以使用一个 url 调用,这个 url 中,你需要包含帐户信息、任务名、token 等信息,一个完整远程调用构建的 shell 命令如下:
curl -X POST --silent http://root:3a538f27d9612343a76f63bfab343315@114.235.120.122:8080/job/UpdateServer/build?token=online
其中, "root:3a538f27d9612343a76f63bfab343315" 是登录帐户的用户名和 API Token(注意不是密码,通过在后台点击用户名后进入个人设置中可以查看),token 参数值指的是在构建任务的 "构建触发器" 中选择 "触发远程构建" 项后输入的身份验证令牌。
注意,如果是参数构建,需要将远程构建URL中的 build 改为 buildWithParameters。
既然有了远程调用的途径,我们就可以使用SVN勾子来实现代码库更新后主动调用远程构建了,以SVN为例,增加 post-commit 如下:
#!/bin/sh
REPOS="$1"
REV="$2"
log_dir="/data/svn/ServerOnlineConfig/hooks/log"
ios_dir="online_iOS"
android_dir="online_Android"
changed_dirs=$(svnlook dirs-changed $REPOS)
update_ios="false"
update_android="false"
for dir in "$changed_dirs"
do
echo "$dir" >> "$log_dir"
if [[ $dir =~ $ios_dir ]]
then
update_ios="true"
echo "update_ios" >> "$log_dir"
fi
if [[ $dir =~ $android_dir ]]
then
update_android="true"
echo "update_android" >> "$log_dir"
fi
done
if [ "$update_ios" = "true" ]
then
curl -X POST --silent http://root:3a538f27d9612343a76f63bfab343315@114.235.120.122:8080/job/UpdatIOSServer/build?token=online
echo "update_ios success" >> "$log_dir"
fi
if [ "$update_android" = "true" ]
then
curl -X POST --silent http://root:3a538f27d9612343a76f63bfab343315@114.235.120.122:8080/job/UpdatAndroidServer/build?token=online
echo "update_android success" >> "$log_dir"
fi
五、构建管道
依赖构建前面已经提到过,就是在一个构建任务中,调用其它构建任务;或者是在调用一个构建任务之前,先检测另一个构建的状态,两者之间存在依赖或顺序关系。这没有什么可说的,就是把一个复杂的构建拆分成独立的子构建系统,既可在需要时独立运行,也可以一条龙构建,便于维护。
六、分布式构建
它主要应用在需要在不同平台构建同一产品,比如开发一个手游,需要同时使用MAC、WINDOWS机器构建iOS\Android\Win版本,这时可以创建多个节点,节点的通信方式有4种,根据自己的需要去配置。分布式构建可以使用构建管道来实现同样的效果,相对的好处是,不用在每台目标机器上安装 jenkins,而只需要在节点机器上配置好编译环境即可。
注:分布式构建我并没有实际使用到,更多的细节尚不清楚。
七、构建结果通知
jenkins 实际上支持非常多的通知方式,如 Email、RSS订阅、IM通知、IRC通知、短信等等,但实际中最常用也最实用的,可能就是邮件通知了。
在系统管理的系统设置界面中,配置好 "系统管理员邮件地址"、"SMTP服务器"、"Default Recipients"(默认接收者邮箱),配置好之后,可以勾选 "发送测试邮件" 来即时进行测试。
这样就可以在构建任务中的 "构建后操作" 中选择邮件通知了,默认使用 "E-mail Notification" 就可以实现功能,如果需要更细致的功能,可以使用 "Editable Email Notification" 项,它可以针对构建的不同结果,细致的对不同的用户发送不同内容的邮件。
八、自动化测试
这一块其实也是 jenkins 提供的非常重要的核心功能,但对 JAVA 最为友好,毕竟它本身就是为了 JAVA 而开发出来的。如果你正好从事JAVA开发,那可以使用它来进行完善的代码覆盖、单元测试、集成测试等等测试,我并不从事 JAVA 开发,这块就略过了。
九、维护管理
使用 jenkins 过程中需要注意的地方,首先是磁盘占用,如果比较频繁的进行编译构建任务,构建结果及产生的二进制文件默认都会存储下来,如果二进制文件比较大,时间长了磁盘可能就占用的比较多。我们可以设置最多保留最近多少次构建数据,或者只保留构建结果而不保留所有构建的二进制文件。此外,也可以借助插件来监控磁盘使用状态。
jenkins 的备份非常简单,最粗暴的是直接备份家目录,只是会比较大,也可以只备份 jobs 目录,根据自己的需要,了解每个目录的作用就可以很好的把握。你可以使用两个插件:Backup manager 或 ThinBackup 来完成备份任务,区别是后者相对于前者更轻量,且不需要重启 jenkins服务。此外,我们可以借助 jenkins 起一个定时备份的构建计划,定时请求备份调用的 url。
在一台新部署的 jenkins 上拷贝另一台 jenkins 的某个 job,是比较常见的情况,直接把 job 拷贝过去就好了,但要注意,最好把 plugins 目录也拷贝过去,因为你的 job 可能用到了某些插件,而新部署的这台 jenkins 可能并没有。
十、macOS
通过 brew install jenkins 来安装,可以通过下面的命令来启动或停止 jenkins 服务:
launchctl load /usr/local/Cellar/jenkins/2.56/homebrew.mxcl.jenkins.plist
launchctl unload /usr/local/Cellar/jenkins/2.56/homebrew.mxcl.jenkins.plist
可以自己定义一下别名来方便操作。
十一、问题汇总
运行一段时间的 jenkins 后出现一个很严重的问题,jenkins.log 文件会急速变大,占尽所有磁盘空间。可以参考:https://stackoverflow.com/questions/31719756/how-to-stop-jenkins-log-from-becoming-huge
大致的意思是,进入 jenkins 的系统管理的日志管理,添加日志级别:
Name: javax.jmdns
Level: off
十二、实例:自动编译 AssetBundle 资源并上传到HTTP服务器
#!/bin/sh UnityPath=/Applications/Unity5.3.5/Unity5.3.5.app/Contents/MacOS/Unity ProjPath=/Users/test/src/xLuaFramework Platform=iOS ShellPath=`pwd` Time=`date "+%Y%m%d_%H%M%S"` #拉SVN cd ${ProjPath} && svn up -r $1 $UnityPath -batchmode -quit -projectPath $ProjPath -executeMethod BuildAssets.BuildiOSAssets #$UnityPath -projectPath $ProjPath -executeMethod BuildAssets.BuildiOSAssets cd $ProjPath/Assets/StreamingAssets/ && tar jcvf $ShellPath/temp/Assets_${Platform}_${Time}.tar.bz2 * #上传 expect <<-EOF set timeout 30 spawn scp $ShellPath/temp/Assets_${Platform}_${Time}.tar.bz2 root@172.18.1.60:/var/www/html/test/bzip expect "password:" send "yourpassword\r" expect eof EOF expect <<-EOF set timeout 30 spawn ssh root@172.18.1.60 "tar jxvf /var/www/html/test/bzip/Assets_${Platform}_${Time}.tar.bz2 -C /var/www/html/test/$Platform" expect "password:" send "yourpassword\r" expect eof EOF echo "更新成功!!!"