使用 Git 运行服务器

感谢 Gitolite,您可以使用 Git 管理 Git 服务器。在我们的关于鲜为人知的 Git 用法的系列中了解如何操作。
153 位读者喜欢这个。
computer servers processing data

Opensource.com

正如我试图在这个系列中展示的那样,在 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.gittesting.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 存储库使用特殊组表示法为每个有权访问服务器的人员提供完全权限。

添加用户

如果您想向您的 Git 服务器添加名为 alice 的用户,则 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,包含用户 alicebob。下一行设置了一个通配符,允许在名为 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 钩子要求经理批准才能将更改合并到主分支。

了解更多

Gitolite 具有比本文介绍的更多的功能,因此请尝试一下。 文档 非常出色,一旦您通读一遍,您就可以自定义您的 Gitolite 服务器,以便为您的用户提供您感到舒适的任何级别的控制。Gitolite 是一个低维护、简单的系统,您可以安装、设置,然后或多或少地忘记它。

Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算机行业工作,通常同时进行。

2 条评论

是的,没错,“通配符存储库”这个名称来自使用的通配符。实际上,这可以说是我和想要该功能的用户之间的工作标题。在发布时找到一个更好的名字……就是没有发生 :) 无论如何,我不擅长命名事物!

这些天,如果我必须更正式一点,我会使用短语“临时的、用户创建的存储库”。不是很朗朗上口 :)

感谢您的阅读,Sitaram,更重要的是感谢您出色的软件。

恕我直言,我喜欢“通配符存储库”这个名称,因为它包含双重含义:它们涉及通配符……但也可能有点野性,这取决于创建它们的人对它们的照顾程度 :^)

回复 ,作者:sitaram(未验证)

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.