adr aequinox alix android apt apu artificial-intelligence asa asciidoc auswahl backup bad-schmiedeberg bash bewegung bom buecher c cfengine checklisten checkmk cisco citrix computernetz container crypto ddr debian denog deutschland dhcp docker dokumentieren duply dvcs ebtables email epub fairphone2 fairphone3 fairphone5 fedora firewall fossilscm git gns3 gre grep guug halberstadt hardware i2c iproute ipsec iptables ipv6 kalender ki konferenz kpartx latex laufen lernen letsencrypt libgcrypt lighttpd linux lua lur make mexiko mikrotik modell monotone mount mysql netbox netflow nfdump nfsen openvpn openwrt pac paketfilter pcap performance perl podman podman-toolbox postfix programmieren projekt proxmox-ve proxy pxelinux python qubes-os rancid raspi reisen rezension rfc rpm rs232 schreiben script seriell sftp shell software spiel stehen switch sysadmin syslog system systemd taskwarrior termux test troubleshoot ubuntu uci vcs virtualbox virtuell vpn wine wireshark xen xml

Mit git subtree andere Bibliotheken einbinden

Wenn ich ein Stück nicht triviale Software entwickle, teile ich die Entwicklung meist in drei Teile auf, die ich unabhängig voneinander verfolge:

  • Die Kernfunktionen lege ich in eine Bibliothek, in der alle Logik steckt und die ein konsistentes API bereitstellt.

  • Um die Bibliothek einfach interaktiv zu testen und die Funktionalität auszuprobieren, schreibe ich ein Kommandozeilenprogramm, welches die Bibliothek über ihr API verwendet.

  • Das eigentliche Programm, mit der endgültigen Benutzeroberfläche erstelle ich meist mit einem Framework und der Bibliothek.

Ein sofort einleuchtender Vorteil dieser Methodik ist, dass es die Fehlersuche erleichtert, weil ich mit dem Kommandozeilenprogramm schnell entscheiden kann, ob ein Problem eher in der Logik der Bibliothek zu suchen ist, oder in der Benutzerschnittstelle des Frameworks.

So gehe ich auch vor, wenn ich Analyzer für Cortex schreibe, die Informationen aus unserer lokalen Umgebung sammeln und für TheHive aufbereiten. Es gibt etliche Analyzer für Cortex, die die unterschiedlichsten Informationen bereitstellen. Doch für unseren lokalen Kontext und unsere konkrete Umgebung nützen diese meist wenig.

Einen Analyzer zu schreiben ist kein Hexenwerk, das ist gut beschrieben und dafür steht eine Python-Bibliothek auf PyPI bereit. Es fehlt nur noch die Programmlogik für unseren Kontext. Und hier greift die eingangs erwähnte Methodik.

Als erstes erstelle ich ein Python-Modul, welches die benötigten Informationen beschafft. Teil dieses Python-Moduls ist das Kommandozeilenprogramm, welches das API der Bibliothek verwendet und mit dem ich das Modul interaktiv ausprobiere und teste, bis es meinen Erwartungen entspricht.

Ist das Python-Modul fertig, schreibe ich den Analyzer, binde das Modul ein und erzeuge daraus einen Container, den Cortex dann aufrufen kann.

Und genau hier habe ich ein kleines Problem, wenn das Python-Modul nicht auf PyPI veröffentlicht ist. Das Dockerfile und der Python-Code für den Analyzer sind in einem Repository, das Python-Modul in einem anderen. Damit der Bau des Containers automatisch durchlaufen kann, müsste ich eine Referenz auf das zweite Repository mit einbauen - egal ob mit git submodule oder über einen Befehl in einem Skript. Damit würde ich jedoch eine Abhängigkeit herstellen, denn im Analyzer interessiert mich nicht, wo das Python-Modul ist, sondern nur was es macht.

Hier hilft mir git subtree (Tutorial bei Atlassian) womit ich den Quelltext des Python-Moduls in den Analyzer kopieren kann. Damit kann ich den Analyzer überall bauen, auch wenn das Repository des Python-Moduls nicht erreichbar ist. Trotzdem kann ich mit wenigen git Befehlen das kopierte Modul aus dem originalen Repository aktualisieren und Änderungen, die ich im Analyzer am Python-Modul vornehme, wieder an das originale Repository zurückschicken.

Wie gehe ich nun konkret vor? Da gibt es zwei Möglichkeiten. Ich kann die URL des Repositories bei git subtree direkt angeben, oder ich erstelle zunächst einen Verweis mit git remote, den ich dann bei den git subtree Befehlen referenziere.

Der zweite Weg ist zwar ein Schritt mehr, ermöglicht mir aber, die Befehle zum Aktualisieren und Zurückgeben von Änderungen in Skripts auszulagern, die ich nicht ändern muss, wenn sich die URL des Repositorys für das Python-Modul ändert. Ich muss lediglich den remote Eintrag bei Git entsprechend anpassen.

Darum ist mein erster Schritt:

git remote add -f $r_name $r_url

Hierbei ist $r_name der Name für das Repository, den ich in Skripten verwende und $r_url die aktuelle URL des Repositorys.

Anschließend füge ich den Inhalt ein:

git subtree add --prefix $pre $r_name $r_branch --squash

Dabei ist $pre der Pfad zu der Stelle, an der ich das Modul im Repository des Analyzers einfüge. Ich verwende meist modules/$modulname. $r_name hatten wir schon, $r_branch ist der Branch aus dem Modul-Repository, den ich einfügen will (meist main). Die Option --squash verwende ich, da mich beim Analyzer die Historie des Python-Moduls nicht interessiert.

So ist das Python-Modul direkt Bestandteil des Analyzers und ich brauche mir keine Sorgen mehr machen, woher ich es bekomme, wenn es nicht über PyPI verfügbar ist.

Will ich eine neuere Version des Moduls mit dem Analyzer verwenden, dann aktualisiere ich diese mit den folgenden Befehlen:

git fetch $r_name
git subtree pull --prefix $pre $r_name $r_branch --squash

Habe ich bei der Arbeit am Analyzer Änderungen an der Kopie des Moduls im Analyzer-Repository vorgenommen, kann ich diese mit folgenden Befehlen ins Modul-Repository zurückgeben:

git subtree push --prefix $pre $r_name $r_branch

Natürlich funktioniert das nur, wenn ich die nötige Berechtigung am Repository des Moduls habe. Fehlt mir diese, kann ich einen Patch mit folgendem Befehl extrahieren:

git diff $commit $pre

Dabei ist $commit der Commit, mit dem ich das Modul-Repository das letzte Mal einkopiert hatte. Diesen finde ich mit git log

Posted 2026-09-22 Tags:

Mit 'git subtree' andere Bibliotheken einbinden
Posted 2026-09-22
Zusammenfassung August 2026
Posted 2026-09-06
Wiederkehrende Aufgaben mit Taskwarrior
Posted 2026-08-30
Zusammenfassung Juli 2026
Posted 2026-08-04
Rootless Container via Systemd starten
Posted 2026-07-26
Systeme verstehen in Theorie und Praxis (4)
Posted 2026-07-15
Zusammenfassung Juni 2026
Posted 2026-07-05
Fehler suchen bei Let's Encrypt Zertifikatserneuerung
Posted 2026-06-28
Systeme verstehen in Theorie und Praxis (3)
Posted 2026-06-18
Zusammenfassung Mai 2026
Posted 2026-06-07