From ac9b94b0b29266ffbda42b911777688eb6cca9a3 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 19 Jun 2026 19:55:46 +0200 Subject: [PATCH] Complete archiso/Calamares profile scaffold (iso/) - Calamares modules: unpackfs (clone), partition/mount/fstab (btrfs subvols), bootloader (systemd-boot + quiet splash), packages (strip live), services (greetd), shellprocess (snapper, flathub, strip-live), branding (Fuji) - bootstrap-profile.sh: releng base + linux-zen swap + overlay our deltas - BUILD.md: build steps, decisions, and honest open items (needs build-test) Co-Authored-By: Claude Opus 4.8 --- distro/MANIFEST.md | 2 +- distro/camel.toml | 1 + iso/BUILD.md | 69 +++++++++++++++++++ iso/bootstrap-profile.sh | 44 ++++++++++++ .../calamares/branding/tanin/branding.desc | 24 +++++++ .../etc/calamares/modules/bootloader.conf | 9 +++ .../airootfs/etc/calamares/modules/fstab.conf | 8 +++ .../airootfs/etc/calamares/modules/mount.conf | 37 ++++++++++ .../etc/calamares/modules/packages.conf | 12 ++++ .../etc/calamares/modules/partition.conf | 11 +++ .../calamares/modules/services-systemd.conf | 13 ++++ .../modules/shellprocess-flathub.conf | 5 ++ .../modules/shellprocess-snapper.conf | 11 +++ .../modules/shellprocess-striplive.conf | 11 +++ .../etc/calamares/modules/unpackfs.conf | 7 ++ .../airootfs/root/customize_airootfs.sh | 0 .../airootfs/usr/local/bin/tanin-installer | 0 17 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 iso/BUILD.md create mode 100755 iso/bootstrap-profile.sh create mode 100644 iso/overrides/airootfs/etc/calamares/branding/tanin/branding.desc create mode 100644 iso/overrides/airootfs/etc/calamares/modules/bootloader.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/fstab.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/mount.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/packages.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/partition.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/services-systemd.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/shellprocess-flathub.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/shellprocess-snapper.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/shellprocess-striplive.conf create mode 100644 iso/overrides/airootfs/etc/calamares/modules/unpackfs.conf mode change 100644 => 100755 iso/overrides/airootfs/root/customize_airootfs.sh mode change 100644 => 100755 iso/overrides/airootfs/usr/local/bin/tanin-installer diff --git a/distro/MANIFEST.md b/distro/MANIFEST.md index aa0c726..444b258 100644 --- a/distro/MANIFEST.md +++ b/distro/MANIFEST.md @@ -83,7 +83,7 @@ waypaper/cliphist) are exactly why `[tanin]` must carry rebuilt AUR packages. package time; `tanin-setup` seeds them on first run. 3. **`[tanin]` repo** — `repo-add -s` to build+sign the DB. Host as a Gitea/Forgejo Arch registry **or** a static dir behind `taninux.kgva.ch`. -4. **ISO** — archiso profile with `[tanin]` pre-configured; Calamares `packages` +4. **ISO** — ✅ scaffolded in `iso/` (archiso releng-base + overrides). Calamares `packages` module installs `tanin-desktop`; greetd + tanin-greet enabled; session target wired. ### Session / dark-mode fix diff --git a/distro/camel.toml b/distro/camel.toml index d5ac25d..e5ccc77 100644 --- a/distro/camel.toml +++ b/distro/camel.toml @@ -180,6 +180,7 @@ icons = ["papirus-icon-theme", "adwaita-icon-theme"] [delivery] model = "own binary repo [tanin] + official Arch repos (EndeavourOS/CachyOS style)" iso_tool = "archiso" +iso_profile = "iso/ — releng-base + overrides; bootstrap-profile.sh assembles + builds. systemd-boot, btrfs+snapper, plymouth, linux-zen, Calamares clone-install. Scaffold; needs build-test." installer = "calamares" calamares_target = "tanin-desktop" # the netinstall/packages module installs just this dotfiles = "tanin-setup seeds ~/.config from /usr/share/tanin/skel (never writes /home at pkg time)" diff --git a/iso/BUILD.md b/iso/BUILD.md new file mode 100644 index 0000000..6412eb0 --- /dev/null +++ b/iso/BUILD.md @@ -0,0 +1,69 @@ +# TANINUX (camel) — ISO build + +archiso profile for a **live + Calamares installer** ISO. Model: the live ISO +**is** the installable system; Calamares clones it to disk (`unpackfs`), then +configures systemd-boot, Btrfs, services and strips the live-only bits. + +## Decisions baked in +- **Kernel:** linux-zen +- **Bootloader (target):** systemd-boot (the ISO itself boots systemd-boot/syslinux) +- **Filesystem:** Btrfs + snapper/snap-pac snapshots (subvol layout: `@`, `@home`, + `@cache`, `@log`, `@snapshots`) +- **Splash:** Plymouth (`quiet splash`, plymouth mkinitcpio hook) +- **Login:** greetd + tanin-greet (enabled on the target by Calamares) +- **Preinstalled:** the whole `tanin-desktop` + firefox, thunderbird, kitty, + nautilus, flatpak(+Flathub), mpv, loupe, GStreamer codecs, noto fonts/emoji/cjk, + file-roller, paru* +- **Repo:** `[tanin]` (Gitea Arch registry), DB-signing key trusted in the keyring + +## Prerequisites +```sh +sudo pacman -S archiso # to build +``` +- **`[tanin]` must be complete & reachable** (it is: git.openbureau.ch). The build + pacman.conf pulls `tanin-desktop` + deps from it (SigLevel=Never at build time). +- **\*paru is AUR** → it must be rebuilt into `[tanin]` before enabling it in + `overrides/packages.x86_64` (currently commented out), or the build fails. + (Rebuild like eww-git: `paru-bin` via makepkg → `publish-tanin-repo.sh`.) + +## Build +```sh +./bootstrap-profile.sh # assemble build-profile/ (releng base + overrides) +./bootstrap-profile.sh --build # assemble + mkarchiso -> out/ +# or manually: +sudo mkarchiso -v -w /tmp/tanin-work -o out build-profile +``` + +## How it fits together +- `overrides/` holds only our deltas; `bootstrap-profile.sh` copies the canonical + `releng` profile and overlays them (so bootloader/mkinitcpio boilerplate stays + authoritative; it also swaps the live kernel `linux` → `linux-zen`). +- `overrides/pacman.conf` — **build-time** (adds `[tanin]`, SigLevel=Never). +- `overrides/airootfs/etc/pacman.conf` — **live + target** (`[tanin]` Optional + TrustAll; the key is imported by `customize_airootfs.sh`). +- `overrides/airootfs/root/customize_airootfs.sh` — locale, import `[tanin]` key, + enable NetworkManager, plymouth hook, live boots to the installer. +- Live boot: getty autologin on tty1 → `/root/.bash_profile` → `tanin-installer` + → `cage -s -- calamares`. +- Calamares (`airootfs/etc/calamares/`): `unpackfs` clone → btrfs subvols (mount.conf) + → systemd-boot (bootloader.conf) → snapper + Flathub (shellprocess) → enable + greetd + strip live bits → done. + +## ⚠️ Open items / needs real build-testing (can't validate without mkarchiso+root) +1. **Calamares end-to-end** — the sequence/module configs are a solid starting + point but UNTESTED; expect to iterate (esp. partition/mount/bootloader on real + hardware + UEFI). +2. **snapper on Btrfs** — `create-config` can conflict with the pre-created + `/.snapshots` subvol; the shellprocess is tolerant (`|| true`) but verify + snapshots actually work (snap-pac before/after pacman). +3. **systemd-boot + snapshots** — no boot-menu snapshot entries (unlike grub-btrfs); + rollback is via `snapper rollback` from a recovery, not the boot menu. +4. **live-vs-target divergence** — `shellprocess-striplive` removes the live + autologin/installer on the target; verify the target boots to greetd, not Calamares. +5. **Plymouth** — a custom Fuji theme isn't shipped yet (uses the default). Add a + `tanin-plymouth` theme later. +6. **Calamares branding** — no logo/slideshow assets yet (text-only); add `logo.png` + + `show.qml` under `branding/tanin/` for polish. +7. **paru** — rebuild into `[tanin]`, then uncomment in `packages.x86_64`. +8. **[tanin] key in the live keyring** — `customize_airootfs.sh` imports it; confirm + `pacman -Sy` works inside the live env and that Calamares' target pacman trusts it. diff --git a/iso/bootstrap-profile.sh b/iso/bootstrap-profile.sh new file mode 100755 index 0000000..b627015 --- /dev/null +++ b/iso/bootstrap-profile.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Assemble the TANINUX archiso profile = canonical `releng` base + our overrides, +# then (optionally) build the ISO. Run as your user; mkarchiso uses sudo. +# +# sudo pacman -S archiso # once +# ./bootstrap-profile.sh # assemble ./build-profile/ +# ./bootstrap-profile.sh --build # assemble + mkarchiso -> ./out/ +# +# Why this approach: we don't hand-maintain the bootloader/mkinitcpio boilerplate +# (error-prone) — we take it from the authoritative releng profile and only +# overlay our deltas (profiledef, pacman.conf, packages, airootfs, calamares). +set -euo pipefail +HERE="$(cd "$(dirname "$0")" && pwd)" +RELENG=/usr/share/archiso/configs/releng +PROFILE="$HERE/build-profile" + +[ -d "$RELENG" ] || { echo "archiso not installed — run: sudo pacman -S archiso"; exit 1; } + +echo "==> base: copy releng -> build-profile" +rm -rf "$PROFILE" +cp -r "$RELENG" "$PROFILE" + +echo "==> kernel: live ISO uses linux-zen (matches the target)" +sed -i 's/^linux$/linux-zen/' "$PROFILE/packages.x86_64" +# point the live boot entries at the zen kernel images +grep -rl -e 'vmlinuz-linux' -e 'initramfs-linux' \ + "$PROFILE/efiboot" "$PROFILE/syslinux" "$PROFILE/grub" 2>/dev/null \ + | xargs -r sed -i -e 's/vmlinuz-linux/vmlinuz-linux-zen/g' \ + -e 's/initramfs-linux/initramfs-linux-zen/g' + +echo "==> overlay TANINUX overrides" +cat "$HERE/overrides/packages.x86_64" >> "$PROFILE/packages.x86_64" +install -m644 "$HERE/overrides/profiledef.sh" "$PROFILE/profiledef.sh" +install -m644 "$HERE/overrides/pacman.conf" "$PROFILE/pacman.conf" +cp -rT "$HERE/overrides/airootfs" "$PROFILE/airootfs" + +echo "==> profile ready: $PROFILE" +if [ "${1:-}" = "--build" ]; then + echo "==> building ISO (sudo mkarchiso) …" + sudo mkarchiso -v -w /tmp/tanin-work -o "$HERE/out" "$PROFILE" + echo "ISO written to $HERE/out/" +else + echo "build with: sudo mkarchiso -v -w /tmp/tanin-work -o \"$HERE/out\" \"$PROFILE\"" +fi diff --git a/iso/overrides/airootfs/etc/calamares/branding/tanin/branding.desc b/iso/overrides/airootfs/etc/calamares/branding/tanin/branding.desc new file mode 100644 index 0000000..500a781 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/branding/tanin/branding.desc @@ -0,0 +1,24 @@ +--- +componentName: tanin +welcomeStyleCalamares: true +windowExpanding: normal + +strings: + productName: TANINUX + shortProductName: TANINUX + version: camel + shortVersion: camel + versionedName: TANINUX (camel) + shortVersionedName: TANINUX + bootloaderEntryName: TANINUX + productUrl: https://taninux.kgva.ch + supportUrl: https://git.openbureau.ch/karim/taninux + +# Fuji palette for the installer sidebar (matches the desktop). +style: + sidebarBackground: "#0f0f0f" + sidebarText: "#f0f0f0" + sidebarTextSelect: "#a39ec4" + sidebarTextHighlight: "#a39ec4" + +# TODO: add productLogo (logo.png) + a slideshow (show.qml) for polish. diff --git a/iso/overrides/airootfs/etc/calamares/modules/bootloader.conf b/iso/overrides/airootfs/etc/calamares/modules/bootloader.conf new file mode 100644 index 0000000..9ce436c --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/bootloader.conf @@ -0,0 +1,9 @@ +--- +efiBootLoader: "systemd-boot" +kernel: "/vmlinuz-linux-zen" +img: "/initramfs-linux-zen.img" +fallback: "/initramfs-linux-zen-fallback.img" +timeout: "3" +# Plymouth splash + quiet boot on the installed system. +kernelParams: [ "quiet", "splash", "rw" ] +installEFIFallback: true diff --git a/iso/overrides/airootfs/etc/calamares/modules/fstab.conf b/iso/overrides/airootfs/etc/calamares/modules/fstab.conf new file mode 100644 index 0000000..768c4ca --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/fstab.conf @@ -0,0 +1,8 @@ +--- +mountOptions: + default: defaults,noatime + btrfs: defaults,noatime,compress=zstd,space_cache=v2 + efi: defaults,noatime,umask=0077 +ssdExtraMountOptions: + btrfs: ssd,discard=async +crypttabOptions: luks diff --git a/iso/overrides/airootfs/etc/calamares/modules/mount.conf b/iso/overrides/airootfs/etc/calamares/modules/mount.conf new file mode 100644 index 0000000..7a81e13 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/mount.conf @@ -0,0 +1,37 @@ +--- +# Snapper-friendly Btrfs subvolume layout (@ root + @snapshots at /.snapshots). +extraMounts: +- device: proc + fs: proc + mountPoint: /proc +- device: sys + fs: sysfs + mountPoint: /sys +- device: /dev + mountPoint: /dev + options: bind +- device: tmpfs + fs: tmpfs + mountPoint: /run +- device: /run/udev + mountPoint: /run/udev + options: bind + +mountOptions: +- mountPoint: / + options: defaults,noatime +- mountPoint: "*" + filesystem: btrfs + options: defaults,noatime,compress=zstd + +btrfsSubvolumes: +- mountPoint: / + subvolume: /@ +- mountPoint: /home + subvolume: /@home +- mountPoint: /var/cache + subvolume: /@cache +- mountPoint: /var/log + subvolume: /@log +- mountPoint: /.snapshots + subvolume: /@snapshots diff --git a/iso/overrides/airootfs/etc/calamares/modules/packages.conf b/iso/overrides/airootfs/etc/calamares/modules/packages.conf new file mode 100644 index 0000000..bd3d082 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/packages.conf @@ -0,0 +1,12 @@ +--- +backend: pacman +pacman: + num_retries: 3 + disable_download_timeout: true + needed_only: false +operations: +# Strip the live-only installer from the installed target. Everything else was +# cloned by unpackfs. +- try_remove: + - calamares + - cage diff --git a/iso/overrides/airootfs/etc/calamares/modules/partition.conf b/iso/overrides/airootfs/etc/calamares/modules/partition.conf new file mode 100644 index 0000000..a67f828 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/partition.conf @@ -0,0 +1,11 @@ +--- +efiSystemPartition: "/boot" # systemd-boot wants the ESP at /boot +efiSystemPartitionSize: 1024M +userSwapChoices: [ none, small, suspend ] +drawNestedPartitions: true +alwaysShowPartitionLabels: true +allowManualPartitioning: true +initialPartitioningChoice: erase +initialSwapChoice: none +defaultFileSystemType: "btrfs" +availableFileSystemTypes: [ "btrfs", "ext4" ] diff --git a/iso/overrides/airootfs/etc/calamares/modules/services-systemd.conf b/iso/overrides/airootfs/etc/calamares/modules/services-systemd.conf new file mode 100644 index 0000000..bf5671a --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/services-systemd.conf @@ -0,0 +1,13 @@ +--- +services: +- name: greetd # the TANINUX login (tanin-greet) — its config is already + mandatory: false # in place from the tanin-greet package scriptlet +- name: NetworkManager + mandatory: false +- name: snapper-cleanup.timer + mandatory: false +- name: snapper-timeline.timer + mandatory: false +targets: +- name: graphical + mandatory: true diff --git a/iso/overrides/airootfs/etc/calamares/modules/shellprocess-flathub.conf b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-flathub.conf new file mode 100644 index 0000000..dba89f0 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-flathub.conf @@ -0,0 +1,5 @@ +--- +dontChroot: false +timeout: 30 +script: +- "flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo" diff --git a/iso/overrides/airootfs/etc/calamares/modules/shellprocess-snapper.conf b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-snapper.conf new file mode 100644 index 0000000..7cd19f5 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-snapper.conf @@ -0,0 +1,11 @@ +--- +dontChroot: false +timeout: 120 +# Best-effort snapper setup on the Btrfs target. The @snapshots subvolume is +# already mounted at /.snapshots (see mount.conf); snapper's own create-config +# can conflict with a pre-existing /.snapshots, so this is tolerant. +# snap-pac then auto-snapshots before/after each pacman transaction. +script: +- command: "snapper --no-dbus -c root create-config / || true" + timeout: 60 +- "snapper --no-dbus -c root set-config NUMBER_LIMIT=10 NUMBER_LIMIT_IMPORTANT=5 TIMELINE_CREATE=no || true" diff --git a/iso/overrides/airootfs/etc/calamares/modules/shellprocess-striplive.conf b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-striplive.conf new file mode 100644 index 0000000..4ed1fc9 --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/shellprocess-striplive.conf @@ -0,0 +1,11 @@ +--- +dontChroot: false +timeout: 30 +# Remove the live-only installer bits from the installed target so it boots the +# desktop (greetd) instead of auto-launching Calamares. +script: +- "rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf" +- "rmdir --ignore-fail-on-non-empty /etc/systemd/system/getty@tty1.service.d 2>/dev/null || true" +- "rm -f /root/.bash_profile" +- "rm -f /usr/local/bin/tanin-installer" +- "systemctl set-default graphical.target" diff --git a/iso/overrides/airootfs/etc/calamares/modules/unpackfs.conf b/iso/overrides/airootfs/etc/calamares/modules/unpackfs.conf new file mode 100644 index 0000000..1f96bdb --- /dev/null +++ b/iso/overrides/airootfs/etc/calamares/modules/unpackfs.conf @@ -0,0 +1,7 @@ +--- +# Clone the live squashfs onto the target. Path matches install_dir=tanin, +# arch=x86_64, airootfs_image_type=squashfs (see profiledef.sh). +unpack: +- source: "/run/archiso/bootmnt/tanin/x86_64/airootfs.sfs" + sourcefs: "squashfs" + destination: "" diff --git a/iso/overrides/airootfs/root/customize_airootfs.sh b/iso/overrides/airootfs/root/customize_airootfs.sh old mode 100644 new mode 100755 diff --git a/iso/overrides/airootfs/usr/local/bin/tanin-installer b/iso/overrides/airootfs/usr/local/bin/tanin-installer old mode 100644 new mode 100755