diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 7f0e733..2335fd5 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -11,5 +11,8 @@
# Selfhosting von Open-Source-Entwicklertools
- [Einleitung](./studienarbeit/1_einleitung.md)
-- [Sourcehut](./studienarbeit/3_sourcehut.md)
+- [GitLab](./studienarbeit/2_gitlab.md)
+- [Gitea](./studienarbeit/3_gitea.md)
+- [Sourcehut](./studienarbeit/4_sourcehut.md)
+- [OneDev](./studienarbeit/5_onedev.md)
- [Anhang: Sourcehut-Setup](./studienarbeit/sourcehut_setup.md)
diff --git a/src/studienarbeit/1_einleitung.md b/src/studienarbeit/1_einleitung.md
index b1932df..93b1d53 100644
--- a/src/studienarbeit/1_einleitung.md
+++ b/src/studienarbeit/1_einleitung.md
@@ -1,26 +1,48 @@
# Selfhosting von Open-Source-Entwicklertools
-Um effizient an Open-Source-Projekten arbeiten zu können,
+Um effizient mit anderen Entwicklern an Open-Source-Projekten arbeiten zu können, muss
+man den Quellcode seines Projekts veröffentlichen, Aufgaben koordinieren und neue
+Codebeiträge entgegen nehmen.
-Der bekannteste Anbieter hierfür ist GitHub. Die Plattform wurde von Tom Preston-Werner,
-Chris Wanstrath, P. J. Hyett and Scott Chacon gegründet und ging 2008 ans Netz. 2018
-wurde die Firma von Microsoft übernommen.
+Hierbei kommt fast immer eine Git-Hosting-Plattform zum Einsatz. Diese erlaubt es einem,
+sein Repository zu veröffentlichen und mit anderen Personen über das Internet
+zusammenzuarbeiten. Andere Nutzer und Entwickler können Softwarefehler melden,
+Vorschläge für neue Features machen und neuen Code zum Projekt beitragen.
-Zum einen ist man bei der Nutzung eines fremden Online-Diensts, insbesondere wenn dieser
-kostenlos ist und man deswegen keinen Vertrag mit dem Anbieter abgeschlossen hat,
-komplett von dessen Entscheidungen und Nutzungsbedingungen abhängig. Der Anbieter kann
-den Dienst einstellen, kostenpflichtig machen oder bestimmte Nutzer ausschließen.
+Der meistgenutzte Git-Hosting-Anbieter ist GitHub. Die Plattform wurde von Tom
+Preston-Werner, Chris Wanstrath, P. J. Hyett and Scott Chacon gegründet und ging 2008
+ans Netz. 2018 wurde die Firma von Microsoft übernommen.
+
+Der große Vorteil von GitHub ist, dass der Dienst für öffentliche Projekte vollkommen
+kostenlos ist. Zudem hat der Dienst mit 100 Millionen Nutzern die mit Abstand größte
+Community an potenziellen Beitragenden.
+
+GitHub bietet auch einen Continuous-Integration-Dienst namens GitHub Actions an, mit dem
+man sein Projekt automatisch testen und veröffentlichen lassen kann. Im Gegensatz zu
+vielen Konkurrenzanbietern setzt GitHub hierbei kein Nutzungslimit bei öffentlichen
+Repositories.
+
+Allerdings hat die Nutzung von GitHub auch seine Nachteile. Zum einen ist man bei der
+Nutzung eines fremden Webdiensts, insbesondere wenn dieser kostenlos ist und man
+deswegen keinen Vertrag mit dem Anbieter abgeschlossen hat, komplett von dessen
+Entscheidungen und Nutzungsbedingungen abhängig. Der Anbieter kann den Dienst
+einstellen, kostenpflichtig machen, Features entfernen oder bestimmte Nutzer
+ausschließen.
Beispielsweise wurde der russische Webentwickler Nikolay Kuchumov wegen eines einzigen
beleidigenden Issues
[2020 auf GitHub gesperrt](https://medium.com/@catamphetamine/how-github-blocked-me-and-all-my-libraries-c32c61f061d3).
-Dabei wurden alle seine Repositories entfernt. Noch absurder: GitHub verlangte eine
-Kopie seines Personalausweis um die Sperre wieder aufzuheben.
+Dabei wurden alle seine Repositories von der Plattform entfernt. Noch absurder: GitHub
+verlangte eine Kopie seines Personalausweis um die Sperre wieder aufzuheben.
-Es gibt auch zahlreiche Bespiele von Open Source-Projekten, die von GitHub wegen
-Verstößen gegen ihre Nutzungsbedingungen oder DMCA-Reports gesperrt wurden. Das
-prominenteste Beispiel hierfür ist der Video-Downloader
-[yt-dlp](github.com/yt-dlp/yt-dlp/).
+Es gibt auch einige Fälle von Open Source-Projekten, die von GitHub wegen angeblichen
+Verstößen gegen das amerikanische Urheberrecht (DMCA) gesperrt wurden. Das prominenteste
+Beispiel hierfür ist der Video-Downloader
+[youtube-dl](github.blog/2020-11-16-standing-up-for-developers-youtube-dl-is-back/).
+Auch das Repository der alternativen Smartwatch-App
+[Gadgetbridge](https://www.heise.de/news/Pebble-Gadgetbridge-unter-Beschuss-3740625.html)
+wurde zeitweise von GitHub gesperrt. Eine selbstgehostete Plattform ist dagegen viel
+schwieriger zu sperren.
Ein weiterer Grund für einige Entwickler, die GitHub-Plattform zu verlassen, ist die
Einführung von GitHub Copilot. Hierbei handelt es sich um ein künstliche Intelligenz,
@@ -30,15 +52,24 @@ hierbei eine Urheberrechtsverletzung, da der AI-generierte Code Schnipsel aus de
Trainingsdaten enthalten kann, die dann ohne Erwähnung des Urhebers in andere Projekte
eingefügt werden.
-Insbesondere bei privaten oder firmeninternen Projekten kann auch Datenschutz ein Grund
-sein, auf Webanwendungen von Fremdanbietern (insbesondere im Ausland) zu verzichten und
-die Daten auf eigenen Servern zu speichern. Da GitHub nicht quelloffen ist und nur mit
-einer kostspieligen Enterprise-Lizenz selbst gehostet werden kann, ist is für solche
-Fälle attraktiv, eine Open-Source-Anwendung einzusetzen.
+Insbesondere bei privaten oder firmeninternen Projekten kann auch der Datenschutz ein
+Grund sein, auf Webanwendungen von Fremdanbietern zu verzichten und die Daten auf
+eigenen Servern zu speichern. Da GitHub nicht quelloffen ist und nur mit einer
+kostspieligen Enterprise-Lizenz selbst gehostet werden kann, ist is für solche Fälle
+attraktiv, eine Open-Source-Anwendung einzusetzen.
+
+Mittlerweile gibt es mehrere Open-Source-Projekte, die Alternativen zu GitHub entwickelt
+hat. Im Gegensatz zu proprietären Webdiensten lassen sich diese Anwendungen auf eigenen
+Servern installieren, sodass man die volle Autonomie über sein System behält.
+
+In dieser Arbeit werde ich vier von ihnen testen und vergleichen.
## Testkriterien
-0\. Über das Projekt
+Ich habe jede Plattform auf meinem Rechner installiert und nach folgenden Kritierien
+getestet:
+
+### 0\. Über das Projekt
Zuerst werde ich einige grundlegende Informationen über die entsprechende Anwendung
präsentieren.
@@ -49,7 +80,7 @@ präsentieren.
- Wie viele Beitragende hat das Projekt?
- Wie sieht die Architektur der Anwendung aus? Welche Dienste werden benötigt?
-1\. Installation und Einrichtung
+### 1\. Installation und Einrichtung
Hier gebe ich eine kurze Anleitung zur Installation und Einrichtung der Anwendung. Ich
werde hierbei bewerten, wie einfach die Installation vonstatten geht.
@@ -57,30 +88,53 @@ werde hierbei bewerten, wie einfach die Installation vonstatten geht.
Monolithisch (d.h. aus einem Dienst) aufgebaute Anwendungen sind in der Regel einfacher
einzurichten, bieten aber weniger Flexibilität bei der Skalierung für viele User.
-Zusätzlich bewerte ich, wie gut das Projekt dokumentiert ist und wie schnell man alle
-relevanten Informationen für die Einrichtung finden kann.
+### 2\. Systemanforderungen
-2\. Systemanforderungen
-
-Hierbei geht es nicht nur um die theoretisch unterstützten Betriebssysteme und
-CPU-Architekturen, sondern auch um den Bedarf an Rechenleistung und Arbeitsspeicher. Im
-Idealfall soll die Software auch auf preisgünstigen Single Board-Computern und VServern
+Hierbei geht es nicht nur um die unterstützten Betriebssysteme und CPU-Architekturen,
+sondern auch um den Bedarf an Rechenleistung und Arbeitsspeicher. Im Idealfall soll die
+Software auch auf preisgünstigen Single Board-Computern und virtualisierten Servern
lauffähig sein, sodass sich jeder ein selbst gehostetes Setup leisten kann und nicht aus
Kostengründen auf proprietäre Anbieter angewiesen ist.
-3\. Import bestehender Projekte
+Getestet wurden CPU-Auslastung und Arbeitsspeicherverbrauch auf einem Rechner mit einem
+Ryzen 5700G-Prozessor (16 Threads) und 32GB RAM. Die angegebene CPU-Auslastung bezieht
+sich auf die ausgelasteten Threads (wie in htop angezeigt), d.h. 100% entspricht einem
+voll ausgelastetem Thread, 16.000% einem voll ausgelasteten Prozessor.
-Eine gute GitHub-Alternative sollte es dem Entwickler ermöglichen, bestehende Projekte
-von anderen Providern zu importieren. Hierbei soll nicht nur das Repository, sondern
-auch z.B. Issues übertragen werden können.
+Neben dem Ressourcenverbrauch im Leerlauf habe ich auch die CPU-Auslastung unter Last
+gemessen. Hierfür habe ich das Repository des Linux-Kernels importiert und mir die
+Versionsgeschichte und die Blame-Ansicht der Makefile im Stammverzeichnis anzeigen
+lassen.
-4\. Bedienung der Webseite
+### 3\. Bedienung
Wie einfach ist die Weboberfläche zu bedienen? Ist es möglich, schnell durch
Repositories zu navigieren? Gibt es eine Suchfunktion, um beispielsweise eine bestimmte
Funktion im Code zu finden?
-5\. Zusatzfeatures
+Zudem habe ich dir Unterstützung für verschiedene Dateiformate getestet. Alle
+Plattformen können Code, Markdown und Textdateien darstellen. Binärdateien können auf
+diese Weise natürlich nicht dargestellt werden, weswegen einige Plattformen spezielle
+Viewer für bestimmte Dateitypen mitbringen. Um dies zu testen, habe ich ein Repository
+mit Dateien in folgenden Formaten angelegt.
+
+- Bilder (\*.jpg, \*.svg)
+- Tabellen (\*.csv, \*.xlsx, \*.ods)
+- Text (\*.rst, \*.tex, \*.docx, \*.odt)
+- PDF-Dokumente
+- 3D-Modelle (\*.stl)
+- Jupyter-Notebooks (\*.ipynb)
+
+Zum Vergleich: GitHub unterstützt alle diese Dateitypen mit Ausnahme von LaTEX- und
+MS/Open Office-Dokumenten.
+
+### 4\. Import bestehender Projekte
+
+Eine gute GitHub-Alternative sollte es dem Entwickler ermöglichen, bestehende Projekte
+von anderen Providern zu importieren. Hierbei soll nicht nur das Repository, sondern
+auch z.B. Issues übertragen werden können.
+
+### 5\. Zusatzfeatures
Bietet die Anwendung zusätzlich zu Git-Repositories, Issues und Pull-Requests noch
weitere Features an?
@@ -89,16 +143,17 @@ Beispiele hierfür wären das Hosting von statischen Websites direkt aus Reposit
heraus, ein Repository für Softwarepakete verschiedener Programmiersprachen oder
Projektmanagement-Tools.
-6\. Continuous Integration
+### 6\. Continuous Integration
Continuous Integration (CI), also das automatische Testen von neuem Code ist ein fester
-Teil des Worflows vieler Entwickler. GitHub bietet mit Actions einen eingebauen
-CI-Dienst an.
+Teil des Worflows vieler Entwickler. Hat die Plattform einen CI-Dienst eingebaut oder
+lässt sie sich mit anderen CI-Diensten integrieren?
-7\. Öffentliche Instanzen
+### 7\. Öffentliche Instanzen
-Gibt es öffentliche Instanzen dieser Anwendung? Wenn ja, wie beliebt sind sie (ungefähre
-Anzahl an Projekten).
+Nicht jeder möchte den Aufwand betreiben, seine Git-Hosting-Plattform selbst zu hosten.
+Deswegen ist es vom Vorteil, wenn es die Möglichkeit gibt, anstelle dessen einer
+öffentlichen Instanz beizutreten.
## Quellen
diff --git a/src/studienarbeit/2_gitlab.md b/src/studienarbeit/2_gitlab.md
new file mode 100644
index 0000000..a25ccd9
--- /dev/null
+++ b/src/studienarbeit/2_gitlab.md
@@ -0,0 +1,278 @@
+# GitLab
+
+2011, drei Jahre nach dem Start von GitHub veröffentlichten Dmytro Zaporozhets und Sytse
+Sijbrandij die erste Version von GitLab. Damit ist GitLab die erste und bekannteste
+Open-Source-Alternative zu GitHub.
+
+GitLab Community Edition ist unter der MIT-Lizenz veröffentlicht. Die Firma hinter
+GitLab verfolgt ein "Open Core"-Geschäftsmodell, d.h. einige fortgeschrittene Features
+sind nicht in der Community Edition enthalten und erfordern die proprietären Versionen
+"Premium" bzw. "Ultimate". Diese sind nur in Form eines Abonnements zum Preis von 29
+(Premium) bzw. 99USD (Ultimate) pro Nutzer und Monat erhältlich. Open-Source-Projekte
+und Bildungseinrichtungen können die Ultimate-Version kostenfrei nutzen.
+
+Im Kern ist GitLab eine Ruby-on-Rails-Webanwendung. Allerdings sind einige Funktionen
+der Plattform (bspw. SSH oder Git-Operationen) an zusätzliche Services ausgelagert. Die
+meisten dieser Services sind in Go implementiert. Das Webfrontend wurde mit Vue.js
+implementiert.
+
+
+
+- **Workhorse** Reverse Proxy, der HTTP-Anfragen an Git oder die Hauptanwendung
+ weiterleitet
+- **Gitaly** Microservice zur Speicherung der Git-Repositories und Verarbeitung von
+ Git-Anfragen
+- **GitLab Shell** SSH-Server
+- **Sidekiq** Task Queue zur Ausführung von Aufgaben im Hintergrund
+
+GitLab verwendet eine PostgreSQL-Datenbank zur Speicherung seiner Daten. Zudem kommt
+eine Redis-Instanz als Cache und Event Queue zum Einsatz.
+
+Getestet wurde GitLab in der Version 16.1.1.
+
+## Installation
+
+Um die Installation der Anwendung trotz ihres Aufbaus aus verschiedenen Services zu
+vereinfachen, stellt GitLab ein Omnibus-Paket zur verfügung. Hierbei handelt es sich um
+ein Linux-Softwarepaket, das die gesamte GitLab-Anwendung mit allen Services (inklusive
+NGINX, Redis und Postgres) beinhalten. Die Pakete sind für die meisten
+Linux-Distributionen (Ubuntu, Debian, Alma Linux, CentOS, OpenSUSE, Raspberry Pi OS)
+verfügbar.
+
+Um Gitlab als Omnibus-Paket zu installieren, muss man zuerst das Gitlab-Repository zu
+seinem System hinzufügen. Hierfür kann man dieses Skript verwenden:
+.
+
+Danach kann man GitLab mit diesem Befehl installieren und starten:
+
+```
+GITLAB_ROOT_PASSWORD="" EXTERNAL_URL="http://gitlab.example.com" apt install gitlab-ce
+```
+
+Der Konfigurationsprozess dauert mehrere Minuten. Wenn der Webserver gestartet ist, kann
+man die Weboberfläche aufrufen und sich anmelden (Benutzername: `root`).
+
+GitLab stellt auch ein Docker-Image (`gitlab/gitlab-ce`) zur Verfügung, welches das
+Omnibus-Paket beinhaltet. Der Einrichtungsprozess ist der gleiche wie bei einer bare
+metal-Installation, mit dem Unterschied dass die Konfiguration durch die
+Umgebungsvariable `GITLAB_OMNIBUS_CONFIG` erfolgt.
+
+[Hier](./assets/gitlab/docker-compose.yml) ist die Docker-Compose-Datei, die ich für
+meine Testinstallation verwendet habe.
+
+Für Unternehmen und große Organisationen mit Tausenden Nutzern bietet GitLab in ihrer
+Dokumentation auch Referenzarchitekturen für hochverfügbare Systemen mit mehreren
+Servern.
+
+## Systemanforderungen
+
+GitLab bietet Pakete für eine
+[Vielzahl von Linux-Distributionen](https://docs.gitlab.com/ee/administration/package_information/supported_os.html),
+sowohl für Intel/AMD als auch für ARM-Prozessoren. Das offizielle Docker-Image ist
+jedoch nur für die arm64-Architektur verfügbar.
+
+GitLab hat unter allen getesteten Plattformen den höchsten Ressourcenverbrauch.
+
+Im Leerlauf bewegt sich die CPU-Last auf meinem Testsystem zwischen 3 und 30 Prozent.
+Der Arbeitsspeicherverbrauch beträgt ganze 6GB.
+
+Aufwändige Git-Operationen können Lastspitzen über 100% für eine Dauer von bis zu 5
+Sekunden pro Anfrage verursachen.
+
+GitLab erwähnt in ihrer Dokumentation, dass man die Konfiguration anpassen kann, um den
+Ressourcenverbrauch etwas zu senken. Nachdem ich diese Zeilen zur Konfigurationsdatei
+hinzugefügt habe, sank der Speicherbedarf auf 2.8GB und die CPU-Auslastung auf 1-12%.
+
+```
+# Reduce the number of running workers to the minimum in order to reduce memory usage
+puma['worker_processes'] = 2
+sidekiq['max_concurrency'] = 9
+# Turn off monitoring to reduce idle cpu and disk usage
+prometheus_monitoring['enable'] = false
+```
+
+Für eine Installation auf Single Board-Computern und kleinen V-Servern ist der
+Speicherverbrauch jedoch weiterhin zu hoch. GitLab gibt als Mindestanforderung 4
+CPU-Kerne und 4GB RAM an.
+
+## Bedienung
+
+Gitlab's Weboberfläche wurde mit dem VueJS-Framework realisiert. Die gesamte
+Weboberfläche wird somit clientseitig mittels JavaScript gerendert. Dies erlaubt eine
+äußerst flüssige Navigation durch die Webseite, da die Seite nicht bei jedem
+Navigationsschritt neu geladen wird. Der Nachteil dieser Lösung: Javascript ist für die
+Darstellung der Webseite zwingend erforderlich.
+
+GitLab bietet die Möglichkeit, den Code eines Repositories zu durchsuchen. Die
+Verwendung einer externen Elasticsearch-Instanz für die Suche und die Möglichkeit, die
+gesamte Gitlab-Instanz zu durchsuchen, ist allerdings den kostenpflichtigen Versionen
+vorbehalten.
+
+GitLab unterstützt in der Standardkonfiguration die meisten Dateiformate unter den
+getesteten Plattformen. Auf der Weboberfläche können Bilder, CSV-Tabellen, PDF-Dokumente
+und stl-Modelle betrachtet werden, alternative Markupsprachen wie Restructured Text
+werden ebenfalls unterstützt. Es gibt sogar die Möglichkeit, GeoJSON-Dateien (Listen von
+GPS-Standorten) auf einer OpenStreetMap-Karte darzustellen.
+
+Eine Besonderheit der Gitea-Weboberfläche stellt die Web-IDE dar. GitLab verfügt über
+eine modifizierte Version von Visual Studio Code, mit der man direkt im Browser an
+seinen Projekten arbeiten kann.
+
+
+
+## Import bestehender Projekte
+
+GitLab erlaubt den Projektimport von GitHub, Bitbucket, FogBugz, Gitea sowie von anderen
+GitLab-Instanzen.
+
+Die Importfunktion ist standardmäßig deaktiviert und muss erst in der _Admin Area_
+aktiviert werden (_Settings_ \> _General_ \> _Visibility and access controls_ \> _Import
+sources_).
+
+Für den Import von GitHub-Projekten muss man sich mit einem Access Token anmelden und
+bekommt anschließend eine Übersicht aller Repositories angezeigt. Hier kann man
+auswählen, welche Repositories übertragen werden sollten. Der Import umfasst auch
+Issues, Pull Requests und Releases.
+
+
+
+Als einzige Plattform im Test bietet GitLab die Möglichkeit, ein Repository mit
+sämtlichen gespeicherten Daten als zip-Datei zu exportieren. Dies erlaubt nicht nur den
+Import auf anderen Instanzen sondern bietet dem Nutzer auch eine Backup-Option.
+
+## Zusatzfeatures
+
+GitLab hat von allen getesteten Plattformen die meisten Features. Einige Features sind
+jedoch der proprietären Premium/Ultimate Edition vorbehalten, die ich nicht getestet
+habe.
+
+Die Projektmanagement-Features von GitLab sind die besten im Test. GitLab erlaubt das
+Erstellen von Issues mit Labels, Verantwortlichen, Fälligkeitsterminen und geleisteter
+Arbeitszeit. Zudem können Issues zu Meilensteinen hinzugefügt werden.
+
+Issue Boards erlauben einen schnellen Überblick über den alle gerade bearbeiteten
+Issues. Es lassen sich Spalten erstellen, die Issues mit einem bestimmten Tag auflisten.
+Erstellt man also z.B. zwei Tags: "Implementierung" und "Review" und legt in seinem
+Board zwei Spalten hierfür an, erhält man eine Übersicht über den Fortschritt aller
+Issues. Issues lassen sich zwischen Spalten verschieben, wodurch sich auch die Tags des
+Issues ändern.
+
+
+
+Ein interessantes Feature ist die Möglichkeit, zu einem Issue mehrere Tasks
+hinzuzufügen. Tasks sind Sub-Issues, die ihre eigene Beschreibung und Diskussion haben,
+aber unter einem Issue zusammengefasst sind. Auf diese Weise lassen sich große Features
+in kleinere Arbeitsschritte aufteilen, die von verschiedenen Teammitgliedern erledigt
+werden können.
+
+
+
+Viele fortgeschrittene Projektmanagement-Features sind allerdings der Enterprise Edition
+vorbehalten. Hierzu gehört z.B. das Anlegen von Boards mit Filtern (z.B. für einen
+bestimmten Meilenstein) oder Aufwandsschätzungen.
+
+Um Projekte zu dokumentieren bietet GitLab ein auf Git und Markdown basierendes Wiki.
+Zudem gibt es mit "Snippets" einen Pastebin, der ebenfalls Git zur Speicherung der
+Codeschnipsel verwendet.
+
+Es gibt auch die Möglichkeit, mit GitLab statische Webseiten zu hosten. Die Seiten
+können mit GitLab CI gebaut und unter einer persönlichen Subdomain veröffentlicht
+werden.
+
+GitLab bietet auch eine Paketregistry für Bibliotheken verschiedener Programmiersprachen
+(z.B. Maven, npm, Python) an. Die Unterstützung für einige Programmiersprachen wie Ruby
+ist allerdings noch experimentell. \*.deb-Pakete sowie Docker-Images können ebenfalls
+mit GitLab gehostet werden.
+
+Zur einfachen Bedienung mit der Kommandozeile bietet GitLab das Tool `glab` an. Damit
+lassen sich beispielsweise Issues und Pull Requests erstellen und bearbeiten, Snippets
+hochladen und CI-Build starten. Es gibt auch ein offizielles VS-Code-Plugin, das
+Pull-Requests, Issues und CI-Builds in den Texteditor integriert.
+
+## Continous Integration
+
+Gitlab verfügt über ein eingebautes CI-System, um Software automatisiert zu testen und
+zu veröffentlichen. Das System kann Builds in Docker-Containern, auf einem
+Kubernetes-Cluster, in einer VirtualBox-Maschine oder ohne Virtualisierung ausführen.
+Hierfür verwendet Gitlab ein verteiltes System aus Runnern. Die Runner kommunizieren
+über das Internet mit der Gitlab-Instanz und können so neue Buildaufträge
+entgegennehmen.
+
+Um einen Runner einzurichten, muss man zuerst die erforderliche Konfigurationsdatei
+erstellen. Hierfür startet man den Runner mit dem Befehl `register`:
+
+```
+docker run --rm -it -v $(pwd)/runner-config:/etc/gitlab-runner gitlab/gitlab-runner register
+```
+
+Daraufhin fragt der Runner nach der URL der Gitlab-Instanz und einem
+Registrierungstoken. Den Token kann man sich entweder in den Repository-Einstellungen
+oder in der Admin-Oberfläche generieren lassen (je nachdem, ob man den Runner nur zu
+einem Projekt oder der gesamten Instanz hinzufügen möchte). Anschließend muss man
+festlegen, wie der Runner die Builds ausführen sollte. In meinem Test habe ich den
+`docker`-Executor gewählt.
+
+Wenn die Konfiguration abgeschlossen ist, kann man den Runner mit diesem Befehl starten
+
+```
+docker run --rm -it -v $(pwd)/runner-config:/etc/gitlab-runner gitlab/gitlab-runner
+```
+
+
+
+Anschließend kann man für sein Repository einen Build definieren. Hierfür muss man eine
+Datei mit dem Namen `.gitlab-ci.yml` im Wurzelverzeichnes des Repositories erstellen, in
+der die einzelnen Schritte des Builds beschrieben werden. GitLab stellt ein Repository
+mit Beispielen für verschiedene Programmiersprachen und Frameworks zur Verfügung, um den
+Einstieg zu erleichtern.
+
+```yml
+image: "rust:latest"
+
+test:cargo:
+ script:
+ - rustc --version && cargo --version # Print version info for debugging
+ - rustup component add rustfmt clippy
+ - cargo fmt --all --check
+ - cargo clippy --all --features=rss -- -D warnings
+ - cargo test --features=rss --workspace
+```
+
+## Öffentliche Instanzen
+
+Gitlab betreibt selbst eine öffentliche Instanz der proprietären Ultimate-Version unter
+[gitlab.com](https://gitlab.com/explore/).
+
+Daneben gibt es eine Vielzahl von communitybetriebenen GitLab-Instanzen, die die freie
+Community Edition verwenden. Viele große Open-Source-Projekte und Organisationen hosten
+eine eigene GitLab-Instanz, wie zum Beispiel [Debian](https://salsa.debian.org),
+[Framasoft](https://framagit.org/public/projects/) oder [KDE](https://invent.kde.org).
+
+## Fazit
+
+GitLab ist zu Recht seit mehr als zehn Jahren die führende quelloffene
+GitHub-Alternative. Mittlerweile bietet GitLab mehr Features als die Konkurrenz von
+Microsoft.
+
+Trotz seiner komplexen Architektur lässt sich GitLab relativ einfach und schnell
+installieren, da das Omnibus-Paket die einzelnen Dienste automatisch konfiguriert.
+
+Insbesondere Unternehmen und große Organisationen werden die professionellen Features
+und den kommerziellen Support zu schätzen wissen.
+
+Darüber hinaus bietet Gitlab selbst in der Open-Source-Version die besten
+Projektmanagement-Features im Test. Wer also keine separate Projektmanagement-Anwendung
+einsetzen möchte, ist mit Gitlab ebenfalls gut beraten.
+
+Wer seine Plattform allerdings auf einem kleinen Single Board Computer oder V-Server
+betreiben möchte, sollte sich dagegen nach einer leichtgewichtigeren Alternative
+umsehen.
+
+## Quellen
+
+- Dokumentation
+- Repository
+- Architekturübersicht
+
+- Liste von öffentlichen GitLab-Instanzen
+
diff --git a/src/studienarbeit/3_gitea.md b/src/studienarbeit/3_gitea.md
new file mode 100644
index 0000000..bffb94b
--- /dev/null
+++ b/src/studienarbeit/3_gitea.md
@@ -0,0 +1,327 @@
+# Gitea
+
+Das Gitea-Projekt begann 2016 als Fork der Git-Hosting-Plattform Gogs. Lunny Xiao, einer
+der Beitragenden von Gogs, war damit unzufrieden, dass der Gründer des Projekts, Joe
+Chen, das Projekt alleine betreuen und keine weiteren Maintainer ernennen wollte.
+
+2022 gründete Lunny Xiao die Firma Gitea Limited. Die Firma bietet Unternehmen Hosting-
+und Supportdienstleistungen für Gitea an. Da einige Mitglieder der Community einem
+kommerziell geleiteten Open-Source-Projekt misstrauen, entstand ein neuer Fork names
+Forgejo. Forgejo steht unter der Leitung von Codeberg, einem Berliner Verein, der seit
+2018 eine öffentliche Gitea-Instanz betreibt. Abgesehen von Design- und Namensänderungen
+unterscheidet sich Forgejo von Gitea momentan kaum.
+
+Gitea ist in Go geschrieben und besteht aus einer einzigen ausführbaren Datei.
+Standardmäßig verwendet Gitea eine interne SQLite-Datenbank, alternativ werden auch
+externe Datenbanken (MySQL, MariaDB, Postgres, MS SQL) unterstützt.
+
+Die Weboberfläche wied serverseitig mit Templates gerendert. Einige Websitekomponenten
+wie z.B. Drop-Down-Menüs erfordern JavaScript.
+
+Getestet wurde die Version 1.20.0-rc2.
+
+## Installation
+
+Gitea stellt kompilierte Binaries für alle gängigen Betriebssysteme unter
+ zur Verfügung. Von dort aus lässt sich die Anwendung
+einfach herunterladen und starten.
+
+Alternativ gibt es auch [offizielle](https://pkgs.org/download/gitea) und
+[inoffizielle](https://gitea.com/gitea/awesome-gitea/src/branch/main/README.md#user-content-packages)
+Pakete für die meisten Linux-Distributionen.
+
+Darüber hinaus stellt Gitea auch ein Docker-Image (`gitea/gitea`) zur Verfügung.
+
+Die Einrichtung ist extrem simpel. Beim ersten Start wird diese Konfigurationsseite
+angezeigt, auf der man die grundlegenden Einstellungen (z.B. Datenbank-URL,
+Admin-Passwort) vornehmen kann. Nach der Bestätigung ist Gitea in wenigen Sekunden
+bereit zur Verwendung.
+
+
+
+Dieser Konfigurationsassistent wird jedoch nur beim ersten Start angezeigt. Alle
+weiteren Konfigurationsänderungen müssen durch die
+`app.ini`-[Konfigurationsdatei](https://docs.gitea.com/1.20/administration/config-cheat-sheet)
+erfolgen. Gitea verfügt zwar über eine Admin-Oberfläche, diese dient allerdings
+hauptsächlich der Nutzerverwaltung und erlaubt keine Konfigurationsänderungen.
+
+## Systemanforderungen
+
+Gitea ist auf jedem Betriebssystem und jeder CPU-Architektur lauffähig, die von der
+Programmiersprache Go unterstützt wird. Binaries für MacOS (amd64/aarch64), FreeBSD
+(amd64), Windows (i386/amd64) und Linux (i386/amd64/arm5/arm6/aarch64) werden offiziell
+zum Download angeboten. Das offizielle Docker-Image ist für die amd64- und
+aarch64-Architektur verfügbar.
+
+Im Leerlauf benötigt der Server ca. 150MB Arbeitsspeicher und verursacht unter 0.1%
+CPU-Auslastung. Damit ist Gitea die mit Abstand leichtgewichtigste Plattform in Test und
+eignet sich perfekt für den Einsatz auf schwächerer Hardware.
+
+## Bedienung
+
+Die Weboberfläche von Gitea wird serverseitig mit Hilfe von Templates gerendert
+(klassische Multi-Page-Anwendung). Dies hat den Vorteil, dass die Seite auch ohne
+JavaScript dargestellt werden kann (wenn auch mit eingeschränkter Bedienbarkeit).
+
+Obwohl bei jedem Navigationsschritt durch ein Repository die gesamte Seite neu geladen
+wird, läuft die Navigation durch Ordner sehr flüssig.
+
+Optisch und funktional ist die Benutzerschnittstelle stark an GitHub angelehnt. Wer also
+vorher GitHub verwendet hat, findet sich auf Gitea schnell zurecht
+
+Der Code in Gitea-Repositories kann durchsucht werden, allerdings ist diese Funktion
+standardmäßig deaktiviert. Um sie zu aktivieren, müssen diese Zeilen zur
+Konfigurationsdatei hinzugefügt werden:
+
+```
+[indexer]
+REPO_INDEXER_ENABLED=true
+```
+
+Standardmäßig verwendet Gitea die Bibliothek [Bleve](https://blevesearch.com/) für die
+Suche, es kann jedoch auch eine externe Elasticsearch-Instanz verwendet werden.
+
+
+
+Gitea kann standardmäßig Bilder, CSV-Dateien, PDFs und Markdown-Dateien auf der
+Weboberfläche darstellen. Andere Markupsprachen wie ReStructured Text werden
+standardmäßig nicht unterstützt. Allerdings bietet Gitea als einzige getestete Plattform
+die Möglichkeit, zusätzliche Renderer in der Konfigurationsdatei zu definieren.
+Beispielsweise kann Gitea Pandoc verwenden, um RST, LaTEX oder Word-Dokumente in HTML zu
+konvertieren und anzuzigen. Es ist auch möglich, mit etwas Bastelei einen Viewer für STL
+oder Excel-Dateien zu installieren.
+
+## Import bestehender Projekte
+
+Gitea bietet die Möglichkeit, Projekte von GitHub, Gitlab, Gogs, OneDev, GitBucket und
+Codebase zu importieren. Neben den Repositories können auch Issues, Pull-Requests und
+Releases importiert werden.
+
+Der Versuch, zwei meiner GitHub-Projekte mit Issues und Pull-Requests zu übertragen,
+scheiterte jedoch mit einer Fehlermeldung.
+
+## Zusatzfeatures
+
+Gitea bietet grundlegende Features zum Projektmanagement. Issues können erstellt, mit
+Labels versehen und bestimmten Entwicklern zugewiesen werden. Es können
+Fälligkeitstermine für Issues festgelegt und die Arbeitszeit hinterlegt werden.
+
+Dazu kommt die Möglichkeit, Issues zu Meilensteinen hinzuzufügen und somit
+beispielsweise den Arbeitsfortschritt für eine neue Version zu verfolgen.
+
+Darüber hinaus können in Gitea Kanbanboards erstellt werden. Allerdings sind diese
+Boards nicht in das restliche Issue-System integriert und deswegen umständlich zu
+nutzen. Issues müssen beispielsweise manuell den Boards hinzugefügt werden. Während
+GitLab Labels verwendet, um die Issues den Spalten zuzuordnen ist in Gitea außerhalb des
+Boards nicht ersichtlich, welchen Status ein Issue hat. Ein Issue, das in die
+Done-Spalte verschoben wird, wird nicht automatisch geschlossen. Umgekehrt führt das
+Schließen eines Issues nicht zu einer Platzierung in der Done-Spalte.
+
+Dokumentation für Gitea-Repositories kann in einem simplen, auf Markdown basierenden
+Wiki veröffentlicht werden.
+
+Das Hosting statischer Webseiten unterstützt Gitea nicht, weswegen das Team von Codeberg
+hierfür eine [eigene Lösung](https://codeberg.org/Codeberg/pages-server) entwickelt hat.
+
+Gitea bietet eine integrierte Registry für Pakete aller gängigen Programiersprachen
+(z.B. Python, npm, Rust). Wer eine Softwarebibliothek entwickelt, kann diese auf seiner
+Gitea-Instanz veröffentlichen, sodass andere Entwickler sie nutzen können. Zudem
+unterstützt die Gitea-Registry Linux-Pakete (.deb und .rpm) sowie Docker-Images.
+
+Gitea unterstützt als einzige getestete Plattform agit. Dies ist ein alternativer
+Git-Workflow, der von Alibaba entwickelt wurde. Agit erlaubt es Entwicklern, Pull
+Requests zu erstellen ohne zuvor einen Fork des Projekts anzulegen. Hierbei wird die
+Änderung mit diesem Befehl in einen versteckten Branch des Reposiories gepusht, worauf
+Gitea automatisch eine PR erstellt.
+
+Dieser Befehl erfordert im Gegensatz zum normalen push keine Schreibrechte im
+entsprechenden Repository.
+
+```
+git push origin HEAD:refs/for/main -o topic="feat/user-search" -o title="Add user search"
+```
+
+Es existiert auch ein Git-Plugin für agit namens
+[`git-repo`](https://git-repo.info/en/2020/03/agit-flow-and-git-repo/), damit man nicht
+jedes Mal diesen langen Befehl eintippen muss, sondern den Beschreibungstext direkt in
+die Kommandozeile tippen kann.
+
+Gitea lässt sich auch mit dem Tool [`tea`](https://gitea.com/gitea/tea) auf der
+Kommandozeile bedienen. Auf diese Weise lassen sich Issues erstellen und lesen oder Pull
+Requests erstellen und abrufen.
+
+Gitea bietet dem Administrator vollen Zugriff auf seinen Webserver und das
+Templatesystem. Dadurch kann man Templates und Stylesheets durch eigens angepasste
+Versionen ersetzen und die Weboberfläche nach seinen Bedürfnissen anpassen. Dies ist
+insbesondere für große Organisationen und Firmen interessant, die ihre
+Git-Hosting-Plattform nach ihrem Corporate Design gestalten möchten.
+
+Ein Beispiel für eine stark angepasste Gitea-Oberfläche ist die Instanz des
+[Blender-Projekts](https://projects.blender.org/), die sich nahtlos in die restliche
+Projektseite einfügt.
+
+## Continous Integration
+
+### Woodpecker
+
+Gitea verfügte lange nicht über einen eingebauten CI-Server. Allerdings gibt es eine
+Schnittstelle, um externe CI-Systeme anzubinden.
+
+Ich habe einige CI-Systeme getestet, die mit Gitea kompatibel sind.
+[Woodpecker](https://woodpecker-ci.org/) ist meiner Meinung nach eines der besten
+Systeme. Bei Woodpecker handelt es sich um einen Fork des Drone CI-Projekts nach deren
+Wechsel von der Apache License zu einer nichtkommerziellen Lizent.
+
+Woodpecker erlaubt den Login mit seinem Gitea-Account und zeigt dem Entwickler auf der
+Startseite eine Liste aller Repositories an. Von dort aus lässt sich die CI für
+bestimmte Repositories aktivieren. Daraufhin konfiguriert Woodpecker die Webhooks des
+Repositories, sodass die Builds automatisch bei Aktualisierungen gestartet werden.
+
+Woodpecker verwendet sogenannte Agents, die mittels GRPC mit dem zentralen Server
+kommunizieren und Buildaufträge empfangen. Die Agents verwenden Docker, um die Builds in
+Containern auszuführen.
+
+
+
+Die Builds werden in einer yml-Datei mit dem Namen `.woodpecker.yml` im
+Wurzelverzeichnes des Repositories definiert. Jeder Buildschritt wird in einem eigenen
+Docker-Container ausgeführt.
+
+```yaml
+pipeline:
+ test:
+ image: rust:latest
+ commands:
+ - rustup component add rustfmt clippy
+ - cargo fmt --all --check
+ - cargo clippy --all --features=rss -- -D warnings
+ - cargo test --features=rss --workspace
+```
+
+Die Installation von Woodpecker ist etwas komplizierter, da Woodpecker sowohl einen
+HTTP-Server als auch einen GRPC-Server bereitstellt. Möchte man Agents auf anderen
+Servern betreiben, sollte auch der GRPC-Server mit TLS gesichert sein. Hierfür kann man
+einen Reverse Proxy (z.B Traefik) verwenden. Allerdings beinhaltet die offizielle
+Dokumentation keine Anleitung hierfür.
+
+[Hier](./assets/woodpecker/docker-compose.yml) ist die Docker-Compose-Datei, die ich für
+meine Setup (mit Traefik) verwendet habe. Vor der Verwendung müssen noch die folgenden
+Konfigurationsvariablen bearbeitet werden:
+
+- `WOODPECKER_HOST` URL der Woodpecker-Instanz
+- `WOODPECKER_GITEA_URL` URL der Gitea-Instanz
+- `WOODPECKER_GITEA_CLIENT` / `WOODPECKER_GITEA_SECRET` OAuth-Zugangsdaten (in Gitea das
+ Einstellungsmenü aufrufen und unter _Create a new OAuth2 Application_ einen neuen
+ Client erstellen. Redirect URI: `/authorize`)
+- `WOODPECKER_AGENT_SECRET` ist das Passwort für alle mit der Instanz verbundenen
+ Agents. Hierfür sollte man sich einfach einen langen Zufallsstring erzeugen,
+ beispielsweise mit `openssl rand -hex 32`.
+
+### Gitea Actions
+
+Mit dem vorletzten Release 1.19 bekam Gitea jedoch ein eigenes CI-System: Gitea Actions.
+Hierbei wurde nicht nur der Name an die Konkurrenz von Microsoft angelehnt. Das System
+basiert auf [act](https://github.com/nektos/act), einer freien Implementation von GitHub
+Actions. Ursprünglich wurde act zum lokalen Testen von GitHub Actions entwickelt. Gitea
+hat die Anwendung stattdessen als Basis für ihr CI-System verwendet.
+
+Standardmäßig sind Gitea Actions in den Einstellungen deaktiviert. Um sie verwenden zu
+können, muss man diese Zeilen zur Konfigurationsdatei hinzufügen:
+
+```
+[actions]
+ENABLED=true
+```
+
+Anschließend muss man wie bei Gitlab und Woodpecker einen Runner einrichten, der die
+Builds mittels Docker ausführt. Der Runner kann als Binary von der
+[Gitea-Download-Seite](https://dl.gitea.com/act_runner/) heruntergeladen werden. Es ist
+auch möglich, den Runner in einem Docker-Container zu betreiben.
+
+Nachdem man den Runner heruntergeladen hat, muss man ihn konfigurieren. Dafür führt man
+den Befehl `act-runner register` auf. Anschließend muss man die Adresse der Instanz und
+einen Registrierungstoken, den man in der Admin-Oberfläche unter _Actions / Runners_
+erzeugen kann.
+
+Anschließend muss man noch die Actions im gewünschten Repository aktivieren, in dem man
+in den Einstellungen den Haken bei _Enable Repository Actions_ setzt.
+
+Die Builds werden als yaml-Dateien im Verzeichnis `.gitea/workflows` definiert. Obwohl
+Gitea die gleiche Syntax wie Github Actions verwendet, sind die Workflows nicht 1:1
+kompatibel. Beispielsweise lädt Gitea vordefinierte Actions wie `actions/checkout` nicht
+von [github.com/actions](https://github.com/actions) sondern von
+[gitea.com/actions](https://gitea.com/actions) herunter, sodass einige Actions nicht
+verfügbar sind.
+
+Außerdem führt GitHub seine Builds in einer virtuellen Maschine mit einer Vielzahl an
+vorinstallierten Programmiersprachen und Entwicklertools aus. Da das Image dieser
+Maschine sehr groß ist, benutzt Gitea stattdessen standardmäßig den
+Debian+NodeJS-Container `node:16-bullseye`. Das Image enthält neben Node.js auch Python,
+gcc, make und curl. Wer andere Programmiersprachen benutzt, muss jedoch Anwendungen
+nachinstallieren (wie beispielsweise Rust im unteren Beispiel). Es ist jedoch möglich,
+andere Docker-Images zu verwenden.
+
+```yaml
+name: Test
+on: [push]
+
+jobs:
+ Test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v3
+ - name: Setup Rust
+ run: |
+ curl https://sh.rustup.rs -sSf | sh -s -- -y
+ source "$HOME/.cargo/env"
+ - name: Test
+ run: |
+ cargo clippy
+ cargo test
+```
+
+
+
+Ein wichtiges Feature, das Gitea Actions momentan noch fehlt ist die Möglichkeit,
+Workflows manuell zu starten. Da Gitea Actions noch relativ neu ist, gehe ich jedoch
+davon aus, dass dieses Feature in Zukunft implementiert wird.
+
+## Öffentliche Instanzen
+
+Die von den Maintainern des Projekts betriebene Instanz unter
+[gitea.com](https://gitea.com/explore/repos) verfügt über 5600 Repositories.
+
+Eine noch größere Instanz betreibt der Berliner Verein Codeberg e.V. Auf
+[codeberg.org](https://codeberg.org) werden 30900 öffentliche Repositories gehostet.
+Zusätzlich zu ihrer Gitea-Instanz bietet Codeberg auch einen Webhosting-Dienst unter
+[\*.codeberg.page](codeberg.page) an. Codeberg betreibt auch einen Woodpecker-CI-Server,
+für dessen Verwendung die Nutzer allerdings manuell freigeschaltet werden müssen.
+
+Da Gitea sehr einfach und günstig zu hosten ist, wird es von einigen Open
+Source-Projekten auch als sekundäre Plattform zusätzlich zu GitHub verwendet.
+Beispielsweise betreibt das Team hinter dem alternativen YouTube-Frontend Invidious eine
+[Gitea-Instanz](https://gitea.invidious.io/iv-org), um vor eventuellen Takedowns des
+Repositories auf GitHub sicher zu sein
+
+## Fazit
+
+Während GitLab meiner Meinung nach die beste Lösung für große Organisationen und
+Unternehmen darstellt, ist Gitea das perfekte System für einzelne Entwickler, kleine
+Teams und Hobbybastler. Durch seinen sparsamen Ressourcenverbrauch ist Gitea auf fast
+jeder Hardware lauffähig und die Einrichtung funktioniert einfach und schnell.
+
+Darüber hinaus lässt sich Gitea mit eigenen Themes und Templates individuell anpassen
+und zu seiner persönlichen Website machen.
+
+Die Projektmanagement-Features von Gitea sind allerdings eher rudimentär. Wer
+Kanbanboards benötigt, sollte Gitlab oder OneDev in Betracht ziehen oder hierfür eine
+externe Software verwenden.
+
+## Quellen
+
+- Projektseite
+- Repository
+- Start von Codeberg (damals TeaHub)
+ ,
+
diff --git a/src/studienarbeit/3_sourcehut.md b/src/studienarbeit/3_sourcehut.md
deleted file mode 100644
index 4a431d4..0000000
--- a/src/studienarbeit/3_sourcehut.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Sourcehut
-
-Die Weboberfläche ist spartanisch designed und kommt fast ohne JavaScript aus.
-
-Der
-[erste Commit](https://git.sr.ht/~sircmpwn/meta.sr.ht/commit/40dcb38349af3f67845857c4ac9003911a653624)
-erfolgte im Oktober 2016,
-[im Jahr 2018](https://drewdevault.com/2018/11/15/sr.ht-general-availability.html) war
-die Alpha-Version der Software öffentlich unter verfügbar.
-
-Sourcehut wird hauptsächlich von Drew DeVault selbst entwickelt, die einzelnen
-Repositories haben zwischen 50 und 100 Contributors.
-
-## Installation
-
-Da Sourcehut aus mehreren Services für die einzelnen Features besteht, gestaltet sich
-die Einrichtung etwas aufwändiger. Die Anleitung zur Installation findet sich auf der
-Dokumentationsseite des Projekts. Allerdings ist diese Anleitung nicht vollständig und
-ich musste an einigen Stellen im Quellcode der Software nachschlagen, wie bestimmte
-Features zu konfigurieren sind.
-
--
--
diff --git a/src/studienarbeit/4_sourcehut.md b/src/studienarbeit/4_sourcehut.md
new file mode 100644
index 0000000..026ec8e
--- /dev/null
+++ b/src/studienarbeit/4_sourcehut.md
@@ -0,0 +1,292 @@
+# Sourcehut
+
+Eine Git-Hosting-Plattform ohne Pull-Requests, einer spartanischen Weboberfläche und
+einem mächtigen Buildsystem - so lässt sich Sourcehut am besten zusammenfassen.
+
+
+
+SourceHut begann im
+[Oktober 2016](https://git.sr.ht/~sircmpwn/meta.sr.ht/commit/40dcb38349af3f67845857c4ac9003911a653624)
+als Hobbyprojekt von Drew DeVault. Drew wollte eine alternative zu den etablierten
+Git-Hosting-Diensten entwickeln, die den klassischen E-Mail-basierten Git-Workflow
+unterstützt anstatt das Funktionsprinzip von GitHub zu kopieren.
+
+[2018](https://drewdevault.com/2018/11/15/sr.ht-general-availability.html) war die
+Alpha-Version der Software öffentlich unter verfügbar.
+
+Die Plattform besteht aus einzelnen Komponenten für die verschiedenen Features:
+
+- meta.sr.ht (Login und Benutzerverwaltung)
+- hub.sr.ht (Projektverwaltung)
+- git.sr.ht / hg.sr.ht (Git/Mercurial Hosting)
+- todo.sr.ht (Issues)
+- lists.sr.ht (Mailinglisten)
+- man.sr.ht (Wiki)
+- paste.sr.ht (Pastebin)
+- builds.sr.ht (Continuous Integration)
+- pages.sr.ht (Statisches Webhosting)
+
+Jede dieser Komponentent besteht wiederum aus 2-3 Diensten: dem in Python/Flask
+implementierten Webfrontend, einem in Go geschriebenen API-Server und eventuell noch
+zusätzliche Dienste wie eine Task Queue.
+
+Jede Komponente legt ihre Daten in einer eigenen PostgreSQL-Datenbank ab. Zusätzlich
+wird noch eine gemeinsame Redis-Instanz als Cache und Event Queue verwendet.
+
+Hier ist eine Übersicht über die einzelnen Dienste:
+
+
+
+## Installation
+
+Da Sourcehut aus mehreren Services für die einzelnen Features besteht, ist die
+Einrichtung mit deutlich mehr Aufwand verbunden. Die Anleitung zur Installation findet
+sich auf der [Dokumentationsseite](https://man.sr.ht/installation.md) des Projekts.
+Allerdings ist diese Anleitung nicht vollständig und ich musste an einigen Stellen im
+Quellcode der Software nachschlagen, wie bestimmte Features zu konfigurieren sind.
+
+Erschwerend kommt hinzu, dass Sourcehut an vielen Stellen keine aussagekräftigen
+Fehlermeldungen liefert. Beispielsweise hatte ich das Problem, dass builds.sr.ht keine
+VMs starten konnte, da diese standardmäßig mit 4GB RAM konfiguriert sind - zu viel für
+meine Test-VM. Der einzige Fehler, der in diesem Fall auf der Webseite angezeigt wird,
+ist der, dass das Build-System innerhalb einer bestimmten Zeit keine Verbindung zur VM
+aufbauen konnte. Der OOM-Fehler beim Start wurde weder geloggt noch an den Nutzer
+weitergegeben.
+
+Auf der Dokumentationsseite wird erwähnt, dass sich das Projekt noch im Alpha-Stadium
+befindet, es ist also zu hoffen, dass die Dokumentation in Zukunft verbessert wird.
+
+Ich habe sämtliche Schritte, die zur Installation meiner Testinstanz erforderlich waren,
+im [Anhang](sourcehut_setup.md) aufgelistet.
+
+## Systemanforderungen
+
+Sourcehut ist auf jedem System lauffähig, das Python 3.10 und Go unterstützt. Allerdings
+sind die Pakete momentan nur für die amd64-Architektur verfügbar. Wer Sourcehut also auf
+einem Raspberry Pi oder ARM-Server installieren will, muss die Pakete selbst
+kompilieren.
+
+Die CPU-Auslastung im Leerlauf ist gering (ca. 1%). Bei aufwändigen Git-Operationen
+sieht die Sache jedoch anders aus. Wenn man sich z.B. die Änderungshistorie der Makefile
+des Linux-Kernels anzeigen lässt, läuft git.sr.ht 30 Sekunden lang mit 100%
+CPU-Auslastung, bis Nginx die Anfrage wegen Zeitüberschreitung abbricht. Dieses Problem
+lässt sich auch auf der offiziellen Instanz reproduzieren
+([Link zum Testen](https://git.sr.ht/~gregkh/linux-stable/log/master/item/Makefile)).
+
+Zum Vergleich: Die Ausführung des Befehls `git --no-pager log Makefile | head -n 1000`
+benötigte auf meinem Testsystem nur 100ms.
+
+Beim Arbeitsspeicherverbrauch macht sich die Microservice-Architektur negativ bemerkbar:
+jeder Python-Dienst reserviert 90-100MB, die in Go geschriebenen API-Server kommen mit
+20-30MB RAM aus. Da die gesamte Sourcehut-Installation aus 14 Python- und 8 Go-Services
+besteht, summiert sich der Arbeitsspeicherbedarf auf ca. 1,5GB.
+
+## Bedienung
+
+Sourcehut's Weboberfläche ist spartanisch designt und kommt fast ohne JavaScript aus.
+Dadurch ist die Webseite ohne Probleme in alten Geräten und Browsern benutzbar.
+
+Die Repository-Ansicht ist klar an GitWeb angelehnt und zeigt die Dateien ähnlich wie
+der `ls -l`-Befehl zusammen mit Größe und Berechtigungen an.
+
+Genau wie GitWeb (und ls) platziert Sourcehut Ordner nicht vor Dateien, was das
+Auffinden bestimmter Ordner unter vielen Dateien erschwert.
+
+Eine Suchfunktion gibt es nicht, dadurch ist es schwierig, auf der Webseite durch große
+Projekte zu navigieren.
+
+Hinzu kommt, dass die Webseite nur Code und Markdown-Dokumente darstellen kann. Bilder,
+PDF-Dokumente oder andere Markupsprachen wie RST werden nicht unterstützt.
+
+
+
+Die einzelnen Komponenten von Sourcehut sind eigenständige Webanwendungen. Dies hat den
+Vorteil, dass man nur einen Teil von Sourcehut installieren kann, wenn man
+beispielsweise den Build-Service oder die Mailinglisten nicht benötigt. Allerdings macht
+diese Aufteilung die Bedienung an vielen Stellen hakelig. Es gibt zwar eine zentrale
+Projektverwaltung (hub.sr.ht), die Repositories, Issue-Tracker und Mailinglisten zu
+bestimmten Projekten zuordnet. Allerdings ist diese Verlinkung eine Einbahnstraße: von
+der Projekseite auf dem Hub kann man alle zugehörigen Repositories, Issue-Tracker und
+Mailinglisten aufrufen, befindet man sich aber bspw. in einem Repository, kann man das
+zugehörige Projekt nicht ohne weiteres ermitteln.
+
+ Projektansicht im SourceHut Hub
+
+Sourcehut unterscheidet sich von GitHub und anderen Code-Hosting-Plattformen vor allem
+dadurch, dass es zur Kollaboration zwischen Entwicklern keine Pull-Requests verwendet.
+Stattdessen basiert das System auf den "klassischen" Git-Workflow, also dem Austausch
+von Patches via E-Mail. Projekteigentümer können Mailinglisten einrichten und darüber
+Patches empfangen.
+
+Dies hat den Vorteil, dass außenstehende Entwickler sich nicht auf der Plattform
+registrieren müssen und ausschließlich via E-Mail mit den Maintainern des Projekts
+kommunizieren können.
+
+Sourcehut bietet Entwicklern auch die Möglichkeit, über die Weboberfläche Patches zu
+erstellen und zu versenden. Dazu muss man das Repository zuerst auf der Plattform
+klonen, die eigenen Commits hochladen und diese anschießend in der Weboberfläche
+auswählen.
+
+
+
+Auch wenn dieser Workflow sicherlich Vorteile mit sich bringt, muss man feststellen,
+dass dies für die meisten Entwickler ungewohnt und umständlich ist. Entwickler, die
+bisher nur mit GitHub und ähnlichen Plattformen gearbeitet haben, werden beim Versuch,
+zu einem Projekt beizutragen, eventuell auf Hindernisse stoßen.
+
+Es gibt auch ein CLI-Tool namens [hut](https://git.sr.ht/~emersion/hut), um die
+verschiedenen Sourcehut-Dienste mit der Kommandozeile zu bedienen. Das Tool erlaubt das
+Erstellen von Issues, Hochladen von Releases, Starten von Builds, Veröffentlichen von
+Webseiten, Hinzufügen von SSH-Keys und einiges mehr.
+
+## Import bestehender Projekte
+
+Die Sourcehut-Weboberfläche erlaubt auf lediglich den Import von öffentlichen
+Git-Repositories per clone. Es gibt keine Möglichkeit zum Import von Issues und
+Pull-Requests werden wie oben erwähnt nicht unterstützt.
+
+## Zusatzfeatures
+
+Wie bereits beschrieben besteht Sourcehut aus einer Vielzahl von Diensten, den
+Entwicklern neben Git-Hosting und Issue Tracking diverse Zusatzfeatures bieten.
+
+man.sr.ht ist ein auf Git basierendes Wiki, das in Markdown geschriebene
+Dokumentationstexte darstellen kann. Allerdings bietet es kaum Features: der einzige
+Unterschied zum Betrachten von Markdown-Dateien in git.sr.ht ist das
+Seiteninhaltsverzeichnis, das man.sr.ht oben anfügt. Es gibt kein Inhaltsverzeichnis
+über die gesamte Dokumentation, genauso wenig wie eine Suchfunktion.
+
+paste.sr.ht ist ein Pastebin zum Speichern und Veröffentlichen von kleineren Texten,
+Skripten und Codeausschnitten. Man kann Pastes öffentlich oder privat speichern und es
+gibt auch die Möglichkeit, Textdateien mit dem `hut`-CLI-Tool hochzuladen.
+
+pages.sr.ht ist ein Webhosting-Dienst, der es einem erlaubt, statische Webseiten unter
+einer persönlichen Subdomain zu veröffentlichen. Hierfür muss man sämtliche Dateien als
+`tar.gz`-Archiv komprimieren und anschließend mit dem `hut`-Tool hochladen.
+
+Das Issue-System von Sourcehut (todo.sr.ht) ist jedoch sehr rudimentär. Es gibt außer
+Labels und der Möglichkeit, verantwortliche Personen zuzuweisen keine Zusatzfunktionen,
+die das Projektmanagement erleichtern. Für größere Projekte ist daher die Verwendung
+einer zusätzlichen Projektmanagement-Software wie Redmine nötig.
+
+## Continous Integration
+
+builds.sr.ht ist ein sehr leistungsfähiges und einfach zu verwendender CI-System.
+
+Builds können über die Weboberfläche, eine API oder durch Git-Pushes und auf der
+Mailigliste eingegangene Patches initiiert werden. Zum Ausführen der Builds werden
+virtuelle Maschinen (mit QEMU/KVM) gestartet, wodurch die Build-Umgebung vom Server
+isoliert ist.
+
+QEMU erlaubt es auch, andere CPU-Architekturen zu emulieren und so beispielsweise
+Embedded Linux-Anwendungen zu testen.
+
+
+
+Sourcehut Builds werden durch
+[yaml-Manifests](https://man.sr.ht/builds.sr.ht/manifest.md) beschrieben. Die Syntax ist
+sehr simpel gehalten. Manifests bestehen aus dem Namen des VM-Images, den benötigten
+Paketen und Repositories und einem oder mehreren Shell-Skripten.
+
+```yaml
+image: alpine/latest
+packages:
+ - cargo
+sources:
+ - https://code.thetadev.de/ThetaDev/short-uuid.git
+tasks:
+ - test: |
+ cd short-uuid
+ cargo test
+```
+
+Es gibt auch die Möglichkeit, für den Build benötige Secrets wie API-Keys und
+SSH-Schlüssel zu hinterlegen. Die Secrets werden auf der Build-VM in Dateien abgelegt,
+von wo aus sie in Buildskripten verwendet werden können (z.B.
+`cargo publish --token "$(<~/.cargo-token)"`). Zudem gibt es die Möglichkeit, SSH- und
+GPG-Schlüssel automatisch zu importieren.
+
+Ein besonderes Feature von builds.sr.ht ist die Möglichkeit, fehlgeschlagene Builds zu
+analysieren. Schlägt ein Build fehl, läuft die entsprechende VM noch 10 Minuten weiter.
+In dieser Zeit kann man sich per SSH mit dem Build-Server verbinden und kann Befehle in
+der entsprechenden Build-VM ausführen. Auf diese Weise kann man Logdateien inspizieren
+oder den Build mit Konfigurationsänderungen neu starten, ohne jedes Mal das
+Buildmanifest zu ändern und neu zu übermitteln.
+
+
+
+Allerdings bietet Sourcehut Builds nicht die Möglichkeit, zu spezifizieren, wann ein
+Build ausgeführt werden soll. Builds werden immer dann gestartet, wenn ein Branch in
+einem Repository aktualisiert wird, in dem sich eine `.builds.yml`-Datei befindet.
+Eingehende Patches in der Mailingliste können ebenfalls einen Build startet.
+
+Es gibt jedoch keine Möglichkeit, Builds nur dann zu starten, wenn ein bestimmter Branch
+oder bestimmte Dateien aktualisiert wurden. Dies kann beispielsweise in Monorepos
+(Repositories mit mehreren Projekten) zu unnötig lange dauernden Builds führen.
+
+## Öffentliche Instanzen
+
+Die öffentliche Sourcehut-Instanz, die von Drew DeVault und seiner Firma betrieben wird,
+befindet sich unter .
+
+sr.ht ist der einige mir bekannte Git-Hosting-Anbieter, der ein kostenpflichtiges
+Abonnement für das Erstellen eigener Projekte erfordert. Solange sich Sourcehut im
+Alpha-Stadium befindet, ist das Abo allerdings optional (außer für die Nutzung des
+Build-Service). Das Abonnement kostet 20€ im Jahr, man kann auch auf freiwilliger Basis
+bis zum 100€ bezahlen, um das Projekt zu unterstützen.
+
+Die kostenpflichtigen Mitgliedschaften erlauben Sourcehut, finanziell unabhängig zu sein
+und nicht den Entscheidungen von Investoren unterworfen zu sein. Sourcehut
+veröffentlicht seine jährlichen Einnahmen und Ausgaben auf ihrem Blog und gibt an, seit
+2019 Profit zu erwirtschaften.
+
+Bekannte Projekte, die auf sr.ht gehostet werden sind das alternative Instagram-Frontend
+[Bibliogram](https://sr.ht/~cadence/bibliogram/),
+[microblog.pub](https://sr.ht/~tsileo/microblog.pub/), eine persönliche
+Microblogging-Anwendung mit ActivityPub-Unterstützung und natürlich
+[Sourcehut](https://sr.ht/~sircmpwn/sourcehut/) selbst. Insgesamt hostet sr.ht ca. 7100
+Projekte.
+
+Es gibt auch Open-Source-Projekte, die ihren Code auf anderen Plattformen hosten und nur
+das Build-System von Sourcehut nutzen. Beispielsweise benutzt die Linux-Distribution
+postmarketOS [Sourcehut Builds](https://build.postmarketos.org/) zum Bau ihrer Pakete.
+
+Wichtig ist noch zu erwähnen, dass die offizielle Sourcehut-Instanz keine Projekte
+erlaubt, die mit
+[Blockchain oder Kryptowährungen](https://sourcehut.org/blog/2022-10-31-tos-update-cryptocurrency/)
+zu tun haben. Sourcehut begründet dies damit, dass Kryptowährungen häufig für Betrug und
+andere Verbrechen eingesetzt werden und große Mengen an Ressourcen verschwenden.
+
+Abgesehen von der offiziellen Instanz gibt es sehr wenige weiterem öffentlichen
+Sourcehut-Instanzen, was wohl auch dem komplizierten Einrichtungsprozess geschuldet ist.
+
+Es existiert eine Instanz unter [gnu.org](https://sourcehut.gnu.org), die sich
+allerdings im Entwicklermodus befindet und über keine öffentlichen Projekte verfügt. Die
+größte alternative Sourcehut-Instanz, die ich gefunden habe, ist
+. Die Instanz wird von einer Webentwicklungsfirma
+betrieben, beherbergt 9 öffentliche Projekte und erlaubt keine Registrierung von
+Außenstehenden.
+
+## Fazit
+
+Das Highlight von sr.ht ist meiner Meinung nach der CI-Dienst. Während die meisten
+anderen CI-Dienste an Repositories gekoppelt sind, erlaubt es Sourcehut, einfach ein
+Build-Manifest mit dem CLI-Tool oder dem Formular auf der Website abzuschicken und
+ausführen zu lassen. Die Möglichkeit fehlgeschlagene Builds zu analysieren ist ebenfalls
+einzigartig.
+
+Allerdings ist die Einrichtung von Sourcehut sehr aufwändig und einige grundlegende
+Features wie eine Suchfunktion fehlen weswegen ich das System in seinem momentanen
+Zustand nicht empfehlen kann.
+
+Hinzu kommt, dass Sourcehut trotz seiner spartanischen Weboberfläche und seinem
+reduziertem Funktionsumfang das System mit dem zweithöchsten Ressourcenverbrauch im Test
+war.
+
+Da sich Sourcehut wie gesagt noch im Alpha-Stadium befindet, lohnt es sich jedoch das
+Projekt weiter zu verfolgen.
+
+## Quellen
+
+- Projektseite
+- Sourcehut Blog
diff --git a/src/studienarbeit/5_onedev.md b/src/studienarbeit/5_onedev.md
new file mode 100644
index 0000000..8394d68
--- /dev/null
+++ b/src/studienarbeit/5_onedev.md
@@ -0,0 +1,232 @@
+# OneDev
+
+Abschließen möchte ich meinen Test mit einer weitgehend unbekannten Plattform, die erst
+2019 als Hobbyprojekt von zwei Entwicklern veröffentlicht wurde, sich aber in Sachen
+Funktionalität nicht vor den anderen Plattformen verstecken muss: OneDev.
+
+
+
+OneDev ist in Java geschrieben und verwendet das Webframework Apache Wicket. Das Projekt
+wird hauptächlich von Robin Shen und Steve Luo entwickelt, insgesamt gibt es ca. 30
+Beitragende. Das Projekt ist unter der MIT-Lizenz veröffentlicht.
+
+Der
+[erste Commit](https://code.onedev.io/onedev/server/~commits/6be8e3f97c97e44cf6b5a9b8360c299cc55388f6)
+erfolgte im April 2012, die erste in Git getaggte Version (2.0.0) wurde 2019
+veröffentlicht. Rechnet man mit dem Datum des ersten Release, ist OneDev die jüngste der
+vier Plattformen, die ich getestet habe.
+
+OneDev besteht aus einer einzigen Java-Anwendung und erfordert bei Verwendung der
+eingebetteten HSQL-Datenbank keine zusätzlichen Dienste zum Betrieb. Es werden auch
+externe Datenbanken (MySQL, MariaDB, Postgres, MS SQL, Oracle) unterstützt.
+
+Getestet wurde die Version 8.5.2.
+
+## Installation
+
+Die OneDev-Entwickler stellen Container-Images für OneDev zur Verfügung
+(`docker.io/1dev/server`), mit denen sich OneDev einfach mittels Docker installieren
+lässt. Alternativ gibt es auch die Möglichkeit, die Java-Anwendung direkt auf seinem
+System zu installieren oder OneDev in einem Kubernetes-Cluster zu betreiben.
+
+Für den Installationsprozess gibt es eine Schritt-für-Schritt-Anleitung auf der
+Dokumentationsseite des Projekts. Allerdings bin ich hiervon abgewichen, da in der
+Installationsanleitung empfohlen wird, den Docker-Socket (`/var/run/docker.sock`) im
+OneDev-Container als Volume einzubinden.
+
+Dies ist nur dann erforderlich, wenn der eingebaute _Server Docker Executor_ anstelle
+eines externen Agents für CI-Jobs verwendet wird.
+
+Da Container mit Docker-Zugriff effektiv über Root-Rechte auf dem Hostsystem verfügen,
+ist dies jedoch mit einem Sicherheitsrisiko verbunden. Deswegen empfehle ich, den
+eingebauten Agent nicht zu nutzen und stattdessen den seperaten Agent-Container
+(`docker.io/1dev/agent`) zu verwenden. Der CI-Agent sollte bei einem Produktionssetup
+auf einem anderen Server bzw. einer anderen VM laufen, auf der sich keine wertvollen
+oder sensiblen Daten befinden - insbesondere wenn nicht vertrauenswürdige Nutzer Zugriff
+auf das CI-System haben.
+
+[Hier](./assets/onedev/docker-compose.yml) ist die Docker-Compose-Datei, die ich für
+meine Testinstallation verwendet habe.
+
+Nach dem Start des Servers kann man auf der Weboberfläche den ersten Benutzeraccount
+anlegen und die URL des Servers konfigurieren.
+
+Anschließend muss noch das CI-System eingerichtet werden. Hierzu öffnet man den
+Menüpunkt _Administration_ \> _Agents_, klickt auf _Tokens_ und generiert sich einen
+neuen Agent Token. Dieser Token muss dem Agent als Umgebungsvariable übergeben werden
+(also z.B. in die Docker-Compose-Datei eintragen). Nach dem Start des Agents muss dieser
+in der Tabelle sichtbar sein.
+
+
+
+Danach öffnet man den Menüpunkt _Job Executors_ und erstellt einen _Remote Docker
+Executor_. Damit ist die Einrichtung des CI-Systems abgeschlossen und man kann den
+ersten Build starten (siehe im Abschnitt
+[Continuous Integration](#continous-integration)).
+
+Standardmäßig erlaubt OneDev nur angemeldeten Benutzern den Zugriff auf die Instanz. Um
+seine Projekte öffentlich verfügbar zu machen, muss noch die Option _Security Settings_
+\> _Enable Anonymous Access_ aktiviert werden.
+
+## Systemanforderungen
+
+OneDev ist auf jedem System mit Java-Unterstützung lauffähig. Das offizielle
+Docker-Image wird für die 64bit Interl/AMD und ARM-Architektur angeboten.
+
+Der Server benötigte auf meinem System ca. 1.2GB Arbeitsspeicher, der CI-Agent ca.
+180MB. Die CPU-Auslastung im Leerlauf beträgt auf meinem System (AMD Ryzen 5700G) ca.
+1%, mit gelegentlichen Spitzen auf 5-10%.
+
+Aufwändige Git-Operationen (History/Blame in großen Repositories) können Lastspitzen von
+bis zu 100% mit einer Dauer von max. 2 Sekunden verursachen. Bei Nutzung der
+Suchfunktion habe ich bis zu 50% Auslastung gemessen.
+
+## Bedienung
+
+OneDev verfügt über eine modern gestaltete Weboberfläche, die mit dem Webframework
+Apache Wicket realisiert wurde. Das Framework lädt beim Navigieren nur die Teile der
+Website vom Server, die sich durch den entsprechenden Navigationsschritt geändert haben
+(also z.B. die Dateiliste).
+
+Dadurch geht das Navigieren durch die Repositories sehr flüssig vonstatten, ohne dass
+die gesamte Seite neu geladen werden muss.
+
+Ein Alleinstellungsmerkmal von OneDev ist die Suchfunktion. OneDev verwendet nicht nur
+eine Textsuchmaschine, sondern analysiert den Code im Repository und bietet so die
+Möglichkeit, nach Klassen und Funktionen zu suchen. Die Suchergebnisse werden während
+dem Tippen angezeigt. Auf diese Weise kann man schnell durch komplexe Softwareprojekte
+navigieren.
+
+
+
+Die Suche kann auch über ein Kontextmenü in der Code-Ansicht aufgrufen werden. Auf diese
+Weise kann man nach Definitionen oder Verwendungen von Funktionen suchen. Es gibt auch
+eine Übersicht aller Klassen und Funktionen einer Datei auf der rechten Seite.
+
+Die Code-Analyse ist für die Sprachen Java, JavaScript, C, C++, CSharp, Go, PHP, Python,
+CSS, SCSS, LESS und R verfügbar. Rust wird leider nicht unterstützt.
+
+
+
+OneDev kann auf der Weboberfläche Code, Markdown-Dokumente und Bilder darstellen. Es
+gibt keine Unterstützung für alternative Markupsprachen wie RST.
+
+## Import bestehender Projekte
+
+OneDev bietet einen Import-Assistenten mit Unterstützung für GitHub, Gitlab, BitBucket,
+und Gitea. Neben dem Git-Repository werden auch Metadaten und Issues übertragen.
+
+Der Importer erlaubt es auch, nach einer Authentifizierung per API-Key sämtliche
+Projekte eines Nutzers oder einer Organisation zu übertragen, was beim Umstieg viel Zeit
+sparen kann.
+
+Es gibt jedoch nicht die Möglichkeit, Projekte aus anderen OneDev-Instanzen zu
+übertragen.
+
+## Zusatzfeatures
+
+OneDev verfügt über umfangreiche Tools zum Projektmanagement. Es gibt die Möglichkeit,
+Issues zu Meilensteinen zuzuordnen (z.B. _Sprint 14_ oder _Version 2.0_). Zudem verfügt
+OneDev über Issue Boards, um Issues je nach Status in mehreren Spalten anzuzeigen.
+
+
+
+Issues können bestimmten Entwicklern zugewiesen werden und es gibt die Möglichkeit,
+Abhängigkeiten zwischen Issues zu definieren (z.B. Issue A muss vor Issue B erledigt
+werden). Was allerdings fehlt ist die Möglichkeit, einem Issue mehrere Labels
+zuzuordnen.
+
+OneDev bietet auch die Möglichkeit, statische Webseiten zu hosten. Hierfür ist im
+Gegensatz zu Gitlab Pages keine separate Domain nötig. Stattdessen wird die Webseite im
+Unterverzeichnis `~site` des Repositorys (z.B. `https://example.com/user/repo/~site`)
+veröffentlicht.
+
+Als einzige getestete Plattform verfügt OneDev über ein Plugin-System. Auf diese Weise
+lassen sich neue Features implementieren, ohne die Software verändern zu müssen.
+Beispielsweise gibt es ein Plugin zum
+[Import von Issues](https://github.com/DevCharly/onedev-plugin-import-redmine/) aus der
+Projektmanagement-Anwendung Redmine.
+
+Weitere Zusatzfeatures wie Paketmanagement bietet OneDev nicht. Darüber hinaus fehlt die
+Möglichkeit, Releases seiner Software hochzuladen und mit Git-Tags zu verknüpfen. Dieses
+Feature beherrschen ansonsten alle getesteten Plattformen.
+
+## Continous Integration
+
+OneDev bietet ein eingebautes CI-System um Projekte zu kompilieren und zu testen. Die
+Jobs können in Docker-Containern, Kubernetes-Pods oder bare metal ausgeführt werden.
+
+Jobs werden in einer yml-Datei definiert, die als `.onedev-buildspec.yml` im
+Wurzelverzeichnis des Repositories abgelegt werden muss.
+
+OneDev bietet jedoch auch eine Weboberfläche, um Builds zu erstellen und zu bearbeiten.
+Auf diese Weise muss man nicht zuerst die yaml-Syntax erlernen, um das CI-System zu
+nutzen. Über die Weboberfläche lassen sich bestimmte Aktionen (z.B. "Befehle ausführen",
+"Docker Image bauen", "Webseite veröffentlichen") auswählen und konfigurieren.
+
+
+
+```yml
+version: 23
+jobs:
+ - name: test
+ steps:
+ - !CheckoutStep
+ name: checkout
+ cloneCredential: !DefaultCredential {}
+ withLfs: false
+ withSubmodules: false
+ condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
+ - !CommandStep
+ name: build
+ runInContainer: true
+ image: rust:latest
+ interpreter: !DefaultInterpreter
+ commands:
+ - rustup component add rustfmt clippy
+ - cargo fmt --all --check
+ - cargo clippy --all --features=rss -- -D warnings
+ - cargo test --features=rss --workspace
+ useTTY: false
+ condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
+ triggers:
+ - !BranchUpdateTrigger {}
+ - !PullRequestUpdateTrigger {}
+ retryCondition: never
+ maxRetries: 3
+ retryDelay: 30
+ timeout: 3600
+```
+
+Die Builds können durch Branch Updates oder neue Pull Requests ausgelöst werden. Es gibt
+auch die Möglichkeit, Builds zeitgesteuert oder manuell zu starten.
+
+## Öffentliche Instanzen
+
+Das OneDev-Team betreibt ihre eigene Instanz unter
+[code.onedev.io](https://code.onedev.io). Allerdings verbietet diese Instanz das
+erstellen eigener Projekte und dient nur der Entwicklung und Demonstration der
+Plattform.
+
+Darüber hinaus habe ich außer einer kleinen privaten Instanz names
+["Winux Projects"](https://projects.winux.it/) keine öffentlichen Instanzen gefunden,
+was sicher auch daran liegt, dass das Projekt momentan noch relativ unbekannt ist.
+
+## Fazit
+
+Obwohl OneDev noch relativ jung und weitgehend unbekannt ist, kann es funktional
+durchaus mit den Konkurrenten mithalten. Insbesondere die intelligente Suchfunktion und
+das einfach zu bedienende CI-System haben mir im Test sehr gut gefallen.
+
+Allerdings ist OneDev immer noch ein Hobbyprojekt von 2 Entwicklern und hat keine Firma
+oder größere Organisation hinter sich. Wer OneDev beispielsweise in einem Unternehmen
+einsetzen möchte, muss die Einrichtung und den Support selbst übernehmen, da es im
+Gegensatz zu GitLab und Gitea keine öffentlichen Instanzen oder SaaS-Angebote gibt.
+
+Wer sich hieran nicht stört, erhält mit OneDev eine leichtgewichtige, einfach zu
+installierende und moderne Git-Hosting-Plattform.
+
+## Quellen
+
+- Projektseite
+- Repository
diff --git a/src/studienarbeit/assets/gitea/actions.png b/src/studienarbeit/assets/gitea/actions.png
new file mode 100644
index 0000000..3a6d89c
Binary files /dev/null and b/src/studienarbeit/assets/gitea/actions.png differ
diff --git a/src/studienarbeit/assets/gitea/homepage.png b/src/studienarbeit/assets/gitea/homepage.png
new file mode 100644
index 0000000..27cf819
Binary files /dev/null and b/src/studienarbeit/assets/gitea/homepage.png differ
diff --git a/src/studienarbeit/assets/gitea/search.png b/src/studienarbeit/assets/gitea/search.png
new file mode 100644
index 0000000..bccbde9
Binary files /dev/null and b/src/studienarbeit/assets/gitea/search.png differ
diff --git a/src/studienarbeit/assets/gitea/setup.png b/src/studienarbeit/assets/gitea/setup.png
new file mode 100644
index 0000000..b259dc3
Binary files /dev/null and b/src/studienarbeit/assets/gitea/setup.png differ
diff --git a/src/studienarbeit/assets/gitea/woodpecker.png b/src/studienarbeit/assets/gitea/woodpecker.png
new file mode 100644
index 0000000..cc72833
Binary files /dev/null and b/src/studienarbeit/assets/gitea/woodpecker.png differ
diff --git a/src/studienarbeit/assets/gitlab/architecture.png b/src/studienarbeit/assets/gitlab/architecture.png
new file mode 100644
index 0000000..dcdb9d7
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/architecture.png differ
diff --git a/src/studienarbeit/assets/gitlab/docker-compose.yml b/src/studienarbeit/assets/gitlab/docker-compose.yml
new file mode 100644
index 0000000..10c3fb3
--- /dev/null
+++ b/src/studienarbeit/assets/gitlab/docker-compose.yml
@@ -0,0 +1,21 @@
+version: "3.6"
+services:
+ web:
+ image: "gitlab/gitlab-ce:latest"
+ restart: unless-stopped
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ external_url 'http://localhost:8001'
+ nginx['listen_https'] = false
+ nginx['listen_port'] = 80
+ nginx['redirect_http_to_https'] = false
+ letsencrypt['enable'] = false
+ GITLAB_ROOT_PASSWORD: secret1234
+ ports:
+ - "8001:80"
+ - "2222:22"
+ volumes:
+ - "./config:/etc/gitlab"
+ - "./logs:/var/log/gitlab"
+ - "./data:/var/opt/gitlab"
+ shm_size: "256m"
diff --git a/src/studienarbeit/assets/gitlab/import.png b/src/studienarbeit/assets/gitlab/import.png
new file mode 100644
index 0000000..91318ff
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/import.png differ
diff --git a/src/studienarbeit/assets/gitlab/issue.png b/src/studienarbeit/assets/gitlab/issue.png
new file mode 100644
index 0000000..3fb10e8
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/issue.png differ
diff --git a/src/studienarbeit/assets/gitlab/kanban.png b/src/studienarbeit/assets/gitlab/kanban.png
new file mode 100644
index 0000000..ba830d6
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/kanban.png differ
diff --git a/src/studienarbeit/assets/gitlab/runners.png b/src/studienarbeit/assets/gitlab/runners.png
new file mode 100644
index 0000000..7af0ac4
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/runners.png differ
diff --git a/src/studienarbeit/assets/gitlab/web_ide.png b/src/studienarbeit/assets/gitlab/web_ide.png
new file mode 100644
index 0000000..315d302
Binary files /dev/null and b/src/studienarbeit/assets/gitlab/web_ide.png differ
diff --git a/src/studienarbeit/assets/onedev/add_agent.png b/src/studienarbeit/assets/onedev/add_agent.png
new file mode 100644
index 0000000..de4ef57
Binary files /dev/null and b/src/studienarbeit/assets/onedev/add_agent.png differ
diff --git a/src/studienarbeit/assets/onedev/build.png b/src/studienarbeit/assets/onedev/build.png
new file mode 100644
index 0000000..5edff29
Binary files /dev/null and b/src/studienarbeit/assets/onedev/build.png differ
diff --git a/src/studienarbeit/assets/onedev/ci_editor.png b/src/studienarbeit/assets/onedev/ci_editor.png
new file mode 100644
index 0000000..215d921
Binary files /dev/null and b/src/studienarbeit/assets/onedev/ci_editor.png differ
diff --git a/src/studienarbeit/assets/onedev/code_navigation.png b/src/studienarbeit/assets/onedev/code_navigation.png
new file mode 100644
index 0000000..b4d6315
Binary files /dev/null and b/src/studienarbeit/assets/onedev/code_navigation.png differ
diff --git a/src/studienarbeit/assets/onedev/docker-compose.yml b/src/studienarbeit/assets/onedev/docker-compose.yml
new file mode 100644
index 0000000..c35eabe
--- /dev/null
+++ b/src/studienarbeit/assets/onedev/docker-compose.yml
@@ -0,0 +1,19 @@
+version: "3"
+services:
+ onedev:
+ image: 1dev/server:latest
+ ports:
+ - 6610:6610
+ - 6611:6611
+ volumes:
+ - ./data:/opt/onedev
+ agent:
+ image: 1dev/agent:latest
+ environment:
+ - "serverUrl=http://onedev:6610"
+ - "agentToken=3922e711-8a7f-4dd0-8b68-fd3ca891ffff"
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - ./work:/agent/work
+ depends_on:
+ - onedev
diff --git a/src/studienarbeit/assets/onedev/homepage.png b/src/studienarbeit/assets/onedev/homepage.png
new file mode 100644
index 0000000..e577248
Binary files /dev/null and b/src/studienarbeit/assets/onedev/homepage.png differ
diff --git a/src/studienarbeit/assets/onedev/kanban.png b/src/studienarbeit/assets/onedev/kanban.png
new file mode 100644
index 0000000..027163e
Binary files /dev/null and b/src/studienarbeit/assets/onedev/kanban.png differ
diff --git a/src/studienarbeit/assets/onedev/search.png b/src/studienarbeit/assets/onedev/search.png
new file mode 100644
index 0000000..1df4329
Binary files /dev/null and b/src/studienarbeit/assets/onedev/search.png differ
diff --git a/src/studienarbeit/assets/sourcehut.dio b/src/studienarbeit/assets/sourcehut.dio
deleted file mode 100644
index aa6a495..0000000
--- a/src/studienarbeit/assets/sourcehut.dio
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/studienarbeit/assets/sourcehut/failed_build.png b/src/studienarbeit/assets/sourcehut/failed_build.png
new file mode 100644
index 0000000..71e8dd2
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/failed_build.png differ
diff --git a/src/studienarbeit/assets/sourcehut/homepage.png b/src/studienarbeit/assets/sourcehut/homepage.png
new file mode 100644
index 0000000..10d0d46
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/homepage.png differ
diff --git a/src/studienarbeit/assets/sourcehut/hub.png b/src/studienarbeit/assets/sourcehut/hub.png
new file mode 100644
index 0000000..faabd0e
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/hub.png differ
diff --git a/src/studienarbeit/assets/oauth.png b/src/studienarbeit/assets/sourcehut/oauth.png
similarity index 100%
rename from src/studienarbeit/assets/oauth.png
rename to src/studienarbeit/assets/sourcehut/oauth.png
diff --git a/src/studienarbeit/assets/oauth_new_client.png b/src/studienarbeit/assets/sourcehut/oauth_new_client.png
similarity index 100%
rename from src/studienarbeit/assets/oauth_new_client.png
rename to src/studienarbeit/assets/sourcehut/oauth_new_client.png
diff --git a/src/studienarbeit/assets/sourcehut/repo.png b/src/studienarbeit/assets/sourcehut/repo.png
new file mode 100644
index 0000000..1f7629c
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/repo.png differ
diff --git a/src/studienarbeit/assets/sourcehut/send_patchset.png b/src/studienarbeit/assets/sourcehut/send_patchset.png
new file mode 100644
index 0000000..43ca636
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/send_patchset.png differ
diff --git a/src/studienarbeit/assets/sourcehut/sourcehut.dio b/src/studienarbeit/assets/sourcehut/sourcehut.dio
new file mode 100644
index 0000000..df756ce
--- /dev/null
+++ b/src/studienarbeit/assets/sourcehut/sourcehut.dio
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/studienarbeit/assets/sourcehut/sourcehut.png b/src/studienarbeit/assets/sourcehut/sourcehut.png
new file mode 100644
index 0000000..8d7c4e7
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/sourcehut.png differ
diff --git a/src/studienarbeit/assets/sourcehut/sourcehut_arch.svg b/src/studienarbeit/assets/sourcehut/sourcehut_arch.svg
new file mode 100644
index 0000000..eb31e5c
--- /dev/null
+++ b/src/studienarbeit/assets/sourcehut/sourcehut_arch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/studienarbeit/assets/sourcehut/successful_build.png b/src/studienarbeit/assets/sourcehut/successful_build.png
new file mode 100644
index 0000000..edceae8
Binary files /dev/null and b/src/studienarbeit/assets/sourcehut/successful_build.png differ
diff --git a/src/studienarbeit/assets/config.ini b/src/studienarbeit/assets/sourcehut_setup/config.ini
similarity index 100%
rename from src/studienarbeit/assets/config.ini
rename to src/studienarbeit/assets/sourcehut_setup/config.ini
diff --git a/src/studienarbeit/assets/nginx/graphql.conf b/src/studienarbeit/assets/sourcehut_setup/nginx/graphql.conf
similarity index 100%
rename from src/studienarbeit/assets/nginx/graphql.conf
rename to src/studienarbeit/assets/sourcehut_setup/nginx/graphql.conf
diff --git a/src/studienarbeit/assets/nginx/nginx_services.conf b/src/studienarbeit/assets/sourcehut_setup/nginx/nginx_services.conf
similarity index 100%
rename from src/studienarbeit/assets/nginx/nginx_services.conf
rename to src/studienarbeit/assets/sourcehut_setup/nginx/nginx_services.conf
diff --git a/src/studienarbeit/assets/nginx/port80.conf b/src/studienarbeit/assets/sourcehut_setup/nginx/port80.conf
similarity index 100%
rename from src/studienarbeit/assets/nginx/port80.conf
rename to src/studienarbeit/assets/sourcehut_setup/nginx/port80.conf
diff --git a/src/studienarbeit/assets/nginx/sourcehut.conf b/src/studienarbeit/assets/sourcehut_setup/nginx/sourcehut.conf
similarity index 100%
rename from src/studienarbeit/assets/nginx/sourcehut.conf
rename to src/studienarbeit/assets/sourcehut_setup/nginx/sourcehut.conf
diff --git a/src/studienarbeit/assets/nginx/web.conf b/src/studienarbeit/assets/sourcehut_setup/nginx/web.conf
similarity index 100%
rename from src/studienarbeit/assets/nginx/web.conf
rename to src/studienarbeit/assets/sourcehut_setup/nginx/web.conf
diff --git a/src/studienarbeit/assets/woodpecker/docker-compose.yml b/src/studienarbeit/assets/woodpecker/docker-compose.yml
new file mode 100644
index 0000000..add0cd6
--- /dev/null
+++ b/src/studienarbeit/assets/woodpecker/docker-compose.yml
@@ -0,0 +1,48 @@
+version: "3"
+services:
+ woodpecker-server:
+ image: woodpeckerci/woodpecker-server:next
+ restart: unless-stopped
+ networks:
+ - proxy
+ environment:
+ - WOODPECKER_OPEN=true
+ - WOODPECKER_HOST=https://ci.thetadev.de
+ - WOODPECKER_GITEA=true
+ - WOODPECKER_GITEA_URL=https://code.thetadev.de
+ - WOODPECKER_GITEA_CLIENT=48060801-dc04-4361-b0a9-eefbfc6f29d0
+ - WOODPECKER_GITEA_SECRET=gto_wefjljwg4ouio34goi4ui34ui34uighjrfvnerrejrekwhgui34g4
+ - WOODPECKER_AGENT_SECRET=f81909f8e70371af65a6e1c6e77d35d4677c3ed242dcadde032fb27a9c5f9c35
+ labels:
+ - "traefik.enable=true"
+ - "traefik.docker.network=proxy"
+ - "traefik.http.routers.woodpecker.entrypoints=websecure"
+ - "traefik.http.routers.woodpecker.rule=Host(`ci.thetadev.de`)"
+ - "traefik.http.routers.woodpecker.service=woodpecker"
+ - "traefik.http.services.woodpecker.loadbalancer.server.port=8000"
+
+ # gRPC service
+ - "traefik.http.routers.woodpecker-grpc.entrypoints=websecure"
+ - "traefik.http.routers.woodpecker-grpc.rule=Host(`ci-grpc.thetadev.de`)"
+ - "traefik.http.routers.woodpecker-grpc.service=woodpecker-grpc"
+ - "traefik.http.services.woodpecker-grpc.loadbalancer.server.port=9000"
+ - "traefik.http.services.woodpecker-grpc.loadbalancer.server.scheme=h2c"
+
+ woodpecker-agent:
+ image: woodpeckerci/woodpecker-agent:next
+ command: agent
+ restart: unless-stopped
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /etc/localtime:/etc/localtime:ro
+ environment:
+ - "WOODPECKER_SERVER=ci-grpc.thetadev.de:443"
+ - "WOODPECKER_AGENT_SECRET=f81909f8e70371af65a6e1c6e77d35d4677c3ed242dcadde032fb27a9c5f9c35"
+ - "WOODPECKER_MAX_PROCS=2"
+ - "WOODPECKER_HOSTNAME=ocloud"
+ - WOODPECKER_GRPC_SECURE=true
+ - WOODPECKER_GRPC_VERIFY=true
+
+networks:
+ proxy:
+ external: true
diff --git a/src/studienarbeit/sourcehut_setup.md b/src/studienarbeit/sourcehut_setup.md
index 57cd4c3..113dbd8 100644
--- a/src/studienarbeit/sourcehut_setup.md
+++ b/src/studienarbeit/sourcehut_setup.md
@@ -108,7 +108,7 @@ weswegen ich meine Konfiguration aus den einzelnen Repositories zusammenkopieren
-
-
-[Beispielkonfiguration](./assets/config.ini)
+[Beispielkonfiguration](./assets/sourcehut_setup/config.ini)
Folgende Optionen müssen angepasst werden:
@@ -123,8 +123,8 @@ Anschließend kann man Nginx so konfigurieren, dass Web-Anfragen an die einzelne
weitergeleitet werden können. Eine Nginx-Beispielkonfiguration findet sich in
[diesem Repository](https://git.sr.ht/~sircmpwn/sr.ht-nginx/tree) auf Sourcehut.
-[Hier](./assets/nginx/nginx_services.conf) befindet sich die angepasste Version (ohne
-HTTPS), die ich für meine Testinstallation verwendet habe.
+[Hier](./assets/sourcehut_setup/nginx/nginx_services.conf) 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
@@ -189,12 +189,12 @@ Die einzelnen Sourcehut-Dienste verwenden OAuth zur Authentifizierung der Nutzer
Dienst muss hierfür über eine eigene Client-Konfiguration verfügen. Diese lässt sich
über das (Legacy) OAuth-Dashboard unter `meta./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 `[.sr.ht]/oauth-client-id` und
@@ -237,24 +237,44 @@ 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
```
-###
-# git.sr.ht (Port: 5001, API-Port 5101)
-
-apk add fcgiwrap git-daemon
+# Abhängigkeiten für git-http server installieren
+apk add git-sr.ht fcgiwrap git-daemon
gitsrht-initdb
+```
-SSH config:
+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_*
+```
-Set a password for git user
+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
@@ -265,11 +285,8 @@ rc-service git.sr.ht-webhooks start
rc-service git.sr.ht-api start
rc-service git.sr.ht start
-# Create logfile:
-touch /var/log/gitsrht-shell
-chown git:git /var/log/gitsrht-shell
-
-Cron: */20 * * * * gitsrht-periodic
+# Cronjob hinzufügen:
+*/20 * * * * gitsrht-periodic
```
### man.sr.ht
@@ -277,9 +294,13 @@ Cron: */20 * * * * gitsrht-periodic
- 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.
+
```
-###
-# man.sr.ht (Port: 5004, API-Port: 5104)
+apk add man.sr.ht
+
+mansrht-initdb
rc-update add man.sr.ht
rc-update add man.sr.ht-api
@@ -293,9 +314,12 @@ rc-service man.sr.ht start
- Web-UI: Port 5011
- API: Port 5111
+paste.sr.ht ist ein simpler Pastebin, mit dem man Codeschnipsel speichern und
+veröffentlichen kann.
+
```
-###
-# paste.sr.ht (Port: 5011, API-Port: 5111)
+apk add paste.sr.ht
+pastesrht-initdb
rc-update add paste.sr.ht
rc-update add paste.sr.ht-api
@@ -309,56 +333,114 @@ rc-service paste.sr.ht start
- 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:
+
+
+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:
+
```
-###
-# builds.sr.ht (Port: 5002, API-Port: 5102)
+# Master-Server
+apk add builds.sr.ht
+# Worker-Server
+builds.sr.ht-worker builds.sr.ht-images
-Nested virtualization must be enabled: https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/
+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
+```
-sudo adduser -SDH docker docker
+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.
-# /etc/sudoers.d
-builds ALL=(docker) NOPASSWD: /var/lib/images/control
+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.
-# Build images
-apk add docker builds.sr.ht-images
+```
+apk add docker
rc-update add docker
rc-service docker start
-docker run --privileged --rm tonistiigi/binfmt --install all
+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
-
-# Skript-Anpassungen
-exec ../genimg => exec ../genimg ${1:-x86_64}
-'modprobe nbd max_part=16' auskommentieren
-syslinux-Installation entfernen
-
-if [ "$arch" == "x86_64" ] || [ "$arch" == "i686" ]; then
- apk add -U \
- -X http://dl-cdn.alpinelinux.org/alpine/$release/main/ \
- -X http://dl-cdn.alpinelinux.org/alpine/$release/community/ \
- --allow-untrusted \
- --arch="$arch" \
- --root=/mnt \
- syslinux
-fi
-
-# Alpine image
docker run -it --rm --privileged -v /var/lib/images:/images alpine:3.17
-apk add qemu-img sfdisk e2fsprogs syslinux
-cd /images/alpine/3.17
-./genimg
+# 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
@@ -370,16 +452,27 @@ rc-service builds.sr.ht-worker start
- API: Port 5103
```
-###
-# todo.sr.ht (Port: 5003, API-Port 5103)
+apk add todo.sr.ht
+```
-NOT todosrht-initdb
+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
+```
-# services
+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
@@ -396,10 +489,13 @@ rc-service todo.sr.ht start
- Web-UI: Port 5006
- API: Port 5106
-```
-###
-# lists.sr.ht (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:
+
+
+```
listssrht-initdb
rc-update add lists.sr.ht