Skip to content

Commit fefca62

Browse files
Kabuki94claude
andcommitted
feat(dash): MiOS ASCII logo + Flatpaks panel + mios-* CLI verbs + dbus fix
Four interlocking changes from the latest boot diagnostics + the operator-stated dashboard polish: 1. MiOS ASCII logo for fastfetch + every console surface Replaced the auto-detected Fedora logo with a MiOS-branded 3D-outlined word-mark at /usr/share/mios/branding/mios.txt. Wired into the fastfetch config via "logo": { "type": "raw", "source": ... } so every dashboard render -- /etc/issue.d pre-login banner, post-login /etc/profile.d/zz-mios-motd.sh, the manual `mios-status` invocation -- shows MiOS branding instead of the upstream Fedora art. 2. Flatpaks panel in the dashboard services block New print_flatpaks() in mios-dashboard.sh that calls flatpak list --system --app --columns=application,version,branch and renders up to 12 entries with green dots, application IDs, version, and branch. Sits between the Quadlet rollup and the git working-tree section so operators see exactly which user-selected Flatpaks were baked into the image (via 40-flatpak-bake.sh from the previous commit). Empty list shows a single line pointing back at the configurator's [desktop].flatpaks edit path. 3. /usr/bin/mios-* operator CLI verbs Audit of `mios *` commands the 36-tools.sh phase warned about as missing. Implementing the user-facing verbs each as a thin shell wrapper around the underlying mechanism so operators don't have to remember the long invocations: - mios-status -> /usr/libexec/mios/mios-dashboard.sh "$@" - mios-update -> bootc upgrade [--check|--apply|--rollback] - mios-rebuild -> stage all + commit + push to localhost:3000 (triggers Forgejo Runner workflow -> bootc switch) - mios-build -> local podman build of /Containerfile + bootc switch --transport containers-storage (skips the runner; for fast iteration) - mios-deploy -> bootc status + reboot prompt to apply staged deployment ; --rollback to undo - mios-flatpaks -> list/add/remove/update/search wrapper + `bake-state` to inspect /usr/lib/mios/state/ flatpak-bake.env from the build .gitignore widened from explicit per-binary whitelist to `!/usr/bin/mios-*` so future operator verbs don't need a per-file gitignore edit. The ones the user-VFIO-toggle / mios-vfio-check / iommu-groups / mios-backup verbs from the 36-tools warning list remain unimplemented -- those need device-specific PCI/IOMMU logic; queued for a follow-up. 4. dbus-daemon-wsl pure socket-activation (THE D-Bus boot failure) Latest boot log showed: [ OK ] Started dbus-daemon-wsl.service dbus-daemon[154]: Failed to start message bus: No socket received. then 25+ cockpit-wsinstance-socket-user.service [FAILED] cascade failures, plus user shells getting "Failed to connect to system scope bus" at every login. Cause: my [Install] section had `WantedBy=multi-user.target`, which tells systemd to start the unit at boot directly. But the ExecStart uses `--systemd-activation`, which means dbus-daemon EXPECTS to receive the listening socket FD via systemd socket-activation. With WantedBy=, systemd starts the unit DIRECTLY -- no FD passed -- and dbus-daemon exits with "No socket received". The entire D-Bus stack stays dead, cascading into cockpit, logind, polkit, homectl. Fix: removed `WantedBy=multi-user.target`. Kept `Alias=dbus.service`. Pure socket-activation: dbus.socket (already listening on /run/dbus/system_bus_socket) triggers Service=dbus.service, the Alias= maps that to this unit, and the socket FD is passed correctly. The unit starts on first client connection (milliseconds after multi-user.target as logind/polkit attempt their first system bus call). Once dbus comes up, the dashboard's "missing" Quadlet rollup will resolve to real states -- it was reporting "missing" because `systemctl show` as the unprivileged user couldn't reach the system bus to query unit LoadState/ActiveState. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent b8c00f3 commit fefca62

11 files changed

Lines changed: 426 additions & 5 deletions

File tree

