Gitlab API 使用

简介

在工作过程中有遇到将仓库的的源码批量导入到gitlab中进行管理的需求,因此有接触到Gitlag API的使用;官方文档的介绍说“Automate GitLab via a simple and powerful API.”,非常适合我要干的事。

认证API

gitlab的大多数API都需要认证,剩下的就是在为提供认证的情况下返回公共数据;gitlab提供四种方法进行认证:

  • OAuth2令牌

    需要传递access_tokenAuthorization参数,例子如下:

    curl https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN
    
    curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/projects
    
  • 个人令牌访问

    需要传递private_tokenPrivate-Token参数,例子如下:

    curl --header "Private-Token: " https://gitlab.example.com/api/v4/projects
    
    curl --header "Authorization: Bearer " https://gitlab.example.com/api/v4/projects
    
  • 会话cookie

    此身份验证方法的主要用户是GitLab本身的Web前端,它可以使用API作为经过身份验证的用户来获取其项目列表,例如,无需显式传递访问令牌

  • GitLab CI作业令牌

    这个是操作gitlab pipeline相关api的令牌,可以用于触发某个项目的编译、获取编译状态及文件等工作

使用python的方式调用上述认证接口的例子如下:

import gitlab

# 个人令牌访问
gl = gitlab.Gitlab('http://10.0.0.1', private_token='JVNSESs8EwWRx5yDxM5q')

# OAuth2令牌
gl = gitlab.Gitlab('http://10.0.0.1', oauth_token='my_long_token_here')

# 用户名/密码 (GitLab << 10.2)
gl = gitlab.Gitlab('http://10.0.0.1', email='jdoe', password='s3cr3t')

# 访问公共数据
gl = gitlab.Gitlab('http://10.0.0.1')

管理API

gitlab管理API为gitlab的管理员提供访问gitlab资源访问,以下是一些常用API的介绍以及示例,示例均采用gitlab python的方式调用。

  • 项目管理
    1. 展示项目列表
      # 获取所有项目 (默认获取 20个)
      projects = gl.projects.list(all=True)
      # 获取打包过的所有项目
      projects = gl.projects.list(archived=1)
      # 获取被公开的所有项目
      projects = gl.projects.list(visibility='public')
      
      # 获取自己拥有的所有项目
      projects = gl.projects.list(owned=True)
      
      # 获取被标记的项目
      projects = gl.projects.list(starred=True)
      
      # 搜索项目
      projects = gl.projects.list(search='keyword')
      
    2. 创建、编辑、删除有权限的项目
      # 创建
      p = gl.projects.create({'name': 'awesome_project'})
      # 编辑
      project.snippets_enabled = 1
      project.save()
      # 删除
      gl.projects.delete(project_id)
      # or
      project.delete()
      
  • 分支管理
    1. 展示分支列表
      branches = project.branches.list()
      
    2. 获取单个分支
      branch = project.branches.get('master')
      
    3. 创建、删除分支
      # 创建
      branch = project.branches.create({'branch': 'feature1',
                            'ref': 'master'})
      # 删除
      project.branches.delete('feature1')
      # or
      branch.delete()
      
    4. 分支保护
      branch.protect()
      branch.unprotect()
      
  • 组管理
    1. 获取组列表
      groups = gl.groups.list()
      
    2. 获取某个组的详细信息
      group = gl.groups.get(group_id)
      
    3. 获取组内的项目列表
      projects = group.projects.list()
      
    4. 创建、更新、删除组
      # 创建
      group = gl.groups.create({'name': 'group1', 'path': 'group1'})
      # 更新
      group.description = 'My awesome group'
      group.save()
      # 删除
      gl.groups.delete(group_id)
      group.delete()
      

仓库代码批量导入gitlab的代码示例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#文件名:gitlabsourcepush

import gitlab
import ConfigParser
import time
import os
import subprocess
import time
from threading import Timer
from git import Repo

#解决字符报错
import sys
reload(sys)
sys.setdefaultencoding('utf8')

