Skip to content

Commit 083d6ec

Browse files
Kabuki94claude
andcommitted
fix(boot): WSL boot-blockers + mios-ai container user lookup
Five interlocking fixes for the boot-time failures surfaced by the deployed WSL2 image (visible in journalctl as cascading service failures + user-shell "Failed to connect to system/user scope bus"): 1. mios-ai container "unable to find user mios-ai": - 50-mios-ai.conf: pin UID/GID to 817 (was dynamic, causing podman's in-container /etc/passwd lookup to fail because the localai image has no mios-ai user). - mios-ai.container, mios-cockpit-link.container: switch User/Group= from name to numeric 817:817. Same UID host-side and container-side keeps shared-volume ownership consistent. - mios-forgejo-runner.container: switch User=root to numeric 0 for parser parity with the other Quadlets. 2. dbus-daemon-wsl.service: remove OOMScoreAdjust=-900. The WSL2 kernel restricts unprivileged OOM-score-adjust below 0; setting -900 caused dbus-daemon to exit before binding the system bus, dbus.socket retries hit the trigger limit, and every service that needs the system bus (logind, polkit, NetworkManager, homectl) cascade-failed with "Failed to connect to system scope bus via local transport". 3. sshd port 22 collision on WSL2 mirrored networking: New sshd.service.d/10-mios-wsl2.conf with ConditionVirtualization=!wsl. Windows host's :22 (Microsoft OpenSSH) is already exposed inside the distro via mirrored networking; sshd in MiOS can't bind. WSL access goes through `wsl -d MiOS` from the host instead. Bare-metal, Hyper-V, QEMU, and VM-shape deployments are unaffected -- sshd binds :22 normally there. 4. /etc/subuid + /etc/subgid for the mios user (WSL firstboot): wsl-firstboot now appends `mios:100000:65536` to both files if absent. Without these, `wsl -d MiOS -- <gui-app>` aborts with "no subuid ranges found for user 'mios' in /etc/subuid" when podman/buildah's rootless path engages. 5. systemd user-session lingering (WSL firstboot): `loginctl enable-linger mios` so the user-systemd manager and user D-Bus session bus start at boot and survive without an interactive login. `wsl -d MiOS -- <cmd>` enters the distro without spawning a login shell; without lingering, GTK apps (ptyxis, epiphany) surface "Cannot autolaunch D-Bus without X11 $DISPLAY" and cgroupv2 falls back to cgroupfs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent c879511 commit 083d6ec

7 files changed

Lines changed: 98 additions & 10 deletions

File tree

etc/containers/systemd/mios-ai.container

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ Environment=CONTEXT_SIZE=4096
2828
Environment=ADDRESS=0.0.0.0:8080
2929
Environment=API_KEY=
3030
Environment=CORS=true
31-
User=mios-ai
32-
Group=mios-ai
31+
# Use NUMERIC UID/GID -- the LocalAI image has no `mios-ai` user in its
32+
# /etc/passwd, so a name-based User= lookup fails with "unable to find
33+
# user mios-ai: no matching entries in passwd file". UID 817 is pinned
34+
# in usr/lib/sysusers.d/50-mios-ai.conf so the host's mios-ai user has
35+
# the same UID, and shared-volume ownership stays consistent.
36+
User=817
37+
Group=817
3338

3439
# OCI image labels for Podman Desktop. Architectural Law 5: this is the
3540
# single MIOS_AI_ENDPOINT every agent on the system targets; surfacing

etc/containers/systemd/mios-cockpit-link.container

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ Label=org.opencontainers.image.documentation=https://cockpit-project.org/documen
5151
Label=io.podman_desktop.openInBrowser=https://localhost:9090/
5252

5353
# Architectural Law 6: unprivileged Quadlet with explicit User/Group.
54-
# Reuse the mios-ai uid for the shim since it's running a single TCP
55-
# relay and doesn't need its own dedicated account in sysusers.d.
56-
User=mios-ai
57-
Group=mios-ai
54+
# Reuse the mios-ai uid (NUMERIC -- the alpine/socat image has no
55+
# `mios-ai` user, and podman looks up names IN the container's
56+
# /etc/passwd. UID 817 is pinned in usr/lib/sysusers.d/50-mios-ai.conf).
57+
User=817
58+
Group=817
5859

5960
[Service]
6061
Restart=on-failure

etc/containers/systemd/mios-forgejo-runner.container

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ Environment=FORGEJO_RUNNER_LABELS=mios-self-hosted,podman,bootc,fedora-44
8383
# the podman socket via the shared containers/storage volume above.
8484
Environment=FORGEJO_RUNNER_DEFAULT_LABELS=mios-self-hosted
8585

86-
User=root
87-
Group=root
86+
# Documented architectural exception (alongside Ceph + K3s): runner
87+
# runs as numeric uid 0 inside the container so it can manipulate
88+
# /var/lib/containers/storage during `podman build`. The runner
89+
# container's job sandbox is what protects the host, not the runner
90+
# itself.
91+
User=0
92+
Group=0
8893

8994
Label=org.opencontainers.image.title=MiOS Forgejo Runner
9095
Label=org.opencontainers.image.description=Self-hosted CI runner for the MiOS self-replication loop. Builds OCI images via podman build, signals bootc-switch.

usr/lib/systemd/system/dbus-daemon-wsl.service

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ Type=notify
2020
NotifyAccess=main
2121
ExecStart=/usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
2222
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
23-
OOMScoreAdjust=-900
23+
# OOMScoreAdjust intentionally OMITTED on WSL.
24+
# The WSL2 kernel restricts unprivileged OOM-score-adjust below 0;
25+
# setting -900 here causes "Unable to set OOM score adjust to -900"
26+
# at startup, the dbus-daemon process exits before binding the bus
27+
# socket, dbus.socket retries hit the trigger limit, and every
28+
# downstream service that needs the system bus (logind, NetworkManager,
29+
# polkit, etc.) cascade-fails. This unit is already gated by
30+
# ConditionVirtualization=wsl, so we know we're on WSL when it runs.
2431
StandardError=journal+console
2532

2633
[Install]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# /usr/lib/systemd/system/sshd.service.d/10-mios-wsl2.conf
2+
#
3+
# WSL2 with mirrored networking (the MiOS default in mios-bootstrap's
4+
# .wslconfig setup) exposes the Windows host's :22 inside the distro's
5+
# network namespace. When sshd tries to bind 0.0.0.0:22 it collides
6+
# with whatever Windows-side service is on that port (typically
7+
# Microsoft OpenSSH, which most Windows installs ship enabled).
8+
# Result: sshd repeatedly fails with "Bind to port 22 on 0.0.0.0
9+
# failed: Address already in use" and gives up.
10+
#
11+
# This drop-in skips the upstream sshd.service on WSL. Cross-distro
12+
# SSH access on WSL goes through `wsl -d MiOS` from the host or
13+
# through the WSL2 bridged-networking interface. Operators who DO
14+
# need sshd reachable from the LAN on WSL can override this drop-in
15+
# with their own at /etc/systemd/system/sshd.service.d/ that adds
16+
# `Port 2200` (or any free port) to sshd_config.d/ and removes the
17+
# ConditionVirtualization gate.
18+
#
19+
# Bare-metal, Hyper-V, QEMU, and VM-shape deployments are unaffected:
20+
# sshd binds :22 normally because there's no host-network collision.
21+
[Unit]
22+
ConditionVirtualization=!wsl

usr/lib/sysusers.d/50-mios-ai.conf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
# 'MiOS' AI Service User
2-
u mios-ai - "'MiOS' AI Service User" /var/lib/mios/ai /sbin/nologin
2+
#
3+
# UID/GID 817 is PINNED so the mios-ai/mios-cockpit-link Quadlets can
4+
# reference it numerically (User=817:817). Earlier dynamic-UID setup
5+
# caused podman to fail with "unable to find user mios-ai: no matching
6+
# entries in passwd file" because the LocalAI / alpine-socat container
7+
# images have no mios-ai user -- podman looks up names IN the container,
8+
# not on the host. Pinning the UID here lets every shared-storage volume
9+
# carry consistent ownership host<->container.
10+
#
11+
# Slot 817 is the next free entry in the 800-829 mios-services range
12+
# (50-mios-services.conf reserves 800, 810-816).
13+
g mios-ai 817
14+
u mios-ai 817:mios-ai "'MiOS' AI Service User" /var/lib/mios/ai /sbin/nologin
315
m mios-ai video
416
m mios-ai render

usr/libexec/mios/wsl-firstboot

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,42 @@ if [[ -f /usr/lib/tmpfiles.d/mios.conf ]]; then
8484
systemd-tmpfiles --create /usr/lib/tmpfiles.d/mios.conf 2>/dev/null || true
8585
fi
8686

87+
# ── subuid / subgid for rootless containers ──
88+
# `wsl -d MiOS -- <gui-app>` runs apps under the user's namespace
89+
# without spawning a login shell. If /etc/subuid lacks an entry for
90+
# the mios user, podman/buildah's rootless mode aborts with:
91+
# "no subuid ranges found for user 'mios' in /etc/subuid"
92+
# Idempotent: appends only if missing. The 100000:65536 range matches
93+
# Fedora's standard rootless-user allocation and doesn't collide with
94+
# MiOS's 800-829 service-user reservation.
95+
if id "$MIOS_USER" &>/dev/null; then
96+
if ! grep -qE "^${MIOS_USER}:" /etc/subuid 2>/dev/null; then
97+
_log "Adding /etc/subuid entry for ${MIOS_USER} (rootless containers)"
98+
echo "${MIOS_USER}:100000:65536" >> /etc/subuid
99+
fi
100+
if ! grep -qE "^${MIOS_USER}:" /etc/subgid 2>/dev/null; then
101+
_log "Adding /etc/subgid entry for ${MIOS_USER} (rootless containers)"
102+
echo "${MIOS_USER}:100000:65536" >> /etc/subgid
103+
fi
104+
fi
105+
106+
# ── Enable systemd user-session lingering for the mios user ──
107+
# Without lingering, `wsl -d MiOS -- <gui-app>` finds no user-systemd
108+
# and no user D-Bus session bus, surfacing as:
109+
# "Cannot autolaunch D-Bus without X11 $DISPLAY"
110+
# "Failed to connect to user scope bus via local transport"
111+
# "cgroupv2 manager is set to systemd but no systemd user session"
112+
# enable-linger starts the user manager at boot and keeps it running
113+
# even when no interactive login is active -- correct semantics for
114+
# WSL where `wsl -d MiOS -- <cmd>` enters the distro without login.
115+
if id "$MIOS_USER" &>/dev/null; then
116+
if ! loginctl show-user "$MIOS_USER" 2>/dev/null | grep -q '^Linger=yes$'; then
117+
_log "Enabling user-systemd lingering for ${MIOS_USER}"
118+
loginctl enable-linger "$MIOS_USER" 2>/dev/null || \
119+
_log "WARN: loginctl enable-linger ${MIOS_USER} failed (may need re-run after login)"
120+
fi
121+
fi
122+
87123
# ── Mark done ──
88124
mkdir -p "$(dirname "$MARKER")"
89125
touch "$MARKER"

0 commit comments

Comments
 (0)