Compare commits
4 commits
32ae08d4e9
...
1dc8c5cef4
Author | SHA1 | Date | |
---|---|---|---|
1dc8c5cef4 | |||
9732eff09a | |||
0e45640871 | |||
0072d648c4 |
|
@ -11,5 +11,8 @@
|
||||||
# Selfhosting von Open-Source-Entwicklertools
|
# Selfhosting von Open-Source-Entwicklertools
|
||||||
|
|
||||||
- [Einleitung](./studienarbeit/1_einleitung.md)
|
- [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)
|
- [Anhang: Sourcehut-Setup](./studienarbeit/sourcehut_setup.md)
|
||||||
|
|
|
@ -1,26 +1,48 @@
|
||||||
# Selfhosting von Open-Source-Entwicklertools
|
# 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,
|
Hierbei kommt fast immer eine Git-Hosting-Plattform zum Einsatz. Diese erlaubt es einem,
|
||||||
Chris Wanstrath, P. J. Hyett and Scott Chacon gegründet und ging 2008 ans Netz. 2018
|
sein Repository zu veröffentlichen und mit anderen Personen über das Internet
|
||||||
wurde die Firma von Microsoft übernommen.
|
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
|
Der meistgenutzte Git-Hosting-Anbieter ist GitHub. Die Plattform wurde von Tom
|
||||||
kostenlos ist und man deswegen keinen Vertrag mit dem Anbieter abgeschlossen hat,
|
Preston-Werner, Chris Wanstrath, P. J. Hyett and Scott Chacon gegründet und ging 2008
|
||||||
komplett von dessen Entscheidungen und Nutzungsbedingungen abhängig. Der Anbieter kann
|
ans Netz. 2018 wurde die Firma von Microsoft übernommen.
|
||||||
den Dienst einstellen, kostenpflichtig machen oder bestimmte Nutzer ausschließen.
|
|
||||||
|
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
|
Beispielsweise wurde der russische Webentwickler Nikolay Kuchumov wegen eines einzigen
|
||||||
beleidigenden Issues
|
beleidigenden Issues
|
||||||
[2020 auf GitHub gesperrt](https://medium.com/@catamphetamine/how-github-blocked-me-and-all-my-libraries-c32c61f061d3).
|
[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
|
Dabei wurden alle seine Repositories von der Plattform entfernt. Noch absurder: GitHub
|
||||||
Kopie seines Personalausweis um die Sperre wieder aufzuheben.
|
verlangte eine Kopie seines Personalausweis um die Sperre wieder aufzuheben.
|
||||||
|
|
||||||
Es gibt auch zahlreiche Bespiele von Open Source-Projekten, die von GitHub wegen
|
Es gibt auch einige Fälle von Open Source-Projekten, die von GitHub wegen angeblichen
|
||||||
Verstößen gegen ihre Nutzungsbedingungen oder DMCA-Reports gesperrt wurden. Das
|
Verstößen gegen das amerikanische Urheberrecht (DMCA) gesperrt wurden. Das prominenteste
|
||||||
prominenteste Beispiel hierfür ist der Video-Downloader
|
Beispiel hierfür ist der Video-Downloader
|
||||||
[yt-dlp](github.com/yt-dlp/yt-dlp/).
|
[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
|
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,
|
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
|
Trainingsdaten enthalten kann, die dann ohne Erwähnung des Urhebers in andere Projekte
|
||||||
eingefügt werden.
|
eingefügt werden.
|
||||||
|
|
||||||
Insbesondere bei privaten oder firmeninternen Projekten kann auch Datenschutz ein Grund
|
Insbesondere bei privaten oder firmeninternen Projekten kann auch der Datenschutz ein
|
||||||
sein, auf Webanwendungen von Fremdanbietern (insbesondere im Ausland) zu verzichten und
|
Grund sein, auf Webanwendungen von Fremdanbietern zu verzichten und die Daten auf
|
||||||
die Daten auf eigenen Servern zu speichern. Da GitHub nicht quelloffen ist und nur mit
|
eigenen Servern zu speichern. Da GitHub nicht quelloffen ist und nur mit einer
|
||||||
einer kostspieligen Enterprise-Lizenz selbst gehostet werden kann, ist is für solche
|
kostspieligen Enterprise-Lizenz selbst gehostet werden kann, ist is für solche Fälle
|
||||||
Fälle attraktiv, eine Open-Source-Anwendung einzusetzen.
|
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
|
## 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
|
Zuerst werde ich einige grundlegende Informationen über die entsprechende Anwendung
|
||||||
präsentieren.
|
präsentieren.
|
||||||
|
@ -49,7 +80,7 @@ präsentieren.
|
||||||
- Wie viele Beitragende hat das Projekt?
|
- Wie viele Beitragende hat das Projekt?
|
||||||
- Wie sieht die Architektur der Anwendung aus? Welche Dienste werden benötigt?
|
- 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
|
Hier gebe ich eine kurze Anleitung zur Installation und Einrichtung der Anwendung. Ich
|
||||||
werde hierbei bewerten, wie einfach die Installation vonstatten geht.
|
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
|
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.
|
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
|
### 2\. Systemanforderungen
|
||||||
relevanten Informationen für die Einrichtung finden kann.
|
|
||||||
|
|
||||||
2\. Systemanforderungen
|
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
|
||||||
Hierbei geht es nicht nur um die theoretisch unterstützten Betriebssysteme und
|
Software auch auf preisgünstigen Single Board-Computern und virtualisierten Servern
|
||||||
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
|
|
||||||
lauffähig sein, sodass sich jeder ein selbst gehostetes Setup leisten kann und nicht aus
|
lauffähig sein, sodass sich jeder ein selbst gehostetes Setup leisten kann und nicht aus
|
||||||
Kostengründen auf proprietäre Anbieter angewiesen ist.
|
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
|
Neben dem Ressourcenverbrauch im Leerlauf habe ich auch die CPU-Auslastung unter Last
|
||||||
von anderen Providern zu importieren. Hierbei soll nicht nur das Repository, sondern
|
gemessen. Hierfür habe ich das Repository des Linux-Kernels importiert und mir die
|
||||||
auch z.B. Issues übertragen werden können.
|
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
|
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
|
Repositories zu navigieren? Gibt es eine Suchfunktion, um beispielsweise eine bestimmte
|
||||||
Funktion im Code zu finden?
|
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
|
Bietet die Anwendung zusätzlich zu Git-Repositories, Issues und Pull-Requests noch
|
||||||
weitere Features an?
|
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
|
heraus, ein Repository für Softwarepakete verschiedener Programmiersprachen oder
|
||||||
Projektmanagement-Tools.
|
Projektmanagement-Tools.
|
||||||
|
|
||||||
6\. Continuous Integration
|
### 6\. Continuous Integration
|
||||||
|
|
||||||
Continuous Integration (CI), also das automatische Testen von neuem Code ist ein fester
|
Continuous Integration (CI), also das automatische Testen von neuem Code ist ein fester
|
||||||
Teil des Worflows vieler Entwickler. GitHub bietet mit Actions einen eingebauen
|
Teil des Worflows vieler Entwickler. Hat die Plattform einen CI-Dienst eingebaut oder
|
||||||
CI-Dienst an.
|
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
|
Nicht jeder möchte den Aufwand betreiben, seine Git-Hosting-Plattform selbst zu hosten.
|
||||||
Anzahl an Projekten).
|
Deswegen ist es vom Vorteil, wenn es die Möglichkeit gibt, anstelle dessen einer
|
||||||
|
öffentlichen Instanz beizutreten.
|
||||||
|
|
||||||
## Quellen
|
## Quellen
|
||||||
|
|
||||||
|
|
278
src/studienarbeit/2_gitlab.md
Normal file
|
@ -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.
|
||||||
|
|
||||||
|
<img src="./assets/gitlab/architecture.png" alt="GitLab Architektur" width="500"/>
|
||||||
|
|
||||||
|
- **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:
|
||||||
|
<https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh>.
|
||||||
|
|
||||||
|
Danach kann man GitLab mit diesem Befehl installieren und starten:
|
||||||
|
|
||||||
|
```
|
||||||
|
GITLAB_ROOT_PASSWORD="<strongpassword>" 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.
|
||||||
|
|
||||||
|
![GitLab-Web-IDE](./assets/gitlab/web_ide.png)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
![GitLab-Import](./assets/gitlab/import.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![GitLab Kanban](./assets/gitlab/kanban.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![GitLab Issue mit Task](./assets/gitlab/issue.png)
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
![Runner](./assets/gitlab/runners.png)
|
||||||
|
|
||||||
|
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 <https://docs.gitlab.com/>
|
||||||
|
- Repository <https://gitlab.com/gitlab-org/gitlab-foss/>
|
||||||
|
- Architekturübersicht
|
||||||
|
<https://docs.gitlab.com/ee/development/architecture.html#gitlab-architecture-overview>
|
||||||
|
- Liste von öffentlichen GitLab-Instanzen
|
||||||
|
<https://wiki.p2pfoundation.net/List_of_Community-Hosted_GitLab_Instances>
|
327
src/studienarbeit/3_gitea.md
Normal file
|
@ -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
|
||||||
|
<https://dl.gitea.com/gitea/> 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.
|
||||||
|
|
||||||
|
![Gitea-Konfiguration](./assets/gitea/setup.png)
|
||||||
|
|
||||||
|
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-Suche](./assets/gitea/search.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Woodpecker CI](./assets/gitea/woodpecker.png)
|
||||||
|
|
||||||
|
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: `<WOODPECKER_URL>/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
|
||||||
|
```
|
||||||
|
|
||||||
|
![Gitea Actions](./assets/gitea/actions.png)
|
||||||
|
|
||||||
|
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 <https://gitea.com>
|
||||||
|
- Repository <https://github.com/go-gitea/gitea/>
|
||||||
|
- Start von Codeberg (damals TeaHub)
|
||||||
|
<https://www.heise.de/news/Neue-Entwickler-Plattform-TeaHub-will-Github-beerben-4078811.html>,
|
||||||
|
<https://blog.codeberg.org/codebergorg-launched.html>
|
|
@ -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 <https://sr.ht> 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.
|
|
||||||
|
|
||||||
- <https://man.sr.ht/installation.md>
|
|
||||||
- <https://man.sr.ht/configuration.md>
|
|
292
src/studienarbeit/4_sourcehut.md
Normal file
|
@ -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 homepage](./assets/sourcehut/homepage.png)
|
||||||
|
|
||||||
|
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 <https://sr.ht> 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:
|
||||||
|
|
||||||
|
![SourceHut architecture](./assets/sourcehut/sourcehut_arch.svg)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
![Repository](./assets/sourcehut/repo.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![SourceHut Hub](./assets/sourcehut/hub.png) 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.
|
||||||
|
|
||||||
|
![Send patchset](./assets/sourcehut/send_patchset.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Erfolgreicher Build](./assets/sourcehut/successful_build.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Fehlgeschlagener Build](./assets/sourcehut/failed_build.png)
|
||||||
|
|
||||||
|
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 <https://sr.ht>.
|
||||||
|
|
||||||
|
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
|
||||||
|
<https://code.netlandish.com/>. 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 <https://sr.ht/~sircmpwn/sourcehut/>
|
||||||
|
- Sourcehut Blog <https://sourcehut.org/blog/>
|
232
src/studienarbeit/5_onedev.md
Normal file
|
@ -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 homepage](./assets/onedev/homepage.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Agent setup](./assets/onedev/add_agent.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Suche](./assets/onedev/search.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![Code-Navigation](./assets/onedev/code_navigation.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![OneDev Issue Board](./assets/onedev/kanban.png)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
![CI-Editor](./assets/onedev/ci_editor.png)
|
||||||
|
|
||||||
|
```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 <https://onedev.io/>
|
||||||
|
- Repository <https://code.onedev.io/onedev/server>
|
BIN
src/studienarbeit/assets/gitea/actions.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
src/studienarbeit/assets/gitea/homepage.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
src/studienarbeit/assets/gitea/search.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/studienarbeit/assets/gitea/setup.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
src/studienarbeit/assets/gitea/woodpecker.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
src/studienarbeit/assets/gitlab/architecture.png
Normal file
After Width: | Height: | Size: 44 KiB |
21
src/studienarbeit/assets/gitlab/docker-compose.yml
Normal file
|
@ -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"
|
BIN
src/studienarbeit/assets/gitlab/import.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
src/studienarbeit/assets/gitlab/issue.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
src/studienarbeit/assets/gitlab/kanban.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
src/studienarbeit/assets/gitlab/runners.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
src/studienarbeit/assets/gitlab/web_ide.png
Normal file
After Width: | Height: | Size: 226 KiB |
BIN
src/studienarbeit/assets/onedev/add_agent.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
src/studienarbeit/assets/onedev/build.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
src/studienarbeit/assets/onedev/ci_editor.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
src/studienarbeit/assets/onedev/code_navigation.png
Normal file
After Width: | Height: | Size: 136 KiB |
19
src/studienarbeit/assets/onedev/docker-compose.yml
Normal file
|
@ -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
|
BIN
src/studienarbeit/assets/onedev/homepage.png
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
src/studienarbeit/assets/onedev/kanban.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
src/studienarbeit/assets/onedev/search.png
Normal file
After Width: | Height: | Size: 77 KiB |
|
@ -1,31 +0,0 @@
|
||||||
<mxfile host="65bd71144e">
|
|
||||||
<diagram id="oiookRJMGbAoKEPYmeVH" name="Page-1">
|
|
||||||
<mxGraphModel dx="811" dy="414" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
|
||||||
<root>
|
|
||||||
<mxCell id="0"/>
|
|
||||||
<mxCell id="1" parent="0"/>
|
|
||||||
<mxCell id="3" value="Frontend<br>:5000" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="40" y="160" width="80" height="40" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="4" value="API<br>:5100" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="120" y="160" width="80" height="40" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="5" value="meta.sr.ht<br>(Nutzerverwaltung)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="140" y="130" width="60" height="10" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="6" value="Webhooks" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="200" y="160" width="80" height="40" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="8" value="Frontend" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="320" y="160" width="80" height="40" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="9" value="API" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="400" y="160" width="80" height="40" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="10" value="hub.sr.ht<br>(Startseite)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="370" y="130" width="60" height="20" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
</root>
|
|
||||||
</mxGraphModel>
|
|
||||||
</diagram>
|
|
||||||
</mxfile>
|
|
BIN
src/studienarbeit/assets/sourcehut/failed_build.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
src/studienarbeit/assets/sourcehut/homepage.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
src/studienarbeit/assets/sourcehut/hub.png
Normal file
After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
BIN
src/studienarbeit/assets/sourcehut/repo.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
src/studienarbeit/assets/sourcehut/send_patchset.png
Normal file
After Width: | Height: | Size: 101 KiB |
109
src/studienarbeit/assets/sourcehut/sourcehut.dio
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram id="oiookRJMGbAoKEPYmeVH" name="Page-1">
|
||||||
|
<mxGraphModel dx="741" dy="808" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="#ffffff" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="3" value="Frontend<br>:5000" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="40" y="80" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" value="API<br>:5100" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="120" y="80" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="meta.sr.ht<br>(Nutzerverwaltung)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="140" y="50" width="60" height="10" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="6" value="Webhooks<br>(Queue)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="80" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" value="Frontend<br>:5014" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="360" y="80" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="9" value="API<br>:5114" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="440" y="80" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" value="hub.sr.ht<br>(Startseite)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="410" y="50" width="60" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="11" value="Frontend<br>:5001" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="40" y="200" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="12" value="API<br>:5101" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="120" y="200" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="13" value="git.sr.ht<br>(Nutzerverwaltung)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="140" y="170" width="60" height="10" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="14" value="Webhooks<br>(Queue)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="200" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="15" value="Frontend<br>:5004" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="360" y="200" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="16" value="API<br>:5104" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="440" y="200" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" value="man.sr.ht<br>(Wiki)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="410" y="170" width="60" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" value="Frontend<br>:5002" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="40" y="320" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="19" value="API<br>:5102" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="120" y="320" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="20" value="builds.sr.ht<br>(CI)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="140" y="290" width="60" height="10" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="21" value="Worker" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="320" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="22" value="Worker" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="210" y="330" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="Frontend<br>:5011" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="360" y="320" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="24" value="API<br>:5111" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="440" y="320" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="25" value="paste.sr.ht<br>(Wiki)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="410" y="290" width="60" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="26" value="Frontend<br>:5006" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="360" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="27" value="API<br>:5106" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="440" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="28" value="lists.sr.ht<br>(Mailinglisten)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="478" y="410" width="60" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="29" value="Process<br>(Queue)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="560" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="30" value="LMTP" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="520" y="440" width="40" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="31" value="Frontend<br>:5003" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="40" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" value="API<br>:5103" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="120" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="33" value="todo.sr.ht<br>(Issues)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#141414;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="158" y="410" width="60" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="34" value="Webhooks<br>(Queue)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="240" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="35" value="LMTP" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="440" width="40" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="36" value="Webhooks<br>(Queue)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="640" y="440" width="80" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
BIN
src/studienarbeit/assets/sourcehut/sourcehut.png
Normal file
After Width: | Height: | Size: 58 KiB |
1
src/studienarbeit/assets/sourcehut/sourcehut_arch.svg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/studienarbeit/assets/sourcehut/successful_build.png
Normal file
After Width: | Height: | Size: 138 KiB |
48
src/studienarbeit/assets/woodpecker/docker-compose.yml
Normal file
|
@ -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
|
|
@ -108,7 +108,7 @@ weswegen ich meine Konfiguration aus den einzelnen Repositories zusammenkopieren
|
||||||
- <https://git.sr.ht/~sircmpwn/todo.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>
|
- <https://git.sr.ht/~sircmpwn/lists.sr.ht/tree/master/item/config.example.ini>
|
||||||
|
|
||||||
[Beispielkonfiguration](./assets/config.ini)
|
[Beispielkonfiguration](./assets/sourcehut_setup/config.ini)
|
||||||
|
|
||||||
Folgende Optionen müssen angepasst werden:
|
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
|
weitergeleitet werden können. Eine Nginx-Beispielkonfiguration findet sich in
|
||||||
[diesem Repository](https://git.sr.ht/~sircmpwn/sr.ht-nginx/tree) auf Sourcehut.
|
[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
|
[Hier](./assets/sourcehut_setup/nginx/nginx_services.conf) befindet sich die angepasste
|
||||||
HTTPS), die ich für meine Testinstallation verwendet habe.
|
Version (ohne HTTPS), die ich für meine Testinstallation verwendet habe.
|
||||||
|
|
||||||
Noch ein Hinweis für Testinstallationen mit internen Domains: Die konfigurierten
|
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
|
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
|
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.
|
über das (Legacy) OAuth-Dashboard unter `meta.<Sourcehut-Domain>/oauth` erstellen.
|
||||||
|
|
||||||
![OAuth-Setup](./assets/oauth.png)
|
![OAuth-Setup](./assets/sourcehut/oauth.png)
|
||||||
|
|
||||||
Als _Base Redirect URI_ trägt man die URL des Dienstes mit dem Pfad `oauth/callback`
|
Als _Base Redirect URI_ trägt man die URL des Dienstes mit dem Pfad `oauth/callback`
|
||||||
ein. Beispiel: `https://git.codeforge.int/oauth/callback`.
|
ein. Beispiel: `https://git.codeforge.int/oauth/callback`.
|
||||||
|
|
||||||
![OAuth-Registrierung](./assets/oauth_new_client.png)
|
![OAuth-Registrierung](./assets/sourcehut/oauth_new_client.png)
|
||||||
|
|
||||||
Die Client-ID und das Client-Secret, das auf der nächsten Seite angezeigt wird, können
|
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
|
nun in die Konfigurationsdatei unter `[<service>.sr.ht]/oauth-client-id` und
|
||||||
|
@ -237,24 +237,44 @@ rc-service hub.sr.ht start
|
||||||
|
|
||||||
### git.sr.ht
|
### 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
|
- Web-UI: Port 5001
|
||||||
- API: Port 5101
|
- API: Port 5101
|
||||||
|
|
||||||
```
|
```
|
||||||
###
|
# Abhängigkeiten für git-http server installieren
|
||||||
# git.sr.ht (Port: 5001, API-Port 5101)
|
apk add git-sr.ht fcgiwrap git-daemon
|
||||||
|
|
||||||
apk add fcgiwrap git-daemon
|
|
||||||
|
|
||||||
gitsrht-initdb
|
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"
|
AuthorizedKeysCommand=/usr/bin/gitsrht-dispatch "%u" "%h" "%t" "%k"
|
||||||
AuthorizedKeysCommandUser=root
|
AuthorizedKeysCommandUser=root
|
||||||
PermitUserEnvironment SRHT_*
|
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 fcgiwrap
|
||||||
rc-update add git.sr.ht
|
rc-update add git.sr.ht
|
||||||
rc-update add git.sr.ht-api
|
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-api start
|
||||||
rc-service git.sr.ht start
|
rc-service git.sr.ht start
|
||||||
|
|
||||||
# Create logfile:
|
# Cronjob hinzufügen:
|
||||||
touch /var/log/gitsrht-shell
|
*/20 * * * * gitsrht-periodic
|
||||||
chown git:git /var/log/gitsrht-shell
|
|
||||||
|
|
||||||
Cron: */20 * * * * gitsrht-periodic
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### man.sr.ht
|
### man.sr.ht
|
||||||
|
@ -277,9 +294,13 @@ Cron: */20 * * * * gitsrht-periodic
|
||||||
- Web-UI: Port 5004
|
- Web-UI: Port 5004
|
||||||
- API: Port 5104
|
- 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
|
||||||
# man.sr.ht (Port: 5004, API-Port: 5104)
|
|
||||||
|
mansrht-initdb
|
||||||
|
|
||||||
rc-update add man.sr.ht
|
rc-update add man.sr.ht
|
||||||
rc-update add man.sr.ht-api
|
rc-update add man.sr.ht-api
|
||||||
|
@ -293,9 +314,12 @@ rc-service man.sr.ht start
|
||||||
- Web-UI: Port 5011
|
- Web-UI: Port 5011
|
||||||
- API: Port 5111
|
- API: Port 5111
|
||||||
|
|
||||||
|
paste.sr.ht ist ein simpler Pastebin, mit dem man Codeschnipsel speichern und
|
||||||
|
veröffentlichen kann.
|
||||||
|
|
||||||
```
|
```
|
||||||
###
|
apk add paste.sr.ht
|
||||||
# paste.sr.ht (Port: 5011, API-Port: 5111)
|
pastesrht-initdb
|
||||||
|
|
||||||
rc-update add paste.sr.ht
|
rc-update add paste.sr.ht
|
||||||
rc-update add paste.sr.ht-api
|
rc-update add paste.sr.ht-api
|
||||||
|
@ -309,56 +333,114 @@ rc-service paste.sr.ht start
|
||||||
- Web-UI: Port 5002
|
- Web-UI: Port 5002
|
||||||
- API: Port 5102
|
- 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
|
||||||
# builds.sr.ht (Port: 5002, API-Port: 5102)
|
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
|
||||||
rc-update add builds.sr.ht-api
|
rc-update add builds.sr.ht-api
|
||||||
|
|
||||||
rc-service builds.sr.ht-api start
|
rc-service builds.sr.ht-api start
|
||||||
rc-service builds.sr.ht 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
|
Zusätzlich sollte man einen neuen Benutzer mit dem Namen `docker` anlegen und der
|
||||||
builds ALL=(docker) NOPASSWD: /var/lib/images/control
|
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-update add docker
|
||||||
rc-service docker start
|
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
|
cd /var/lib/images
|
||||||
docker build -t qemu qemu/Dockerfile .
|
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
|
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
|
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
|
# Start worker
|
||||||
rc-update add builds.sr.ht-worker
|
rc-update add builds.sr.ht-worker
|
||||||
rc-service builds.sr.ht-worker start
|
rc-service builds.sr.ht-worker start
|
||||||
|
@ -370,16 +452,27 @@ rc-service builds.sr.ht-worker start
|
||||||
- API: Port 5103
|
- API: Port 5103
|
||||||
|
|
||||||
```
|
```
|
||||||
###
|
apk add todo.sr.ht
|
||||||
# todo.sr.ht (Port: 5003, API-Port 5103)
|
```
|
||||||
|
|
||||||
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"
|
wget "https://git.sr.ht/~sircmpwn/todo.sr.ht/blob/master/schema.sql"
|
||||||
psql -U todo -d todo.sr.ht -f schema.sql
|
psql -U todo -d todo.sr.ht -f schema.sql
|
||||||
todo-migrate stamp head
|
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
|
||||||
rc-update add todo.sr.ht-api
|
rc-update add todo.sr.ht-api
|
||||||
rc-update add todo.sr.ht-lmtp
|
rc-update add todo.sr.ht-lmtp
|
||||||
|
@ -396,10 +489,13 @@ rc-service todo.sr.ht start
|
||||||
- Web-UI: Port 5006
|
- Web-UI: Port 5006
|
||||||
- API: Port 5106
|
- 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.
|
||||||
# lists.sr.ht (Port: 5006, API-Port 5106)
|
|
||||||
|
|
||||||
|
Eine Anleitung für die Mail-Konfiguration findet sich hier:
|
||||||
|
<https://man.sr.ht/lists.sr.ht/configuration.md>
|
||||||
|
|
||||||
|
```
|
||||||
listssrht-initdb
|
listssrht-initdb
|
||||||
|
|
||||||
rc-update add lists.sr.ht
|
rc-update add lists.sr.ht
|
||||||
|
|