Zentrales Mercurial über HTTP

aus PUG, der Penguin User Group
Wechseln zu: Navigation, Suche

Einleitung

Man kennt das ja, man möchte mal eben mit ein paar Teammitgliedern ein Projekt erstellen, bei dem Dateien über eine Versions- Verwaltungssoftware zentral zur Verfügung gestellt werden sollen. Normalerweise werden dafür Programme verwendet, die einen Dienst mitbringen und so die Verwaltung und Authentifizierung übernehmen.
Mercurial dagegen verfügt zwar über einen eingebauten Webserver, um zumindest das Depot (Repository) schnell über HTTP zu publizieren, doch ist sein Funktionsumfang und Geschwindigkeit eher begrenzt. Des weiteren läuft in vermutlich sehr vielen Fällen bereits ein Apache auf dem selben Rechner. Warum also nicht beides kombinieren?
Ein weiterer Vorteil besteht in dem Zugang zum Depo. Es ist nur HTTP Zugriff nötig und damit entfällt der Shell Zugang. Zwar ließe sich dies ebenfalls umsetzen, mit einem speziell angepassten SSH-Login Wrapper, doch diese Anleitung wird sich auf den Zugang via HTTP beschränken.
Wunderbarerweise gibt es Mercurial nicht nur für Unix Varianten, sondern ebenfalls auch für Windows, sodass auch die Klickbenutzer von einer Versionsverwaltung profitieren.
In diesen Fall beziehe ich mich auf Debian Etch, sollte jedoch ohne Probleme auf andere Distributionen umsetzbar sein.

Installation

Da von Etch Mercurial ein wenig Staub angesetzt hat, habe ich mich dazu entschlossen es aus den Backports aufzufrischen:
  • Erst die Backports dem Etch bekannt machen:
  • /etc/apt/sources.list
Ascii.png
[...]
deb http://www.backports.org/debian etch-backports main contrib non-free
Gnome-terminal.png
# apt-get update
# apt-get install debian-backports-keyring
Nun können Mercurial einspielen:
Gnome-terminal.png
# apt-get -t etch-backports install mercurial

Konfiguration

Mercurial

Wir werden unser Depot auf dem zentralen Server unter /var/depos/projekt1/daten zur Verfügung stellen. Dazu erstellen wir erst einmal die Ordner:
Gnome-terminal.png
# mkdir -p /var/depos/projekt1/daten
Als nächstes kopieren wir eine Datei in den Ordner, welche bei der Installation von Mercurial automatisch mitgeliefert wird. Diese Datei ruft Python- spezifische Funktionen auf und stellt später unser Depot über HTTP übersichtlich dar:
Gnome-terminal.png
# cp /usr/share/doc/mercurial/examples/hgweb.cgi /var/depos/projekt1/index.cgi
# chmod +x /var/depos/projekt1/index.cgi
Wir sich sehen lässt, muss unser Webserver also CGI Scripte unterstützen. Für einen Apachen eine Kleinigkeit ;-)
Weiterhin muss der Inhalt der Datei angepasst werden:
  • /var/depos/projekt1/index.cgi
Ascii.png
#!/usr/bin/env python

import cgitb
cgitb.enable()

#import os
# os.environ["HGENCODING"] = "UTF-8"

from mercurial.hgweb.hgweb_mod import hgweb
from mercurial.hgweb.request import wsgiapplication
import mercurial.hgweb.wsgicgi as wsgicgi

def make_web_app():
    return hgweb("/var/depos/projekt1/daten/", "Projekt1")