class SourceManager():
    def __init__(self, config_path):
        self._init_config(config_path)
        self._init_gitlab()

    #配置文件初始化
    def _init_config(self, config_path):
        self.config = ConfigParser.ConfigParser()
        self.config.readfp(open(config_path))
        self.gitlab_url = self.config.get("gitlab", "gitlab_url")
        self.gitlab_ssh_url = self.config.get("gitlab", "gitlab_ssh_url")
        self.gitlab_namespace = self.config.get("gitlab", "gitlab_namespace")
        self.sourcepath = self.config.get("gitlab", "sourcepath")
        self.not_found_fp = open('not_found.list', "w")
        self.found_fp = open('found.list', "w")

    #gitlab初始化
    def _init_gitlab(self):
        try:
            self.git = gitlab.Gitlab(self.gitlab_url, self.config.get("gitlab", "token_secret"))
        except Exception as e:
            print "gitlab connect with error: " + e.message
            exit(1)

    def execute(self, commands, cwd=None, extended_output=False, timeout=30):
        if cwd is None:
            cwd = self.sourcepath

        env = os.environ.copy()
        env["LC_MESSAGE"] = "C"

        proc = subprocess.Popen(commands, shell=True, env=env, cwd=cwd, 
            stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=None)
        kill_proc = lambda p: p.kill()
        timeout = 300
        timer = Timer(timeout, kill_proc, [proc])
        timer.start()
        while proc.poll() is None:
            time.sleep(0.1)
        timer.cancel()

        status = proc.returncode

        stdout = proc.stdout.read()
        stderr = proc.stderr.read()
        if stdout.endswith('\n'):
            stdout = stdout[:-1]
        if stderr.endswith('\n'):
            stderr = stderr[:-1]

        return status

    def gitlab_create_project(self, pkgname):
        self.git.projects.create(self.gitlab_namespace+'/'+pkgname)

    def getsource(self, pkgname):
        if self.execute('apt source %s' % pkgname) != 0:
            self.not_found_fp.write(pkgname+'\n')
            return False

        return True

    def git_init(self, pkgname):
        #匹配源码包的实际路径
        pkgdir = None
        for file in os.listdir(self.sourcepath):
            if os.path.isdir(file):
                if pkgname in file:
                    pkgdir = file

        if pkgdir is None:
            return

        cwd = self.sourcepath+'/'+pkgdir
        remote_url = self.gitlab_ssh_url+self.gitlab_namespace+'/'+pkgname+'.git'
        repo = git.Repo.init(cwd)
        repo.index.add(repo.untracked_files)
        repo.index.commit("Init Commit")
        origin = repo.git.remote_create("origin", remote_url)
        create_head('master', origin.refs.master).set_tracking_branch(origin.refs.master).checkout()
        #push需要在gitlab添加ssh-key
        origin.push()

    #def gitlab_handle(self, pkgname):

    #获取deb仓库源码并上传gitlab仓库
    def sourcepush(self, pkgname):
        '''
        1:gitlab创建对应仓库并提交代码
        2:apt source获取仓库源码
        3:进入源码目录创建git仓库
        4:上传到gitlab
        '''
        self.gitlab_create_project(pkgname)
        self.getsource(pkgname)
        self.git_int(pkgname)

if  __name__  == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--pkglist', default='pkglist.txt')
    parser.add_argument('--config', default='gitlab.conf')
    parser.add_argument("--action", default='all')

    args = parser.parse_args()

    sourceManager = SourceManager(config_path=args.config)

    if args.action == 'all':
        for pkgname in open(args.pkglist):
            sourceManager.sourcepush(pkgname.strip())

    if args.action == 'source':
        for pkgname in open(args.pkglist):
            sourceManager.getsource(pkgname.strip())

使用示例如下:

gitlabsourcepush --pkglist list.txt --config gitlab.conf

其中的"list.txt"是按行记录的源码包名称的文件;"gitlab.conf"是存有gitlab相关配置信息的文件,具体格式如下:

[gitlab]
token_secret=uYKAJpAs3J5eU6zSVcdf
gitlab_url=http://10.0.12.186/
gitlab_ssh_url=ssh://git@10.0.12.186:2224/
gitlab_namespace=github-linuxdeepin-mirror
gitlab_user=gitmirror
ssl_verify=False
gitlab_api_version=4
sourcepath=/home/go/source

1 条思考于 “Gitlab API 使用

发表评论

电子邮件地址不会被公开。 必填项已用*标注