mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 01:00:13 +02:00
Installer: cleanup of the lazy Nix removal and install --clone
- The nix.mount drop-in is also removed when the uninstall fails or is interrupted (exit trap), and when daemon-reload failed after writing it. - --dir with a trailing slash no longer puts the temporary clone inside the directory it replaces. - The template's repository uses Nix's git when SteamOS has none, so the template marker exists there too (--clone needs it). - A failed Nix uninstall during the reinstall of a broken Nix says so. - clone_config: one branch per case; shorter comments, help and docs. - Tests: an interrupted uninstall, --dir with a trailing slash; a redundant "used as it is" case dropped.
This commit is contained in:
1 parent
85523b63ad
commit
18c261a0a7
5 files changed
+98
-116
No files matched your search
@@ -94,16 +94,15 @@ Your own config in a git repository: `--clone <git-url>` clones it into
|
|||||||
`~/nix-config` (`--dir <path>`, branch `--ref <branch>`) and installs it like
|
`~/nix-config` (`--dir <path>`, branch `--ref <branch>`) and installs it like
|
||||||
`--flake <dir>`. URLs: `git@github.com:owner/repo`, `https://...` or
|
`--flake <dir>`. URLs: `git@github.com:owner/repo`, `https://...` or
|
||||||
`github:owner/repo`. Without a Home Manager configuration it first activates
|
`github:owner/repo`. Without a Home Manager configuration it first activates
|
||||||
the template, whose git credential helpers then clone a private repository:
|
the template, so a private repository clones with its git credential
|
||||||
your GitHub CLI login (`~/.config/gh`, kept by `uninstall`) or
|
helpers: your GitHub CLI login (`~/.config/gh`, kept by `uninstall`) or
|
||||||
`~/.git-credentials`; git never asks for a password. If the clone fails, it
|
`~/.git-credentials`, never a password prompt. If the clone fails, it offers
|
||||||
offers `gh auth login` (browser or one-time code, works with 2FA); an SSH URL
|
`gh auth login` (browser or one-time code, works with 2FA); an SSH URL uses
|
||||||
uses your key instead. The clone then replaces the template. Keep the
|
your key instead. Keep the template's `programs.git`/`programs.gh` lines
|
||||||
template's `programs.git`/`programs.gh` lines (see [Usage](#usage)) in your
|
(see [Usage](#usage)) in your config, or the helpers go with the switch to
|
||||||
config, or the helpers go with the switch to it. Only a missing
|
it. Only a missing `~/nix-config` or the unchanged template is replaced by
|
||||||
`~/nix-config` or the unchanged template is replaced by the clone; anything
|
the clone; anything else there is used as it is. So re-running continues
|
||||||
else there is used as it is, without cloning. So re-running continues where
|
where it stopped (after a failed switch it just switches again).
|
||||||
it stopped (after a failed switch it just switches again).
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- install --clone git@github.com:owner/my-config
|
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- install --clone git@github.com:owner/my-config
|
||||||
|
|||||||
+25
-32
@@ -46,27 +46,20 @@ desktop can't reach it with its own environment) and uses the installed
|
|||||||
`home-manager` if there is one, else Home Manager's `master`.
|
`home-manager` if there is one, else Home Manager's `master`.
|
||||||
|
|
||||||
`install --clone` takes SteamOS' `git`, else `nix run nixpkgs#git`, always
|
`install --clone` takes SteamOS' `git`, else `nix run nixpkgs#git`, always
|
||||||
with `GIT_TERMINAL_PROMPT=0`. Each step checks whether an earlier run did it
|
with `GIT_TERMINAL_PROMPT=0`. "The unchanged template": `create_config`
|
||||||
(Nix works: not installed). The target directory is cloned into only when it
|
writes the hash of the configuration's files (without `.git`) to
|
||||||
is missing, empty or the untouched template: `create_config` writes the hash
|
`.git/steam-frame-nix-template`; it must still match, with at most one
|
||||||
of the configuration's files (without `.git`) to
|
commit. Any other directory is used as it is, `--ref` ignored. The template
|
||||||
`.git/steam-frame-nix-template`, and the template counts as untouched while
|
is created and activated only into an empty target without
|
||||||
the files still match and there is at most one commit. Anything else (the
|
`~/.config/home-manager`; with another configuration linked, git clones
|
||||||
clone of an earlier run, a changed template, any other directory) is used
|
with that one's helpers. The switch to an existing template is skipped when
|
||||||
as it is: no clone, `--ref` ignored, straight to the switch.
|
it is linked, Home Manager is installed and git has a credential helper.
|
||||||
|
The clone goes to `.<dir>.clone.XXXXXX` next to the target (removed on
|
||||||
Into an empty target, the template comes first, but only without a Home
|
failure or exit), then replaces the template (checked unchanged again).
|
||||||
Manager configuration (no `~/.config/home-manager`); with one, git clones
|
`gh auth login --hostname github.com --git-protocol https`, with the Home
|
||||||
with that configuration's helpers. The switch to the template is skipped
|
Manager profile's `gh`, is offered only for `https://github.com/` URLs and
|
||||||
when it is linked, Home Manager is installed and git has a credential
|
with a terminal. Tests: section G of `modules/cleanup/check.nix` (a logging
|
||||||
helper. The clone goes to `.<dir>.clone.XXXXXX` next to the target (removed
|
git, a fake nix, `STEAM_FRAME_NIX_TTY` instead of `/dev/tty`).
|
||||||
if it fails, the template stays), replaces the template (checked unchanged
|
|
||||||
again), then Home Manager switches to it. A failed switch leaves the clone,
|
|
||||||
so a rerun only switches. `gh auth login --hostname github.com
|
|
||||||
--git-protocol https`, with the Home Manager profile's `gh`, is offered only
|
|
||||||
for `https://github.com/` URLs and with a terminal. Tests: section G of
|
|
||||||
`modules/cleanup/check.nix` (a logging git, a fake nix,
|
|
||||||
`STEAM_FRAME_NIX_TTY` instead of `/dev/tty`).
|
|
||||||
|
|
||||||
`restart-check` (run by the session module's activation after
|
`restart-check` (run by the session module's activation after
|
||||||
`steamFrameUserServices`, and by `install` at its end) compares the
|
`steamFrameUserServices`, and by `install` at its end) compares the
|
||||||
@@ -78,16 +71,16 @@ with the debugger drop-in, looks for a listener on port 8087 in
|
|||||||
`STEAM_FRAME_NIX_CGROUP` (section F of `modules/cleanup/check.nix`).
|
`STEAM_FRAME_NIX_CGROUP` (section F of `modules/cleanup/check.nix`).
|
||||||
|
|
||||||
`uninstall` removes Nix with nix-installer (from a root-owned copy in
|
`uninstall` removes Nix with nix-installer (from a root-owned copy in
|
||||||
`/tmp`), whose `systemctl stop nix.mount` fails while a process uses `/nix`,
|
`/tmp`), whose `systemctl stop nix.mount` fails while a process uses `/nix`;
|
||||||
and in the Steam session some always do until logout (e.g. Steam and
|
in the Steam session some always do until logout (e.g. Steam and
|
||||||
xdg-desktop-portal, once they mapped a file from the store). So first a
|
xdg-desktop-portal, once they mapped a file from the store). So a runtime
|
||||||
runtime drop-in, `/run/systemd/system/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf`
|
drop-in, `/run/systemd/system/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf`
|
||||||
with `LazyUnmount=yes`, makes that stop detach `/nix` (`umount -l`): the
|
with `LazyUnmount=yes`, makes that stop detach `/nix` (`umount -l`): the
|
||||||
programs keep their open files until they exit. The drop-in is removed
|
programs keep their open files until they exit. The drop-in is removed
|
||||||
afterwards. Before that, for information, it lists the processes whose
|
afterwards, also on failure or Ctrl+C. Listed first, for information: the
|
||||||
`exe`, `cwd`, `root` or an `fd` links into `/nix`, or whose `maps` names a
|
processes whose `exe`, `cwd`, `root` or an `fd` links into `/nix`, or whose
|
||||||
file there (only the user's own are readable), except the script itself,
|
`maps` names a file there (only the user's own are readable), except the
|
||||||
its subshells and its process group (the `curl | bash` pipeline). Tests:
|
script itself, its subshells and its process group (the `curl | bash`
|
||||||
section H of `modules/cleanup/check.nix` (`STEAM_FRAME_NIX_PROC` as a fake
|
pipeline). Tests: section H of `modules/cleanup/check.nix`
|
||||||
`/proc`, `STEAM_FRAME_NIX_SYSTEM_RUNTIME` for the drop-in, a logging
|
(`STEAM_FRAME_NIX_PROC` as a fake `/proc`, `STEAM_FRAME_NIX_SYSTEM_RUNTIME`
|
||||||
nix-installer).
|
for the drop-in, a logging nix-installer).
|
||||||
+54
-61
@@ -7,7 +7,7 @@
|
|||||||
# curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- cleanup --all
|
# curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- cleanup --all
|
||||||
#
|
#
|
||||||
# Run `install.sh --help` for details. Works from a file or piped into bash
|
# Run `install.sh --help` for details. Works from a file or piped into bash
|
||||||
# (prompts read from /dev/tty; tests: STEAM_FRAME_NIX_TTY).
|
# (prompts read from /dev/tty).
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
TEMPLATE="${STEAM_FRAME_NIX_TEMPLATE:-github:lhns/steam-frame-nix}"
|
TEMPLATE="${STEAM_FRAME_NIX_TEMPLATE:-github:lhns/steam-frame-nix}"
|
||||||
@@ -28,13 +28,14 @@ USER_NAME="$(id -un)"
|
|||||||
USER_ID="$(id -u)"
|
USER_ID="$(id -u)"
|
||||||
OUTER_RUNTIME_DIR="${STEAM_FRAME_NIX_RUNTIME_DIR:-/run/user/$USER_ID}"
|
OUTER_RUNTIME_DIR="${STEAM_FRAME_NIX_RUNTIME_DIR:-/run/user/$USER_ID}"
|
||||||
SFN_PROC="${STEAM_FRAME_NIX_PROC:-/proc}" # tests: a fake /proc
|
SFN_PROC="${STEAM_FRAME_NIX_PROC:-/proc}" # tests: a fake /proc
|
||||||
SFN_TTY="${STEAM_FRAME_NIX_TTY:-/dev/tty}"
|
SFN_TTY="${STEAM_FRAME_NIX_TTY:-/dev/tty}" # tests: a file
|
||||||
# Runtime drop-in for the uninstall (tests: another directory).
|
# uninstall_nix: nix.mount detaches lazily (tests: another directory)
|
||||||
NIX_MOUNT_DROPIN="${STEAM_FRAME_NIX_SYSTEM_RUNTIME:-/run/systemd/system}/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf"
|
NIX_MOUNT_DROPIN="${STEAM_FRAME_NIX_SYSTEM_RUNTIME:-/run/systemd/system}/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf"
|
||||||
|
|
||||||
ASSUME_YES=0
|
ASSUME_YES=0
|
||||||
RO_RELOCK=0
|
RO_RELOCK=0
|
||||||
CLONE_TMP=''
|
CLONE_TMP='' # an unfinished --clone, removed on exit
|
||||||
|
NIX_DROPIN=0 # NIX_MOUNT_DROPIN written, removed on exit
|
||||||
|
|
||||||
# --- output -----------------------------------------------------------------
|
# --- output -----------------------------------------------------------------
|
||||||
|
|
||||||
@@ -63,12 +64,11 @@ Commands:
|
|||||||
--dir (default ~/nix-config) on branch --ref,
|
--dir (default ~/nix-config) on branch --ref,
|
||||||
then used like --flake <dir>. Without a Home
|
then used like --flake <dir>. Without a Home
|
||||||
Manager configuration it activates the template
|
Manager configuration it activates the template
|
||||||
first, so git clones with its credential helpers
|
first, for git's credential helpers (gh,
|
||||||
(gh, ~/.git-credentials); if that fails it offers
|
~/.git-credentials), and offers 'gh auth login'
|
||||||
'gh auth login'. Only a missing directory or the
|
if the clone fails. Only a missing directory or
|
||||||
unchanged template is replaced by the clone;
|
the unchanged template is replaced by the clone;
|
||||||
anything else there is used as it is (a rerun
|
anything else there is used as it is
|
||||||
after a failed switch just switches)
|
|
||||||
otherwise ~/.config/home-manager
|
otherwise ~/.config/home-manager
|
||||||
neither exists a new config in ~/nix-config from the
|
neither exists a new config in ~/nix-config from the
|
||||||
steam-frame-nix template, linked to
|
steam-frame-nix template, linked to
|
||||||
@@ -174,7 +174,8 @@ ro_relock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on_exit() {
|
on_exit() {
|
||||||
[[ -z $CLONE_TMP ]] || rm -rf -- "$CLONE_TMP" # an unfinished --clone
|
[[ -z $CLONE_TMP ]] || rm -rf -- "$CLONE_TMP"
|
||||||
|
nix_dropin_remove
|
||||||
ro_relock
|
ro_relock
|
||||||
}
|
}
|
||||||
trap on_exit EXIT
|
trap on_exit EXIT
|
||||||
@@ -248,8 +249,16 @@ install_nix() {
|
|||||||
|
|
||||||
nix_mounted() { mountpoint -q /nix 2>/dev/null; }
|
nix_mounted() { mountpoint -q /nix 2>/dev/null; }
|
||||||
|
|
||||||
|
nix_dropin_remove() {
|
||||||
|
(( NIX_DROPIN )) || return 0
|
||||||
|
NIX_DROPIN=0
|
||||||
|
sudo rm -f "$NIX_MOUNT_DROPIN"
|
||||||
|
sudo rmdir "${NIX_MOUNT_DROPIN%/*}" 2>/dev/null || true
|
||||||
|
sudo systemctl daemon-reload || true
|
||||||
|
}
|
||||||
|
|
||||||
uninstall_nix() {
|
uninstall_nix() {
|
||||||
local rc=0 bin='' lazy=0 users=()
|
local rc=0 bin='' users=()
|
||||||
need_sudo
|
need_sudo
|
||||||
ro_unlock
|
ro_unlock
|
||||||
step "Uninstalling Nix"
|
step "Uninstalling Nix"
|
||||||
@@ -268,22 +277,16 @@ uninstall_nix() {
|
|||||||
# `systemctl stop nix.mount` would fail. With LazyUnmount= that stop
|
# `systemctl stop nix.mount` would fail. With LazyUnmount= that stop
|
||||||
# detaches /nix; the programs keep their open files until they exit.
|
# detaches /nix; the programs keep their open files until they exit.
|
||||||
if nix_mounted; then
|
if nix_mounted; then
|
||||||
if sudo mkdir -p "${NIX_MOUNT_DROPIN%/*}" \
|
NIX_DROPIN=1
|
||||||
&& printf '%s\n' '# steam-frame-nix: removing Nix detaches /nix while programs use it.' \
|
sudo mkdir -p "${NIX_MOUNT_DROPIN%/*}" \
|
||||||
'[Mount]' 'LazyUnmount=yes' | sudo tee "$NIX_MOUNT_DROPIN" >/dev/null \
|
&& printf '%s\n' '# steam-frame-nix: removing Nix detaches /nix while programs use it.' \
|
||||||
&& sudo systemctl daemon-reload; then
|
'[Mount]' 'LazyUnmount=yes' | sudo tee "$NIX_MOUNT_DROPIN" >/dev/null \
|
||||||
lazy=1
|
&& sudo systemctl daemon-reload \
|
||||||
else
|
|| warn "could not add $NIX_MOUNT_DROPIN; removing Nix fails if a program still uses /nix"
|
||||||
warn "could not add $NIX_MOUNT_DROPIN; removing Nix fails if a program still uses /nix"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
sudo "$bin" uninstall --no-confirm || rc=$?
|
sudo "$bin" uninstall --no-confirm || rc=$?
|
||||||
[[ $bin == "$NIX_INSTALLER_BIN" ]] || sudo rm -f "$bin"
|
[[ $bin == "$NIX_INSTALLER_BIN" ]] || sudo rm -f "$bin"
|
||||||
if (( lazy )); then
|
nix_dropin_remove
|
||||||
sudo rm -f "$NIX_MOUNT_DROPIN"
|
|
||||||
sudo rmdir "${NIX_MOUNT_DROPIN%/*}" 2>/dev/null || true
|
|
||||||
sudo systemctl daemon-reload || true
|
|
||||||
fi
|
|
||||||
hash -r # commands found in /nix are gone
|
hash -r # commands found in /nix are gone
|
||||||
ro_relock
|
ro_relock
|
||||||
return "$rc"
|
return "$rc"
|
||||||
@@ -299,7 +302,7 @@ ensure_nix() {
|
|||||||
warn "Nix is installed ($NIX_RECEIPT) but not working"
|
warn "Nix is installed ($NIX_RECEIPT) but not working"
|
||||||
confirm "Uninstall and reinstall Nix?" || die "aborted"
|
confirm "Uninstall and reinstall Nix?" || die "aborted"
|
||||||
[[ -x $NIX_INSTALLER_BIN ]] || die "$NIX_INSTALLER_BIN is missing; can't uninstall the broken Nix"
|
[[ -x $NIX_INSTALLER_BIN ]] || die "$NIX_INSTALLER_BIN is missing; can't uninstall the broken Nix"
|
||||||
uninstall_nix
|
uninstall_nix || die "the Nix uninstall failed (see above)"
|
||||||
elif [[ -d /nix ]] && [[ -n $(ls -A /nix 2>/dev/null) ]]; then
|
elif [[ -d /nix ]] && [[ -n $(ls -A /nix 2>/dev/null) ]]; then
|
||||||
die "/nix exists but was not installed by nix-installer (no $NIX_RECEIPT); remove it or fix that Nix first"
|
die "/nix exists but was not installed by nix-installer (no $NIX_RECEIPT); remove it or fix that Nix first"
|
||||||
fi
|
fi
|
||||||
@@ -326,23 +329,20 @@ set_let() { # file name value
|
|||||||
sed -i "s|^\( *$name = \)\"[^\"]*\";|\1\"$value\";|" "$file"
|
sed -i "s|^\( *$name = \)\"[^\"]*\";|\1\"$value\";|" "$file"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Marker of a configuration create_config made: the hash of its files, in
|
# create_config's marker in .git: the hash of the files it wrote, so
|
||||||
# .git (never a file of the configuration). `install --clone` replaces
|
# `install --clone` replaces the template only while it is unchanged.
|
||||||
# such a configuration while it is unchanged (template_untouched).
|
|
||||||
TEMPLATE_MARK=steam-frame-nix-template
|
TEMPLATE_MARK=steam-frame-nix-template
|
||||||
|
|
||||||
# Hash of a configuration's files (without .git).
|
config_hash() { # dir: its files without .git
|
||||||
config_hash() {
|
|
||||||
(cd "$1" && find . -path ./.git -prune -o ! -type d -print0 | LC_ALL=C sort -z \
|
(cd "$1" && find . -path ./.git -prune -o ! -type d -print0 | LC_ALL=C sort -z \
|
||||||
| xargs -0 -r sha256sum | sha256sum) | cut -d' ' -f1
|
| xargs -0 -r sha256sum | sha256sum) | cut -d' ' -f1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Whether <dir> is the template as create_config made it: the marker
|
# The marker matches the files, at most one commit.
|
||||||
# matches its files, at most one commit.
|
|
||||||
template_untouched() { # dir
|
template_untouched() { # dir
|
||||||
local m=$1/.git/$TEMPLATE_MARK n
|
local m=$1/.git/$TEMPLATE_MARK n
|
||||||
[[ -f $m ]] || return 1
|
[[ -f $m ]] || return 1
|
||||||
n="$(git -C "$1" rev-list --count HEAD 2>/dev/null || echo 0)"
|
n="$(git_any -C "$1" rev-list --count HEAD 2>/dev/null || echo 0)"
|
||||||
[[ $(<"$m") == "$(config_hash "$1")" ]] && (( n <= 1 ))
|
[[ $(<"$m") == "$(config_hash "$1")" ]] && (( n <= 1 ))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,16 +370,11 @@ create_config() { # dir [question]
|
|||||||
info "user $USER_NAME, home $HOME, system $system"
|
info "user $USER_NAME, home $HOME, system $system"
|
||||||
|
|
||||||
# Flakes in a git repository only see tracked files.
|
# Flakes in a git repository only see tracked files.
|
||||||
if command -v git >/dev/null 2>&1; then
|
git_any -C "$dir" init -q
|
||||||
git -C "$dir" init -q
|
git_any -C "$dir" add -A
|
||||||
git -C "$dir" add -A
|
nix flake lock "$dir"
|
||||||
nix flake lock "$dir"
|
git_any -C "$dir" add flake.lock
|
||||||
git -C "$dir" add flake.lock
|
config_hash "$dir" >"$dir/.git/$TEMPLATE_MARK"
|
||||||
config_hash "$dir" >"$dir/.git/$TEMPLATE_MARK"
|
|
||||||
else
|
|
||||||
warn "git not found; $dir is used as a plain directory"
|
|
||||||
nix flake lock "$dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "${HM_CONFIG_LINK%/*}"
|
mkdir -p "${HM_CONFIG_LINK%/*}"
|
||||||
ln -s "$dir" "$HM_CONFIG_LINK"
|
ln -s "$dir" "$HM_CONFIG_LINK"
|
||||||
@@ -425,15 +420,11 @@ gh_login() { # url
|
|||||||
"$gh" auth login --hostname github.com --git-protocol https <"$SFN_TTY"
|
"$gh" auth login --hostname github.com --git-protocol https <"$SFN_TTY"
|
||||||
}
|
}
|
||||||
|
|
||||||
# --clone: <dir> missing (or empty) or the untouched template gets the clone
|
# --clone, resumable: a missing (or empty) <dir> or the untouched template
|
||||||
# of <url>; anything else in <dir> is used as it is (also the clone of an
|
# there gets the clone of <url>; anything else is used as it is (e.g. the
|
||||||
# earlier run whose switch failed). Each step checks whether an earlier run
|
# clone of an earlier run whose switch failed). Without an active Home
|
||||||
# did it already:
|
# Manager configuration the template is activated first, for git's
|
||||||
# - without a Home Manager configuration (or with the template in <dir>
|
# credential helpers.
|
||||||
# linked), the template is created in <dir> and activated, so git has
|
|
||||||
# the credential helpers (skipped if they are there);
|
|
||||||
# - <url> is cloned next to <dir> (on failure the template stays active
|
|
||||||
# in <dir>); the template is removed and the clone takes its place.
|
|
||||||
clone_config() { # url dir ref
|
clone_config() { # url dir ref
|
||||||
local url dir=$2 ref=$3 tmpl=0 parent link=''
|
local url dir=$2 ref=$3 tmpl=0 parent link=''
|
||||||
url="$(clone_url "$1")"
|
url="$(clone_url "$1")"
|
||||||
@@ -445,21 +436,21 @@ clone_config() { # url dir ref
|
|||||||
tmpl=1
|
tmpl=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The template, for git's credential helpers.
|
|
||||||
if [[ -L $HM_CONFIG_LINK || -e $HM_CONFIG_LINK ]]; then
|
if [[ -L $HM_CONFIG_LINK || -e $HM_CONFIG_LINK ]]; then
|
||||||
link="$(readlink -f "$HM_CONFIG_LINK" || true)"
|
link="$(readlink -f "$HM_CONFIG_LINK" || true)"
|
||||||
fi
|
fi
|
||||||
if (( ! tmpl )) && [[ -z $link ]]; then
|
if [[ -z $link ]]; then
|
||||||
create_config "$dir" "No Home Manager configuration found. First activate the steam-frame-nix template from $dir (git's credential helpers, e.g. 'gh auth login'), then replace it with the clone of $url?"
|
if (( tmpl )); then # an earlier run's template; the link was removed
|
||||||
tmpl=1
|
|
||||||
hm_activate "$dir#$USER_NAME" || die "the switch to the template failed (see above); run install --clone again to continue"
|
|
||||||
elif (( tmpl )) && [[ -z $link || $link -ef $dir ]]; then
|
|
||||||
if [[ -z $link ]]; then
|
|
||||||
mkdir -p "${HM_CONFIG_LINK%/*}"
|
mkdir -p "${HM_CONFIG_LINK%/*}"
|
||||||
ln -s "$dir" "$HM_CONFIG_LINK"
|
ln -s "$dir" "$HM_CONFIG_LINK"
|
||||||
info "linked $HM_CONFIG_LINK -> $dir"
|
info "linked $HM_CONFIG_LINK -> $dir"
|
||||||
|
else
|
||||||
|
create_config "$dir" "No Home Manager configuration found. Activate the steam-frame-nix template in $dir first (for git's credentials), then replace it with the clone of $url?"
|
||||||
|
tmpl=1
|
||||||
fi
|
fi
|
||||||
if [[ -n $link ]] && hm_installed && git_has_helpers; then
|
hm_activate "$dir#$USER_NAME" || die "the switch to the template failed (see above); run install --clone again to continue"
|
||||||
|
elif (( tmpl )) && [[ $link -ef $dir ]]; then
|
||||||
|
if hm_installed && git_has_helpers; then
|
||||||
step "The template in $dir is active with git's credential helpers (skipped)"
|
step "The template in $dir is active with git's credential helpers (skipped)"
|
||||||
else
|
else
|
||||||
hm_activate "$dir#$USER_NAME" || die "the switch to the template failed (see above); run install --clone again to continue"
|
hm_activate "$dir#$USER_NAME" || die "the switch to the template failed (see above); run install --clone again to continue"
|
||||||
@@ -516,6 +507,8 @@ cmd_install() {
|
|||||||
clone_url "$clone" >/dev/null
|
clone_url "$clone" >/dev/null
|
||||||
clone_dir=${clone_dir:-$DEFAULT_CONFIG_DIR}
|
clone_dir=${clone_dir:-$DEFAULT_CONFIG_DIR}
|
||||||
[[ $clone_dir == /* ]] || clone_dir=$PWD/$clone_dir
|
[[ $clone_dir == /* ]] || clone_dir=$PWD/$clone_dir
|
||||||
|
clone_dir=${clone_dir%"${clone_dir##*[!/]}"} # no trailing /
|
||||||
|
[[ -n ${clone_dir%/*} ]] || die "--dir: '$clone_dir' is not below a directory"
|
||||||
elif [[ -n $clone_dir || -n $clone_ref ]]; then
|
elif [[ -n $clone_dir || -n $clone_ref ]]; then
|
||||||
die "install: --dir and --ref need --clone"
|
die "install: --dir and --ref need --clone"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -448,20 +448,14 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
|
|||||||
has "$res" "hm switch --flake $HOME/nix-config -b"
|
has "$res" "hm switch --flake $HOME/nix-config -b"
|
||||||
[ "$($GIT -C $HOME/nix-config config --get remote.origin.url)" = git@github.com:owner/config ] || fail "existing directory changed"
|
[ "$($GIT -C $HOME/nix-config config --get remote.origin.url)" = git@github.com:owner/config ] || fail "existing directory changed"
|
||||||
|
|
||||||
# --dir (relative) and --ref; an active configuration: no template, the
|
# --dir (relative, trailing /) and --ref; an active configuration: no
|
||||||
# existing link stays
|
# template, the existing link stays
|
||||||
res=$(cd $HOME && inst --clone github:owner/config --dir cfg --ref dev)
|
res=$(cd $HOME && inst --clone github:owner/config --dir cfg/ --ref dev)
|
||||||
grep -qF "clone --branch dev -- https://github.com/owner/config.git $HOME/.cfg.clone." $LOG || fail "ref: $(cat $LOG)"
|
grep -qF "clone --branch dev -- https://github.com/owner/config.git $HOME/.cfg.clone." $LOG || fail "ref: $(cat $LOG)"
|
||||||
! switched_to_template || fail "template with a configuration"
|
! switched_to_template || fail "template with a configuration"
|
||||||
clone_ok $HOME/cfg dev
|
clone_ok $HOME/cfg dev
|
||||||
has "$res" "hm switch --flake $HOME/cfg -b"
|
has "$res" "hm switch --flake $HOME/cfg -b"
|
||||||
[ "$(readlink $HOME/.config/home-manager)" = $HOME/nix-config ] || fail "link replaced"
|
[ "$(readlink $HOME/.config/home-manager)" = $HOME/nix-config ] || fail "link replaced"
|
||||||
# not a configuration: not cloned over, kept (and no flake to switch to)
|
|
||||||
mkdir $HOME/plain; echo x > $HOME/plain/x
|
|
||||||
res=$(inst --clone github:owner/config --dir $HOME/plain 2>&1) && fail "plain dir used"
|
|
||||||
has "$res" "using it as it is (not cloning)"
|
|
||||||
has "$res" "has no flake.nix"
|
|
||||||
there $HOME/plain/x
|
|
||||||
# a failed clone: the hint, nothing left
|
# a failed clone: the hint, nothing left
|
||||||
res=$(inst --clone https://example.org/missing.git --dir $HOME/m 2>&1) && fail "missing repo"
|
res=$(inst --clone https://example.org/missing.git --dir $HOME/m 2>&1) && fail "missing repo"
|
||||||
has "$res" "gh auth login"
|
has "$res" "gh auth login"
|
||||||
@@ -542,7 +536,7 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
|
|||||||
# nix-installer: logs its arguments and the lazy-unmount drop-in it sees
|
# nix-installer: logs its arguments and the lazy-unmount drop-in it sees
|
||||||
D=$root/run-system/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf
|
D=$root/run-system/nix.mount.d/50-steam-frame-nix-lazy-unmount.conf
|
||||||
export D LOG=$root/log RC=0
|
export D LOG=$root/log RC=0
|
||||||
printf '#!%s\n[ "$1" = --version ] && exit 0\necho "nix-installer $*" >> $LOG\ncat $D >> $LOG 2>/dev/null || echo "no drop-in" >> $LOG\nexit $RC\n' \
|
printf '#!%s\n[ "$1" = --version ] && exit 0\necho "nix-installer $*" >> $LOG\ncat $D >> $LOG 2>/dev/null || echo "no drop-in" >> $LOG\n[ $RC != term ] || { kill -TERM $PPID; exit 1; }\nexit $RC\n' \
|
||||||
"$(command -v bash)" > $root/nix-installer
|
"$(command -v bash)" > $root/nix-installer
|
||||||
chmod +x $root/nix-installer
|
chmod +x $root/nix-installer
|
||||||
uninst() { # mounted: 1|0
|
uninst() { # mounted: 1|0
|
||||||
@@ -575,6 +569,10 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
|
|||||||
res=$(RC=1 uninst 1) && fail "uninstall succeeded: $res"
|
res=$(RC=1 uninst 1) && fail "uninstall succeeded: $res"
|
||||||
has "$res" "its uninstaller failed. Reboot, then run uninstall again"
|
has "$res" "its uninstaller failed. Reboot, then run uninstall again"
|
||||||
gone $D $HOME/.config/home-manager
|
gone $D $HOME/.config/home-manager
|
||||||
|
# interrupted (TERM): the drop-in goes too
|
||||||
|
res=$(RC=term uninst 1) && fail "interrupted uninstall succeeded: $res"
|
||||||
|
has "$(cat $LOG)" "LazyUnmount=yes"
|
||||||
|
gone $D
|
||||||
SH
|
SH
|
||||||
echo "H ok"
|
echo "H ok"
|
||||||
touch $out
|
touch $out
|
||||||
|
|||||||
+2
-3
@@ -10,9 +10,8 @@
|
|||||||
programs.home-manager.enable = true; # the `home-manager` command
|
programs.home-manager.enable = true; # the `home-manager` command
|
||||||
|
|
||||||
# git credentials for HTTPS (`install.sh install --clone` uses them):
|
# git credentials for HTTPS (`install.sh install --clone` uses them):
|
||||||
# GitHub through the GitHub CLI (log in once: gh auth login, works with
|
# github.com through the GitHub CLI (gh auth login), other hosts from
|
||||||
# 2FA), other hosts from ~/.git-credentials. git itself is SteamOS's;
|
# ~/.git-credentials. git is SteamOS's; Home Manager writes its config.
|
||||||
# Home Manager only writes its config. Remove to manage git yourself.
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = null;
|
package = null;
|
||||||
|
|||||||
Reference in new issue
Block a user