wsgicgi.launch(wsgiapplication(make_web_app))
Wie zu erkennen ist, haben wir den Pfad in dieser Datei hinterlegen müssen, wo sich später unser Depot befindet. Hier also /var/depos/projekt1/daten/.
Als nächstes müssen wir natürlich das Verzeichnis mit dem Kommando hg initialisieren:
Gnome-terminal.png
# hg init /var/depos/projekt1/daten
Es wird ein verstecktes Verzeichnis .hg im /var/depos/projekt1/daten erzeugt. Innerhalb dieses Verzeichnisses legen wir eine Konfigurationsdatei hgrc an, über welche wir verschiedene Dinge kontrollieren können.
Ascii.png
[web]
description = Unser Projekt 1
author = Major Motoko Kusanagi <projectleader@section9.anime>
allow_archive = gz bz2 
push_ssl = false
# allow_push = bartou, kusanagi
allow_push = *

[web]
style = gitweb 
Wie zu erkennen ist, können wir hier eine Beschreibung einfügen, den Autor, welche Archivtypen zur Verfügung stehen um Dateien herunterzuladen etc. pp.
Eine Besonderheit ist hier push_ssl =false. Normalerweise erzwingt Mercurial SSL für die Übertragung, wenn aber, wie in diesem Fall, der Webserver kein SSL liefern kann, dann können wir mit dieser Funktion SSL deaktivieren.
Mit allow_push = * erlauben wir zunächst einmal jedem Dateien zu laden und hoch zu laden. Für die ersten Tests können wir dies zunächst so belassen.
Da später der Webserver in dieses Verzeichnis schreiben muss, benötigt er dazu noch die passenden Rechte. Dazu können entweder die Standard Methoden genutzt werden, oder ACL.
  • Mit ACL
Gnome-terminal.png
# setfacl -m group:www-data:rwx /var/depos/projekt1/daten
# setfacl -d -m group:www-data:rwx /var/depos/projekt1/daten
Messagebox info.png

Natürlich müssen die ACL Werkzeuge installiert worden sein, und das Dateisystem muss ACL unterstützen. Bei XFS ist dies immer der Fall, bei anderen muss geprüft werden: mount -o remount,acl / . Wobei "/" natürlich durch das Jeweilige Verzeichnis ersetzt werden muss, wo /var liegt. Ansonsten verrät "mount" ob ACL enthalten ist. Wenn nicht, in der /etc/fstab dies nachtragen.


  • Ohne ACL
Gnome-terminal.png
# chown www-data:www-data  -R /var/depos/projekt1/daten
# chmod 775 /var/depos/projekt1/daten
# chmod g+s /var/depos/projekt1/daten
Eigentlich ist es überflüssig, dafür zu sorgen, dass die neu erstellten Dateien dem User www-data überstellt werden, doch ich habe zumeist die schlechte Angewohnheit Dateien als Root zu erstellen, und vergesse später die Rechte zu ändern und ärgere mich darüber, dass der Webserver nicht schreiben kann. Ihr könnt also die jeweils zweite Zeile auch ignorieren ;-)

Apache

Nun folgt der Apache Teil. Dieser Teil ist eher schwammig zu beschreiben. Denn je nachdem wie euer Apache konfiguriert wurde, könnt ihr entweder einen kompletten Vhost erstellen, oder eben zu einem bestehenden Vhost das neue Verzeichnis hinzufügen.
Wie dem Auch sei, dort sollte folgendes enthalten sein:
Ascii.png
ScriptAlias /hg/ /var/depos/projekt1/
<Directory "/var/depos/projekt1/">
     Order allow,deny
     Allow from all
     AllowOverride All
     AddHandler cgi-script .cgi
</Directory>
Unser Depot wird später damit unter http://foo.domain.anime/hg/ (Wichtig, der / am Ende) erreichbar sein. Den Rest erledigen wir per .htaccess. Diese muss im selben Verzeichnis liegen, wie die index.cgi und enthält folgendes:
Ascii.png

