Before we would run systemd-run with the user's home dir as the working
directory, but this causes issues when the home dir is on a separate
partition and that partition cannot be mounted, as the transient unit
created by systemd-run would gain a dependency on the home mount and fail.
Since the root partition is guaranteed to be mounted, using that as the
working directory avoids this issue and allows doing a remote
nixos-rebuild to fix the issue preventing /home from being mounted.
By executing the whole switching process using one script, we avoid
some ssh roundtrips that would slow down deployment swith --target-host.
For the other benefits, see https://github.com/NixOS/nixpkgs/issues/266290
SSH merges its arguments by space-concatenation - it does not preserve
the array structure.
This is arguably a historic mistake, whose fix would be too breaking.
I suppose it will stay this way forever, until perhaps a better behavior
can be opted in to using a flag, and I don't think this flag exists yet.
To make multi-argument commands work reliably over ssh, we need to escape
them, which is what the ${@@Q} incantation achieves.
In https://github.com/NixOS/nixpkgs/issues/333734 it was noticed that
executing the list-generations with sudo would fail. The reason was,
that the variable $PAGER was set, but empty.
${PAGER:cat} only has the default of cat if PAGER is unset, but it will
not default to cat if the variable is empty instead.
One way of fixing this would have been to change it to ${PAGER:-cat},
but since a pager requires pressing an additional key to exit, it is a
bit annoying in the first place, so it was removed instead.
Lore overrides have been included with binlore's source up to now, but
this hasn't worked very well. (It isn't as easy to self-service for
people working in nixpkgs, and its use of partial pnames for matching
breaks down around some edge cases like version numbers appearing
early in perl pnames, or multiple packages having identical pnames.)
Most nixos-rebuild commands support a relative flake path, however
`repl` uses `builtins.getFlake` and that requires an absolute path. So
ensure we pass an absolute path to it, providing UX consistency. Only do
so when the path exists in order to passthrough URLs as-is.
pkgs.lib and lib need not match, so prefer the one that the modules get.
For example:
```nix
nix-repl> :lf nixpkgs
nix-repl> (lib.nixosSystem { modules = [ ({ lib, ... }: assert lib?nixosSystem; { nixpkgs.hostPlatform = "x86_64-linux"; }) ]; }).pkgs.lib?nixosSystem
false
```
The code is backwards compatible, for the case where you evaluate a
config whose nixpkgs doesn't have the preceding commit yet.
This solves again the problem solved by 09fd207cb8.
To quote:
> We always want to use `ssh -t` to force PTY allocation as there may be
> interactive SSH prompts like trusting unknown hosts.
However, the creation of a pseudoterminal causes the remote stdout and stderr
to point to the same tty, resulting in a single stream in the ssh client,
which breaks other usages of ssh, such as `--build-host`.
Hence, this commit only sets the flag for invocations that need it -
or would need it if sudo were disabled. That should help with development
and gives a somewhat more consistent user experience.