Jenkins进阶系列之——08Jenkins纳入版本控制
2014-12-08:已不再担任SCM和CI的职位,Jenkins系列的文章如无必要不会再维护。
2014-07-25:更新shell脚本
2014-06-05:更新shell脚本
2014-01-09:更新shell脚本,修改Jenkins文件删除后不能自动从版本控制删除的bug
是不是有过这种经历:某天手贱,把某一个配置更改了。然后只能在那儿苦逼的看着,然后的然后把以前的配置重新配一次。坑爹的是以前配置的什么都忘记了。。。尼玛,坑啊( ⊙ o ⊙ )!
某天在群里和一群人吹牛逼,突然冒出一个人说手贱把某个job删除了,有没有办法恢复。然后我们果断的告诉了ta实情。然后这聊天的主题就跑到把jenkins加入到版本控制中。我也曾经手贱过。运气好,前几天要测试一些东西,在另一台机器上面还有备份。所以折腾折腾,就写了这篇文章。
系统:CentOS 5.8、6.4
版本控制软件:Subversion 1.7+
思路:写一个脚本(shell)定时去跑一次add、delete和commit。
- 建立普通用户
用一个用户会出问题,jenkins构建的时候会直接报错。这个问题的解决方法:将用户目录下.subversion的auth目录删除就可以了
useradd froad #建立普通用户跑Jenkins,root用户用了跑shell脚本
#启动Jenkins略过
#因为我是用root用户登录,然后 su froad切换的,所以就没有设置密码。 - 安装Subversion1.7以上版本(当做客户端给root用户使用)
。其实有用的就是bin/svn这个程序而已。如果你安装了Subversion edge
直接把bin和lib目录拷贝过来就行了。为什么要用1.7以上的?因为1.7后.svn目录只有一个了。我嫌以前的版本.svn目录太多了,烦!提供个解压即可用的svn(从subversion edge中拷贝出来的) 点我去下载 - 远程Subversion的一些准备工作
如果你喜欢可以创建一个新的库和用户,如果你不like,随便你!
- 检出svn目录
[root@localhost ~]# /home/froad/svn/bin/svn co https://192.168.xxx.xxx/svn/Jenkins/trunk /home/froad/.jenkins/ --username jenkins
#说明:/home/froad/.jenkins这个参数可以直接把检出的.svn目录放到.jenkins目录,我是懒人不想在mv一次。--username是svn的用户
#svn语法:svn co url path --username xxx
Error validating server certificate for 'https://192.168.xxx.xxx:443':
- The certificate is not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
- The certificate hostname does not match.
Certificate information:
- Hostname: froad-jskfb
- Valid: from Apr :: GMT until Apr :: GMT
- Issuer: (null), (null), (null), (null), (null) ((null))
- Fingerprint: D6:EB::xxxxxxxxxxxxxxxFC:7D::
(R)eject, accept (t)emporarily or accept (p)ermanently? p #说明:R 拒绝 t 暂时接受 p 永久接受
Authentication realm: <https://192.168.xxx.xxx:> VisualSVN Server
Password for 'jenkins': ************* #说明:输入你的用户密码
-----------------------------------------------------------------------
ATTENTION! Your password for authentication realm: <https://192.168.xxx.xxx:> VisualSVN Server can only be stored to disk unencrypted! You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible. See the documentation for details. You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
'/root/.subversion/servers'.
-----------------------------------------------------------------------
Store password unencrypted (yes/no)? yes #说明:存储未加密的密码
Checked out revision . #现在版本库都检出了,下面的就简单了。add一下,然后commit一下。打完收工。
#如果你是这么想的,那么结果会郁闷死你。接着往下看吧。 - 更改Jenkins的workspace目录
为什么要更改workspace目录呢?因为里面有个捣蛋的目录.svn。这个目录是个深坑,开始我花了大力气去忽略这个目录。坑爹的是,如果我把工作目录清空了,然后在构建就会一直报错。因为SVNkit跑去找JENKINS_HOME下的.svn目录(这个目录就是我们上面检出的)。
测试的时候是直接把.svn目录检出到test_007ka目录。大家将就看。除了目录不一样,其他没有区别。
SVNkit会先去找.svn目录,如果到顶层目录还是没有找到.svn目录,就会在workspace目录检出。这是svn和git的一个特性。哪儿看到的?那个《git权威指南》。
系统管理→系统设置→主目录(的右边问号下面)→高级(是不是忽略了啊\(^o^)/~)→工作空间根目录- ${JENKINS_HOME} — Jenkins home directory.#JENKINS_HOME这个参数不用说了
- ${ITEM_ROOTDIR} — Root directory of a job for which the default workspace is
allocated.#ITEM_ROOTDIR:默认的工作空间目录。完整的路径就是JENKINS_HOME/jobs/xxxx/workspace - ${ITEM_FULL_NAME} — '/'-separated job name, like
"foo/bar".#ITEM_FULL_NAME:job的名称,这个就是我们需要的。
- 点开后面的问号可以看见3个参数(配置路径需要的):
我们只需要把workspace目录赶出JENKINS_HOME目录就行了。上配置:
workspace:/home/froad/workspace/${ITEM_FULL_NAME} #前面的目录随便你改,只需要在最后带上${ITEM_FULL_NAME}
JENKINS_HOME:/home/froad/.jenkins #给你们对比着看
#好了,这下.svn目录不打架了。我也不用头疼了。 - 删除已经存在的workspace目录
find . -type d -name "workspace"|xargs rm -rf #看见find后面的那个点了么,改成你的路径就行了
- 配置Subversion忽略目录
貌似将JENKINS_HOME目录直接提交到Subversion,数据量不是一般的高啊!我这个Jenkins才跑3个月都10Gb了。
如果要提交上去,花费的时间,不是一般的长啊。
注意:你用的什么用户,就在用户目录下面改。我用的root用户。
进入用户目录的.subversion打开config文件,找到global-ignores。大概在105行。
把global-ignores前的#去掉,注意#后面的空格要删掉。然后在=后面添加 modules
modules目录是maven项目产生的,我的Jenkins就是这个目录大。把这个目录删除了也就几百Mb。如果你有其他目录想忽略,请自行添加,记得用空格分隔就行了。
写个shell脚本svn_commit.sh
这个脚本随便你放在哪儿,我想偷懒。直接放在Jenkins的主目录,顺便也版本控制下。。O(∩_∩)O~
声明:脚本写的很丑,勿喷!#!/bin/bash # ------------------------------------------------------
# Jenkins的Subversion备份脚本
# 请将本脚本放到JENKINS_HOME目录
# 作者:zjl
# version:4.1
# time:2014-07-25 17:36
# # 更新日志
# version:4.1
# 修护删除文件导致版本过时提交失败的bug # version:4.0
# 修护从${TMP_STATUS_LOG}文本读取一行,变量前空格丢失的bug
# 修护从${TMP_STATUS_LOG}文本截取文件名某些情况错误的bug
# 优化脚本对特殊路径的处理
# 添加svn commit失败邮件告警功能
# 删除add 、commit时强制指定的用户 # version:2.0
# 修改Jenkins文件删除后不能自动从版本控制删除的bug # 检出命令:svn co https://192.168.xxx.xxx/svn/Jenkins/trunk /home/froad/.jenkins/ --username jenkins #
# ------------------------------------------------------ # 获取当前系统时间分割日志文件(如果错误时邮件内容过大,可以将时间写的更精确)
# 精确到分钟
# DATE=`date "+%Y%m%d%H%M"`
# 精确到小时
DATE=`date "+%Y%m%d%H"` # SVN_HOME的路径
SVN_HOME="/home/froad/svn" # SVN程序的路径
SVN="${SVN_HOME}/bin/svn" # JENKINS_HOME的路径
JENKINS_HOME="/home/froad/jenkins" # 邮件告警设置
# 收件人(多个收件人用空格或逗号分隔)
MAIL_TO="xxx@qq.com"
# 伪造发件人(不能和收件人的邮件后缀相同,否则发送不了邮件)
MAIL_FROM="jenkins_svn@163.com"
# 主题/标题
MAIL_SUBJECT="[ERROR]Jenkins SVN commit fail !"
# 邮件发送类型
# 0:通用普通,163、QQ等邮箱会识别成垃圾邮件
# 1:Centos 6.x Mail version 12.4 7/29/08.
# 2:Centos 5.x Mail version 8.1 6/6/93.
# 请根据自己的Mail版本选择使用
MAIL_TYPE="1" # 日志文件
LOG_HOME="/root/.subversion/logs" LOG_FILE="${LOG_HOME}/svn_commit_${DATE}.log" # svn_status日志文件
TMP_STATUS_LOG="${LOG_HOME}/status.log" # svn_add 方法已停止使用,由svn_status代替。
#function svn_add()
#{
#使用svn add命令将文件添加到版本控制
# "${SVN}" add "${JENKINS_HOME}/*" --force &>>"${LOG_FILE}"
#退出码
# EXIT_NUM=$?
# echo "svn add退出码:${EXIT_NUM} !" >>"${LOG_FILE}"
#} function send_mail(){ # 检查邮件参数
# 收件人为空
if [ -z "${MAIL_TO}" ];then echo "[error]MAIL_TO 参数为空!">>"${LOG_FILE}"
return fi
# 伪造发件人发送时,发件人为空
if [ "${MAIL_TYPE}"=="1" -o "${MAIL_TYPE}"=="2" ];then if [ -z "${MAIL_FROM}" ];then echo "[error]MAIL_FROM 参数为空!">>"${LOG_FILE}"
return fi
fi # LC_ALL=zh_CN.UTF-8 保证发送邮件时中文不会乱码
# mail相关请查看 http://ju.outofmemory.cn/entry/24406 if [ "${MAIL_TYPE}"=="1" ] ;then
# 1:Centos 6.x Mail version 12.4 7/29/08.
LC_ALL=zh_CN.UTF- mail -s "${MAIL_SUBJECT}" -r "${MAIL_FROM}" "${MAIL_TO}" < "${LOG_FILE}" elif [ "${MAIL_TYPE}"=="2" ] ;then # 2:Centos 5.x Mail version 8.1 6/6/93.
LC_ALL=zh_CN.UTF- mail -s "${MAIL_SUBJECT}" "${MAIL_TO}" -- -f "${MAIL_FROM}" < "${LOG_FILE}" else # 0:通用普通,163、QQ等邮箱会识别成垃圾邮件
# 注意:此方法可能会被163等邮箱识别为垃圾邮件
LC_ALL=zh_CN.UTF- mail -s "${MAIL_SUBJECT}" "${MAIL_TO}" < "${LOG_FILE}" fi
} function svn_status()\
{ # 使用svn status命令判断文件是否删除、修改或者其他操作
"${SVN}" status "${JENKINS_HOME}" > "${TMP_STATUS_LOG}" # 从文件中读取一行
cat "${TMP_STATUS_LOG}" | while read line;do # 从文本中读取回来的内容必须用引号,不然前面的空格会丢失
# 获取第一个字符,根据第一个字符判断情况
l=`echo "${line}"|cut -c1`
# 获取文件的相对路径(获取第8个字符后的所有内容,前6个字符是svn的状态,2个字符间隔)
# 详细状态请查询:http://www.subversion.org.cn/svnbook/nightly/svn.ref.svn.c.status.html
f=`echo "${line}" | cut -c9-` # 状态为A(增加)时,不需要任何操作,直接返回。
if [ "${l}" == "A" ];then
continue
fi # 状态为D(删除)时,不需要任何操作,直接返回。
if [ "${l}" == "D" ];then
continue
fi # 状态为M(修改)时,不需要任何操作,直接返回。
if [ "${l}" == "M" ];then
continue
fi # 状态为I(忽略)时,不需要任何操作,直接返回。
if [ "${l}" == "I" ];then
continue
fi # 状态为?(未受控制)时,调用add命令然后返回。ps:不知道怎么的有时候从文件中读取回来的?变成了0
if [ "${l}" == "0" ] || [ "${l}" == "?" ];then "${SVN}" add "${JENKINS_HOME}/${f}" >>"${LOG_FILE}" continue fi # 状态为!(丢失或者不完整)时,调用delete命令然后返回。
if [ "${l}" == "!" ];then "${SVN}" delete "${JENKINS_HOME}/${f}" >>"${LOG_FILE}" continue fi echo "[info]其他情况:${line}" >>"${LOG_FILE}" done # 删除临时文件
# rm -rf ${TMP_STATUS_LOG} } function svn_update()
{
echo "svn update ...">>"${LOG_FILE}" "${SVN}" update &>>"${LOG_FILE}" svn_commit } function svn_commit()
{ # 使用svn commit命令提交到服务器
"${SVN}" commit --message="crontab commit" &>>"${LOG_FILE}" EXIT_NUM=$? if [ ! ${EXIT_NUM} == "0" ];then if [ -z ${ISOUTOFDATE} ] ;then
# 确保这个if只执行一次
ISOUTOFDATE="1"
# 判断是否需要更新后在尝试提交(默认查找最后10行,-n xx指定行数)
isUpdate=`tail "${LOG_FILE}" | grep "is out of date"`
echo "[debug]+:${isUpdate}"
if [ ! -z "${isUpdate}" ];then
svn_update
return
fi
fi
echo "[error]退出码:${EXIT_NUM} svn commit失败,请查看日志!">>"${LOG_FILE}" # 调用发送mail方法
send_mail return fi echo "svn commit退出码:${EXIT_NUM} !">>"${LOG_FILE}" } echo "[begin] 当前时间:`date "+%Y%m%d_%H%M%S"`" >>"${LOG_FILE}" if [ ! -d "${LOG_HOME}" ];then mkdir -p "${LOG_HOME}" fi # 进入到svn工作目录,防止出现稀奇古怪的错误
cd "${JENKINS_HOME}" # 调用方法
svn_status
svn_commit echo "[end] 当前时间:`date "+%Y%m%d_%H%M%S"`" >>"${LOG_FILE}" # 输出空行隔离
echo >>"${LOG_FILE}"脚本写好了,建议先运行一次。测试下有没有错误。
- 添加定时提交
crontab -u root -e
*/ * * * * sh /home/froad/.jenkins/svn_commit.sh #每30分钟提交一次 - 一个备份插件
Jenkins Job Configuration History Plugin,可以记录配置的更改。可以记录谁,什么时间,修改了什么。
- 结尾
普通用户开机自动启动Jenkins:
su 用户名 -c "sh path"
#例如:su froad -c "sh /usr/local/jenkins/bin/startup.sh"
将上面的命令加入到/etc/rc.d/rc.local文件中非root用户不能使用1024以下的端口,比较麻烦。有不懂的,下面留言。有好的建议,下面留言。欢迎交流!
Jenkins进阶系列之——08Jenkins纳入版本控制的更多相关文章
- Jenkins进阶系列之——17Jenkins升级、迁移和备份
升级Jenkins Jenkins的开发迭代非常快,每周发布一个开发版本,长期支持版每半年更新一次(ps:大版本更新).如此频繁的更新,怎么升级呢? war:下载新版的war文件,替换旧版本war文件 ...
- Jenkins进阶系列之——18Jenkins语言本地化
在Jenkins中,英语一大片,看着各种蛋疼.非常高兴的是,Jenkins作为一个主流流行的持续构建工具,提供了一个本地化语言的配置界面. 你可以找到它,在Jenkins每页的左下角.如下图: 点击帮 ...
- Jenkins进阶系列之——02email-ext邮件通知模板
发现一个很好的邮件通知模板,根据我的需求定制了一些.分享一下. Default Subject: 构建通知:${BUILD_STATUS} - ${PROJECT_NAME} - Build # ${ ...
- Jenkins进阶系列之——07更改Jenkins的主目录
Jenkins默认会存放在用户主目录下的.jenkins文件夹中 如:Linux root用户:/root/.jenkins 注意:这是linux版本的.windows系统请自行更改.这个值在Jenk ...
- Jenkins进阶系列之——09配置Linux系统ssh免密码登陆
ssh认证的完整描述:https://www.ibm.com/developerworks/cn/linux/security/openssh/part1/ 说明:点我去查看 今天我们只说生成ssh的 ...
- Jenkins进阶系列之——12详解Jenkins节点配置
2014-03-02:修正对于lable标签的理解.(1.532.1版本已经给出了官方解释) 2013-12-22:添加JNLP端口修改,修改了一些错误. Jenkins有个很强大的功能:分布式构建( ...
- Jenkins进阶系列之——13修改Jenkins权限控制
说明:本方法适用于安全矩阵和项目矩阵授权策略的Jenkins. 很多童鞋在使用jenkins的时候忘记配置权限或者权限配置错误,然后各种蛋疼.最近闲着无事,折腾了下.好了,闲话少扯. Jenkins的 ...
- Jenkins进阶系列之——16一个完整的JENKINS下的ANT BUILD.XML文件
网上看见的,确实很全,该有的基本都覆盖到了.自己拿来稍微改改就可以用了. 注:property中的value是你自己的一些本地变量.需要改成自己的 <?xml version="1.0 ...
- Jenkins进阶系列之——01使用email-ext替换Jenkins的默认邮件通知
1 简述 众所周知,Jenkins默认提供了一个邮件通知,能在构建失败.构建不稳定等状态后发送邮件.但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容.无法定义发送邮件的格式.无法定义灵活 ...
随机推荐
- Effective Java 27 Favor generic methods
Static utility methods are particularly good candidates for generification. The type parameter list, ...
- 利用mysql对特殊字符和超长字符会进行截断的特性 进行存储型XSS攻击——WordPress <4.1.2 & <=4.2 存储型xss
转自:Baidu Security LabXteam http://xteam.baidu.com/?p=177 漏洞概述 本次漏洞出现两个使用不同方式截断来实现的存储型xss,一种为特殊字符截断,一 ...
- Winpcap
Winpcap网络开发库入门
- VS2010 单文档+多视图+Outlook风格
先来个段子 十年生死两茫茫,喜羊羊,灰太狼.舒克贝塔,蓝猫话凄凉.纵使相逢应不识,圣斗士,美猴王.老夫聊发少年狂,治肾亏,不含糖.锦帽貂裘,千骑用康王.为报倾城随太守,三百年,九芝堂.夜来幽梦忽还乡, ...
- 百度地图Api进阶教程-点击生成和拖动标注4.html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- web.xml文件报错:cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'.
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" ...
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
http://blog.csdn.net/u012917616/article/details/40921833 不废话,直接上.sh脚本: export NDK=/home/xxx/my_softw ...
- Oracle 性能优化之一二
本人使用oracle时间不多,但是在项目中积累了一些经验教训,记录于此,以方便自己和他人解决类似的问题. 1.temp space超出限制的问题 问题场景: 在复杂的ETL query中,有时候一张f ...
- 警惕javascript变量的全局污染问题
作用域的概念总是和变量形影不离,它不是javascript语言独有的概念,只是其运用上与其他大型语言略有不同,JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基 ...
- 读高性能JavaScript编程学英语 第一章第三页第一段话
When the browser encounters a <script> tag, as in this HTML page, there is no way of knowing w ...