# TANINUX — Verteilung als „Distro" Ziel: ein Calamares-Installer, der eine fertige TANINUX-Umgebung aufsetzt. Modell: **eigenes Binär-Repo `[tanin]` nur für eigene Pakete**, alles Standard aus den **offiziellen Arch-Repos** (wie CachyOS/EndeavourOS). ## Pakete | Paket | Repo | Inhalt | |------------------|-------------|-----------------------------------------------------| | `taninux` | `[tanin]` | App: tsettings + thub + TUI, Helper, polkit, .desktop | | `tanin-eww` | `[tanin]` | eww Panel/Dock-Config + Scripts (→ /usr/share) | | `tanin-setup` | `[tanin]` | seedet `~/.config` aus /usr/share + Portal/Session-Fix | | `tanin-desktop` | `[tanin]` | **Metapackage**: depends = eigene + Arch-Pakete | `tanin-desktop` zieht per `depends` die Arch-Pakete aus den normalen Repos und die eigenen aus `[tanin]`. AUR bleibt Opt-in → `paru` ist `optdepends`, kein hartes `depends` (Metapackage baut also nichts aus dem AUR). ## Dotfile-Auslieferung (wichtig) AUR/Binär-Pakete dürfen **nicht** nach `/home` schreiben. Daher: 1. Default-Configs ins Paket nach `/usr/share/tanin/` (oder `/etc/skel/`). 2. `tanin-setup` kopiert sie beim ersten Start nach `~/.config` (idempotent, überschreibt nichts ohne `--force`) und richtet das Session-Portal ein (siehe „Dark Mode / Portal" unten). ## Phasen 1. **Fundament** — `packaging/taninux/PKGBUILD` (fertig), LICENSE (✅ da, GPL-3.0-or-later), `cd packaging/taninux && makepkg -si` lokal testen. 2. **Meta + Config** — `tanin-desktop` (Skelett da), `tanin-eww`, `tanin-setup`. 3. **Eigenes Repo `[tanin]`**. Hosts: - **Code** → `git.openbureau.ch/karim/taninux` (PKGBUILD-`source`, woher `makepkg` klont) - **Projekt + Repo** → `taninux.kgva.ch` (PKGBUILD-`url`/Homepage **und** pacman-`Server`) DB bauen + signieren: ```sh repo-add -s tanin.db.tar.zst *.pkg.tar.zst # -s signiert mit Packager-Key ``` Hosten — zwei Optionen: - **Gitea/Forgejo Arch-Registry** (falls git.openbureau.ch das kann): Pakete pushen, `Server = https://git.openbureau.ch/api/packages/karim/arch/`. `taninux.kgva.ch` als Reverse-Proxy/Vanity davor. - **Statisches Verzeichnis** hinter `taninux.kgva.ch`: `*.pkg.tar.zst` + `tanin.db`. `pacman.conf`-Snippet für **bestehende** User (unverändert, siehe Warnung): ```ini [tanin] # TEMPORÄR + UNSICHER: TrustAll akzeptiert JEDES Paket ohne Signaturprüfung. # Nur zum Bootstrappen, solange die DB noch nicht signiert ist. Sobald der # Packager-Key steht -> auf "Required DatabaseOptional" umstellen (siehe unten). SigLevel = Optional TrustAll Server = https://taninux.kgva.ch/$arch ``` > **Wichtig:** Dieses Snippet bleibt bewusst auf `Optional TrustAll`, auch > nachdem Signing verdrahtet ist (siehe unten) — würde man es hier auf > `Required` umstellen, würde das nächste `-Syu` bei allen bestehenden > Usern gegen das *heute* unsignierte Repo fehlschlagen. Neue Installs > (ISO/Calamares) bekommen `Required DatabaseOptional` bereits vorkonfiguriert > (siehe `iso/overrides/airootfs/etc/pacman.conf`). Bestehende User steigen > über den **Cutover**-Abschnitt unten manuell um, sobald das Repo signiert > ausgeliefert wird. #### Repo-Signing Verdrahtet (`packaging/`): - `packaging/gen-signing-key.sh` erzeugt den Packager-Key EINMALIG (Ed25519, `gpg --batch --gen-key`, interaktive Passphrase — kein Hardcoding) und druckt danach die Export-/Cutover-Schritte aus. - `build-tanin-repo.sh`, `finish-tanin-repo.sh`, `aur-autoupdate.sh` lesen `GPGKEY` aus der Umgebung und **brechen fail-closed ab**, wenn er fehlt — es wird nie stillschweigend unsigniert gebaut. Pakete werden mit `makepkg --sign` (bzw. bei `aur-autoupdate.sh`, das im isolierten `makechrootpkg`-Chroot baut, per `gpg --detach-sign` direkt nach dem Kopieren aus dem Chroot) signiert, die DB mit `repo-add -s -k "$GPGKEY"`. Noch manuell/offen: 1. `packaging/gen-signing-key.sh` einmal ausführen (noch nicht geschehen — dieser Repo-Stand enthält KEINEN Key) und den privaten Key sicher sichern (siehe Skript-Output). 2. Public Key exportieren nach `iso/overrides/airootfs/etc/pacman.d/tanin-repo.gpg` (+ `iso/build-profile/...`, wird bei jedem `bootstrap-profile.sh`-Lauf aus `overrides/` neu kopiert) und öffentlich unter `taninux.kgva.ch/tanin.gpg` (o. ä.) ablegen. 3. In `iso/overrides/airootfs/root/customize_airootfs.sh` eine zweite `pacman-key --lsign-key `-Zeile ergänzen (siehe Kommentar dort) — ohne die bleibt der Key zwar importiert, aber nicht getrustet. 4. `GPGKEY` in `packaging/systemd/tanin-aur-update.service` setzen (dort als Kommentar vorbereitet) und den geheimen Key ins `GNUPGHOME` des `tanin-build`-Users legen (siehe „Build-Infrastruktur" unten). 5. Sobald das ausgelieferte Repo tatsächlich signierte Pakete + DB serviert: bestehende User per **Cutover**-Anleitung (unten) umstellen. 6. **Calamares / ISO** ✅ — `archiso`-Profil mit `[tanin]` vorkonfiguriert + Calamares `packages`-Modul, das `tanin-desktop` installiert (`iso/build-profile/`, gebaute ISO in `iso/out/`). Neue Installs starten direkt mit `Required DatabaseOptional`. #### Cutover für bestehende User (Optional TrustAll → Required DatabaseOptional) Erst durchführen, wenn Schritt 1–4 oben erledigt sind und `taninux.kgva.ch` (bzw. die Gitea-Registry) tatsächlich signierte Pakete + eine signierte DB ausliefert — vorher würde `Required` jedes `-Syu` brechen. ```sh # 1) Packager-Pubkey importieren + lokal signieren (einmalig, als root) curl -o /tmp/tanin-repo.gpg https://taninux.kgva.ch/tanin.gpg # oder gleicher Pfad wie oben pacman-key --add /tmp/tanin-repo.gpg pacman-key --lsign-key # Fingerprint aus gen-signing-key.sh # 2) In /etc/pacman.conf das [tanin]-SigLevel umstellen # von SigLevel = Optional TrustAll # auf SigLevel = Required DatabaseOptional # 3) Testen sudo pacman -Sy sudo pacman -S tanin-desktop --dbonly # oder ein beliebiges [tanin]-Paket ``` Schlägt Schritt 3 fehl ("signature is unknown trust" o. ä.), war entweder Schritt 1 unvollständig (Key nicht lsigned) oder das Repo liefert noch nicht signierte Pakete — dann bei `Optional TrustAll` bleiben. ## Dark Mode / Portal (Session-Fix) libadwaita-Apps (Nautilus etc.) lesen Hell/Dunkel über `org.freedesktop.portal.Settings`. Damit das Portal startet, muss die Session `graphical-session.target` aktivieren. `tanin-setup` legt dafür `~/.config/systemd/user/-session.target` an und ergänzt die Compositor- Autostarts: ```sh exec-once = dbus-update-activation-environment --systemd --all exec-once = systemctl --user start -session.target ``` ## Build-Infrastruktur Der tägliche AUR-Rebuild (`packaging/aur-autoupdate.sh`, via `packaging/systemd/tanin-aur-update.timer`) braucht `makechrootpkg` / `arch-nspawn` / `mkarchroot` als root — effektiv root-äquivalent (baut beliebige, aus dem AUR gezogene `PKGBUILD`s in einem chroot). Das lief bisher per NOPASSWD-`sudo` auf dem persönlichen Account `karim`. Stattdessen jetzt: ein dedizierter, gesperrter Systemaccount **`tanin-build`** (`packaging/systemd/setup-build-user.sh`, Home `/var/lib/tanin-build`, kein Passwort/Login) — nur dieser Account bekommt den NOPASSWD-Sudo-Grant (`packaging/systemd/tanin-aur-update.sudoers`), und der systemd-Service läuft mit `User=tanin-build`/`Group=tanin-build`. Ein kompromittiertes AUR-PKGBUILD (oder ein Bug in der Pipeline) kann so nicht mehr `karim`s eigentlichen Account root-äquivalent übernehmen — nur den isolierten Build-Account, der sonst nichts kann. Konsequenzen für Pfade: Der systemd-Unit nutzt `%h`-Spezifier, die jetzt gegen `tanin-build`s Home auflösen, nicht mehr `/home/karim`. `setup-build-user.sh` synct dafür einmalig einen Checkout nach `/var/lib/tanin-build/taninux` (muss nach `git pull` erneut laufen) und legt `/var/lib/tanin-build/.gnupg` an — dort muss der geheime Packager-Key (siehe „Repo-Signing" oben) importiert sein, sonst kann `tanin-build` nichts signieren. Einrichtung: `sudo packaging/systemd/setup-build-user.sh` (erstellt User, synct Repo, installiert Sudoers-Drop-in + `.service`/`.timer` als System-Units). ## Hosts - **Code:** `git.openbureau.ch/karim/taninux` (+ Repo für die eww-Config, Absprache mit der eww-Instanz). - **Projekt/Repo:** `taninux.kgva.ch` (Homepage + `[tanin]`-pacman-Server). ## Offene Voraussetzungen - **LICENSE**-Datei ablegen (Vorschlag GPL-3.0-or-later): `curl -L https://www.gnu.org/licenses/gpl-3.0.txt -o LICENSE`. - `taninux.kgva.ch` ans Repo-Hosting hängen (Gitea-Arch-Registry oder statisch).