Installer: cleanup of restart-check, --clone and the uninstall changes

- uninstall: nix-installer's copy outside /nix is made and run as root
  (a user-writable copy run by sudo could be swapped); README uninstall
  paragraph shortened to one account of what happens when Nix stays.
- session.nix: the restart-check activation after steamFrameUserServices,
  so the latter's comment is above it again.
- install.sh: a duplicate `local` in port_listening; comments.
- docs/cleanup.md: the installer internals of --clone (how an existing
  clone is recognised, which git) and restart-check (what it compares,
  test overrides); README keeps the usage.
- README install paragraph: shorter list of the dashboard patches.
This commit is contained in:
Pierre Kisters committed 2026-10-01 18:18:54 +02:00
1 parent 59afc2f616
commit b852a1eb07
4 files changed
+44 -29

No files matched your search

+9 -11
View File
@@ -84,11 +84,10 @@ runs `home-manager switch`; what it sets up is listed under
[Set up by install.sh](#set-up-by-installsh). Everything works in the running
session right away, except two settings read only at a process start: the
[keyboard layout](docs/session.md#keyboard-layout) (next Steam session start)
and the [SteamVR dashboard patches](docs/steamvr-debugger.md) (VR pet, the VR
keyboard's suggestion strip, window curvature and the other patches of
SteamVR's dashboard; next SteamVR start). If you use them, the installer ends
with "Restart once": reboot once. Re-running it just switches
again (`--yes` answers every question). Afterwards edit
and the [SteamVR dashboard patches](docs/steamvr-debugger.md) (VR pet, VR
keyboard suggestions, window curvature, ...; next SteamVR start). If they
are waiting, the installer ends with "Restart once": reboot once. Re-running
it just switches again (`--yes` answers every question). Afterwards edit
`~/nix-config/home.nix` and switch (see [Usage](#usage)).
Your own config in a git repository: `--clone <git-url>` clones it into
@@ -501,12 +500,11 @@ stops Home Manager's user services (reverting the UI patches), runs
`cleanup --all`, runs `home-manager uninstall`, then removes Nix and the
per-user Nix state (see [Set up by install.sh](#set-up-by-installsh)). If
SteamVR is running, its key is restored when SteamVR stops (the closing
message says so). Programs started from the Nix store keep `/nix` busy:
before removing Nix, `uninstall` lists them and waits until you close them
(with `--yes`, it stops instead); close them or run it right after a reboot.
If Nix's own uninstaller fails anyway, the rest still runs (the `~/.config/home-manager` link goes) except
the per-user Nix state, and the closing message says to reboot and run
`uninstall` again. Your configuration, `*.hm-backup-*` files, app data and
message says so). Nix can't be removed while programs started from the Nix
store run: `uninstall` lists them and waits; close them or run it right
after a reboot. If Nix stays (in use, `--yes`, or its uninstaller failed),
the rest still runs (the `~/.config/home-manager` link goes) except the
per-user Nix state, and the closing message says to run `uninstall` again. Your configuration, `*.hm-backup-*` files, app data and
Flatpaks stay.
To drop steam-frame-nix from a Home Manager configuration you keep, first
+16 -1
View File
@@ -45,6 +45,21 @@ What `install.sh install` sets up is listed in the README under
desktop can't reach it with its own environment) and uses the installed
`home-manager` if there is one, else Home Manager's `master`.
`install --clone` takes SteamOS' `git`, else `nix run nixpkgs#git`. An
existing directory is reused only if it is the top of a clone whose
`origin` is the same repository: URLs are compared as lower-case
host/path without `.git` (so `git@host:o/r`, `ssh://git@host/o/r` and
`https://host/o/r.git` match), and with `--ref` it must be on that branch.
`restart-check` (run by the session module's activation after
`steamFrameUserServices`, and by `install` at its end) compares the
keyboard layout drop-in on `gamescope-session.service` with
`XKB_DEFAULT_*` in the environment of the first readable process in that
unit's cgroup (gamescope's own isn't readable), and, while SteamVR runs
with the debugger drop-in, looks for a listener on port 8087 in
`/proc/net/tcp*`. Tests use `STEAM_FRAME_NIX_PROC` and
`STEAM_FRAME_NIX_CGROUP` (section F of `modules/cleanup/check.nix`).
`uninstall` removes Nix with nix-installer, which fails when it can't
unmount `/nix` (`systemctl stop nix.mount`). Before that it scans `/proc`
for processes using `/nix`: their `exe`, `cwd`, `root` or an `fd` links into
@@ -56,6 +71,6 @@ the script itself, its subshells (descendants) and its process group (the
`uninstall` from another terminal. Nothing is killed: it asks to close them
and re-checks on Enter, or (`--yes`, no terminal) stops before Nix. A bash
from the Nix store re-executes the script with `/usr/bin/bash` first, and
nix-installer runs from a copy outside `/nix`. The check uses
nix-installer runs from a root-owned copy in `/tmp`. The check uses
`STEAM_FRAME_NIX_PROC` as a fake `/proc` (section H of
`modules/cleanup/check.nix`).
+13 -11
View File
@@ -234,17 +234,19 @@ install_nix() {
}
uninstall_nix() {
local rc=0 bin
local rc=0 bin=
need_sudo
ro_unlock
step "Uninstalling Nix"
# From a copy: the uninstaller running from /nix would keep /nix busy.
bin="$(mktemp)"
if ! { cp "$NIX_INSTALLER_BIN" "$bin" && chmod +x "$bin" && "$bin" --version >/dev/null 2>&1; }; then
rm -f "$bin"; bin=$NIX_INSTALLER_BIN
# From a root-owned copy: the uninstaller running from /nix would keep
# /nix busy.
if ! bin="$(sudo mktemp)" || ! sudo cp "$NIX_INSTALLER_BIN" "$bin" \
|| ! sudo chmod 700 "$bin" || ! sudo "$bin" --version >/dev/null 2>&1; then
[[ -n $bin ]] && sudo rm -f "$bin"
bin=$NIX_INSTALLER_BIN
fi
sudo "$bin" uninstall --no-confirm || rc=$?
[[ $bin == "$NIX_INSTALLER_BIN" ]] || rm -f "$bin"
[[ $bin == "$NIX_INSTALLER_BIN" ]] || sudo rm -f "$bin"
ro_relock
return "$rc"
}
@@ -1056,7 +1058,6 @@ session_xkb() { # LAYOUT|VARIANT
# Whether something listens on 127.0.0.1/::1/any :<port> (/proc/net/tcp*).
port_listening() { # port
local hex
local hex f files=()
printf -v hex '%04X' "$1"
for f in "$SFN_PROC/net/tcp" "$SFN_PROC/net/tcp6"; do [[ -r $f ]] && files+=("$f"); done
@@ -1178,7 +1179,8 @@ nix_users() {
grep -ls '[[:space:]]/nix/' "$SFN_PROC"/[0-9]*/maps || true
} | while IFS= read -r p; do p=${p#"$SFN_PROC"/}; echo "${p%%/*}"; done | sort -un \
| while read -r pid; do
[[ $pid != "$self" ]] && { read -r name <"$SFN_PROC/$pid/comm"; } 2>/dev/null || continue
[[ $pid != "$self" ]] || continue
{ read -r name <"$SFN_PROC/$pid/comm"; } 2>/dev/null || continue # exited
# argv[0]'s name says more than comm (often a thread name)
argv0=''; { IFS= read -r -d '' argv0 <"$SFN_PROC/$pid/cmdline"; } 2>/dev/null || true
[[ ${argv0##*/} == '' || ${argv0##*/} == exe ]] || name=${argv0##*/}
@@ -1274,9 +1276,9 @@ cmd_uninstall() {
cmd_cleanup --all
remove_hm
# A failed Nix uninstall (e.g. /nix still busy) must not skip the rest:
# Home Manager is gone by now, so its config link goes regardless; the
# per-user Nix files stay for a Nix that may still be there.
# Nix still in use or a failed Nix uninstall must not skip the rest: Home
# Manager is gone by now, so its config link goes regardless; the per-user
# Nix files stay for the Nix that is still there.
local nix_failed=''
if (( ! keep_nix )); then
if [[ -x $NIX_INSTALLER_BIN ]]; then
+6 -6
View File
@@ -98,12 +98,6 @@ in {
# In a subshell: the outer session's environment must not leak into
# activation steps that run later.
# Read-only; a warning, never a failed switch.
config.home.activation.steamFrameRestartCheck = lib.hm.dag.entryAfter [ "steamFrameUserServices" ] ''
STEAM_FRAME_NIX_RUNTIME_DIR=${lib.escapeShellArg cfg.runtimeDir} XDG_CONFIG_HOME=${lib.escapeShellArg config.xdg.configHome} \
${lib.getExe restartCheck} || true
'';
config.home.activation.steamFrameUserServices = lib.hm.dag.entryAfter [ "reloadSystemd" ] (''
(
export XDG_RUNTIME_DIR=${lib.escapeShellArg cfg.runtimeDir} DBUS_SESSION_BUS_ADDRESS=${lib.escapeShellArg cfg.bus}
@@ -121,4 +115,10 @@ in {
'' + ''
)
'');
# Read-only; a warning, never a failed switch.
config.home.activation.steamFrameRestartCheck = lib.hm.dag.entryAfter [ "steamFrameUserServices" ] ''
STEAM_FRAME_NIX_RUNTIME_DIR=${lib.escapeShellArg cfg.runtimeDir} XDG_CONFIG_HOME=${lib.escapeShellArg config.xdg.configHome} \
${lib.getExe restartCheck} || true
'';
}