46.[Python]使用pyolite方便管理gitolite

来源:互联网 发布:大数据都包括什么 编辑:程序博客网 时间:2024/06/07 12:27

  • 简介
  • 安装
  • 使用方法
    • 用户管理
    • 仓库管理
  • API详解
    • Pyolite类
    • UserManager类
    • User类
    • ListKeys类
    • RepositoryManager类
    • Repository类
    • ListUsers类
    • Repo类
    • Git类
    • Manager类
  • 注意事项

转载请注明原始出处:http://blog.csdn.net/a464057216/article/details/52661365

简介

gitolite通过操作其gitolite-admin仓库完成git服务器的管理,这里介绍使用Python的pyolite管理gitolite的方法,从而能够编写脚本提高工作效率。

在学习本文前,您可以需要掌握一些基本的gitolite原理、SSH公钥/私钥管理等知识。

安装

  • pip install pyolite命令安装pyolite。
  • gitolite-admin/conf目录下创建repos子目录,然后在gitolite-admin/conf/gitolite.conf文件的最后一行追加如下内容:
include     "repos/*.conf"
  • 删除gitolite.conftesting.git项目,同时在git服务器上删掉这个仓库的目录。

最后将改动push到git服务器。

使用方法

pyolite的GitHub项目的examples目录已经展示了简单的使用方法。因为它没有详细的文档,如下是我阅读完其源码之后的总结。
码字不易,如果您觉得对您的工作有帮助或者想要转载,欢迎在文末留言,谢谢!

用户管理

# -*- coding:utf-8 -*-from pyolite import Pyoliteadmin_repository = '/Users/mars/learnspace/gitolite-admin'# Pyolite对象用来管理gitolite-admin仓库olite = Pyolite(admin_repository=admin_repository)# users表示用户集合,all()返回所有git用户print "All git users:", olite.users.all()# 获取由第一个参数指定的git用户# 如果该git用户不存在,按照key_path和name创建一个git用户并返回#alice = olite.users.get_or_create("alice",#                           key_path="/Users/linglingguo/.ssh/alice5.pub")# 指定key和name创建一个git用户并返回alice = olite.users.create(name="alice",                           key='ssh-ed25519 AAAAC3Nz...0wq4S aliceed25519')# 获取一个git用户alice = olite.users.get(name="alice")# 获取一个git用户的公钥列表print "Alice's keys:", alice.keys# 为一个git用户添加公钥(通过指定公钥内容)alice.keys.append('ssh-rsa AAAAB3N...qPMu57 alice5')# 为一个git用户添加公钥(通过指定公钥文件路径)alice.keys.append('/Users/linglingguo/.ssh/alice4.pub')# 删除一个git用户的公钥(被删除的参数必须是公钥的内容)alice.keys.remove('ssh-rsa AAAAB3Nza...L3R51EIhqPMu57 alice5')# 判断用户是否是gitolite管理用户print "If %s is admin: %s" % (alice.name, alice.is_admin)

仓库管理

# -*- coding:utf-8 -*-from pyolite import Pyoliteadmin_repository = '/Users/linglingguo/learnspace/gitolite-admin'# Pyolite对象用来管理gitolite-admin仓库olite = Pyolite(admin_repository=admin_repository)# 获取一个仓库,如果没有就创建后返回loo = olite.repos.get_or_create("loo")# 获取一个仓库mars = olite.repos.get("mars")# 创建一个仓库并返回suson = olite.repos.create("suson")# 向仓库添加用户并设置访问权限(RW+CD),通过传入User对象完成alice = olite.users.get_or_create("alice",                           key_path="/Users/linglingguo/.ssh/alice5.pub")mars.users.add(alice, "RW+")# 向仓库添加用户并设置访问权限,通过传入User名字完成# 这样添加时,并没有判断是否是合法git用户,需要调用者自己判断mars.users.add('new_person', "R")# 编辑某个仓库下的用户权限# 编辑前未判断用户是否在这个项目中,也未判断权限字符串是否合法(我已经提交了pull request到原项目修改)mars.users.edit('new_person', "RW")# 删除某个仓库中的某个用户mars.users.remove('new_person')# 查看仓库的用户列表print "%s's users: %s" % (mars.name, mars.users)

API详解

Pyolite类

pyolite.Pyolite类是对gitolite-admin仓库的抽象,包含如下属性(括号中的内容表示属性的类型):

  • (str) admin_repository: gitolite-admin代码库的绝对路径。
  • (UserManager) users: gitolite的用户集合。
  • (RepositoryManager) repos: gitolite的代码库集合。

