Display arrangement persistence + centering fix, packaging hardening

- core/display.py: write_positions() persists Arrangement's drag-and-drop
  layout into niri's config.kdl (one output { position x= y= } per output),
  validated via `niri validate` on a temp copy with a .kdl.bak backup before
  writing — same pattern as core/keybindings.py's rebind(). Previously the
  page only ever called `niri msg output … position set`, which niri treats
  as live-only and drops on the next login/reload.
- gui/pages/display.py: Arrangement's Apply now runs each output's `niri msg
  output … position set` synchronously instead of queuing them all on the
  single-shot ProcessRunner (which rejects a second run() while the first is
  still async) — a 2-monitor apply previously moved only the first output
  and silently dropped the rest. _dock_to_nearest keeps the free axis at the
  dragged position (so a shorter display can sit vertically centered next to
  a taller rotated one) rather than forcing corner alignment.
- core/panel.py, files/__init__.py: incidental fixes alongside the above.
- packaging/: signing-key generation script + build-user systemd setup for
  the [tanin] AUR auto-rebuild pipeline; PKGBUILD bumped to pkgrel=5.
- src/taninux/browser/: new module for browser theme sync (Fuji accent).
This commit is contained in:
2026-07-13 14:19:50 +02:00
parent 8fb8efcbbd
commit faaba27ed4
26 changed files with 1516 additions and 56 deletions
+92 -16
View File
@@ -44,7 +44,7 @@ AUR/Binär-Pakete dürfen **nicht** nach `/home` schreiben. Daher:
`taninux.kgva.ch` als Reverse-Proxy/Vanity davor.
- **Statisches Verzeichnis** hinter `taninux.kgva.ch`: `*.pkg.tar.zst` + `tanin.db`.
`pacman.conf`-Snippet für User:
`pacman.conf`-Snippet für **bestehende** User (unverändert, siehe Warnung):
```ini
[tanin]
# TEMPORÄR + UNSICHER: TrustAll akzeptiert JEDES Paket ohne Signaturprüfung.
@@ -54,22 +54,73 @@ AUR/Binär-Pakete dürfen **nicht** nach `/home` schreiben. Daher:
Server = https://taninux.kgva.ch/$arch
```
#### Repo-Signing (TODO)
> **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.
Zielzustand (bevor das Repo öffentlich empfohlen wird):
1. Packager-GPG-Key erzeugen (`gpg --full-gen-key`) und öffentlich ablegen
(z. B. `taninux.kgva.ch/tanin.gpg`), damit User ihn importieren können.
2. DB **signiert** bauen: `repo-add -s tanin.db.tar.zst *.pkg.tar.zst`
(`-s` signiert DB + jedes hinzugefügte Paket mit dem Packager-Key).
3. Key beim User installieren (`pacman-key --add`, `pacman-key --lsign-key`)
und dann in `pacman.conf` scharfschalten:
```ini
SigLevel = Required DatabaseOptional
```
→ jedes Paket muss signiert sein; die DB-Signatur ist optional.
4. **Calamares / ISO** ✅ — `archiso`-Profil mit `[tanin]` vorkonfiguriert +
Calamares `packages`-Modul, das `tanin-desktop` installiert
(`iso/build-profile/`, gebaute ISO in `iso/out/`).
#### 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 <packager-fpr>`-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 14 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 <packager-fingerprint> # 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)
@@ -83,6 +134,31 @@ exec-once = dbus-update-activation-environment --systemd --all
exec-once = systemctl --user start <wm>-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,