Jenkins进阶系列之——08Jenkins纳入版本控制

释放双眼,带上耳机,听听看~!

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

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

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

系统:CentOS 5.8

版本控制软件:Subversion 1.7+

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

  1. 建立普通用户

用一个用户会出问题,jenkins构建的时候会直接报错。貌似是因为https证书的问题。如果你是用的http协议可以尝试一个用户搞定。Jenkins进阶系列之——08Jenkins纳入版本控制

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

 


1
2
3
4
1useradd froad    #建立普通用户跑Jenkins,root用户用了跑shell脚本  
2#启动Jenkins略过  
3#因为我是用root用户登录,然后 su froad切换的,所以就没有设置密码。
4
  1. 安装Subversion1.7以上版本(当做客户端给root用户使用)

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

 

  1. 远程Subversion的一些准备工作

如果你喜欢可以创建一个新的库和用户,如果你不like,随便你!

 

  1. 检出svn目录


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1[root@localhost ~]# /home/froad/svn/bin/svn co https://192.168.xxx.xxx/svn/Jenkins/trunk /home/froad/.jenkins/  --username jenkins
2#说明:/home/froad/.jenkins这个参数可以直接把检出的.svn目录放到.jenkins目录,我是懒人不想在mv一次。--username是svn的用户
3#svn语法:svn co url path --username xxx
4Error validating server certificate for 'https://192.168.xxx.xxx:443':
5 - The certificate is not issued by a trusted authority. Use the
6   fingerprint to validate the certificate manually!
7 - The certificate hostname does not match.
8Certificate information:
9 - Hostname: froad-jskfb
10 - Valid: from Apr 16 03:04:08 2013 GMT until Apr 14 03:04:08 2023 GMT
11 - Issuer: (null), (null), (null), (null), (null) ((null))
12 - Fingerprint: D6:EB:58:xxxxxxxxxxxxxxxFC:7D:04:64
13(R)eject, accept (t)emporarily or accept (p)ermanently? p #说明:R 拒绝 t 暂时接受 p 永久接受
14Authentication realm: <https://192.168.xxx.xxx:443> VisualSVN Server
15Password for 'jenkins': ************* #说明:输入你的用户密码
16-----------------------------------------------------------------------
17ATTENTION!  Your password for authentication realm:
18
19   <https://192.168.xxx.xxx:443> VisualSVN Server
20
21can only be stored to disk unencrypted!  You are advised to configure
22your system so that Subversion can store passwords encrypted, if
23possible.  See the documentation for details.
24
25You can avoid future appearances of this warning by setting the value
26of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
27'/root/.subversion/servers'.
28-----------------------------------------------------------------------
29Store password unencrypted (yes/no)? yes #说明:存储未加密的密码
30Checked out revision 1.
31
32
33#现在版本库都检出了,下面的就简单了。add一下,然后commit一下。打完收工。
34#如果你是这么想的,那么结果会郁闷死你。接着往下看吧。  
35
36
  1.  更改Jenkins的workspace目录

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

测试的时候是直接把.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目录就行了。上配置:


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

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


1
2
1find . -type d -name "workspace"|xargs rm -rf  #看见find后面的那个点了么,改成你的路径就行了
2
  • 配置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~
