# Binary-cache update mechanism for Jovian-NixOS desktops. # # Replaces the upstream holo-update/steamos-update stubs with a script that # checks the private binary cache for a newer system closure, and provides a # root-level systemd service to apply it. Steam's deck UI calls # `steamos-update check` periodically; exit 7 = no update, exit 0 = update # applied or available. # # The deploy endpoint is ${binary_cache_url}/deploy/${hostname} — a plain # text file containing the /nix/store path of the latest closure, published # by CI after a successful build. { pkgs, lib, hostname, username, site_config, ... }: let deploy-url = "${site_config.binary_cache.url}/deploy/${hostname}"; steamos-update-script = pkgs.writeShellScript "steamos-update" '' export PATH=${ lib.makeBinPath [ pkgs.curl pkgs.coreutils pkgs.systemd ] } STORE_PATH=$(curl -sf --max-time 30 "${deploy-url}" || true) if [ -z "$STORE_PATH" ]; then >&2 echo "[steamos-update] server unreachable" exit 7 fi CURRENT=$(readlink -f /nix/var/nix/profiles/system) if [ "$CURRENT" = "$STORE_PATH" ]; then >&2 echo "[steamos-update] no update available" exit 7 fi # check-only mode: just report that an update exists if [ "''${1:-}" = "check" ] || [ "''${1:-}" = "--check-only" ]; then >&2 echo "[steamos-update] update available" exit 0 fi # 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 { nixpkgs.overlays = [ (_final: prev: { jovian-stubs = prev.jovian-stubs.overrideAttrs (old: { buildCommand = (old.buildCommand or "") + '' install -D -m 755 ${steamos-update-script} $out/bin/holo-update install -D -m 755 ${steamos-update-script} $out/bin/steamos-update ''; }); }) ]; 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=${ lib.makeBinPath [ pkgs.curl pkgs.coreutils pkgs.nix ] } STORE_PATH=$(curl -sf --max-time 30 "${deploy-url}" || true) if [ -z "$STORE_PATH" ]; then echo "server unreachable" exit 1 fi CURRENT=$(readlink -f /nix/var/nix/profiles/system) if [ "$CURRENT" = "$STORE_PATH" ]; then echo "already up to date: $STORE_PATH" exit 0 fi echo "applying $STORE_PATH (was $CURRENT)" nix-store -r --add-root /nix/var/nix/gcroots/pull-update-apply-latest --indirect "$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 the primary user to trigger pull-update-apply 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; } }); ''; }