diff --git a/docs/signed-repo.md b/docs/signed-repo.md index 02b5340..224476e 100644 --- a/docs/signed-repo.md +++ b/docs/signed-repo.md @@ -74,7 +74,7 @@ Pacman fetches `
.db` + `
.db.sig` from `Server`. ## Dispatch the workflow Forgejo UI: **Actions → "Publish signed [breadway] repo" → Run workflow**. -Select this branch (`feature/signed-repo`) until it is on `main`. +Select `main`. API (`workflow_dispatch`): @@ -83,11 +83,9 @@ curl -fsS -X POST \ -H "Authorization: token ${RELEASE_TOKEN}" \ -H "Content-Type: application/json" \ "https://git.breadway.dev/api/v1/repos/Breadway/bos/actions/workflows/signed-repo.yml/dispatches" \ - -d '{"ref":"feature/signed-repo"}' + -d '{"ref":"main"}' ``` -After merge, use `"ref":"main"`. - It also runs after the in-repo AUR republish workflows complete (`calamares` / `bibata` / `powerlevel10k` / `yay-bin`). breadlock lives in another repo; that job can fire this one with `repository_dispatch` event @@ -151,5 +149,5 @@ and the verify commands above succeed: 3. Only then flip that section to `SigLevel = Required`. Do not do those three steps against Forgejo's registry. See -`iso/pacman.conf` and `iso/airootfs/etc/pacman.conf`. This branch does +`iso/pacman.conf` and `iso/airootfs/etc/pacman.conf`. This tree does **not** change either file. diff --git a/iso/airootfs/etc/calamares/modules/welcome.conf b/iso/airootfs/etc/calamares/modules/welcome.conf index 33bf7ad..c31ea71 100644 --- a/iso/airootfs/etc/calamares/modules/welcome.conf +++ b/iso/airootfs/etc/calamares/modules/welcome.conf @@ -3,9 +3,19 @@ showSupportUrl: false showKnownIssuesUrl: false showReleaseNotesUrl: false +# 3.4.2 schema: `check` is shown; only `required` blocks Next. Internet is +# informational so offline installs proceed. Do not probe archlinux.org. requirements: requiredStorage: 20 requiredRam: 2.0 - checkInternet: true - checkPower: true - internetCheckUrl: "https://archlinux.org" + internetCheckUrl: "https://breadway.dev" + check: + - storage + - ram + - power + - internet + - root + required: + - storage + - ram + - root diff --git a/iso/airootfs/etc/calamares/post-install.sh b/iso/airootfs/etc/calamares/post-install.sh index 5817f2e..b8d4736 100644 --- a/iso/airootfs/etc/calamares/post-install.sh +++ b/iso/airootfs/etc/calamares/post-install.sh @@ -8,8 +8,6 @@ # Best-effort: do NOT use `set -e`; a single failure here must not abort the rest. set -uo pipefail -MAIN_USER="$(getent passwd 1000 | cut -d: -f1 || true)" - # Whether Calamares encrypted the root partition (LUKS) — checked once here, # used below to conditionally wire mkinitcpio's encrypt hook and GRUB's # cryptodisk support. `lsblk TYPE` reports "crypt" for a cryptsetup-opened @@ -33,6 +31,14 @@ rm -f /usr/local/bin/bos-live-setup /usr/local/bin/bos-launch-calamares rm -f /etc/sudoers.d/99-bos-live userdel -r liveuser 2>/dev/null || true +# Live ISO creates liveuser as UID 1000; Calamares then creates the real +# account as 1001. Capture AFTER userdel so Snapper ALLOW_USERS and skel +# copy the installed user, not the deleted live account. +MAIN_USER="$(getent passwd 1000 | cut -d: -f1 || true)" +if [[ -z "$MAIN_USER" || "$MAIN_USER" == "liveuser" ]]; then + MAIN_USER="$(getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 && $1 != "liveuser" { print $1; exit }')" +fi + # unpackfs copies the entire live squashfs onto the target. Remove live-only # packages (Calamares + archiso boot chain + memtest/EFI-shell payloads) so # they do not stay on disk forever. pacman -Rs (not -Rns) keeps /etc configs diff --git a/iso/airootfs/etc/skel/.config/hypr/autostart.json b/iso/airootfs/etc/skel/.config/hypr/autostart.json index ee66107..be2b4ac 100644 --- a/iso/airootfs/etc/skel/.config/hypr/autostart.json +++ b/iso/airootfs/etc/skel/.config/hypr/autostart.json @@ -7,6 +7,7 @@ { "command": "breadhelp --autostart", "label": "BOS Help (first-run onboarding)", "enabled": true }, { "command": "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", "label": "Wallpaper command bus (breadpaper listen)", "enabled": true }, { "command": "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", "label": "Screenshot command bus (breadshot listen)", "enabled": true }, + { "command": "bash -c 'command -v breadlock >/dev/null && exec breadlock listen'", "label": "Lock command bus (breadlock listen)", "enabled": true }, { "command": "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", "label": "Launcher command bus (breadbox listen)", "enabled": true }, { "command": "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", "label": "Help command bus (breadhelp listen)", "enabled": true }, { "command": "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", "label": "Search command bus (breadsearch listen)", "enabled": true }, diff --git a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua index 565da5b..f03e5b5 100644 --- a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua +++ b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua @@ -137,9 +137,9 @@ hl.on("hyprland.start", function() -- Clipboard history is breadclipd, a bakery-managed systemd --user -- service (auto-started from /usr/lib/systemd/user — see -- build-local.sh's service bake) rather than an exec-once here. - -- Prefer bread-polkit when bakery has published it; otherwise the - -- ISO's polkit-gnome agent. command -v so a missing binary does not - -- leave the session without an auth agent. + -- Prefer bread-polkit if it is on PATH (not baked; lockfile does not + -- ship it). Otherwise the ISO's polkit-gnome agent. command -v so a + -- missing binary does not leave the session without an auth agent. "sh -c 'if command -v bread-polkit >/dev/null; then exec bread-polkit; else exec /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1; fi'", "awww-daemon", -- Set the default wallpaper once the daemon is up (retry until ready). @@ -194,6 +194,7 @@ hl.on("hyprland.start", function() "breadhelp --autostart", "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", + "bash -c 'command -v breadlock >/dev/null && exec breadlock listen'", "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", diff --git a/iso/airootfs/etc/skel/.config/hypr/scripts/system/autostart.lua b/iso/airootfs/etc/skel/.config/hypr/scripts/system/autostart.lua index 46f4970..63e364f 100644 --- a/iso/airootfs/etc/skel/.config/hypr/scripts/system/autostart.lua +++ b/iso/airootfs/etc/skel/.config/hypr/scripts/system/autostart.lua @@ -22,6 +22,7 @@ local DEFAULT_EXTRA = { { command = "breadhelp --autostart", enabled = true }, { command = "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", enabled = true }, { command = "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", enabled = true }, + { command = "bash -c 'command -v breadlock >/dev/null && exec breadlock listen'", enabled = true }, { command = "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", enabled = true }, { command = "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", enabled = true }, { command = "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", enabled = true }, diff --git a/iso/airootfs/usr/local/bin/bos-update b/iso/airootfs/usr/local/bin/bos-update index 16b9da8..a34f70b 100644 --- a/iso/airootfs/usr/local/bin/bos-update +++ b/iso/airootfs/usr/local/bin/bos-update @@ -47,7 +47,15 @@ fi echo bold "==> Bread ecosystem (bakery update --all)" if command -v bakery >/dev/null; then - bakery update --all || echo "WARN: bakery update failed" + # /usr/local is root-owned. Never run bakery as the user against it; + # bakery itself also tries sudo -n then pkexec for privileged writes. + if sudo -n true >/dev/null 2>&1; then + sudo -n bakery update --all || echo "WARN: bakery update failed" + elif command -v pkexec >/dev/null; then + pkexec bakery update --all || echo "WARN: bakery update failed" + else + echo "WARN: bakery update needs sudo -n or pkexec for /usr/local" + fi else echo "bakery not found; skipping" fi diff --git a/iso/bread-lockfile.toml b/iso/bread-lockfile.toml index 6154893..8e21593 100644 --- a/iso/bread-lockfile.toml +++ b/iso/bread-lockfile.toml @@ -3,8 +3,8 @@ # build-local.sh and CI (scripts/ci-stage-bakery.py) read this file. A missing # *required* binary fails the bake: a hollow ISO is worse than a failed build. # optional_bins are baked when the verified stable index publishes them, and -# skipped with a warning when it does not (today: bread 0.8.0 has no -# bread-emit / bread-module-host). +# skipped with a warning when it does not. bread 0.8.0 ships bread-emit and +# bread-module-host, so those are required_bins. # # A flat `bins` list is still accepted and treated as required_bins. # @@ -23,6 +23,8 @@ required_bins = [ "bakery", "bread", "breadd", + "bread-emit", + "bread-module-host", "breadman", "breadbar", "breadbox", @@ -41,19 +43,13 @@ required_bins = [ "breadhelp", ] -# Bake if the verified index publishes them; do not fail the ISO if absent. -optional_bins = [ - "bread-emit", - "bread-module-host", -] - # Package name → version. Must exist at dl.breadway.dev/// and # should match the signed index so CI can verify sha256. # [[pin]] { package, version } is accepted as well and merged (conflict = bake error). [versions] -bakery = "0.7.3" +bakery = "0.7.4" bread = "0.8.0" -bread-theme = "0.7.3" +bread-theme = "0.7.4" breadbar = "0.3.2" breadbox = "0.3.2" breadcrumbs = "2.1.8" diff --git a/scripts/ci-publish-signed-repo.sh b/scripts/ci-publish-signed-repo.sh index 08fbb53..f063ce2 100755 --- a/scripts/ci-publish-signed-repo.sh +++ b/scripts/ci-publish-signed-repo.sh @@ -81,6 +81,8 @@ repo_add_signed() { fi [[ -e breadway.db.tar.gz.sig || -e breadway.db.sig ]] \ || die "repo-add -s did not write breadway.db*.sig" + # gpg writes 0600; nginx and the next publish need world-readable files. + find . -maxdepth 1 -type f -exec chmod a+r {} + || true } ensure_arch_tools() { @@ -125,7 +127,12 @@ sign_and_index_anywhere() { rt="$(container_runtime)" || die \ "need host gpg+repo-add, or docker/podman to run archlinux:latest (no Forgejo container: — host must see /srv/breadway-dl)" # Host job + bind-mount, same reason bakery writes /srv without container:. + # Run as the runner user: root-owned 0600 .sig files made chmod/nginx fail + # (run 1050) and would block the next `rm -rf` of a previous tree. "$rt" run --rm --network=host \ + --user "$(id -u):$(id -g)" \ + -e HOME=/tmp \ + -e TMPDIR=/tmp \ -e GPG_PRIVATE_KEY \ -e BREADWAY_SIGN_ONLY=1 \ -e BREADWAY_REPO_DIR=/repo \ @@ -243,8 +250,10 @@ publish_tree() { parent="$(dirname "$DEST")" dest_name="$(basename "$DEST")" mkdir -p "$parent" - chmod a+rX "$STAGE" - find "$STAGE" -type f -exec chmod a+r {} + + chmod a+rX "$STAGE" || true + # gpg --detach-sign often writes 0600 files the runner cannot chmod; + # do not fail the publish after repo-add -s already succeeded. + find "$STAGE" -type f -exec chmod a+r {} + || true prev="$parent/${dest_name}.prev" rm -rf "$prev" if [[ -e "$DEST" ]]; then diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh index ccdc571..28b5c28 100755 --- a/scripts/smoke-test.sh +++ b/scripts/smoke-test.sh @@ -40,22 +40,15 @@ check "grub-btrfs present" "pacman -Qq grub-btrfs" echo "== enabled system services ==" for unit in NetworkManager.service greetd.service bluetooth.service tlp.service \ - cups.socket avahi-daemon.service ufw.service systemd-timesyncd.service; do + cups.socket avahi-daemon.socket ufw.service systemd-timesyncd.service; do check "$unit enabled" "systemctl is-enabled $unit" done check "graphical.target is default" "[ \"\$(systemctl get-default)\" = graphical.target ]" echo "== bread ecosystem on PATH ==" -for bin in bakery bread breadd breadbar breadbox breadbox-sync breadcrumbs breadpad breadman; do +for bin in bakery bread breadd bread-emit bread-module-host breadbar breadbox breadbox-sync breadcrumbs breadpad breadman; do check "$bin found" "command -v $bin" done -for bin in bread-emit bread-module-host; do - if command -v "$bin" >/dev/null 2>&1; then - ok "$bin found" - else - note "$bin not on PATH (optional until stable bread ships it)" - fi -done echo "== bos-settings ==" check "bos-settings installed" "command -v bos-settings"