Git-Repositories ohne Root-Rechte hosten mit Gitolite
Über die Vorzüge von Git brauche ich an dieser Stelle nicht viele Worte verlieren. Das verteilte Versionkontrollsystem ist bei der Software-Entwicklung ein äußerst nützliches Werkzeug. Ein Server ist dabei nicht unbedingt notwendig, um es zu verwenden. Aber ein zentrales Repository, das immer erreichbar ist, hat durchaus einige Vorteile. In diesem Artikel möchte ich zeigen, wie einfach es ist, für einzelne Benutzer oder für Gruppen Repositories auf einem Server zu hosten. Und das Beste dabei ist: mehr als einen SSH-Zugang mit einfachen Benutzerrechten braucht man dazu nicht!
Im Folgenden gehen wir davon aus, dass ein SSH-Zugang mit dem Benutzernamen “benutzer” auf dem Server “server” vorhanden ist.
Einzelne Benutzer
Möchte man ganz allein an einem Repository arbeiten, so ist die
Einrichtung besonders simpel. Es reicht aus, auf dem Server mit git
init --bare repo.git
1 ein “nacktes” Repository zu erzeugen,
also ein Repository das keine Arbeitsverzeichnis enthält. Unter der
Annahme, dass der vorhergehende Befehl im Verzeichnis $HOME/git des
Servers ausgeführt wurde, kann auf der lokalen Maschine jetzt mittels
git clone benutzer@server:git/repo.git
ein Klon des Repositories
erstellt werden. Mit git push
und git pull
Änderungen zwischen
lokalem und entferntem Repository übermittelt werden.
Gruppen
Nehmen wir nun an, dass wir auch anderen Personen lesenden oder schreibenden Zugriff auf ein oder mehrere Repositories gewähren wollen. Außerdem nehmen wir an, dass wir diesen Personen nur den Zugriff auf die Repositories nicht aber auf unser komplettes Benutzerkonto gestatten wollen. Ohne die notwendigen Rechte, um eigens dafür eine Unix-Gruppe zu erstellen, scheint das Problem nur schwierig zu lösen zu sein. Doch dank gitolite kann man einen anderen Weg gehen. Neben Git muss der Server dazu nur zwei Voraussetzungen erfüllen:
- der Server muss SSH-Authentifizierung mittels Schlüsselpaar erlauben, und
- es muss ein Perl-Interpreter vorhanden sein.
Beides sollte unter den meisten Unix-Systemen gegeben sein.
Kurz zur Funktionsweise von Gitolite. SSH erlaubt die Authentifizierung mittels Schlüsselpaar. Gitolite nutzt diesen Mechanismus, um am Schlüssel zu erkennen, welcher Gitolite-Benutzer sich einloggt. Gitolite erlaubt dabei aber den Benutzern nur den Zugriff auf die Git-Repositories nicht auf den vollständigen Benutzer-Account.
Gitolite einrichten
Als erstes erstellen wir auf dem lokalen Rechner ein SSH-Schlüsselpaar.
Dazu wird das Kommando ssh-keygen
verwendet. Die Voreinstellung für
den Dateinamen kann man mit Return bestätigen. Es ist ratsam eine gute
Passphrase zu verwenden2. Den öffentlichen Teil des soeben
erzeugten Schlüsselpaares kopiert man nun auf den Server. Der Name der
Datei auf dem Server kann dabei frei gewählt werden, und entspricht dem
Namen unter dem Gitolite den Benutzer später kennen wird (hier:
“alice”).
scp $HOME/.ssh/id_rsa.pub benutzer@server:alice.pub
Nun loggen wir uns auf dem Server ein und stellen mittels echo $PATH
sicher, dass der Ordner bin
im Homeverzeichnis existiert und Teil des
Suchpfads für ausführbare Dateien ist. Falls nicht:
mkdir $HOME/bin
export PATH=$HOME/bin:$PATH
Damit die Änderung von $PATH
auch nach dem Schließen des Terminals
oder dem Ausloggen erhalten bleibt, trägt man die zweite Zeile außerdem
in die Datei $HOME/.profile
oder $HOME/.bashrc
ein.
Nun wird Gitolite installiert und initialisiert. Hier im Beispiel wird
Gitolite in das Verzeichnis $HOME/src/gitolite
installiert.
mkdir $HOME/src
cd $HOME/src
git clone git://github.com/sitaramc/gitolite
gitolite/install -ln
cd $HOME
gitolite setup -pk alice.pub
Falls vorher schon der selbe SSH-Schlüssel zur Anmeldung verwendet
wurden, wird nach der Eingabe des letzten Befehls eventuell eine Warnung
angezeigt. Der Grund ist, dass der Schlüssel nun doppelt in der Datei
$HOME/.ssh/authorized_keys
vorhanden ist. Falls dies der Fall ist,
sollte der entsprechende alte Eintrag entfernt werden. ACHTUNG: Mit
dem Schlüssel ist dann aber keine Anmeldung mehr mit vollem
Shell-Zugriff möglich, es sei denn der folgende Schritt wird ausgeführt.
Einem Gitolite-Nutzer Shell-Zugriff erlauben
Dem Gitolite-Nutzer (hier “alice”) dem der eigentliche SSH-Zugang gehört, sollte man vollen Zugriff auf den (Unix-)Nutzeraccount gewähren. Dazu wird zunächst der Befehl `echo alice
$HOME/.gitolite.shell-users
ausgeführt. Dann wird an zwei Stellen die Datei
$HOME/.gitoliterc` bearbeitet. Die erste Stelle ist die folgende Zeile:
# SHELL_USERS_LIST => "$ENV{HOME}/.gitolite.shell-users",
Hier wird das Zeichen # entfernt. Die zweite Stelle sieht so aus:
# give some users direct shell access
# 'Shell',
Auch hier wird in der zweiten Zeile das # entfernt. Anschließend muss
noch der Befehl gitolite compile; gitolite trigger POST_COMPILE
ausgeführt werden.
Administration von Gitolite
Damit ist die Einrichtung von Gitolite abgeschlossen. Nun stellt sich die Frage, wie man weitere Benuter und Repositories hinzufügt. In Gitolite wird die gesamte Administration über ein dafür bei der Initialisierung erzeugtes Repository abgewickelt. Auf dem lokalen Rechner wird dieses daher erst mal geklont:
git clone benutzer@server:gitolite-admin.git
In diesem Repository befinden sich zwei Unterverzeichnisse, conf
und
keydir
. Benutzer kann man nun einfach hinzufügen, indem man deren
öffentliche Schlüssel nach keydir
kopiert und sie nach dem Schema
name.pub
benennt.
Um Repositories hinzuzufügen muss die Datei conf/gitolite.conf
bearbeitet werden. Ein Beispieleintrag sähe folgendermaßen aus:
``` text gitolite-admin/conf/gitolite.conf repo foo RW+ = alice R = bob RW = eve
In diesem Beispiel hat Alice darf lesen, schreiben und Rewinds
durchführen; Bob darf nur lesen; Eve darf lesen und schreiben, aber
keine Rewinds durchführen.
Nachdem Änderungen durchgeführt wurden, müssen diese committet werden und
auf den Server gepusht werden. Erst dann werden sie wirksam und hier im
Beispiel wird das Repository foo erstellt. Anschließend kann etwa Eve
mit
``` bash
git clone benutzer@server:foo.git
das Repository klonen. Wobei der Unix-Benuter “benutzer” für alle Gitolite-Benutzer der selbe ist.