python-gitlab自动同步mysql存储过程以及本地文件上传gitlab

**运行环境: Python 2.7.5 , linux **

参考文档

restfulAPI: https://docs.gitlab.com/ee/api/
官方Api: https://python-gitlab.readthedocs.io/en/v1.10.0/

python-gitlab简介

pip install python-gitlab
#官方建议使用配置文件
vi .python-gitlab.cfg
[global]
default = gitlab
ssh_verify = False
timeout = 8

[gitlab]
url = http://xxxxxxxxx
private_token = xxxxxxxxx

gitlab中private_token的获取

gitlab.jpg

gitlab demo 简单使用,主要是理解api

# coding:utf-8
'''
用于上传存储过程以及本地文件到gitlab中
'''

import gitlab

def allprojects():
    #######获取gitlab的所有projects###
    projects = gl.projects.list(all=True)
    for project in projects:
        print project.name, project.id


def allgroups():
    #######获取gitlab的所有group名称以及ID###
    all_groups = gl.groups.list(all=True)
    for group in all_groups:
        print group.name, group.id


def allusers():
    #######获取gitlab的所有user名称以及ID###
    users = gl.users.list(all=True)
    for user in users:
        print user.username, user.id, user.name, user.state


def assgroup():
    #######获取gitlab指定组内所有user以及project名称以及ID信息,本例中组ID为58###
    gid = int(raw_input('Input the group ID: '))
    group = gl.groups.get(gid)
    print group.name
    # members = group.members.list(all=True)
    # for me in members:
    #    print me.username,me.id
    projects = group.projects.list(all=True)
    for project in projects:
        print group.name, project.name
    #######################################


def projectinfo():
    pid = int(raw_input('Input the pid: '))
    projects = gl.projects.get(pid)
    return projects


def projectid():
    gid = int(raw_input('Input the group ID: '))
    group = gl.groups.get(gid)
    repo = str(raw_input('Input your repo name: '))
    project = gl.projects.get(group.name + '/' + repo)
    print project.id


def assuser():
    #######获取gitlab指定user###
    uid = int(raw_input('Input the user ID: '))
    user = gl.users.get(uid)
    print user.name


if __name__ == '__main__':
    ## login
    gl = gitlab.Gitlab.from_config('gitlab', ['.python-gitlab.cfg'])

    info = {1: 'allprojects()', 2: 'allgroups()', 3: 'allusers()', 4: 'projectinfo()', 5: 'projectid()', 6: 'assuser()',
            7: 'assgroup()'}
    serp = '-' * 20
    print '''%s
    1. 列出所有的projects
    2. 列出所有的groups
    3. 列出所有的users
    4. 根据project的ID列出project的所有信息
    5. 列出指定的project ID
    6. 列出指定的user
    7. 列出指定的组内的信息
    %s''' % (serp, serp)
    num = int(raw_input('Input yout choice: '))
    exec info[num]

下面进入mysql存储过程的同步,多的话不说,直接上代码; 【这个是参考别人的文档所写】
将同步后的文件写入到 /home/hadoop/shell/$db 目录,用于后续用python-gitlab上传

vi export.sh
#!/bin/bash
#set -x


#将mysql中存储过程代码直接导出为文件
dbcn="mysql -hrm-2zera5z4rl,com -udb_user -p*";
db=db_channel;
ii=0;
# 查询当前数据库中的存储过程
ct=`$dbcn -N -e " select count(1) from mysql.proc as p where 1=1 and p.db='$db' and p.type like 'P%';"`;
# 先删除目录,然后新建存放目录
rm -rf /home/hadoop/shell/$db
mkdir -p /home/hadoop/shell/$db

 
while true;
do
if [ $ii -lt $ct ]
then 
p=$ii;
let ii++;

# 通过序号获取每个存储过程的名称 
spname=`$dbcn -N -e " select p.name from mysql.proc as p where 1=1 and p.db='$db' and p.type like 'P%' limit $p,1;"`;

sleep 0;
ss=`$dbcn -N -e " 
SELECT   
CONCAT(
'
CREATE DEFINER=',CHAR(96),
LEFT(DEFINER, -1+LOCATE('@',DEFINER)),
CHAR(96),'@',CHAR(96),
RIGHT(DEFINER,LENGTH(DEFINER)-LOCATE('@',DEFINER)),
CHAR(96)
,' PROCEDURE ',CHAR(96),p.name ,CHAR(96),'(',p.param_list,')
', p.body ,REPEAT(CHAR(36),2)) AS sql_create 
FROM mysql.proc AS p 
WHERE 1=1 
and p.db='$db' 
and p.type LIKE 'P%'
AND p.name ='$spname'
;"
`
echo -e "$ss" > /home/hadoop/shell/$db/$spname.sql
if [ $? -ne 0 ]; then
    echo 'fail'
        exit 0;
else 
    echo 'success'
fi

# 循环结束
else 
echo '_while finished';
exit 0;
fi
done


用于将存储过程以及python脚本&shell脚本上传到服务器

# coding:utf-8
'''
用于上传存储过程以及本地文件到gitlab中
'''

import gitlab
import subprocess
import json
import requests
import time
import os


def projectinfo(pid):
    projects = gl.projects.get(pid)
    return projects
    # print projects.name, projects.http_url_to_repo


