编辑推荐:
本文来自hahack,文章介绍如何利用
Gitlab API 实现一套简单灵活的数据同步机制,从而实现在多个 Gitlab
站点间同步数据。
需求描述
在继续写数学系列前,我想切回去之前的 Git 系列写点东西。我想写系列文章也可以像操作系统的进程调度一样,一个系列暂时写不动了,先
保存现场 跳去另一个 topic 写点东西,同时也给自己留点 buffer 再酝酿一下这个暂时 中断
的系列。等这个系列酝酿够了,再 恢复现场 ,继续还这个系列的技术债。
对于一个规模较大的企业,存在多个 Gitlab 站点是很常见的事情。
比如,我们团队在公司发布统一的 Gitlab 之前早已经搭了一个团队用的 Gitlab ,当公司开始推
Git 时,由于我们已经对自己团队的 Gitlab 做了大量的定制,因此并不打算迁移到公司的 Gitlab
。
自己搭建 Gitlab 的好处是可以随心所欲的进行定制,像加远程钩子之类的东西想加就加。但缺点就是平台的维护成本也落到了自己身上。相比之下,公司
Gitlab 则没有什么维护成本,服务的稳定性由更专业的运维人员保证,也不用考虑扩容的问题,但灵活定制就别想了。如果能够实现
Gitlab 间的数据自动同步,我们可以没有顾忌的使用自己的 Gitlab 平台,一旦出现问题,再无痛迁移到公司的
Gitlab 。这样一方面避免了单点问题,节省了维护成本;另一方面也能尽可能保证灵活可定制。本文想讨论的就是多个
Gitlab 站点间的数据同步问题。
要实现数据同步,Gitlab 官方提供了一套备份恢复机制。但这套机制并不能很好地满足我们的需求:
需要两台机器的管理员权限。进行备份和恢复的机器都需要能 SSH 进去执行操作。而我们是不可能拥有公司
Gitlab 的管理员权限的;
会覆盖目标站点的数据。在恢复数据时,目标站点原有的一切数据都会被覆盖。而公司的 Gitlab 有很多个团队的数据,我们的同步不能影响到其他团队的数据;
Gitlab 版本兼容问题。Gitlab 的备份机制要求原站点和目标站点的 Gitlab 版本兼容,否则将恢复失败。而我们的
Gitlab 版本和公司的 Gitlab 版本并不相同,日后存在一方升级导致无法同步的可能。
出于以上的考虑,我们自己设计了一套同步工具。与 Gitlab 官方的备份恢复机制相比,它具有以下一些优点:
无需 ssh 账户权限。所有操作都通过 Gitlab API 和 Git 操作完成,不用 ssh
登录到机器进行操作;
同步数据类型灵活。可以选择同步组织、仓库代码、wiki、组织成员关系、权限控制信息等类型的数据;
不覆盖目标站点数据。只对目标站点相同组织内的数据进行同步,不影响其他团队的数据;
没有 Gitlab 版本兼容问题。同步过程利用了 Gitlab API ,而 Gitlab API
比 Gitlab 稳定,因此版本兼容问题比较少见。即使出现 API 接口的变更,也可以通过升级工具的接口调用来实现兼容。
下面将逐步说明整套同步的方案。为了方便描述,我把同步原 Gitlab 站点称为 A Gitlab,把同步目标站点称为
B Gitlab 。
数据的自动同步主要经历如下几步:
同步所有组织,如果建立了新组织,将自动给 B Gitlab 添加该组织;
同步所有组织的所有仓库的代码和 wiki 到 B Gitlab 。
同步所有用户的组织关系。
同步所有仓库的权限控制信息。
组织同步
利用 Gitlab API 列举出 A Gitlab 中的所有 groups,然后在 B Gitlab
中自动新建不存在的组织。
列举 Gitlab 的所有组织:
GET /groups
返回示例:
[
{
"id": 1,
"name":