实例化Pyolite实例时,admin_repository是必选参数,如果admin_repository不是一个目录,会抛出异常:ValueError('Admin repository path should point to directory')

UserManager类

pyolite.managers.user.UserManager类是Manager类的子类,用来管理git用户。从Manager类继承了如下属性:

  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
  • (Git) git:表示gitolite-admin绝对路径的Git对象。

从Manager类继承了如下方法:

  • create(name, key=None, key_path=None):创建名字为name的User对象并返回这个用户对象,必须提供key(ssh公钥内容)或key_path(ssh公钥文件路径)参数之一,如果同时提供,key_path参数被忽略,如果都没有提供,报异常:ValueError('You need to specify a key or key_path')

该操作其实是在gitolite-admin/keydir目录下,先使用git用户名字建立一个目录,再按照SSH公钥的md5建立子目录,最后把公钥内容写到子目录中以git用户名字命名的公钥文件中(相同的公钥不会重复添加),比如:

keydir/alice├── 7a0db30e3d42c0e044bdbbe7d71dc96e│   └── alice.pub└── caf5253d8ea374498a40c89d864b6d8e    └── alice.pub2 directories, 2 files
  • get(name):返回名字为nameUser对象,如果在keydirconf目录都找不到,返回None
  • get_or_create(name, key=None,key_path=None):从Manager类继承来的方法,如果get(name)返回的不是None,则直接返回其User对象;如果get(name)返回None,则调用create(name, key=None, key_path=None)创建用户后返回新创建的User对象。

UserManager类的特殊方法如下:

  • all():根据keydir中的公钥返回目前所有有权限访问git服务器的用户User对象的列表。

User类

pyolite.models.user.User类表示git用户,由UserManger类管理,初始化方法如下:

User(path, git, name, repos, keys),初始化一个User对象,其中初始化了如下属性:

  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
  • (Git) git:表示gitolite-admin绝对路径的Git对象。
  • (str) name:git用户的名字。
  • (list) repos:git用户有权限访问的仓库列表,默认是[]。
  • (ListKeys) keys:git用户的SSH公钥列表,默认是空列表。

包含如下方法:

  • get_by_name(name, path, git):类方法,返回名字为name的User对象。其中:

    • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
    • (Git) git:表示gitolite-admin绝对路径的Git对象。
    • (str) name:git用户的名字。
  • get(user, path, git):类方法,返回字为useruser实参为一个str)的User对象,或者返回User对象自己(user实参为一个User对象)。

  • 对User对象作为str()repr()的参数时,返回形如< name >的字符串。

User类还包含如下属性:
* is_admin:返回User对象是否是git管理员,值为True或False。

ListKeys类

pyolite.models.lists.ListKeys类是对git用户的所有公钥的抽象,是Python内建的list的子类。包含如下属性:

  • (User) user:User对象,表示这个ListKeys对象属于哪个用户。
  • (list) self:python内建的list对象,存储某个用户的所有SSH公钥。

包含如下方法:

  • append(key):添加key到ListKeys,其中key可以是SSH公钥内容或者SSH公钥文件路径(重复的key不会被添加)。
    *+ keys:如果要添加多个key到ListKeys,可以直接使用加法运算符,这里的keys参数一个list型的列表,其中每个元素是SSH公钥内容或者SSH公钥文件路径。
  • remove(key):从ListKeys对象中删除一个key,在删除时key这个参数必须是SSH公钥内容。实际它删除了gitolite-admin/keydir/目录下对应的公钥文件及其父级目录(通过计算md5生成的目录)。如果ListKeys中不存在这个key,报异常:ValueError("Invalid key")

RepositoryManager类

pyolite.managers.reopsitory.RepositoryManager类继承自Manager类,用来管理git仓库。从Manager类继承了如下属性:

  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
  • (Git) git:表示gitolite-admin绝对路径的Git对象。

从Manager类继承了如下方法:

  • get(lookup_repo):返回名字为lookup_repo的Repository对象,如果没找到返回None。
  • create(lookup_repo):新建名为lookup_repo的仓库,并且返回该Repository对象。如果该仓库已经存在,报异常: ValueError('Repository %s already exists' % lookup_repo)
    调用该方法会在gitolite-admin/conf/repos目录中创建名为lookup_repo.conf的文件,内容是repo lookup_repo\n
  • get_or_create(name):如果get(lookup_repo)返回的不是None,则直接返回其Repository对象;如果get(lookup_repo)返回None,则调用create(lookup_repo)创建仓库后返回新创建的Repository对象。