# 获得project下单个文件   README.md
def getContent(pid):
    projects = projectinfo(pid)
    # 获得文件
    f = projects.files.get(file_path='code/shell/export.sh', ref='master')
    # 第一次decode获得bytes格式的内容
    content = f.decode()
    # # 存到本地
    with open('export.sh', 'wb') as code:
        code.write(content)


def uploadeFile(pid):
    projects = projectinfo(pid)
    # projects.upload("export.sh", filepath="xxxxxx")
    # 这个方法上传文件限制很大 , file_path 文件名   f.content 用于生成文件内容 ;一定要用 base64 
    f = projects.files.create({'file_path': 'export.sh',
                               'branch': 'master',
                               'content': 'test',
                               'author_email': 'xxx',
                               'author_name': 'xxx',
                               'encoding': 'base64',
                               'commit_message': 'Create export.sh'})
    # 将数据写入
    f.content = open('insert_channel_basic.sql').read()
    f.save(branch='master', commit_message='Update testfile')


# 【实际中用到这个方法】多文件提交参考 : https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
def commit_file(projects, data):
    projects.commits.create(data)


def judgeType(projects, file_path):
    try:
        projects.files.get(file_path=file_path, ref='master')
        return True
    except Exception as e:
        return False


# jMap 用于生成最后的对象; path 文件路径;  jsonList用于生成中间对象
def getData(path, projects, gitlab_source_dir, message):
    jsonList = []
    jMap = {}
    jMap["branch"] = 'master'
    jMap["commit_message"] = message
    for file in os.listdir(path):
        file_dir = os.path.join(path, file)
        # 判断当前路径是文件还是目录 ,排除 pyc造成的编译问题
        if os.path.isfile(file_dir) and 'pyc' not in file:
            gitlab_dir = '%s%s' % (gitlab_source_dir, file)
            aMap = {}
            # 存在就更新, 不存在就创建
            if judgeType(projects, gitlab_dir):
                aMap["action"] = "update"
            else:
                aMap["action"] = "create"
            aMap["file_path"] = gitlab_dir
            aMap["content"] = open(file_dir).read()
            jsonList.append(aMap)
    jMap["actions"] = jsonList
    return jMap


def run_it(cmd):
    '''
    通过python执行shell命令
    :param cmd: sh /home/hadoop/shell/export.sh
    '''
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True,
                         stderr=subprocess.PIPE)
    # print ('running:%s' % cmd)
    out, err = p.communicate()
    if p.returncode != 0:
        print("Non zero exit code:%s executing: %s \nerr course ---> %s" % (p.returncode, cmd, err))
        # 如果出错直接告警
        raise RuntimeError('导出存储过程失败')


if __name__ == '__main__':
    # 用于钉钉告警
    url = "xxxx"
    header = {
        "Content-Type": "application/json",
        "charset": "utf-8"
    }

    ## login
    gl = gitlab.Gitlab.from_config('gitlab', ['.python-gitlab.cfg'])

    # 用于将gitlab上面文件写入本地
    # getContent(87)

    # 1. 将mysql存储过程通过shell脚本写入到指定目录
    try:
        cmd = 'sh /home/hadoop/shell/export.sh'
        path = '/home/hadoop/shell/db_channel'
        pid = 92
        run_it(cmd)
        # 获取对应project 对象
        projects = projectinfo(pid)
        # 将目录下的文件循环读取,然后批量提交到gitlab中
        # dir /home/hadoop/shell/db_channel
        # 用于存放拼接好的对象, 如果文件最开始不存在,用update 会报错
        jsonList = []
        jMap = {}
        jMap["branch"] = 'master'
        jMap["commit_message"] = 'update production sql'
        for file in os.listdir(path):
            file_dir = os.path.join(path, file)
            gitlab_dir = '%s%s' % ("code/production/", file)
            aMap = {}
            # 存在就更新, 不存在就创建
            if judgeType(projects, gitlab_dir):
                aMap["action"] = "update"
            else:
                aMap["action"] = "create"
            aMap["file_path"] = gitlab_dir
            aMap["content"] = open(file_dir).read()
            jsonList.append(aMap)
        jMap["actions"] = jsonList
        # 用于存储过程的同步
        commit_file(projects, jMap)

        # 2. 用于shell脚本的同步
        pathShell = "/home/hadoop/shell"
        gitlab_source_dirShell = "code/shell/"
        message_shell = "update shell file"
        shell_data = getData(pathShell, projects, gitlab_source_dirShell, message_shell)
        commit_file(projects, shell_data)

        # 3. 用于上传python 脚本, 如果之后有新的路径,只需要添加进list中
        pythonList = ['/home/hadoop/py']
        for pathPython in pythonList:
            gitlab_source_dirPython = "code/Python/"
            message_python = "update python file"
            python_data = getData(pathPython, projects, gitlab_source_dirPython, message_python)
            commit_file(projects, python_data)

    except Exception as e:
        nowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        data = {
            "msgtype": "text",
            "text": {
                "content": "【Fail:gitlab自动同步失败】:【" + nowTime + "】\n" + "【错误原因】:\n" + str(e)
            }
        }
        sendData = json.dumps(data).encode("utf-8")
        requests.post(url=url, data=sendData, headers=header)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 208,927评论 6 486
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,265评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 154,818评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,856评论 1 280
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,873评论 5 378
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,461评论 1 286
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,663评论 3 403
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,364评论 0 262
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,827评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,271评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,353评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,022评论 4 326
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,542评论 3 309
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,550评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,794评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,921评论 2 357
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,176评论 2 345