about summary refs log tree commit diff
path: root/pkgs/os-specific/linux/nixos-rebuild
diff options
context:
space:
mode:
authorPatryk Wychowaniec <pwychowaniec@pm.me>2022-12-23 21:23:36 +0100
committerPatryk Wychowaniec <pwychowaniec@pm.me>2023-01-15 18:16:49 +0100
commit2c55eba8f4604d1eef22f7bfd7df01312fe07272 (patch)
treefd0cf784c145f78b4321fb3b5069e49e5cf6c9ad /pkgs/os-specific/linux/nixos-rebuild
parent65e07f20cf04f5db9921dcfa202591997e0f7cd2 (diff)
downloadnixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar.gz
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar.bz2
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar.lz
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar.xz
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.tar.zst
nixlib-2c55eba8f4604d1eef22f7bfd7df01312fe07272.zip
nixos: add --specialisation to nixos-rebuild
This commit fixes a papercut in nixos-rebuild where people wanting to
switch to a specialisation (or test one) were forced to manually figure
out the specialisation's path and run its activation script - since now,
there's a dedicated option to do just that.

This is a backwards-compatible change which doesn't affect the existing
behavior, which - to be fair - might still be considered sus by some
people, the painful scenario here being:

- you boot into specialisation `foo`,
- you run `nixos-rebuild switch`,
- whoops, you're no longer at specialisation `foo`, but you're rather
  brought back to the base system.

(it's especially painful for cases where specialisation is used to load
extra drivers, e.g. Nvidia, since then launching `nixos-rebuild switch`,
while forgetting that you're inside a specialisation, can cause some
parts of your system to get accidentally unloaded.)

I've tried to mitigate that by improving specialisations so that they
create a dedicated file somewhere in `/run/current-system` containing
the specialisation's name (which `nixos-rebuild` could then use as the
default value for `--specialisation`), but I haven't been able to come
up with anything working (plus it would be a breaking change then).

Closes https://github.com/NixOS/nixpkgs/issues/174065
Diffstat (limited to 'pkgs/os-specific/linux/nixos-rebuild')
-rw-r--r--pkgs/os-specific/linux/nixos-rebuild/default.nix3
-rwxr-xr-xpkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh26
2 files changed, 27 insertions, 2 deletions
diff --git a/pkgs/os-specific/linux/nixos-rebuild/default.nix b/pkgs/os-specific/linux/nixos-rebuild/default.nix
index 34611d3f4009..b0a00972eca2 100644
--- a/pkgs/os-specific/linux/nixos-rebuild/default.nix
+++ b/pkgs/os-specific/linux/nixos-rebuild/default.nix
@@ -23,7 +23,8 @@ substituteAll {
 
   # run some a simple installer tests to make sure nixos-rebuild still works for them
   passthru.tests = {
-    simple-installer-test = nixosTests.installer.simple;
+    simple-installer = nixosTests.installer.simple;
+    specialisations = nixosTests.nixos-rebuild-specialisations;
   };
 
   meta = {
diff --git a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh
index 217e04d35720..b0b155c784ad 100755
--- a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh
+++ b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh
@@ -28,6 +28,7 @@ rollback=
 upgrade=
 upgrade_all=
 profile=/nix/var/nix/profiles/system
+specialisation=
 buildHost=
 targetHost=
 remoteSudo=
@@ -107,6 +108,14 @@ while [ "$#" -gt 0 ]; do
         fi
         shift 1
         ;;
+      --specialisation|-c)
+        if [ -z "$1" ]; then
+            log "$0: ‘--specialisation’ requires an argument"
+            exit 1
+        fi
+        specialisation="$1"
+        shift 1
+        ;;
       --build-host|h)
         buildHost="$1"
         shift 1
@@ -365,6 +374,10 @@ if [[ -n $flake ]]; then
     fi
 fi
 
+if [[ ! -z "$specialisation" && ! "$action" = switch && ! "$action" = test ]]; then
+    log "error: ‘--specialisation’ can only be used with ‘switch’ and ‘test’"
+    exit 1
+fi
 
 tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX)
 
@@ -559,7 +572,18 @@ fi
 # If we're not just building, then make the new configuration the boot
 # default and/or activate it now.
 if [[ "$action" = switch || "$action" = boot || "$action" = test || "$action" = dry-activate ]]; then
-    if ! targetHostCmd "$pathToConfig/bin/switch-to-configuration" "$action"; then
+    if [[ -z "$specialisation" ]]; then
+        cmd="$pathToConfig/bin/switch-to-configuration"
+    else
+        cmd="$pathToConfig/specialisation/$specialisation/bin/switch-to-configuration"
+
+        if [[ ! -f "$cmd" ]]; then
+            log "error: specialisation not found: $specialisation"
+            exit 1
+        fi
+    fi
+
+    if ! targetHostCmd "$cmd" "$action"; then
         log "warning: error(s) occurred while switching to the new configuration"
         exit 1
     fi