diff --git a/iso/airootfs/etc/sudoers.d/99-bos-live b/iso/airootfs/etc/sudoers.d/99-bos-live new file mode 100644 index 0000000..591d9b9 --- /dev/null +++ b/iso/airootfs/etc/sudoers.d/99-bos-live @@ -0,0 +1,3 @@ +# Live medium only: the unprivileged live user may escalate without a password +# so the installer (Calamares) can run as root from the Wayland session. +liveuser ALL=(ALL) NOPASSWD: ALL diff --git a/iso/airootfs/etc/systemd/system/bos-live-setup.service b/iso/airootfs/etc/systemd/system/bos-live-setup.service new file mode 100644 index 0000000..22e91f5 --- /dev/null +++ b/iso/airootfs/etc/systemd/system/bos-live-setup.service @@ -0,0 +1,14 @@ +[Unit] +Description=Set up the BOS live user and session +# Only on the live medium — the installed system has no archisobasedir cmdline. +ConditionKernelCommandLine=archisobasedir +Before=getty@tty1.service +After=systemd-tmpfiles-setup.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/bos-live-setup + +[Install] +WantedBy=multi-user.target diff --git a/iso/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf b/iso/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf index b9d22eb..b10ceb2 100644 --- a/iso/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf +++ b/iso/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf @@ -1,3 +1,3 @@ [Service] ExecStart= -ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin root - $TERM +ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin liveuser - $TERM diff --git a/iso/airootfs/etc/systemd/system/multi-user.target.wants/bos-live-setup.service b/iso/airootfs/etc/systemd/system/multi-user.target.wants/bos-live-setup.service new file mode 120000 index 0000000..a8d5e7d --- /dev/null +++ b/iso/airootfs/etc/systemd/system/multi-user.target.wants/bos-live-setup.service @@ -0,0 +1 @@ +../bos-live-setup.service \ No newline at end of file diff --git a/iso/airootfs/usr/local/bin/bos-launch-calamares b/iso/airootfs/usr/local/bin/bos-launch-calamares new file mode 100644 index 0000000..d7f3fe9 --- /dev/null +++ b/iso/airootfs/usr/local/bin/bos-launch-calamares @@ -0,0 +1,7 @@ +#!/bin/sh +# Launch Calamares as root on the live user's Wayland session. +# Calamares performs partitioning/bootloader work and needs root; the live user +# has passwordless sudo (see /etc/sudoers.d/99-bos-live). We preserve the Wayland +# environment so the root process renders on the user's compositor. +export QT_QPA_PLATFORM=wayland +exec sudo --preserve-env=WAYLAND_DISPLAY,XDG_RUNTIME_DIR,QT_QPA_PLATFORM calamares diff --git a/iso/airootfs/usr/local/bin/bos-live-setup b/iso/airootfs/usr/local/bin/bos-live-setup new file mode 100644 index 0000000..8944865 --- /dev/null +++ b/iso/airootfs/usr/local/bin/bos-live-setup @@ -0,0 +1,54 @@ +#!/bin/bash +# Create the unprivileged BOS live user and its Hyprland session. +# +# Hyprland refuses to run as root (superuser-privileges check), so the live +# session must run as a normal user. Calamares — which does need root — is +# launched onto the user's Wayland socket via passwordless sudo (see +# bos-launch-calamares). Runs once at boot, before the tty1 autologin getty. +set -e + +if ! id liveuser &>/dev/null; then + useradd -m -s /bin/bash liveuser + for g in wheel video input audio storage power; do + getent group "$g" >/dev/null 2>&1 && gpasswd -a liveuser "$g" >/dev/null || true + done + passwd -d liveuser >/dev/null +fi + +install -d -m 0700 -o liveuser -g liveuser /home/liveuser/.config/hypr + +# Minimal live compositor config: auto-launch the installer. +cat >/home/liveuser/.config/hypr/hyprland.conf <<'EOF' +monitor=,preferred,auto,1 + +exec-once = bos-launch-calamares + +general { + border_size = 2 + col.active_border = rgba(88c0d0ff) + col.inactive_border = rgba(4c566aff) +} +decoration { rounding = 4 } +input { + kb_layout = us + follow_mouse = 1 +} +misc { + disable_hyprland_logo = true + disable_splash_rendering = true +} +EOF + +# Start Hyprland on tty1 login; capture output and fall back to a shell so a +# failed compositor start is visible rather than a blank looping cursor. +cat >/home/liveuser/.bash_profile <<'EOF' +if [[ "$(tty)" == /dev/tty1 ]] && [[ -z "$WAYLAND_DISPLAY" ]]; then + export WLR_RENDERER_ALLOW_SOFTWARE=1 + export WLR_NO_HARDWARE_CURSORS=1 + Hyprland &>/var/log/hyprland-live.log + echo "Hyprland exited (rc=$?). Log: /var/log/hyprland-live.log" + exec bash -i +fi +EOF + +chown -R liveuser:liveuser /home/liveuser diff --git a/iso/profiledef.sh b/iso/profiledef.sh index 0085552..1d1e595 100644 --- a/iso/profiledef.sh +++ b/iso/profiledef.sh @@ -15,5 +15,8 @@ airootfs_image_type="squashfs" airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M') file_permissions=( ["/etc/shadow"]="0:0:400" + ["/etc/sudoers.d/99-bos-live"]="0:0:440" ["/etc/calamares/post-install.sh"]="0:0:755" + ["/usr/local/bin/bos-live-setup"]="0:0:755" + ["/usr/local/bin/bos-launch-calamares"]="0:0:755" )