借助 Gitolite,你可以使用 Git 來管理 Git 伺服器。在我們的系列文章中了解這些鮮為人知的 Git 用途。
正如我在系列文章中演示的那樣,Git 除了跟蹤原始碼外,還可以做很多事情。信不信由你,Git 甚至可以管理你的 Git 伺服器,因此你可以或多或少地使用 Git 本身來執行 Git 伺服器。
當然,這涉及除日常使用 Git 之外的許多元件,其中最重要的是 Gitolite,該後端應用程式可以管理你使用 Git 的每個細微的設定。Gitolite 的優點在於,由於它使用 Git 作為其前端介面,因此很容易將 Git 伺服器管理整合到其他基於 Git 的工作流中。Gitolite 可以精確控制誰可以存取你伺服器上的特定儲存庫以及他們具有哪些許可權。你可以使用常規的 Linux 系統工具自行管理此類事務,但是如果有好幾個使用者和不止一兩個倉庫,則需要大量的工作。
Gitolite 的開發人員做了艱苦的工作,使你可以輕鬆地為許多使用者提供對你的 Git 伺服器的存取權,而又不讓他們存取你的整個環境 —— 而這一切,你可以使用 Git 來完成全部工作。
Gitolite 並不是圖形化的管理員和使用者面板。優秀的 Gitea 專案可提供這種體驗,但是本文重點介紹 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 的重要組成部分。
如果沒有 Gitolite,則如果某人請求存取你在伺服器上託管的 Git 儲存庫時,則必須向該人提供使用者帳戶。Git 提供了一個特殊的外殼,即 git-shell
,這是一個僅執行 Git 任務的特別的特定 shell。這可以讓你有個只能通過非常受限的 Shell 環境來過濾存取你的伺服器的使用者。
這個解決方案是一個辦法,但通常意味著使用者可以存取伺服器上的所有儲存庫,除非你具有用於組許可權的良好模式,並在建立新儲存庫時嚴格遵循這些許可權。這種方式還需要在系統級別進行大量手動設定,這通常是只有特定級別的系統管理員才能做的工作,而不一定是通常負責 Git 儲存庫的人員。
Gitolite 通過為需要存取任何儲存庫的每個人指定一個使用者名稱來完全迴避此問題。預設情況下,該使用者名稱是 git
,並且由於 Gitolite 的文件中假定使用的是它,因此在學習該工具時保留它是一個很好的預設設定。對於曾經使用過 GitLab 或 GitHub 或任何其他 Git 託管服務的人來說,這也是一個眾所周知的約定。
Gitolite 將此使用者稱為託管使用者。在伺服器上建立一個帳戶以充當託管使用者(我習慣使用 git
,因為這是慣例):
$ sudo adduser --create-home git
為了控制該 git
使用者帳戶,該帳戶必須具有屬於你的有效 SSH 公鑰。你應該已經進行了設定,因此複製你的公鑰(而不是你的私鑰)新增到 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
的家使用者目錄將有一個 repository
目錄,該目錄(目前)包含儲存庫 git-admin.git
和 testing.git
。這就是該伺服器所需的全部設定,現在請登出 git
使用者。
管理 Gitolite 就是編輯 Git 儲存庫中的文字檔案,尤其是 gitolite-admin.git
中的。你不會通過 SSH 進入伺服器來進行 Git 管理,並且 Gitolite 也建議你不要這樣嘗試。在 Gitolite 伺服器上儲存你和你的使用者的儲存庫是個裸儲存庫,因此最好不要使用它們。
$ git clone [email protected]:gitolite-admin.git gitolite-admin.git$ cd gitolite-admin.git$ ls -1confkeydir
該儲存庫中的 conf
目錄包含一個名為 gitolite.conf
的檔案。在文字編輯器中開啟它,或使用 cat
檢視其內容:
repo gitolite-admin RW+ = id_ed22519repo testing RW+ = @all
你可能對該組態檔的功能有所了解:gitolite-admin
代表此儲存庫,並且 id_ed25519
金鑰的所有者具有讀取、寫入和管理 Git 的許可權。換句話說,不是將使用者對映到普通的本地 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/home/desktop/
中。另一個金鑰可能放到 keydir/home/desktop/
中,依此類推。Gitolite 遞回地在 keydir
中搜尋與儲存庫“使用者”相匹配的 .pub
檔案,並將所有匹配項視為相同的身份。
當你將金鑰新增到 keydir
目錄時,必須將它們提交回伺服器。這是一件很容易忘記的事情,這裡有一個使用自動化的 Git 應用程式(例如 Sparkleshare)的真正的理由,因此任何更改都將立即提交給你的 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_ed22519repo testing RW+ = @allrepo widgets RW+ = alice
現在,Alice(也僅有 Alice 一個人)可以克隆該儲存庫:
[alice]$ git clone [email protected]:widgets.gitCloning into 'widgets'...warning: You appear to have cloned an empty repository.
在第一次推播時,Alice 必須使用 -u
選項將其分支傳送到空儲存庫(如同她在任何 Git 主機上做的一樣)。
為了簡化使用者管理,你可以定義儲存庫組:
@qtrepo = widgets@qtrepo = gamesrepo gitolite-admin RW+ = id_ed22519repo testing RW+ = @allrepo @qtrepo RW+ = alice
正如你可以建立組儲存庫一樣,你也可以對使用者進行分組。預設情況下存在一個使用者組:@all
。如你所料,它包括所有使用者,無一例外。你也可以建立自己的組:
@qtrepo = widgets@qtrepo = games@developers = alice bobrepo gitolite-admin RW+ = id_ed22519repo testing RW+ = @allrepo @qtrepo RW+ = @developers
與新增或修改金鑰檔案一樣,對 gitolite.conf
檔案的任何更改都必須提交並推播以生效。
預設情況下,Gitolite 假設儲存庫的建立是從上至下進行。例如,有權存取 Git 伺服器的專案經理建立了一個專案儲存庫,並通過 Gitolite 管理倉庫新增了開發人員。
實際上,你可能更願意向使用者授予建立儲存庫的許可權。Gitolite 稱這些為“野生倉庫(通配倉庫)”(我不確定這是關於倉庫的形成方式的描述,還是指組態檔所需的萬用字元)。這是一個例子:
@managers = alice bobrepo foo/CREATOR/[a-z]..* C = @managers RW+ = CREATOR RW = WRITERS R = READERS
第一行定義了一組使用者:該組稱為 @managers
,其中包含使用者 alice
和 bob
。下一行設定了萬用字元允許建立尚不存在的儲存庫,放在名為 foo
的目錄下的建立該儲存庫的使用者名稱的子目錄中。例如:
[alice]$ git clone [email protected]:foo/alice/cool-app.gitCloning into cool-app'...Initialized empty Git repository in /home/git/repositories/foo/alice/cool-app.gitwarning: You appear to have cloned an empty repository.
野生倉庫的建立者可以使用一些機制來定義誰可以讀取和寫入其儲存庫,但是他們是有範圍限定的。在大多數情況下,Gitolite 假定由一組特定的使用者來管理專案許可權。一種解決方案是使用 Git 掛鉤來授予所有使用者對 gitolite-admin
的存取許可權,以要求管理者批准將更改合併到 master 分支中。
Gitolite 具有比此介紹性文章所涵蓋的更多功能,因此請嘗試一下。其文件非常出色,一旦你通讀了它,就可以自定義 Gitolite 伺服器,以向使用者提供你喜歡的任何級別的控制。Gitolite 是一種維護成本低、簡單的系統,你可以安裝、設定它,然後基本上就可以將其忘卻。