持续集成 Master-Slave 结构的 jenkins 平台维护

William · 2017年07月03日 · 最后由 开普敦人 回复于 2017年10月20日 · 2187 次阅读

前言

相信 Jenkins 在大家平时的工作中不言而喻,在持续构建中,尤其是持续进行移动 app 打包中有很大的作用。但是每一次构建都要生成很多产物,时间长了对机器的空间有极大的压力,同时基于 master 和 slave 结构的 ci 平台,删除了 slave 上的构建 job 或者历史,但是由于某种原因,master 机器所在的空间并不能删除,导致空间浪费,所以打算写一个自动清理的脚本,来帮助我们完成这个工作。

Jenkins RESTful API

jenkins 提供了丰富形式的 api,在社区之前也有提到过: Jenkins RESTful API 定制化。在这里不做过多的说明了。

  • 在这里说几点 api 中要注意的坑
  • 构建历史 - API中记录的当前项目的构建历史的数目最大为100个,如果你的项目构建历史超过100个,那么保存的是最近构建的100个项目
  • 构建状态 - API中job状态没有记录某一个构建历史的构建状态

当然还有一些其他坑,需要自己去实践。

查找数据

接下来需要在平台上找到所需要的数据:

写一个删除 job 的脚本

#!/usr/bin/python  
# -*- coding: utf-8 -*-

import os
import json, urllib2


def clean_jobs():
    jobs = []
    url = 'http://ci.xxx.xxxx.com/api/json?pretty=true'
    req = urllib2.Request(url=url)
    res = urllib2.urlopen(req)
    res = res.read()
    data = json.loads(res)

    print '当前有job数目:' + str(len(data['jobs']))
    for i in range(len(data['jobs'])):
        jobs.append( data['jobs'][i]['name'])

    os.chdir('/jobs/jenkinsjobs/')
    for i in os.listdir('.'):
        if os.path.isdir(i):
            if i not in jobs:
                print i + '已经在jenkins中删除了,需要清除工作空间'
                os.popen('rm -rf ' + i)
            else:
                print  + '不需要清除'


if __name__ == '__main__':
    clean_jobs()

查找所有的构建记录

既然 api 中只能提供最近的 100 个构建记录,那么就只能通过自己找其他方式了。翻看 job 网页的源代码发现:

也就是能找到全部构建历史,在项目 URL 后面添加

/buildHistory/all

这个网页有全部的构建历史。OK,接下来写删除构建历史的脚本。
此处只删除占用空间最大的十个 job 的构建历史。

#!/usr/bin/python  
# -*- coding: utf-8 -*-
import os
import re
import time
import urllib2

time_now = time.strftime('%Y-%m-%d_%H:%M:%S', time.localtime(time.time()))


# 获取占用空间最大的前十个job
def get_jobs():
    os.chdir('/jobs/jenkinsjobs/')
    os.popen('du -sh * |grep [0-9]G |sort -rn |head > /jobs/abc/' + time_now + '.txt')
    print '导出占用最大的前十个job到:/jobs/abc/' + time_now + '.txt'
    clean_builds_history()


# 查找那些有哪些构建历史
def clean_builds_history():
    try :
        os.chdir('/jobs/abc/')
        his_list = []
        f = open(time_now + '.txt', 'r')
        for line in f:
            job = line.split()[1]
            print 'job是:' + job
            url = 'http://ci.xxx.xxxx.com/job/' + job + '/buildHistory/all'
            req = urllib2.Request(url=url)
            res = urllib2.urlopen(req)
            res = res.read()
            match = re.compile(r'#\d+')
            for i in match.findall(res):
                his_list.append(i.replace('#', ""))
            # 切换到对应的job的构建目录中,如果构建历史中没有该次构建,删除本地的文件
            os.chdir('/jobs/jenkinsjobs/' + job + '/builds/')
            for i in os.listdir('.'):
                if os.path.isdir(i):
                    if i.isdigit():
                        if i not in his_list:
                            print job + '中' + i + '需要删除'
                            os.popen('rm -rf ' + i)
                        else:
                            print job + '不需要清除历史'
    except Exception as e:
        print e



if __name__ == '__main__':
    get_jobs()

当然脚本是没办法判断构建是不是一定要删除的,所以 CI 平台上的构建历史需要手动定期删除,脚本只是清理没有回传到 master 机器上的 job 和构建历史。

共收到 4 条回复 时间 点赞

有一个定期清理全局任务的插件. 名字忘记了.

可以定期清理 Master 构建空间吗?

William 回复

可以啊,每次新一轮的 job 自动清理前面的数据 Delete workspace before builds starts

William 回复

可以啊,每次新一轮的 job 自动清理前面的数据 Delete workspace before builds starts

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册