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切换的,所以就没有设置密码。
- useradd froad #建立普通用户跑Jenkins,root用户用了跑shell脚本
- 安装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一下。打完收工。
- #如果你是这么想的,那么结果会郁闷死你。接着往下看吧。
- [root@localhost ~]# /home/froad/svn/bin/svn co https://192.168.xxx.xxx/svn/Jenkins/trunk /home/froad/.jenkins/ --username jenkins
- 更改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分钟提交一次
- crontab -u root -e
- 一个备份插件
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以下的端口,比较麻烦。有不懂的,下面留言。有好的建议,下面留言。欢迎交流!
- su 用户名 -c "sh path"
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默认提供了一个邮件通知,能在构建失败.构建不稳定等状态后发送邮件.但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容.无法定义发送邮件的格式.无法定义灵活 ...
随机推荐
- su su -
http://www.ha97.com/4001.html su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shell环境仍然是普通用户的Shell:而后者连用户和Shell环 ...
- xamarin.android 给View控件 添加数字提醒效果-BadgeView
本文代码从java项目移植到.net项目 java开源项目:https://github.com/jgilfelt/android-viewbadger using System; using S ...
- 通用cube refresh方案
通用cube refresh c# script 解决方法: 需要设置的变量如下: User::varcubename,User::varolapconnstr,User::varolapdbname ...
- Java向上转型与向下转型
一.向上转型 例如:Parent p=new Son(); 这样引用p只能调用子类中重载父类的方法:但属性是父类的:如果想调用子类属性的话,可以用getter()方法. 二.向下转型 子类对象的父类引 ...
- MIT jos 6.828 Fall 2014 训练记录(lab 4)
源代码参见我的github: https://github.com/YaoZengzeng/jos Part A: Multiprocessor Support and Cooperative Mul ...
- python如何控制数据库?
http://www.w3cschool.cc/python/python-mysql.html 通过利用MySQLdb可以操作数据库 实例: 以下实例链接Mysql的TESTDB数据库: # enc ...
- HDU 4041 Eliminate Witches! --模拟
题意: 给一个字符串,表示一颗树,要求你把它整理出来,节点从1开始编号,还要输出树边. 解法: 模拟即可.因为由括号,所以可以递归地求,用map存对应关系,np存ind->name的映射,每进入 ...
- Unity-WIKI 之 DebugConsole
功能预览 使用说明 1.把 DebugConsole.cs 放在 Standard Assets 目录下(重要) 2.如果你想修改 DebugConsole的一些参数,把DebugConsole.cs ...
- Linux下php安装memcache扩展
安装环境:CentOS 6.4 php扩展memcache的作用是为了支持memcached数据库缓存服务器,下面是安装方法. 1.下载 下载地址:http://pecl.php.net/packag ...
- 【shiro】shiro学习笔记1 - 初识shiro
[TOC] 认证流程 st=>start: Start e=>end: End op1=>operation: 构造SecurityManager环境 op2=>operati ...