正如我在此系列文章中试图展示的那样,在 Git 4 月 7 日迎来 14 周年之际,Git 可以做很多超出跟踪源代码范围的事情。信不信由你,Git 甚至可以管理你的 Git 服务器,因此你或多或少可以使用 Git 本身运行 Git 服务器。
当然,这涉及到很多超出日常 Git 的组件,尤其是 Gitolite,这是一个后端应用程序,用于管理您使用 Git 配置的繁琐部分。Gitolite 最棒的地方在于,因为它使用 Git 作为其前端界面,所以很容易将 Git 服务器管理集成到您其余的基于 Git 的工作流程中。Gitolite 提供对谁可以访问您服务器上的特定仓库以及他们拥有哪些权限的精确控制。您可以使用常用的 Linux 系统工具自行管理这类事情,但是如果您在半打用户中拥有不止一两个仓库,则需要做很多工作。
Gitolite 的开发者们已经完成了艰苦的工作,使您可以轻松地为许多用户提供对您的 Git 服务器的访问权限,而无需让他们访问您的整个环境——并且您可以使用 Git 完成所有这些操作。
Gitolite 不是 GUI 管理员和用户面板。优秀的 Gitea 项目提供了这种体验,但是本文重点介绍 Gitolite 的简单优雅和令人安心的熟悉感。
安装 Gitolite
假设您的 Git 服务器运行 Linux,您可以使用软件包管理器安装 Gitolite(CentOS 和 RHEL 上使用 yum,Debian 和 Ubuntu 上使用 apt,OpenSUSE 上使用 zypper,等等)。例如,在 RHEL 上
$ sudo yum install gitolite3
许多仓库仍然有旧版本的 Gitolite 用于遗留支持,但是当前版本是版本 3。
您必须具有对服务器的无密码 SSH 访问权限。如果您愿意,可以使用密码登录,但是 Gitolite 依赖于 SSH 密钥,因此您必须配置使用密钥登录的选项。如果您不知道如何配置服务器以进行无密码 SSH 访问,请先学习如何执行此操作(Steve Ovens 的 Ansible 文章的“设置 SSH 密钥身份验证”部分对此进行了很好的解释)。这是安全服务器管理以及运行 Gitolite 的重要组成部分。
配置 Git 用户
如果没有 Gitolite,如果有人请求访问您在服务器上托管的 Git 仓库,则您必须为该人提供用户帐户。Git 提供了一个特殊的 shell,即 git-shell,这是一个超特定的 shell,仅执行 Git 任务。这使您可以拥有只能通过非常有限的 shell 环境过滤器访问您的服务器的用户。
该解决方案有效,但是通常意味着用户可以访问您服务器上的所有仓库,除非您对组权限有非常好的架构,并且在每次创建新仓库时严格维护这些权限。它还需要在系统级别进行大量手动配置,该区域通常为特定级别的系统管理员保留,而不一定是通常负责 Git 仓库的人员。
Gitolite 完全绕过了这个问题,它为每个需要访问任何仓库的人指定一个用户名。默认情况下,用户名是 git,并且由于 Gitolite 的文档假设使用它,因此在您学习该工具时最好保留默认设置。对于任何曾经使用过 GitLab 或 GitHub 或任何其他 Git 托管服务的人来说,这也是一个众所周知的约定。
Gitolite 将此用户称为托管用户。在您的服务器上创建一个帐户以充当托管用户 (我将坚持使用 git,因为这是约定俗成的做法)
$ sudo adduser --create-home git
为了让您控制 git 用户帐户,它必须具有属于您的有效公共 SSH 密钥。您应该已经设置好了,所以将您的公钥(不是您的私钥)cp 到 git 用户的主目录
$ sudo cp ~/.ssh/id_ed25519.pub /home/git/
$ sudo chown git:git /home/git/id_ed25519.pub
如果您的公钥不以扩展名 .pub 结尾,则 Gitolite 将不会使用它,因此请相应地重命名该文件。切换到该用户帐户以运行 Gitolite 的设置
$ sudo su - git
$ gitolite setup --pubkey id_ed25519.pub
设置脚本运行后,git 用户主目录将具有一个 repositories 目录,该目录(目前)包含文件 git-admin.git 和 testing.git。这就是服务器所需的所有设置,因此请注销。
使用 Gitolite
管理 Gitolite 就是编辑 Git 仓库中的文本文件,特别是 gitolite-admin.git。您不会通过 SSH 连接到您的服务器进行 Git 管理,并且 Gitolite 鼓励您不要尝试这样做。您和您的用户存储在 Gitolite 服务器上的仓库是裸仓库,因此最好远离它们。
$ git clone git@example.com:gitolite-admin.git gitolite-admin.git
$ cd gitolite-admin.git
$ ls -1
conf
keydir
此仓库中的 conf 目录包含一个名为 gitolite.conf 的文件。在文本编辑器中打开它或使用 cat 查看其内容
repo gitolite-admin
RW+ = id_ed22519
repo testing
RW+ = @all
您可能已经了解此配置文件的作用:gitolite-admin 代表此仓库,并且 id_ed25519 密钥的所有者具有读取、写入和 Git 管理权限。换句话说,Gitolite 不是将用户映射到正常的本地 Unix 用户(因为您的所有用户都使用 git 托管用户身份登录),而是将用户映射到 keydir 目录中列出的 SSH 密钥。
testing.git 仓库使用特殊的组表示法,为每个有权访问服务器的人员授予完全权限。
添加用户
如果您想将名为 alice 的用户添加到您的 Git 服务器,则 Alice 必须将她的公共 SSH 密钥发送给您。Gitolite 使用 .pub 扩展名左侧的任何内容作为您的 Git 用户的标识符。与其使用默认密钥名称值,不如为密钥指定一个指示密钥所有者的名称。如果用户有多个密钥(例如,一个用于她的笔记本电脑,一个用于她的台式机),则可以使用子目录来避免文件名冲突。例如,Alice 从她的笔记本电脑使用的密钥可能会以默认的 id_rsa.pub 发送给您,因此将其重命名为 alice.pub 或类似的名称(或让用户根据他们在计算机上的本地用户帐户命名密钥),并将其放入 gitolite-admin.git/keydir/work/laptop/ 目录中。如果她从她的台式机发送给您另一个密钥,请将其命名为 alice.pub(与上一个相同),并将其添加到 keydir/work/desktop/ 中。另一个密钥可能会进入 keydir/home/desktop/,依此类推。Gitolite 递归搜索 keydir 以查找与仓库“用户”匹配的 .pub 文件,并将任何匹配项视为相同的身份。
当您将密钥添加到 keydir 目录时,您必须将它们提交回您的服务器。这是一件很容易忘记的事情,因此这里有一个真正的论点,即使用像 Sparkleshare 这样的自动化 Git 应用程序,以便立即将任何更改提交回您的 Gitolite 管理员。当您第一次忘记提交和推送——并浪费您和您的用户三个小时的时间进行故障排除时——您将看到 Gitolite 是使用 Sparkleshare 的完美理由。
$ git add keydir
$ git commit -m 'added alice-laptop-0.pub'
$ git push origin HEAD
默认情况下,Alice 可以访问 testing.git 目录,以便她可以使用它测试连接性和功能。
设置权限
与用户一样,目录权限和组与您可能习惯使用的(或在网上找到信息的)普通 Unix 工具是分离的。项目的权限在 gitolite-admin.git/conf 目录中的 gitolite.conf 文件中授予。有四个级别的权限
- R 允许只读。对仓库具有 R 权限的用户可以克隆它,仅此而已。
- RW 允许用户执行分支的快进推送、创建新分支和创建新标签。或多或少,这对于大多数用户来说感觉像是一个“正常”的 Git 仓库。
- RW+ 允许可能具有破坏性的 Git 操作。用户可以执行正常的快进推送,以及回退推送、执行变基以及删除分支和标签。这可能不是您想要授予项目上所有贡献者的权限。
- - 显式拒绝访问仓库。这基本上与用户未在仓库的配置中列出相同。
通过调整 gitolite.conf 来创建新仓库或修改现有仓库的权限。例如,要授予 Alice 管理名为 widgets.git 的新仓库的权限
repo gitolite-admin
RW+ = id_ed22519
repo testing
RW+ = @all
repo widgets
RW+ = alice
现在 Alice——只有 Alice——可以克隆仓库
[alice]$ git clone git@example.com:widgets.git
Cloning into 'widgets'...
warning: You appear to have cloned an empty repository.
在她最初的推送中,Alice 必须使用 -u 选项将她的分支发送到空仓库(就像她必须对任何 Git 主机执行的操作一样)。
为了简化用户管理,您可以定义仓库组
@qtrepo = widgets
@qtrepo = games
repo gitolite-admin
RW+ = id_ed22519
repo testing
RW+ = @all
repo @qtrepo
RW+ = alice
就像您可以创建组仓库一样,您可以对用户进行分组。默认情况下存在一个用户组:@all。正如您可能期望的那样,它包含所有用户,没有例外。您可以创建自己的
@qtrepo = widgets
@qtrepo = games
@developers = alice bob
repo gitolite-admin
RW+ = id_ed22519
repo testing
RW+ = @all
repo @qtrepo
RW+ = @developers
与添加或修改密钥文件一样,对 gitolite.conf 文件的任何更改都必须提交并推送才能生效。
创建仓库
默认情况下,Gitolite 假设仓库创建是从上到下发生的。例如,有权访问 Git 服务器的项目经理创建一个项目仓库,并通过 Gitolite 管理仓库添加开发人员。
在实践中,您可能更喜欢授予用户创建仓库的权限。Gitolite 将这些称为“通配符仓库”(我不确定这是否是对仓库如何产生的评论,还是对配置文件中允许它发生的通配符的引用)。这是一个例子
@managers = alice bob
repo foo/CREATOR/[a-z]..*
C = @managers
RW+ = CREATOR
RW = WRITERS
R = READERS
第一行定义了一个用户组:该组名为 @managers,包含用户 alice 和 bob。下一行设置了一个通配符,允许在名为 foo 的目录中创建尚不存在的仓库,后跟一个以创建仓库的用户命名的子目录。例如
[alice]$ git clone git@example.com:foo/alice/cool-app.git
Cloning into cool-app'...
Initialized empty Git repository in /home/git/repositories/foo/alice/cool-app.git
warning: You appear to have cloned an empty repository.
有一些机制供通配符仓库的创建者定义谁可以读取和写入他们的仓库,但是它们的范围有限。在大多数情况下,Gitolite 假设一组特定的用户管理项目权限。一种解决方案是授予所有用户访问 gitolite-admin 的权限,使用 Git 钩子来要求管理器批准将更改合并到 master 分支中。
了解更多
Gitolite 具有比本文介绍的更多的功能,因此请尝试一下。 文档非常出色,一旦您通读一遍,您就可以自定义您的 Gitolite 服务器,以便为您的用户提供您感到舒适的任何级别的控制。Gitolite 是一个低维护、简单的系统,您可以安装、设置,然后在很大程度上忘记它。
2 条评论