这个脚本是遍历MR,如果发现这个MR是需要rebase的或者已经merge了,会自动kill相应的jenkins job。
添加crontab定时任务:*/5 * * * * python3 kill_gitlab_job.py
开启 kill rebase任务可能影响jenkins调试,谨慎开启
kill_gitlab_job.py
import re
import os
import copy
import time
import gitlab
import sqlite3
import logging
import requests
from datetime import datetime
from sqlite3 import OperationalError
from configparser import ConfigParser
from kill_jenkins_job import main
logger = logging.getLogger()
logger.setLevel(logging.WARNING) # 设置打印级别
formatter = logging.Formatter(
'%(asctime)s %(filename)s %(funcName)s [line:%(lineno)d] '
'%(levelname)s %(message)s')
# 设置屏幕打印的格式
sh = logging.StreamHandler()
sh.setFormatter(formatter)
logger.addHandler(sh)
# 设置log保存
fh = logging.FileHandler("kill_gitlab_job.log", encoding='utf8')
fh.setFormatter(formatter)
logger.addHandler(fh)
class GitlabJob(object):
def __init__(self):
cp = ConfigParser()
config_path = os.path.dirname(os.path.abspath(__file__))
cfg = os.path.join(config_path, 'config.cfg')
cp.read(cfg)
self.username = cp.get('gitlab', 'username')
self.password = cp.get('gitlab', 'password')
self.session = requests.session()
self.csrf_toke = None
self.gitlab_login()
self.gl = gitlab.Gitlab.from_config('gitlab', ['config.cfg'])
self.gl.auth()
self.job_map = {
}
self.conn = sqlite3.connect('./gitlab_mr.db')
self.cur = self.conn.cursor()
self.rebase_table_name = 'gitlab_mr_rebase'
self.init_db()
self.notice = 'MESSAGE: No commit more than {} days, this merge ' \
'request will as draft'
self.mr_has_conflicts = dict()
self.mr_has_conflicts_message = '{} merge is not possible, ' \
'you can merge'
def init_db(self):
try:
sql = f"""CREATE TABLE {
self.rebase_table_name} (
id integer primary key autoincrement,
`repo_id` INT NOT NULL,
`branch` VARCHAR(256) NOT NULL DEFAULT '',
`mr_iid` VARCHAR(50) NOT NULL DEFAULT ''
);"""
self.cur.execute(sql)
logging.info("create table success")
except OperationalError as o:
# logging.error(str(o))
pass
except Exception as e:
# logging.error(e)
pass
def gitlab_login(self):
index_url = 'https://gitlab.test.com/'
response = self.session.get(index_url)
self.csrf_toke = re.search(r'name="csrf-token" content="(.*?)"',
response.text).group(1)
login_url = 'https://gitlab.test.com/users/auth/ldapmain/callback'
data = {
'authenticity_token': self.csrf_toke,
'username': self.username,
'password': self.password,
'remember_me': '1',
}
response = self.session.post(login_url, data=data)
def handle_task(self, project_id=9999, project_setting=dict):
project = self.gl.projects.get(project_id)
if project_setting['kill_rebase_job']:
mr_list = project.mergerequests.list(all=True,
state='opened')
for mr in mr_list:
if mr.draft:
continue
self.handle_need_rebase_job(project, mr)
if project_setting['kill_merged_job']:
merged_mr_list = project.mergerequests.list(all=True,
state='merged')
ctime = datetime.now()
for mr in merged_mr_list:
try:
merged_time = datetime.strptime(
str(mr.merged_at).split(".")[0], "%Y-%m-%dT%H:%M:%S")
diff = ctime - merged_time
diff_day = int(diff.total_seconds() / 24 / 3600)
print(diff_day)
except Exception as e:
logging.error("diff time error:" + str(e))
diff_day = 2
if diff_day <= 1:
self.handle_merged_job(project, mr)
def handle_merged_job(self, project, mr):
if not mr.pipelines.list():
return
if len(mr.commits()) == 0:
return
commit_sha = [i for i in mr.commits()][0].short_id
commit = project