Options +ExecCGI
RewriteEngine On
RewriteBase /hg
RewriteRule ^$ index.cgi  [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.cgi/$1  [QSA,L]

# Für unsere spätere Benutzerauthentifizierung:

# AuthUserFile /etc/apache2/depot-pass
# AuthGroupFile /dev/null
# AuthName "Projekt1"
# AuthType Basic
# <LimitExcept GET>
# Require valid-user
# </LimitExcept>

Da wir in der .htaccess definiert haben, dass nur authentifizierte Benutzer die Funktion GET aufrufen dürfen, benötigen wir dazu ebenfalls eine Passwortdatei. Sie auf jeden Fall außerhalb des Verzeichnisses liegen, welches wir nach außen freigeben. Dazu bietet sich z.B. /etc/apache2 an:
Gnome-terminal.png

# htpasswd -c /etc/apache2/depot-pass batou
<passwort>
# chown www-data /etc/apache2/depot-pass
# chmod 440 /etc/apache2/depo-pass
# htpasswd /etc/apache2/depot-pass kusanagi

Ist dies geschehen, sollte vor einem Apache reload in jedem Fall die Konfiguration überprüft werden:
Gnome-terminal.png
# apache2ctl -t
Syntax OK
# apache2ctl -k graceful
Oder auch:
# /etc/init.d/apache2 reload
Hat auch das geklappt, ist unter http://foo.domain.anime/hg/ eine Webseite zu sehen, die noch nicht allzuviel enthält.

Depot

Depot hochladen

Um nun ein lokales Mercurial Depot von daheim hoch zu laden, sollte zuvor noch eine .hgrc im Heimatverzeichnis erstellt werden:
  • User Kusanagi
Gnome-terminal.png
$ echo -e "[ui] \nusername = Major Moko Kusanagi <projectleader@section9.anime>" > ~/.hgrc
Nun können wir das Depot hochladen:
Gnome-terminal.png
$ cd lokales_projekt1
$ hg ci -m "Erstes Initialisieren"
$ hg push http://foo.domain/hg/
Ein erneuter Blick auf die Webseite sollte nun das gewünschte Ergebnis zeigen.

Depot Klonen

Damit andere das Depot herunterladen können, genügt folgende Zeile:
  • User Batou
Gnome-terminal.png
$ hg clone http://foo.domain.anime/hg/
Damit entsteht lokal ein neues Verzeichnis und darin enthalten sind alle Dateien aus dem Depot.

Arbeiten und hochladen

  • User Batou
Wurden Änderungen lokal vorgenommen, können diese natürlich auch wieder nach dem hg commit hoch geladen werden:
Gnome-terminal.png
$ hg ci -m "Batou hatte eine Idee zum Aendern"
$ hg push
Mercurial merkt sich den Pfad, wo er die Dateien bezogen hat und somit muss nichts mehr angegeben werden. Sollte dies mal nicht so sein, wie im folgenden Fall, lässt sich dies ändern:
  • User Kusanagi
  • ~/lokales_projekt1/.hg/hgrc
Ascii.png
[paths]
default = http://foo.domain.anime/hg/
default-push = http://foo.domain.anime/hg/
Wir erstellen also eine .hgrc in unserem Mercurial Verzeichnis, und tragen dort ein, wo sein Standard Depot ist. Nun brauchen wir fortan nicht mehr die Adresse einzutragen.
Gnome-terminal.png
$ hg pull
$ hg update
Hat alles geklappt, genügt es nun für die Benutzer- Authentifizierung die entsprechenden Zeilen von den Kommentarzeichen zu befreien.
Um nicht jedesmal den Benutzernamen und das Kennwort eintragen zu müssen, kann man dies auch gleich in die .hgrc schreiben:
  • ~/lokales_projekt1/.hg/hgrc
Ascii.png
[paths]
default = http://batou:Geheim@domain.foo.anime/hg/

Quellen

http://www.selenic.com/mercurial/wiki/index.cgi/PublishingRepositories - Die Original Englische Anleitung http://www.selenic.com/mercurial/wiki/index.cgi/ServerInstall


--Denny 14:53, 18. Nov. 2007 (CET)