.gitignore

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,15 @@ usr/*
159159
!/usr/libexec/
160160
!/usr/share/
161161

162-
# usr/bin -- only MiOS-owned CLIs
162+
# usr/bin -- only MiOS-owned CLIs. Glob covers all mios-* operator
163+
# verbs (mios-status, mios-update, mios-rebuild, mios-build, mios-deploy,
164+
# mios-flatpaks, plus future additions). Each is a thin shell wrapper
165+
# around the underlying mechanism (bootc / podman / git-against-/.git /
166+
# the local Forgejo at localhost:3000) so operators don't have to
167+
# remember the long invocations.
163168
usr/bin/*
164169
!/usr/bin/mios
165-
!/usr/bin/mios-env
166-
!/usr/bin/mios-sync-env
170+
!/usr/bin/mios-*
167171

168172
# usr/share -- mios/ build files + doc/mios/ KB docs
169173
usr/share/*

usr/bin/mios-build

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env bash
2+
# mios-build -- run a LOCAL podman build of the live working tree at /,
3+
# without going through the Forgejo Runner. Produces localhost/mios:latest
4+
# in the host's containers-storage directly. Useful for fast iteration when
5+
# you want to skip the push -> runner -> sentinel -> watch -> bootc switch
6+
# loop and just rebuild + switch immediately.
7+
#
8+
# mios-build # podman build + bootc switch (no reboot)
9+
# mios-build --apply # build, switch, AND reboot
10+
# mios-build --no-switch # build only; don't stage with bootc
11+
# mios-build --tag <name> # use a custom local tag (default: mios:latest)
12+
#
13+
# For the full closed-loop pattern (push -> runner -> CI -> bootc switch),
14+
# use mios-rebuild instead.
15+
16+
set -euo pipefail
17+
18+
TAG="localhost/mios:latest"
19+
DO_SWITCH=1
20+
DO_REBOOT=0
21+
22+
while (( $# > 0 )); do
23+
case "$1" in
24+
--apply) DO_REBOOT=1; shift ;;
25+
--no-switch) DO_SWITCH=0; shift ;;
26+
--tag) TAG="$2"; shift 2 ;;
27+
--help|-h)
28+
sed -n '2,15p' "$0" | sed 's/^# \?//'
29+
exit 0
30+
;;
31+
*)
32+
echo "mios-build: unknown flag '$1' (try --help)" >&2
33+
exit 2
34+
;;
35+
esac
36+
done
37+
38+
if [[ $EUID -ne 0 ]]; then
39+
exec sudo -E "$0" "$@"
40+
fi
41+
42+
if [[ ! -f /Containerfile ]]; then
43+
echo "ERROR: /Containerfile not found. Is this a MiOS-deployed root?" >&2
44+
exit 1
45+
fi
46+
47+
# Source build args from install.env so the rebuild matches the installed identity.
48+
if [[ -r /etc/mios/install.env ]]; then
49+
# shellcheck disable=SC1091
50+
set -a; source /etc/mios/install.env; set +a
51+
fi
52+
53+
BUILD_ARGS=()
54+
[[ -n "${MIOS_LINUX_USER:-}" ]] && BUILD_ARGS+=(--build-arg "MIOS_USER=${MIOS_LINUX_USER}")
55+
[[ -n "${MIOS_HOSTNAME:-}" ]] && BUILD_ARGS+=(--build-arg "MIOS_HOSTNAME=${MIOS_HOSTNAME}")
56+
[[ -n "${MIOS_AI_MODEL:-}" ]] && BUILD_ARGS+=(--build-arg "MIOS_AI_MODEL=${MIOS_AI_MODEL}")
57+
[[ -n "${MIOS_AI_EMBED_MODEL:-}" ]] && BUILD_ARGS+=(--build-arg "MIOS_AI_EMBED_MODEL=${MIOS_AI_EMBED_MODEL}")
58+
[[ -n "${MIOS_OLLAMA_BAKE_MODELS:-}" ]] && BUILD_ARGS+=(--build-arg "MIOS_OLLAMA_BAKE_MODELS=${MIOS_OLLAMA_BAKE_MODELS}")
59+
60+
echo "[mios-build] building ${TAG} from /"
61+
podman build "${BUILD_ARGS[@]}" -f /Containerfile -t "${TAG}" /
62+
63+
if (( DO_SWITCH )); then
64+
echo "[mios-build] staging via bootc switch (containers-storage transport)"
65+
bootc switch --transport containers-storage "${TAG}"
66+
fi
67+
68+
if (( DO_REBOOT )); then
69+
echo "[mios-build] rebooting in 3s ..."
70+
sleep 3
71+
systemctl reboot
72+
else
73+
echo
74+
echo "Build staged. Reboot to apply:"
75+
echo " sudo systemctl reboot"
76+
fi
77+
78+
exit 0

usr/bin/mios-deploy

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env bash
2+
# mios-deploy -- apply a staged bootc deployment. Companion to
3+
# mios-build / mios-rebuild / mios-update -- those STAGE a new
4+
# deployment via `bootc switch` or `bootc upgrade`; mios-deploy is
5+
# the explicit "reboot to activate" step.
6+
#
7+
# mios-deploy # show staged deployments + reboot prompt
8+
# mios-deploy --now # reboot immediately
9+
# mios-deploy --status # show staged + booted deployments; no reboot
10+
# mios-deploy --rollback # rollback to previous deployment, then reboot
11+
set -euo pipefail
12+
13+
case "${1:-}" in
14+
--status)
15+
bootc status
16+
exit 0
17+
;;
18+
--now)
19+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" "$@"; fi
20+
echo "Rebooting to activate the staged deployment in 3s ..."
21+
sleep 3
22+
systemctl reboot
23+
;;
24+
--rollback)
25+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" "$@"; fi
26+
bootc rollback
27+
echo "Rollback staged. Rebooting in 3s to activate ..."
28+
sleep 3
29+
systemctl reboot
30+
;;
31+
--help|-h)
32+
sed -n '2,11p' "$0" | sed 's/^# \?//'
33+
exit 0
34+
;;
35+
"")
36+
bootc status
37+
echo
38+
read -rp "Reboot now to activate the staged deployment? [y/N] " ans
39+
case "${ans,,}" in
40+
y|yes)
41+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" --now; fi
42+
echo "Rebooting in 3s ..."
43+
sleep 3
44+
systemctl reboot
45+
;;
46+
*)
47+
echo "Aborted. Run 'mios-deploy --now' or 'sudo systemctl reboot' when ready."
48+
;;
49+
esac
50+
;;
51+
*)
52+
echo "mios-deploy: unknown flag '$1' (try --help)" >&2
53+
exit 2
54+
;;
55+
esac

usr/bin/mios-flatpaks

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env bash
2+
# mios-flatpaks -- thin wrapper over `flatpak` for the MiOS-shipped
3+
# system-wide Flatpak surface. Operator-friendly verbs that don't
4+
# require remembering the long flatpak invocations.
5+
#
6+
# mios-flatpaks list list all installed system Flatpaks
7+
# mios-flatpaks add <ref> install <ref> from flathub system-wide
8+
# mios-flatpaks remove <ref> uninstall <ref> system-wide
9+
# mios-flatpaks update update all installed Flatpaks
10+
# mios-flatpaks search <term> search flathub for <term>
11+
# mios-flatpaks bake-state show the build-time bake state
12+
# (/usr/lib/mios/state/flatpak-bake.env)
13+
#
14+
# To make a Flatpak persist across `bootc switch` (the self-replication
15+
# loop), edit the canonical mios.toml [desktop].flatpaks array via the
16+
# configurator HTML at /usr/share/mios/configurator/index.html, then
17+
# `mios-rebuild` to push and trigger a runner-side rebuild.
18+
set -euo pipefail
19+
20+
cmd="${1:-list}"
21+
shift || true
22+
23+
case "$cmd" in
24+
list|ls)
25+
flatpak list --system --app --columns=application,version,branch,origin "$@"
26+
;;
27+
add|install)
28+
if [[ -z "${1:-}" ]]; then
29+
echo "mios-flatpaks add <flathub-ref> (e.g. com.valvesoftware.Steam)" >&2
30+
exit 2
31+
fi
32+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" add "$@"; fi
33+
flatpak install --system --noninteractive --assumeyes flathub "$@"
34+
;;
35+
remove|uninstall|rm)
36+
if [[ -z "${1:-}" ]]; then
37+
echo "mios-flatpaks remove <flathub-ref>" >&2
38+
exit 2
39+
fi
40+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" remove "$@"; fi
41+
flatpak uninstall --system --noninteractive --assumeyes "$@"
42+
;;
43+
update|upgrade)
44+
if [[ $EUID -ne 0 ]]; then exec sudo -E "$0" update "$@"; fi
45+
flatpak update --system --noninteractive --assumeyes "$@"
46+
;;
47+
search)
48+
if [[ -z "${1:-}" ]]; then
49+
echo "mios-flatpaks search <term>" >&2
50+
exit 2
51+
fi
52+
flatpak search "$@"
53+
;;
54+
bake-state)
55+
if [[ -r /usr/lib/mios/state/flatpak-bake.env ]]; then
56+
cat /usr/lib/mios/state/flatpak-bake.env
57+
else
58+
echo "No bake state recorded (image may pre-date 40-flatpak-bake.sh)."
59+
fi
60+
;;
61+
--help|-h|help)
62+
sed -n '2,15p' "$0" | sed 's/^# \?//'
63+
;;
64+
*)
65+
echo "mios-flatpaks: unknown verb '$cmd' (try --help)" >&2
66+
exit 2
67+
;;
68+
esac

usr/bin/mios-rebuild

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env bash
2+
# mios-rebuild -- push the live working tree at / to the local Forgejo
3+
# at localhost:3000 so the Forgejo Runner Quadlet picks up the change,
4+
# runs .forgejo/workflows/build-mios.yml, produces a new OCI image at
5+
# localhost/mios:latest, and the host's mios-bootc-switch.path watcher
6+
# stages it for the next reboot.
7+
#
8+
# This is the "edit anywhere -> push -> rebuild -> bootc switch" closed
9+
# self-replication loop. The git working tree at / is the deployed
10+
# system itself.
11+
#
12+
# mios-rebuild [-m "<commit msg>"] stage all changes, commit, push
13+
# mios-rebuild --status show last build sentinel content
14+
# mios-rebuild --no-push commit only; don't trigger build
15+
#
16+
# Prerequisites checked at runtime:
17+
# - / is a git working tree (.git exists)
18+
# - Forgejo at localhost:3000 is reachable (mios-forge.service active)
19+
# - Origin remote points at the local forge
20+
21+
set -euo pipefail
22+
23+
DEFAULT_MSG="mios-rebuild: live root snapshot $(date -u +%FT%TZ)"
24+
COMMIT_MSG="$DEFAULT_MSG"
25+
DO_PUSH=1
26+
27+
while (( $# > 0 )); do
28+
case "$1" in
29+
-m|--message) COMMIT_MSG="$2"; shift 2 ;;
30+
--no-push) DO_PUSH=0; shift ;;
31+
--status)
32+
if [[ -r /var/lib/mios/forge-runner/last-build.txt ]]; then
33+
echo "Last Forge Runner build:"
34+
cat /var/lib/mios/forge-runner/last-build.txt
35+
else
36+
echo "No build sentinel yet -- runner hasn't completed a build."
37+
fi
38+
exit 0
39+
;;
40+
--help|-h)
41+
sed -n '2,21p' "$0" | sed 's/^# \?//'
42+
exit 0
43+
;;
44+
*)
45+
echo "mios-rebuild: unknown flag '$1' (try --help)" >&2
46+
exit 2
47+
;;
48+
esac
49+
done
50+
51+
if [[ ! -d /.git ]]; then
52+
echo "ERROR: / is not a git working tree. Run mios-forge-firstboot first" >&2
53+
echo " to initialize the local forge and seed the working tree." >&2
54+
exit 1
55+
fi
56+
57+
# Validate the local forge is up before committing -- fail-fast beats
58+
# committing changes that have nowhere to go.
59+
if (( DO_PUSH )); then
60+
if ! curl -fsS --max-time 3 -o /dev/null "http://localhost:3000/api/v1/version"; then
61+
echo "ERROR: Forgejo at http://localhost:3000/ is not reachable." >&2
62+
echo " Check: systemctl status mios-forge.service" >&2
63+
exit 1
64+
fi
65+
fi
66+
67+
if [[ -z "$(git -C / status --porcelain)" ]]; then
68+
echo "Working tree clean -- nothing to commit."
69+
if (( DO_PUSH )); then
70+
echo "Forcing a runner trigger by pushing the current HEAD."
71+
git -C / push origin HEAD || {
72+
echo "ERROR: push failed. Verify origin: git -C / remote -v" >&2
73+
exit 1
74+
}
75+
echo
76+
echo "Pushed. Runner workflow should kick off shortly. Watch with:"
77+
echo " journalctl -fu mios-forgejo-runner.service"
78+
fi
79+
exit 0
80+
fi
81+
82+
echo "[mios-rebuild] staging all changes under /"
83+
git -C / add -A
84+
85+
echo "[mios-rebuild] committing: ${COMMIT_MSG}"
86+
git -C / commit -m "$COMMIT_MSG"
87+
88+
if (( DO_PUSH )); then
89+
echo "[mios-rebuild] pushing to local Forgejo (localhost:3000)"
90+
git -C / push origin HEAD
91+
echo
92+
echo "Pushed. Runner workflow should kick off shortly. Watch with:"
93+
echo " journalctl -fu mios-forgejo-runner.service"
94+
echo "Once the build completes, the host stages it via:"
95+
echo " bootc switch --transport containers-storage localhost/mios:latest"
96+
echo "Reboot to apply: sudo systemctl reboot"
97+
fi
98+
99+
exit 0

usr/bin/mios-status

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
# mios-status -- live MiOS system dashboard. Thin wrapper around
3+
# /usr/libexec/mios/mios-dashboard.sh; exists at /usr/bin/ so operators
4+
# don't have to remember the libexec path. All flags pass through:
5+
# mios-status full dashboard (header + fastfetch + services)
6+
# mios-status --services-only just the loop status block
7+
# mios-status --no-color plain ASCII (for piping)
8+
exec /usr/libexec/mios/mios-dashboard.sh "$@"

usr/bin/mios-update

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
# mios-update -- pull the next published MiOS image and stage it for
3+
# the next reboot. Wraps `bootc upgrade` so operators don't need to
4+
# remember the bootc verbs.
5+
#
6+
# mios-update # fetch + stage; reboot to apply
7+
# mios-update --apply # fetch, stage, AND reboot now
8+
# mios-update --check # show what's available; don't stage
9+
# mios-update --rollback # undo the last upgrade (boot the previous deployment)
10+
#
11+
# To switch to a DIFFERENT image (rather than upgrade the current one):
12+
# sudo bootc switch ghcr.io/mios-dev/mios:<tag>
13+
# sudo systemctl reboot
14+
#
15+
# To rebuild from your live working tree at /, see `mios-rebuild`.
16+
set -euo pipefail
17+
18+
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
19+
sed -n '2,18p' "$0" | sed 's/^# \?//'
20+
exit 0
21+
fi
22+
23+
if [[ $EUID -ne 0 ]]; then
24+
exec sudo -E "$0" "$@"
25+
fi
26+
27+
case "${1:-}" in
28+
--check)
29+
bootc upgrade --check
30+
;;
31+
--apply)
32+
bootc upgrade --apply
33+
;;
34+
--rollback)
35+
bootc rollback
36+
echo "Rollback staged. Reboot to apply: sudo systemctl reboot"
37+
;;
38+
"")
39+
bootc upgrade
40+
echo
41+
echo "Update staged for next boot. Apply now with:"
42+
echo " sudo systemctl reboot # full reboot"
43+
echo " sudo bootc upgrade --apply # immediate apply"
44+
;;
45+
*)
46+
echo "mios-update: unknown flag '$1'" >&2
47+
echo "Try: mios-update --help" >&2
48+
exit 2
49+
;;
50+
esac

0 commit comments

Comments
 (0)