fix(bluebuild): rpm-ostree → containerfile RUN to dodge chmod bug
Some checks failed
Build veilor-os Installer ISO / Build installer ISO (push) Failing after 27s
Build veilor-os OCI (BlueBuild) / Build + push OCI (push) Failing after 29m14s

Run 189 + 191 (2026-05-08) both died at the surviving rpm-ostree module:

  chmod: changing permissions of '/tmp/modules/rpm-ostree/rpm-ostree.sh':
  Operation not permitted
  subprocess exited with status 1

Same buildah userns=host bind-mount bug we already worked around for
type:files / type:script / type:systemd — BlueBuild's helper script
tries to chmod itself inside its own bind-mounted layer and the host's
unprivileged user can't change perms on a kernel-mounted overlay path.

Workaround: drop the type:rpm-ostree module, fold its 10-package install
list into the existing type:containerfile snippet as a raw RUN. Per BB
docs each snippets[] entry = its own layer, so all three RUN concerns
(repo curl + rpm-ostree install + brand sed + systemctl enable/disable)
are merged into ONE snippet = ONE layer to keep the A1b commit-cost
collapse intact (~40min/layer wallclock on our fuse-overlayfs runner).

Added repo files inside the same RUN — secureblue base ships neither:
  - https://repository.mullvad.net/rpm/stable/mullvad.repo
  - https://pkgs.tailscale.com/stable/fedora/tailscale.repo
The previous type:rpm-ostree must have been silently failing on these
two pkgs (build never got past the chmod gate to find out).

Ordering: pkgs first (so systemctl enable yggdrasil / disable tailscaled
see their unit files), then brand+units in a best-effort group, then
rpm-ostree cleanup -m && ostree container commit to finalize the layer
(BB's wrapped rpm-ostree module does this implicitly; raw RUN must do
it manually for parity with secureblue / Universal Blue base).

Module count: 7 → 6.
Expected outcome: build clears past STEP rpm-ostree, no chmod gate left.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
s8n-ru 2026-05-08 12:53:03 +01:00
parent c0ea2b3911
commit 505b5f0006

View file

