15 KiB
Anhang: Installation von Sourcehut
Da ich im Internet keine vollständige Installationsanleitung für Sourcehut gefunden habe, beschreibe ich hier den vollständigen Installationsvorgang für meine Testinstanz.
Ich habe Sourcehut wie vom Entwickler empfohlen auf einer Alpine-Linux-VM installiert. Die Sourcehut-Pakete werden auch für Arch und Debian (Sid) angeboten.
Alle aufgelisteten Befehle müssen als Root-User ausgeführt werden, sofern es nicht anders beschrieben ist.
Sourcehut-Repo
Zuerst muss das Sourcehut-Repository zum Paketmanager des Systems hinzugefügt werden. Die URLs für verschiedene Distributionen sind in der Dokumentation des Projekts angegeben.
echo "https://mirror.sr.ht/alpine/v3.17/sr.ht" > /etc/apk/repositories
wget -q -O /etc/apk/keys/alpine@sr.ht.rsa.pub https://mirror.sr.ht/alpine/alpine@sr.ht.rsa.pub
apk update
Grundlegende Dienste
Zu Beginn müssen die grundlegenden Dienste eingerichtet werden: die Postgres-Datenbank, Redis und ein Nginx-Webserver, der als Reverse Proxy zwischen dem Nutzer und den einzelnen Diensten steht.
Beim Einrichten der Dienste ist zu beachten, dass Alpine Linux OpenRC anstelle des systemd-Init-Systems verwendet und alle neu installierten Dienste manuell aktiviert und gestartet werden müssen.
apk add postgresql redis nginx
rc-service postgresql setup
rc-update add postgresql
rc-service postgresql start
rc-update add nginx
rc-update add redis
rc-service nginx start
rc-service redis start
Wenn Postgres läuft, kann man die Datenbanken und Nutzer für die einzelnen Dienste erstellen.
su postgres
psql
CREATE USER meta WITH PASSWORD '1234';
CREATE DATABASE "meta.sr.ht";
ALTER DATABASE "meta.sr.ht" OWNER TO meta;
GRANT ALL PRIVILEGES ON DATABASE "meta.sr.ht" TO meta;
CREATE USER hub WITH PASSWORD '1234';
CREATE DATABASE "hub.sr.ht";
ALTER DATABASE "hub.sr.ht" OWNER TO hub;
GRANT ALL PRIVILEGES ON DATABASE "hub.sr.ht" TO hub;
CREATE USER git WITH PASSWORD '1234';
CREATE DATABASE "git.sr.ht";
ALTER DATABASE "git.sr.ht" OWNER TO git;
GRANT ALL PRIVILEGES ON DATABASE "git.sr.ht" TO git;
CREATE USER man WITH PASSWORD '1234';
CREATE DATABASE "man.sr.ht";
ALTER DATABASE "man.sr.ht" OWNER TO man;
GRANT ALL PRIVILEGES ON DATABASE "man.sr.ht" TO man;
CREATE USER todo WITH PASSWORD '1234';
CREATE DATABASE "todo.sr.ht";
ALTER DATABASE "todo.sr.ht" OWNER TO todo;
GRANT ALL PRIVILEGES ON DATABASE "todo.sr.ht" TO todo;
CREATE USER lists WITH PASSWORD '1234';
CREATE DATABASE "lists.sr.ht";
ALTER DATABASE "lists.sr.ht" OWNER TO lists;
GRANT ALL PRIVILEGES ON DATABASE "lists.sr.ht" TO lists;
CREATE USER paste WITH PASSWORD '1234';
CREATE DATABASE "paste.sr.ht";
ALTER DATABASE "paste.sr.ht" OWNER TO paste;
GRANT ALL PRIVILEGES ON DATABASE "paste.sr.ht" TO paste;
CREATE USER builds WITH PASSWORD '1234';
CREATE DATABASE "builds.sr.ht";
ALTER DATABASE "builds.sr.ht" OWNER TO builds;
GRANT ALL PRIVILEGES ON DATABASE "builds.sr.ht" TO builds;
Alle Sourcehut-Dienste werden über eine einzige Datei unter /etc/sr.ht/config.ini
konfiguriert. Sourcehut stellte jedoch keine vollständige Beispielkonfiguration bereit,
weswegen ich meine Konfiguration aus den einzelnen Repositories zusammenkopieren musste.
- https://git.sr.ht/~sircmpwn/meta.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/hub.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/git.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/man.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/paste.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/builds.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/todo.sr.ht/tree/master/item/config.example.ini
- https://git.sr.ht/~sircmpwn/lists.sr.ht/tree/master/item/config.example.ini
Folgende Optionen müssen angepasst werden:
- Die Domains/URLs der Webseiten (in meiner Beispielkonfiguration
*.codeforge.int). - Datenbank-URLs/Passwörter (Option:
connection-string) - GPG-Keys (ein GPG-Schlüsselpaar ohne Passwort erstellen und unter
mail/pgp-privkey,mail/pgp-pubkeyundmail/pgp-key-idangeben) service-key,network-key,webhooks/private-key(siehe meta.sr.ht)- OAuth-Client-IDs/Secrets (siehe meta.sr.ht)
Anschließend kann man Nginx so konfigurieren, dass Web-Anfragen an die einzelnen Dienste weitergeleitet werden können. Eine Nginx-Beispielkonfiguration findet sich in diesem Repository auf Sourcehut.
Hier befindet sich die angepasste Version (ohne HTTPS), die ich für meine Testinstallation verwendet habe.
Noch ein Hinweis für Testinstallationen mit internen Domains: Die konfigurierten Domains/URL müssen auf der Maschine, auf der Sourcehut läuft, erreichbar sein. Eventuell müssen diese Domains also in die /etc/hosts-Datei eingetragen werden. Ansonsten funktioniert die OAuth-Authentifizierung sowie das CI-System nicht.
Sourcehut-Dienste
Jede einzelne Sourcehut-Anwendung (git.sr.ht, builds.sr.ht, todo.sr.ht, etc) besteht aus mehreren Diensten. Dazu zählen das Python-Webfrontend, ein in Go geschriebener API-Server und eventuell noch zusätzliche Dienste wie eine Task Queue.
Die Einrichtung einer Sourcehut-Anwendung erfordert folgende Schritte
- Installation des Pakets
- Initialisierung der Datenbank mit dem Skript
<service>-initdb - Starten der Dienste
Bei einigen Diensten sind noch zusätzliche Konfigurationsanpassungen notwendig.
meta.sr.ht
- Web-UI: Port 5000
- API: Port 5100
meta.sr.ht ist der Dienst zur Nutzerverwaltung und Authentisierung und muss deswegen zuerst installiert werden.
# Paket installieren
apk add meta.sr.ht
# Datenbank initialisieren
metasrht-initdb
# Schlüssel erzeugen und in die Konfigurationsdatei eintragen
# [sr.ht] > service-key
srht-keygen service
# [sr.ht] > network-key
srht-keygen network
# [webhooks] > private-key
srht-keygen webhook
# Dienste starten
rc-update add meta.sr.ht
rc-update add meta.sr.ht-api
rc-update add meta.sr.ht-webhooks
rc-service meta.sr.ht start
rc-service meta.sr.ht-api start
rc-service meta.sr.ht-webhooks start
# Admin-Benutzer erstellen
metasrht-manageuser -t admin -e thetadev@example.com thetadev
# Cronjob hinzufügen
crontab -e
0 0 * * * metasrht-daily
Die einzelnen Sourcehut-Dienste verwenden OAuth zur Authentifizierung der Nutzer. Jeder
Dienst muss hierfür über eine eigene Client-Konfiguration verfügen. Diese lässt sich
über das (Legacy) OAuth-Dashboard unter meta.<Sourcehut-Domain>/oauth erstellen.
Als Base Redirect URI trägt man die URL des Dienstes mit dem Pfad oauth/callback
ein. Beispiel: https://git.codeforge.int/oauth/callback.
Die Client-ID und das Client-Secret, das auf der nächsten Seite angezeigt wird, können
nun in die Konfigurationsdatei unter [<service>.sr.ht]/oauth-client-id und
[<service>.sr.ht]/oauth-client-secret eingetragen werden.
Standardmäßig verlangt Sourcehut nach einer manuellen Einwilligung für die Nutzung eines
OAuth-Diensts. Um die internen Sourcehut-Dienste als vertrauenswürdig zu markieren und
den Einwilligungsbildschirm für neue Nutzer zu deaktivieren, muss man eine manuelle
Änderung an der Datenbank vornehmen und das Feld preauthorized für die entsprechenden
OAuth-Clients auf true setzen.
su postgres
psql
\c "meta.sr.ht"
UPDATE oauthclient SET preauthorized=true;
hub.sr.ht
hub.sr.ht fungiert als Startseite für Sourcehut. Hier kann man Projekte erstellen, suchen und aufrufen.
- Web-UI: Port 5014
- API: Port 5114
# hub.src.ht (Port: 5014, API-Port: 5114)
apk add hub.sr.ht
hubsrht-initdb
rc-update add hub.sr.ht
rc-update add hub.sr.ht-api
rc-service hub.sr.ht-api start
rc-service hub.sr.ht start
git.sr.ht
git.sr.ht ist der eigentliche Git-Hosting-Dienst. Sourcehut bietet auch einen Dienst für das Versionskontrollsystem Mercurial an, diesen habe ich jedoch nicht getestet.
- Web-UI: Port 5001
- API: Port 5101
# Abhängigkeiten für git-http server installieren
apk add git-sr.ht fcgiwrap git-daemon
gitsrht-initdb
Diese Zeilen müssen zur /etc/ssh/sshd_config hinzugrfügt werden. Dadurch kann der
SSH-Server Nutzer anhand der auf Sourcehut hinterlegten SSH-Zugangsdaten
authentifizieren.
AuthorizedKeysCommand=/usr/bin/gitsrht-dispatch "%u" "%h" "%t" "%k"
AuthorizedKeysCommandUser=root
PermitUserEnvironment SRHT_*
Da SSH den Login von Nutzern mit nicht gesetztem Passwort verbietet, muss der Account
git mit einem beliebigen Passwort versehen werden.
Anschließend muss noch eine Logdatei für das Skript gitsrht-shell, dass bei einer
SSH-Verbindung aufgerufen wird, erstellt werden.
touch /var/log/gitsrht-shell
chown git:git /var/log/gitsrht-shell
Nachdem alles konfiguriert wurde, kann man den Dienst starten und das Skript
gitsrht-periodic in den crontab eintragen.
rc-update add fcgiwrap
rc-update add git.sr.ht
rc-update add git.sr.ht-api
rc-update add git.sr.ht-webhooks
rc-service fcgiwrap start
rc-service git.sr.ht-webhooks start
rc-service git.sr.ht-api start
rc-service git.sr.ht start
# Cronjob hinzufügen:
*/20 * * * * gitsrht-periodic
man.sr.ht
- Web-UI: Port 5004
- API: Port 5104
man.sr.ht ist ein Git-gestütztes Wiki. Der Dienst hängt von git.sr.ht zur Verwaltung der Repositories ab.
apk add man.sr.ht
mansrht-initdb
rc-update add man.sr.ht
rc-update add man.sr.ht-api
rc-service man.sr.ht-api start
rc-service man.sr.ht start
paste.sr.ht
- Web-UI: Port 5011
- API: Port 5111
paste.sr.ht ist ein simpler Pastebin, mit dem man Codeschnipsel speichern und veröffentlichen kann.
apk add paste.sr.ht
pastesrht-initdb
rc-update add paste.sr.ht
rc-update add paste.sr.ht-api
rc-service paste.sr.ht-api start
rc-service paste.sr.ht start
builds.sr.ht
- Web-UI: Port 5002
- API: Port 5102
builds.sr.ht ist der Continuous-Integration-Dienst von Sourcehut.
Da der Dienst KVM zur Virtualisierung verwendet, muss auf dem Hostsystem Nested virtualization aktiviert werden, sollte der Dienst selbst in einer KVM-gestützten virtuellen Maschine installiert werden: https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/
builds.sr.ht besteht aus zwei Komponenten: dem Master-Server und dem Worker. Der Master-Server verwaltet die Builds, die Worker führen sie aus. Aus Sicherheitsgründen wird empfohlen, die Worker auf einem seperaten System zu installieren. Bei meiner Testinstallation habe ich jedoch beide Komponenten auf dem selben System installiert.
Zuerst installiert man die erforderlichen Pakete und initialisiert die Datenbank:
# Master-Server
apk add builds.sr.ht
# Worker-Server
builds.sr.ht-worker builds.sr.ht-images
buildsrht-initdb
Der Nutzer builds muss genauso wie der git-Nutzer mit einem beliebigen Password
versehen werden, um den SSH-Zugriff auf fehlgeschlagene Builds zu ermöglichen.
Anschließend kann man den Master-Server starten
rc-update add builds.sr.ht
rc-update add builds.sr.ht-api
rc-service builds.sr.ht-api start
rc-service builds.sr.ht start
Der Worker benutzt standardmäßig eine QEMU-Installation in einem Docker-Container, um die Build-VMs zu betreiben. Deswegen muss man zuerst Docker installieren und starten.
Zusätzlich sollte man einen neuen Benutzer mit dem Namen docker anlegen und der
Docker-Gruppe hinzufügen. Dann konfiguriert man sudo so, dass der builds-Nutzer das
/var/lib/images/control-Skript zum Start der Buildmaschinen als docker-Nutzer
aufrufen kann. Auf diese Weise muss man dem Build-Nutzer keine vollen Root- oder
Docker-Rechte geben.
apk add docker
rc-update add docker
rc-service docker start
sudo adduser -SDH docker docker
visudo
# Diese Zeile in die sudoers-Datei eintragen
builds ALL=(docker) NOPASSWD: /var/lib/images/control
cd /var/lib/images
docker build -t qemu qemu/Dockerfile .
Als nächstes muss man die VM-Images bauen. Im Ordner /var/lib/images befinden sich
Skripte für eine Vielzahl von Betriebssystemen und CPU-Architekturen.
Ich habe zum Testen das Alpine 3.17-Image in einem Docker-Container gebaut. Dazu musste
ich zunächst eine kleine Annpassung am Buildskript vornehmen. Das Skript unter
/var/lib/images/alpine/genimg enthält den Befehl modprobe nbd max_part=16, der in
einem Docker-Container nicht ausgeführt werden kann. Dieser Befehl muss deshalb
auskommentiert werden und stattdessen vorher auf dem Hostsystem ausgeführt werden.
Anschließend kann man das Image bauen:
modprobe nbd max_part=16
docker run -it --rm --privileged -v /var/lib/images:/images alpine:3.17
# Im Docker-Container
cd /images/alpine/3.17
apk add qemu-img sfdisk syslinux e2fsprogs
./genimg
Mit der Datei /etc/image-control.conf kann der Worker konfiguriert werden
(zugewiesener Arbeitsspeicher, Methode der Virtualisierung).
MEMORY=4096
default_means=docker
Nachdem der Worker konfiguriert wurde, kann man ihn mit dem Skript
/var/lib/images/control testen.
Hinweis: wenn der Container nicht startet, sollte man prüfen, ob das System genug RAM zum Start der VM zur Verfügung hat.
./control alpine/latest boot x86_64 12345
docker ps # Prüfen, ob der Container gestartet wurde
# Über die SSH-Verbindung kann man nun Befehle auf der Build-VM ausführen
ssh -p 12345 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no build@localhost
./control alpine/latest cleanup 12345
Jetzt kann der Worker gestartet werden:
# Start worker
rc-update add builds.sr.ht-worker
rc-service builds.sr.ht-worker start
todo.sr.ht
- Web-UI: Port 5003
- API: Port 5103
apk add todo.sr.ht
Im Gegensatz zu den anderen Diensten konnte ich die Datenbank für den todo-Dienst nicht
mit todosrht-initdb erfolgreich initialisieren. Offenbar fehlten in diesem Skript
bestimmte Datenbankobjekte, sodass die Anwendung Fehler lieferte. Stattdessen habe ich
die schema.sql-Datei aus dem sourcehut-Repository verwendet.
wget "https://git.sr.ht/~sircmpwn/todo.sr.ht/blob/master/schema.sql"
psql -U todo -d todo.sr.ht -f schema.sql
todo-migrate stamp head
Anschließend können die Dienste gestartet werden.
Hinweis: Der LMTP-Dienst ist dafür da, E-Mails zu empfangen, sodass man auf Issues per Mail antworten kann. Hierfür ist ein Mailserver nötig, weswegen ich diesen Dienst in meiner Testinstallation nicht vollständig konfigurieren konnte.
rc-update add todo.sr.ht
rc-update add todo.sr.ht-api
rc-update add todo.sr.ht-lmtp
rc-update add todo.sr.ht-webhooks
rc-service todo.sr.ht-webhooks start
rc-service todo.sr.ht-lmtp start
rc-service todo.sr.ht-api start
rc-service todo.sr.ht start
lists.sr.ht
- Web-UI: Port 5006
- API: Port 5106
lists.sr.ht ist der Mailingslisten-Dienst für Sourcehut. Mangels eines eigenen Mailservers konnte ich diesen Dienst in meiner Test-VM nicht einrichten.
Eine Anleitung für die Mail-Konfiguration findet sich hier: https://man.sr.ht/lists.sr.ht/configuration.md
listssrht-initdb
rc-update add lists.sr.ht
rc-update add lists.sr.ht-api
rc-update add lists.sr.ht-lmtp
rc-update add lists.sr.ht-process
rc-update add lists.sr.ht-webhooks
rc-service lists.sr.ht-webhooks start
rc-service lists.sr.ht-process start
rc-service lists.sr.ht-lmtp start
rc-service lists.sr.ht-api start
rc-service lists.sr.ht start