声明:脚本写的很丑,勿喷!
需要版本控制的文件或目录,命名不能是 ${xxxx} 格式。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
1#!/bin/bash
2
3#Jenkins的Subversion备份脚本
4#请将本脚本放到JENKINS_HOME目录
5#作者:zjl
6#version:2.0
7#time:2014-01-07 18:36
8#
9
10
11
12#获取当前系统时间
13DATE=`date "+%Y%m%d"`
14
15SVN_HOME=/home/froad/svn
16
17JENKINS_HOME=/home/froad/jenkins
18
19#日志文件
20LOG_HOME=/root/.subversion/logs
21
22LOG_FILE=${LOG_HOME}/svn_commit_${DATE}.log
23
24TMP_STATUS_LOG=${LOG_HOME}/status.log
25
26
27echo "[begin] 当前时间:`date "+%Y%m%d_%H%M%S"`" >>${LOG_FILE}
28
29if [ ! -d "${LOG_HOME}" ];then
30
31    mkdir -p ${LOG_HOME}
32    
33fi
34
35#进入到svn工作目录,防止出现稀奇古怪的错误
36cd ${JENKINS_HOME}
37
38function svn_add()
39{
40
41    #使用svn add命令将文件添加到版本控制
42    ${SVN_HOME}/bin/svn add  ${JENKINS_HOME}/*  --username=jenkins  --force &>>${LOG_FILE}
43    
44    #退出码
45    EXIT_NUM=$?
46
47    echo "svn add退出码:${EXIT_NUM} !" >>${LOG_FILE}
48}
49
50
51
52function svn_status()
53{
54
55    #使用svn status命令判断文件是否删除、修改或者其他操作
56    ${SVN_HOME}/bin/svn status  "/${JENKINS_HOME}" > ${TMP_STATUS_LOG}
57
58    #循环从文件中读取一行
59    cat ${TMP_STATUS_LOG} | while read line;do
60
61        #获取第一个字符,根据第一个字符判断情况
62        l=`echo ${line}|cut -c1`
63
64        #状态为A(增加)时,不需要任何操作,直接返回。
65        if [ "${l}" == "A"  ];then
66            continue
67        fi
68
69        #状态为D(删除)时,不需要任何操作,直接返回。
70        if [ "${l}" == "D"  ];then
71            continue
72        fi
73
74        #状态为M(修改)时,不需要任何操作,直接返回。
75        if [ "${l}" == "M"  ];then
76            continue
77        fi
78
79        #状态为?(未受控制)时,调用add命令然后返回。ps:不知道怎么的有时候从文件中读取回来的?变成了0
80        if [ "${l}" == "0" ] || [ "${l}" == "?"  ];then
81        
82            ${SVN_HOME}/bin/svn add  "${JENKINS_HOME}/`echo ${line} | cut -d ' ' -f 2- `" >>${LOG_FILE}
83            
84            continue
85            
86        fi
87
88        #状态为!(丢失或者不完整)时,调用delete命令然后返回。
89        if [ "${l}" == "!"  ];then
90
91            ${SVN_HOME}/bin/svn delete "${JENKINS_HOME}/`echo ${line} | cut -d ' ' -f 2- `" >>${LOG_FILE}
92            
93            continue
94            
95        fi
96
97        echo "[info]其他情况:"${line} >>${LOG_FILE}
98    done
99    
100    #删除临时文件
101    rm -rf ${TMP_STATUS_LOG}
102
103}  
104
105
106function svn_commit()
107{
108
109    #使用svn commit命令提交到服务器
110    ${SVN_HOME}/bin/svn commit ${JENKINS_HOME}/*  --message="crontab commit" --username=jenkins &>>${LOG_FILE}
111
112    EXIT_NUM=$?
113
114    if [ ! ${EXIT_NUM} == "0" ];then
115
116        echo "[error]退出码:${EXIT_NUM} svn commit失败,请查看日志!">>${LOG_FILE}
117        return
118
119    fi
120    
121    echo "svn commit退出码:${EXIT_NUM} !">>${LOG_FILE}
122    
123}
124
125#调用方法
126svn_add
127svn_status
128svn_commit
129
130echo "[end] 当前时间:`date "+%Y%m%d_%H%M%S"`" >>${LOG_FILE}
131
132#输出空行隔离
133echo  >>${LOG_FILE}
134

 

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

  •  添加定时提交


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

 

  • 结尾

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


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

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

给TA打赏
共{{data.count}}人
人已打赏
安全经验

职场中的那些话那些事

2021-9-24 20:41:29

安全经验

elk+redis 搭建nginx日志分析平台

2021-11-28 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索