Repository类

pyolite.models.repository.Repository类是一个git仓库的抽象,包含如下属性:

  • (str) name:仓库名字。
  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
  • (Git) git:表示gitolite-admin绝对路径的Git对象。
  • (ListUsers) users:该仓库的用户列表。

Repository类的初始化函数为Repository(name, path, git),参数含义如上(初始化时并不需要users参数)。

包含如下方法:

  • get_by_name(name, path, git):类方法,返回名字为name的Repository对象。其中:

    • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
    • (Git) git:表示gitolite-admin绝对路径的Git对象。
    • (str) name:仓库的名字。
  • Repository对象作为str()的参数时,返回形如< name >的字符串。

ListUsers类

pyolite.models.lists.ListUsers类用来对仓库中的用户进行管理,包含如下属性:

  • (Repository) repository_model:表示属于哪个Repository对象。
  • (Repo) repo:表示该仓库的配置文件的Repo对象。

包含如下方法:

  • get_or_create(user):user参数可以是str类型的用户名字,也可以是User对象,直接获取或者创建后返回一个User对象。
  • add(user, permission):向仓库添加对应权限的用户,user参数可以是str类型的用户名字,也可以是User对象,permissoin参数可以是'RW+CD'中的任意字符组合,方法返回被添加的User对象。
  • edit(user, permission):修改仓库中对应用户的权限,user参数可以是str类型的用户名字,也可以是User对象,permissoin参数可以是'RW+CD'中的任意字符组合,方法返回被修改的User对象。
  • remove(user):删除仓库中某个用户的访问权限,user参数可以是str类型的用户名字,也可以是User对象。
  • ListUsers对象作为str()的参数时,返回由用户名称组成的列表的字符串形式,比如[ mars, loo ]
  • set(users): 代码中这个方法没有表调用过,从实现上看也稍欠考虑,这里就不介绍了。

Repo类

注意与Repository类区分,pyolite.repo.Repo类是对一个具体的配置文件的抽象。包含如下属性:

  • (Path) path:指向具体的配置文件的unipath.Path对象,如unipath.Path(u'/Users/mars/learnspace/gitolite-admin/conf/repos/mars.conf')
  • (list) users:有权限操作该Repo的所有git用户的名字的列表,比如[mars, loo]

包含如下方法:

  • replace(pattern, string):将配置文件中匹配正则表达式pattern的部分用string替换。
  • write(string):将string的内容追加写入配置文件。
  • overwrite(string):将string的内容覆盖写入配置文件。

Git类

因为gitolite的操作都是依靠操作gitolite-admin仓库实现的,所以pyolite将git的操作抽象成了pyolite.git.Git类。包含如下属性:

  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。

包含如下方法:

  • commit(objects, message)objects参数是要提交的目录的列表,比如['keydir']或者['keydir', 'conf']message是表示git操作提交时的注释信息。

Manager类

pyolite.managers.manager.Manager类是一个抽象基类,不能被实例化,日常无需使用这个类,所以放在最后介绍。包含如下属性:

  • (Path) path:表示gitolite-admin绝对路径的unipath.Path对象。
  • (Git) git:表示gitolite-admin绝对路径的Git对象。

包含如下方法:

  • get_or_create(lookup_entity, *args, **kwargs):非抽象方法,子类不必须实现。
  • get(entity): 抽象方法,子类必须实现。
  • create(entity): 抽象方法,子类必须实现。

注意事项

我仔细阅读了pyolite这个工具的源码,发现了一些问题如下:
1. [bug]针对git用户的公钥文件操作没有加锁,并发操作时会出问题。
2. [bug]针对某个仓库的配置文件添加、更新、删除用户权限时,没有判断这个用户是不是git服务器上的合法用户,如果不是,应该抛出异常。
3. [Improvement]没有实现gitolite中用户组、仓库组的支持。
4. [bug]针对某个仓库的配置文件更新用户权限时,没有判断用户是否有权限操作这个仓库,以及没有判断更新后的权限的合法性(应该属于set("RW+CD"))。

关于最后一个bug我已经修复并提交了pull request到原项目。
如果觉得我的文章对您有帮助,欢迎关注我(CSDN:Mars Loo的博客)或者为这篇文章点赞,谢谢

1 0
原创粉丝点击