@ -16,12 +16,31 @@
# Run 183 (2026-05-08) ate 3h10min before runner timeout: each RUN/COPY # Run 183 (2026-05-08) ate 3h10min before runner timeout: each RUN/COPY
# layer COMMIT under fuse-overlayfs over secureblue's 130-layer hardened # layer COMMIT under fuse-overlayfs over secureblue's 130-layer hardened
# base costs ~40min wallclock (STEP 10..13 each 3843min). Ergo: every # base costs ~40min wallclock (STEP 10..13 each 3843min). Ergo: every
# saved module = ~40min saved. Collapsed: # saved module = ~40min saved. Collapsed (A1b):
# - 5× rpm-ostree → 1× (-4 layers) # - 5× rpm-ostree → 1× (-4 layers)
# - 2× containerfile (brand sed + systemctl enable) → 1× (-1 layer) # - 2× containerfile (brand sed + systemctl enable) → 1× (-1 layer)
# - 4× copy left as-is — BlueBuild copy module is one src/dest per # - 4× copy left as-is — BlueBuild copy module is one src/dest per
# entry per https://blue-build.org/reference/modules/copy/ # entry per https://blue-build.org/reference/modules/copy/
# Net: 12 → 7 modules, ~5×40min ≈ 3h20min off wallclock budget. # Net: 12 → 7 modules, ~5×40min ≈ 3h20min off wallclock budget.
#
# Run 189 + 191 (2026-05-08) — surviving rpm-ostree module hit the same
# `chmod: Operation not permitted` bug we already worked around for
# type:files / type:script / type:systemd: BlueBuild's helper scripts
# (here `/tmp/modules/rpm-ostree/rpm-ostree.sh`) try to chmod themselves
# inside their own buildah bind-mount under userns=host and fail.
#
# A1c fix: drop type:rpm-ostree, fold its install list into the existing
# containerfile module as a raw RUN. Per BB containerfile docs each
# `snippets:` entry = its own layer, so we MERGE pkg-install + brand +
# systemctl into ONE snippet (= one RUN, one layer). Ordering: install
# packages first (yggdrasil/tailscale/etc must exist before systemctl
# enable/disable touches their units), then brand sed, then unit toggles.
# `ostree container commit` ends the snippet because BB's rpm-ostree
# module wraps it implicitly; raw RUN must do it manually for parity.
# Mullvad + Tailscale repo files curl'd in same RUN — secureblue base
# does not ship either repo, and the previous type:rpm-ostree must have
# silently failed earlier (build never got that far in 189/191).
# Net: 7 → 6 modules, one more layer commit avoided.
--- ---
name: veilor-os name: veilor-os
description: Hardened security-branded Fedora KDE on top of secureblue. description: Hardened security-branded Fedora KDE on top of secureblue.
@ -60,7 +79,7 @@ modules:
source: config/just source: config/just
destination: /usr/share/ublue-os/just destination: /usr/share/ublue-os/just
# ── 2. All package layering in one rpm-ostree pass ────────────── # ── 2. Packages + branding + unit toggles in ONE RUN snippet ────
# secureblue removes sudo + replaces with run0 (too disruptive for # secureblue removes sudo + replaces with run0 (too disruptive for
# daily-driver) — restore. Xwayland was disabled for attack-surface # daily-driver) — restore. Xwayland was disabled for attack-surface
# reduction — restore for Element/Slack/Qt5 apps. Mullvad Browser # reduction — restore for Element/Slack/Qt5 apps. Mullvad Browser
@ -70,64 +89,72 @@ modules:
# fallback). Reticulum/RetiNet stays opt-in via ujust. Memory # fallback). Reticulum/RetiNet stays opt-in via ujust. Memory
# hygiene + ergonomic deps for veilor-postinstall + veilor-doctor. # hygiene + ergonomic deps for veilor-postinstall + veilor-doctor.
# #
# Collapsed from 5 rpm-ostree modules → 1 to drop 4 layer commits # Repos: secureblue base ships neither mullvad nor tailscale repos.
# (~160min wallclock on our buildah+fuse-overlayfs runner). # curl them into /etc/yum.repos.d/ inside the same RUN, before the
- type: rpm-ostree # rpm-ostree install. Both pinned to upstream stable for Fedora.
install:
- sudo
- xorg-x11-server-Xwayland
- mullvad-browser
- tailscale
- yggdrasil
- zram-generator
- jq
- vim-enhanced
- tmux
- htop
# ── 3. Branding overrides + systemd unit toggles in one RUN ─────
# Use raw `type: containerfile` (RUN line) instead of `type: script`
# / `type: systemd` — bluebuild's helper scripts fail 'chmod:
# Operation not permitted' on their own bind-mounted layer under
# podman/buildah privileged. Raw RUN bypasses the helper.
# #
# Single snippet (= single layer) merges: # Branding + unit toggles run in the same RUN (= same layer) AFTER
# - brand sed of /etc/os-release + GRUB_DISTRIBUTOR # rpm-ostree install so systemctl enable yggdrasil / disable tailscaled
# - kde-theme + v03-theme apply scripts # see their unit files.
# - plymouth default-theme #
# - chmod +x on shipped veilor-* scripts/binaries # Helper-script avoidance: BlueBuild's `type: rpm-ostree` /
# - fc-cache rebuild # `type: files` / `type: script` / `type: systemd` modules all hit
# - systemctl enable yggdrasil + veilor-{firstboot,modules-lock, # `chmod: Operation not permitted` on their own bind-mounted helper
# postinstall}.service + veilor-doctor.timer # script under buildah userns=host (run 189 + 191, last-frame error:
# - systemctl disable tailscaled (Day-1-disabled per threat model) # `chmod: changing permissions of '/tmp/modules/rpm-ostree/rpm-ostree.sh':
# Operation not permitted`). Raw `type: containerfile` RUN bypasses
# the whole helper-script layer.
#
# ostree container commit at the end mirrors what BB's wrapped
# rpm-ostree module does implicitly — finalizes the layer for the
# secureblue / Universal Blue base expectation.
# #
# brand-leak grep moved to CI smoke-test in build-bluebuild.yml # brand-leak grep moved to CI smoke-test in build-bluebuild.yml
# (STEP 14 hung under buildah overlayfs, run 171 2026-05-07). # (STEP 14 hung under buildah overlayfs, run 171 2026-05-07).
- type: containerfile - type: containerfile
snippets: snippets:
- | - |
RUN sed -i -e 's|^GRUB_DISTRIBUTOR=.*|GRUB_DISTRIBUTOR="veilor-os"|' /etc/default/grub 2>/dev/null || true ; \ RUN set -euo pipefail ; \
bash /usr/share/veilor-os/scripts/kde-theme-apply.sh 2>/dev/null || true ; \ curl -fsSL https://repository.mullvad.net/rpm/stable/mullvad.repo \
bash /usr/share/veilor-os/scripts/30-apply-v03-theme.sh 2>/dev/null || true ; \ -o /etc/yum.repos.d/mullvad.repo ; \
plymouth-set-default-theme details 2>/dev/null || true ; \ curl -fsSL https://pkgs.tailscale.com/stable/fedora/tailscale.repo \
chmod +x /usr/share/veilor-os/scripts/*.sh \ -o /etc/yum.repos.d/tailscale.repo ; \
/usr/share/veilor-os/scripts/selinux/*.sh \ rpm-ostree install \
/usr/local/bin/veilor-* 2>/dev/null || true ; \ sudo \
fc-cache -f 2>/dev/null || true ; \ xorg-x11-server-Xwayland \
if [ -f /etc/os-release ]; then \ mullvad-browser \
sed -i \ tailscale \
-e 's|^NAME=.*|NAME="veilor-os"|' \ yggdrasil \
-e 's|^PRETTY_NAME=.*|PRETTY_NAME="veilor-os 0.7 (atomic)"|' \ zram-generator \
-e 's|^ID=.*|ID=veilor|' \ jq \
-e 's|^ID_LIKE=.*|ID_LIKE="fedora kinoite"|' \ vim-enhanced \
/etc/os-release || true ; \ tmux \
fi ; \ htop ; \
systemctl enable yggdrasil.service 2>/dev/null || true ; \ { sed -i -e 's|^GRUB_DISTRIBUTOR=.*|GRUB_DISTRIBUTOR="veilor-os"|' /etc/default/grub 2>/dev/null || true ; \
systemctl disable tailscaled.service 2>/dev/null || true ; \ bash /usr/share/veilor-os/scripts/kde-theme-apply.sh 2>/dev/null || true ; \
systemctl enable veilor-firstboot.service 2>/dev/null || true ; \ bash /usr/share/veilor-os/scripts/30-apply-v03-theme.sh 2>/dev/null || true ; \
systemctl enable veilor-modules-lock.service 2>/dev/null || true ; \ plymouth-set-default-theme details 2>/dev/null || true ; \
systemctl enable veilor-postinstall.service 2>/dev/null || true ; \ chmod +x /usr/share/veilor-os/scripts/*.sh \
systemctl enable veilor-doctor.timer 2>/dev/null || true /usr/share/veilor-os/scripts/selinux/*.sh \
/usr/local/bin/veilor-* 2>/dev/null || true ; \
fc-cache -f 2>/dev/null || true ; \
if [ -f /etc/os-release ]; then \
sed -i \
-e 's|^NAME=.*|NAME="veilor-os"|' \
-e 's|^PRETTY_NAME=.*|PRETTY_NAME="veilor-os 0.7 (atomic)"|' \
-e 's|^ID=.*|ID=veilor|' \
-e 's|^ID_LIKE=.*|ID_LIKE="fedora kinoite"|' \
/etc/os-release || true ; \
fi ; \
systemctl enable yggdrasil.service 2>/dev/null || true ; \
systemctl disable tailscaled.service 2>/dev/null || true ; \
systemctl enable veilor-firstboot.service 2>/dev/null || true ; \
systemctl enable veilor-modules-lock.service 2>/dev/null || true ; \
systemctl enable veilor-postinstall.service 2>/dev/null || true ; \
systemctl enable veilor-doctor.timer 2>/dev/null || true ; \
} ; \
rpm-ostree cleanup -m ; \
ostree container commit
# ── 4. signing config ─────────────────────────────────────────── # ── 4. signing config ───────────────────────────────────────────
# cosign.pub committed alongside this recipe; cosign.key kept off # cosign.pub committed alongside this recipe; cosign.key kept off