You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(self-replication): close the git push -> build -> bootc switch loop
The defining MiOS feature -- live `/` is a git working tree, Forgejo at
localhost:3000 hosts the bare repo, the OS rebuilds itself -- was
structurally incomplete. This commit lands every missing piece so the
loop closes end-to-end with no manual operator steps after firstboot.
Self-replication loop:
- new etc/containers/systemd/mios-forgejo-runner.container Quadlet
(Privileged=true, documented architectural exception alongside
mios-ceph + mios-k3s; shares /var/lib/containers/storage with host)
- new .forgejo/workflows/build-mios.yml (podman build, bootc-label
verification, sentinel-file handoff to the host watcher)
- usr/libexec/mios/forge-firstboot.sh: extends admin bootstrap to
also create the initial <admin>/mios repo via /api/v1/user/repos
and mint a Forgejo Runner registration token (CLI first, admin
API fallback) into /etc/mios/forge/runner-token (mode 0600)
- new usr/libexec/mios/bootc-switch-from-build.sh + matching
mios-bootc-switch.{service,path}: host-side watcher that reads the
runner's sentinel and runs `bootc switch --transport
containers-storage <ref>`. Privilege boundary stops at the file --
runner doesn't touch bootc, host doesn't touch the build.
- new usr/lib/tmpfiles.d/mios-forge-runner.conf for the state dirs
- .gitignore: whitelist .forgejo/, mios-*.{path,socket}; exclude
runtime state (forge-runner/, bootc-switch-history.tsv,
firstboot sentinels) so it never round-trips through `git push`
Build hardening / attack-surface reduction:
- usr/share/mios/PACKAGES.md: split build toolchain (gcc, g++, make,
cmake, golang, selinux-policy-devel, binutils, pkgconf-pkg-config)
out of packages-containers into a new packages-build-toolchain
block; a deployed runtime no longer carries compilers
- automation/12-virt.sh installs the new block early; new
automation/91-strip-build-toolchain.sh removes it after SBOM and
before cleanup, with a verification pass that no compiler binary
remains in PATH
- automation/build.sh marks 91-strip-build-toolchain.sh non-fatal
- mios-bootstrap/build-mios.sh adds packages-build-toolchain to the
FHS-install exclude list (deployed FHS hosts never get it)
Quadlet parser fix (was disabling all Quadlets, including Forgejo):
- etc/containers/systemd/mios-forge.container: remove inline `# ...`
comments after PublishPort= (systemd unit syntax doesn't allow
trailing comments; the malformed value broke
podman-system-generator and prevented every Quadlet from rendering)
Boot-log noise + race fixes:
- usr/lib/systemd/system/dbus-daemon-wsl.service: Type=notify +
NotifyAccess=main, closes the startup race that surfaced as
"Failed to connect to system scope bus via local transport:
Connection refused" at user login on WSL2
- new usr/lib/systemd/system/coreos-warn-invalid-mounts.service.d/
10-mios-wsl2.conf: ConditionVirtualization=!wsl, suppresses the
composefs/read-only MOTD warnings that are structurally
impossible on WSL2
External repo resilience:
- automation/05-enable-external-repos.sh: every external scurl + dnf
copr op now uses a try_fetch wrapper with warn-on-failure +
partial-file cleanup, so a single transient HTTP 22 from any one
external mirror no longer tanks the whole build
- VSCodium RPM repo block removed -- applications ship as Flatpaks
per the project invariant (VM | Container | Flatpak only)
Configurator HTML + Containerfile cleanup:
- usr/share/mios/configurator/index.html: full Flatpak catalog (40
apps, 8 pre-selected as the MiOS minimal default, 32 opt-in
across Gaming / GNOME core / Alternatives); parser fix for
multi-line arrays; emit improved for long arrays; schema 1.2.0
- Containerfile: drop the always-empty /usr/lib/extensions/source
sysext-pack RUN (no automation populates it; tools/mios-sysext-
pack.sh stays in tree for future use; commented recipe shows
how to re-enable when sysext sources are actually staged)
- automation/37-aichat.sh: header flags the open Distrobox
migration; packages-ai block emptied (aichat ships as tarball,
not RPM)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
0 commit comments