From 0c881602e96abd16e1db14deffce823de39ef61f Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 17 Apr 2026 23:26:15 -0400 Subject: [PATCH] yarn: fix steamos update flow --- system/system-yarn.nix | 78 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/system/system-yarn.nix b/system/system-yarn.nix index f74be6c..3698c01 100644 --- a/system/system-yarn.nix +++ b/system/system-yarn.nix @@ -75,12 +75,54 @@ # LACT (Linux AMDGPU Configuration Tool): https://github.com/ilya-zlobintsev/LACT environment.systemPackages = with pkgs; [ lact + jovian-stubs ]; systemd.packages = with pkgs; [ lact ]; systemd.services.lactd.wantedBy = [ "multi-user.target" ]; systemd.services.lactd.serviceConfig.ExecStartPre = "${lib.getExe pkgs.bash} -c \"sleep 3s\""; + # root-level service that applies a pending update. Triggered by + # steamos-update (via systemctl start) when the user accepts an update. + # Runs as root so it can write the system profile and boot entry. + systemd.services.pull-update-apply = { + description = "Apply pending NixOS update pulled from binary cache"; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.writeShellScript "pull-update-apply" '' + set -uo pipefail + export PATH=${ + pkgs.lib.makeBinPath [ + pkgs.curl + pkgs.coreutils + pkgs.nix + ] + } + STORE_PATH=$(curl -sf --max-time 30 "https://nix-cache.sigkill.computer/deploy/yarn" || true) + if [ -z "$STORE_PATH" ]; then + echo "server unreachable" + exit 1 + fi + echo "applying $STORE_PATH" + nix-store -r "$STORE_PATH" || { echo "fetch failed"; exit 1; } + nix-env -p /nix/var/nix/profiles/system --set "$STORE_PATH" || { echo "profile set failed"; exit 1; } + "$STORE_PATH/bin/switch-to-configuration" boot || { echo "boot entry failed"; exit 1; } + echo "update applied; reboot required" + ''; + }; + }; + + # Allow primary user to start pull-update-apply.service without a password + security.polkit.extraConfig = '' + polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.systemd1.manage-units" && + action.lookup("unit") == "pull-update-apply.service" && + subject.user == "${username}") { + return polkit.Result.YES; + } + }); + ''; + nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ @@ -106,7 +148,7 @@ final.lib.makeBinPath [ final.curl final.coreutils - final.nix + final.systemd ] } @@ -129,14 +171,15 @@ exit 0 fi - >&2 echo "[steamos-update] downloading update..." - nix-store -r "$STORE_PATH" || { >&2 echo "[steamos-update] fetch failed"; exit 1; } - - >&2 echo "[steamos-update] installing update..." - nix-env -p /nix/var/nix/profiles/system --set "$STORE_PATH" || { >&2 echo "[steamos-update] profile set failed"; exit 1; } - "$STORE_PATH/bin/switch-to-configuration" boot || { >&2 echo "[steamos-update] boot entry failed"; exit 1; } - - >&2 echo "[steamos-update] update installed, reboot to apply" + # apply: trigger the root-running systemd service to install the update + >&2 echo "[steamos-update] applying update..." + if systemctl start --wait pull-update-apply.service; then + >&2 echo "[steamos-update] update installed, reboot to apply" + exit 0 + else + >&2 echo "[steamos-update] apply failed; see 'journalctl -u pull-update-apply'" + exit 1 + fi ''; in { @@ -154,6 +197,12 @@ exit 0 STUB + # jupiter-biosupdate: no-op (not a real steam deck) + cat > $out/bin/jupiter-biosupdate << 'STUB' + #!/bin/sh + exit 0 + STUB + # steamos-reboot: reboot the system cat > $out/bin/steamos-reboot << 'STUB' #!/bin/sh @@ -188,10 +237,17 @@ exec /run/wrappers/bin/pkexec "$@" STUB - # sudo: pass through to doas + # sudo: strip flags and run the command directly (no escalation). + # privileged ops are delegated to root systemd services via systemctl. cat > $out/bin/sudo << 'STUB' #!/bin/sh - exec /run/wrappers/bin/doas "$@" + while [ $# -gt 0 ]; do + case "$1" in + -*) shift ;; + *) break ;; + esac + done + exec "$@" STUB find $out/bin -type f -exec chmod 755 {} +