Jenkins纳入版本控制

2012-01-09:更新shell脚本,修改Jenkins文件删除后不能自动从版本控制删除的bug

是不是有过这种经历:某天手贱,把某一个配置更改了。然后只能在那儿苦逼的看着,然后的然后把以前的配置重新配一次。坑爹的是以前配置的什么都忘记了。。。尼玛,坑啊( ⊙ o ⊙ )!

某天在群里和一群人吹牛逼,突然冒出一个人说手贱把某个job删除了,有没有办法恢复。然后我们果断的告诉了ta实情。然后这聊天的主题就跑到把jenkins加入到版本控制中。我也曾经手贱过。运气好,前几天要测试一些东西,在另一台机器上面还有备份。所以折腾折腾,就写了这篇文章。

系统:CentOS 5.8

版本控制软件:Subversion 1.7+

思路:写一个脚本(shell)定时去跑一次add和commit。

  1. 建立普通用户
    用一个用户会出问题,jenkins构建的时候会直接报错。貌似是因为https证书的问题。如果你是用的http协议可以尝试一个用户搞定。

     这个问题的解决方法:将用户目录下.subversion的auth目录删除就可以了

     

    useradd froad #建立普通用户跑Jenkins,root用户用了跑shell脚本
    #启动Jenkins略过
    #因为我是用root用户登录,然后 su froad切换的,所以就没有设置密码。

  2. 安装Subversion1.7以上版本(当做客户端给root用户使用)
    。其实有用的就是bin/svn这个程序而已。如果你安装了Subversion edge 直接把bin和lib目录拷贝过来就行了。为什么要用1.7以上的?因为1.7后.svn目录只有一个了。我嫌以前的版本.svn目录太多了,烦!提供个解压即可用的svn(从subversion edge中拷贝出来的) 点我去下载

     

  3. 远程Subversion的一些准备工作
    如果你喜欢可以创建一个新的库和用户,如果你不like,随便你!

     

  4. 检出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 16 03:04:08 2013 GMT until Apr 14 03:04:08 2023 GMT - Issuer: (null), (null), (null), (null), (null) ((null)) - Fingerprint: D6:EB:58:xxxxxxxxxxxxxxxFC:7D:04:64 (R)eject, accept (t)emporarily or accept (p)ermanently? p #说明:R 拒绝 t 暂时接受 p 永久接受 Authentication realm: <https://192.168.xxx.xxx:443> VisualSVN Server
    Password for 'jenkins': ************* #说明:输入你的用户密码 ----------------------------------------------------------------------- ATTENTION!  Your password for authentication realm:
    
       <https://192.168.xxx.xxx:443> 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 1. #现在版本库都检出了,下面的就简单了。add一下,然后commit一下。打完收工。
    #如果你是这么想的,那么结果会郁闷死你。接着往下看吧。 
    复制代码

  5.  更改Jenkins的workspace目录

     为什么要更改workspace目录呢?因为里面有个捣蛋的目录.svn。这个目录是个深坑,开始我花了大力气去忽略这个目录。坑爹的是如果我把工作目录清空了,然后在构建就会一直报错。因为SVNkit跑去找JENKINS_HOME下的.svn目录(这个目录就是我们上面检出的)。

    测试的时候是直接把.svn目录检出到test_007ka目录。大家将就看。除了目录不一样,其他没有区别。

     SVNkit会先去找.svn目录,如果到顶层目录还是没有找到.svn目录,就会在workspace目录检出。这是svn和Git的一个特性。哪儿看到的?那个《git权威指南》。
    系统管理→系统设置→主目录(的右边问号下面)→高级(是不是忽略了啊\(^o^)/~)→工作空间根目录

      点开后面的问号可以看见3个参数(配置路径需要的):

      • ${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的名称,这个就是我们需要的。

     我们只需要把workspace目录赶出JENKINS_HOME目录就行了。上配置:

    workspace:/home/froad/workspace/${ITEM_FULL_NAME} #前面的目录随便你改,只需要在最后带上${ITEM_FULL_NAME} JENKINS_HOME:/home/froad/.jenkins #给你们对比着看
    #好了,这下.svn目录不打架了。我也不用头疼了。

  6. 删除已经存在的workspace目录

     为什么要删除已经存在的workspace?想知道结果?跳过这一步,执行下面一步就知道结果了。

    find . -type d -name "workspace"|xargs rm -rf #看见find后面的那个点了么,改成你的路径就行了

  7. 配置Subversion忽略目录

     貌似将JENKINS_HOME目录直接提交到Subversion,数据量不是一般的高啊!我这个Jenkins才跑3个月都10Gb了。

     如果要提交上去,花费的时间,不是一般的长啊。

     注意:你用的什么用户,就在用户目录下面改。我用的root用户。

     进入用户目录的.subversion打开config文件,找到global-ignores。大概在105行。

     把global-ignores前的#去掉,注意#后面的空格要删掉。然后在=后面添加 modules

     modules目录是maven项目产生的,我的Jenkins就是这个目录大。把这个目录删除了也就几百Mb。如果你有其他目录想忽略的自行添加,记得用空格分隔就行了。

  8. 写个shell脚本svn_commit.sh

     这个脚本随便你放在哪儿,我想偷懒。直接放在Jenkins的主目录,顺便也版本控制下。。O(∩_∩)O~
     声明:脚本写的很丑,勿喷!需要版本控制的文件或目录,命名不能是 ${xxxx} 格式。

    复制代码
    #!/bin/bash
    
    #Jenkins的Subversion备份脚本
    #请将本脚本放到JENKINS_HOME目录
    #作者:zjl
    #version:2.0
    #time:2014-01-07 18:36
    #
    
    
    
    #获取当前系统时间 DATE=`date "+%Y%m%d"`
    
    SVN_HOME=/home/froad/svn
    
    JENKINS_HOME=/home/froad/jenkins #日志文件 LOG_HOME=/root/.subversion/logs
    
    LOG_FILE=${LOG_HOME}/svn_commit_${DATE}.log TMP_STATUS_LOG=${LOG_HOME}/status.log 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}
    
    function svn_add()
    { #使用svn add命令将文件添加到版本控制 ${SVN_HOME}/bin/svn add  ${JENKINS_HOME}/*  --username=jenkins  --force &>>${LOG_FILE} #退出码 EXIT_NUM=$? echo "svn add退出码:${EXIT_NUM} !" >>${LOG_FILE}
    }
    
    
    
    function svn_status()
    { #使用svn status命令判断文件是否删除、修改或者其他操作 ${SVN_HOME}/bin/svn status "/${JENKINS_HOME}" > ${TMP_STATUS_LOG} #循环从文件中读取一行 cat ${TMP_STATUS_LOG} | while read line;do #获取第一个字符,根据第一个字符判断情况 l=`echo ${line}|cut -c1` #状态为A(增加)时,不需要任何操作,直接返回。 if [ "${l}" == "A" ];then continue fi #状态为D(删除)时,不需要任何操作,直接返回。 if [ "${l}" == "D" ];then continue fi #状态为M(修改)时,不需要任何操作,直接返回。 if [ "${l}" == "M" ];then continue fi #状态为?(未受控制)时,调用add命令然后返回。ps:不知道怎么的有时候从文件中读取回来的?变成了0 if [ "${l}" == "0" ] || [ "${l}" == "?" ];then
            
                ${SVN_HOME}/bin/svn add "${JENKINS_HOME}/`echo ${line} | cut -d ' ' -f 2- `" >>${LOG_FILE} continue fi #状态为!(丢失或者不完整)时,调用delete命令然后返回。 if [ "${l}" == "!" ];then
    
                ${SVN_HOME}/bin/svn delete "${JENKINS_HOME}/`echo ${line} | cut -d ' ' -f 2- `" >>${LOG_FILE} continue fi
    
            echo "[info]其他情况:"${line} >>${LOG_FILE}
        done #删除临时文件 rm -rf ${TMP_STATUS_LOG}
    
    }   
    
    
    function svn_commit()
    { #使用svn commit命令提交到服务器 ${SVN_HOME}/bin/svn commit ${JENKINS_HOME}/*  --message="crontab commit" --username=jenkins &>>${LOG_FILE}
    
        EXIT_NUM=$? if [ ! ${EXIT_NUM} == "0" ];then
    
            echo "[error]退出码:${EXIT_NUM} svn commit失败,请查看日志!">>${LOG_FILE} return fi
        
        echo "svn commit退出码:${EXIT_NUM} !">>${LOG_FILE}
        
    } #调用方法 svn_add
    svn_status
    svn_commit
    
    echo "[end] 当前时间:`date "+%Y%m%d_%H%M%S"`" >>${LOG_FILE} #输出空行隔离 echo  >>${LOG_FILE}
    复制代码

     

    脚本写好了,建议先运行一次。测试下有没有错误。

  9.  添加定时提交

    crontab -u root -e */30 * * * * sh /home/froad/.jenkins/svn_commit.sh  #每30分钟提交一次

     

  10. 结尾

    普通用户开机自动启动Jenkins:

    su 用户名 -c "sh path" #例如:su froad -c "sh /usr/local/jenkins/bin/startup.sh" 将上面的命令加入到/etc/rc.d/rc.local文件中

    非root用户不能使用1024以下的端口,比较麻烦。有不懂的,下面留言。有好的建议,下面留言。欢迎交流!

转:http://www.cnblogs.com/zz0412/p/jenkins_jj_08.html 点击打开链接

Posted in 介绍及安装说明.