about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2305.section.xml10
-rw-r--r--nixos/doc/manual/man-nixos-rebuild.xml51
-rw-r--r--nixos/doc/manual/release-notes/rl-2305.section.md2
-rw-r--r--nixos/tests/all-tests.nix2
-rw-r--r--nixos/tests/nixos-rebuild-specialisations.nix131
-rw-r--r--nixos/tests/specialisation.nix43
-rw-r--r--pkgs/os-specific/linux/nixos-rebuild/default.nix3
-rwxr-xr-xpkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh26
8 files changed, 221 insertions, 47 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
index e1317621418d..0b99ddee4b99 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
@@ -10,7 +10,7 @@
       In addition to numerous new and upgraded packages, this release
       has the following highlights:
     </para>
-    <itemizedlist spacing="compact">
+    <itemizedlist>
       <listitem>
         <para>
           Cinnamon has been updated to 5.6, see
@@ -18,6 +18,14 @@
           pull request</link> for what is changed.
         </para>
       </listitem>
+      <listitem>
+        <para>
+          <literal>nixos-rebuild</literal> now supports an extra
+          <literal>--specialisation</literal> option that can be used to
+          change specialisation for <literal>switch</literal> and
+          <literal>test</literal> commands.
+        </para>
+      </listitem>
     </itemizedlist>
   </section>
   <section xml:id="sec-release-23.05-new-services">
diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml
index cab871661a75..c80bfaaf51a4 100644
--- a/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixos/doc/manual/man-nixos-rebuild.xml
@@ -113,6 +113,18 @@
      </group> <replaceable>name</replaceable>
    </arg>
 
+   <arg>
+    <group choice='req'>
+    <arg choice='plain'>
+     <option>--specialisation</option>
+    </arg>
+
+    <arg choice='plain'>
+     <option>-c</option>
+    </arg>
+     </group> <replaceable>name</replaceable>
+   </arg>
+
    <sbr />
 
    <arg>
@@ -204,6 +216,20 @@
        <command>nixos-rebuild switch</command> or <command>nixos-rebuild
        boot</command> remain available in the GRUB menu.
       </para>
+      <para>
+        Note that if you are using specializations, running just
+        <command>nixos-rebuild switch</command> will switch you back to the
+        unspecialized, base system - in that case, you might want to use this
+        instead:
+<screen>
+<prompt>$ </prompt>nixos-rebuild switch --specialisation your-specialisation-name
+</screen>
+        This command will build all specialisations and make them bootable just
+        like regular <command>nixos-rebuild switch</command> does - the only
+        thing different is that it will switch to given specialisation instead
+        of the base system; it can be also used to switch from the base system
+        into a specialised one, or to switch between specialisations.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -233,6 +259,16 @@
        configuration resulting from the last call to <command>nixos-rebuild
        switch</command> or <command>nixos-rebuild boot</command>).
       </para>
+      <para>
+        Note that if you are using specialisations, running just
+        <command>nixos-rebuild test</command> will activate the unspecialised,
+        base system - in that case, you might want to use this instead:
+<screen>
+<prompt>$ </prompt>nixos-rebuild test --specialisation your-specialisation-name
+</screen>
+        This command can be also used to switch from the base system into a
+        specialised one, or to switch between specialisations.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -501,6 +537,21 @@
 
    <varlistentry>
     <term>
+     <option>--specialisation</option>
+    </term>
+    <term>
+     <option>-c</option>
+    </term>
+    <listitem>
+     <para>
+      Activates given specialisation; when not specified, switching and testing
+      will activate the base, unspecialised system.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>
      <option>--build-host</option>
     </term>
     <listitem>
diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md
index 1620e98f3aa3..44dba3777851 100644
--- a/nixos/doc/manual/release-notes/rl-2305.section.md
+++ b/nixos/doc/manual/release-notes/rl-2305.section.md
@@ -10,6 +10,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - Cinnamon has been updated to 5.6, see [the pull request](https://github.com/NixOS/nixpkgs/pull/201328#issue-1449910204) for what is changed.
 
+- `nixos-rebuild` now supports an extra `--specialisation` option that can be used to change specialisation for `switch` and `test` commands.
+
 ## New Services {#sec-release-23.05-new-services}
 
 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index acc42acf37a6..35d0fc0b9784 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -436,7 +436,6 @@ in {
   netdata = handleTest ./netdata.nix {};
   networking.networkd = handleTest ./networking.nix { networkd = true; };
   networking.scripted = handleTest ./networking.nix { networkd = false; };
-  specialisation = handleTest ./specialisation.nix {};
   netbox = handleTest ./web-apps/netbox.nix {};
   # TODO: put in networking.nix after the test becomes more complete
   networkingProxy = handleTest ./networking-proxy.nix {};
@@ -464,6 +463,7 @@ in {
   nix-serve-ssh = handleTest ./nix-serve-ssh.nix {};
   nixops = handleTest ./nixops/default.nix {};
   nixos-generate-config = handleTest ./nixos-generate-config.nix {};
+  nixos-rebuild-specialisations = handleTest ./nixos-rebuild-specialisations.nix {};
   nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; };
   node-red = handleTest ./node-red.nix {};
   nomad = handleTest ./nomad.nix {};
diff --git a/nixos/tests/nixos-rebuild-specialisations.nix b/nixos/tests/nixos-rebuild-specialisations.nix
new file mode 100644
index 000000000000..c61f81b8ca65
--- /dev/null
+++ b/nixos/tests/nixos-rebuild-specialisations.nix
@@ -0,0 +1,131 @@
+import ./make-test-python.nix ({ pkgs, ... }: {
+  name = "nixos-rebuild-specialisations";
+
+  nodes = {
+    machine = { lib, pkgs, ... }: {
+      imports = [
+        ../modules/profiles/installation-device.nix
+        ../modules/profiles/base.nix
+      ];
+
+      nix.settings = {
+        substituters = lib.mkForce [ ];
+        hashed-mirrors = null;
+        connect-timeout = 1;
+      };
+
+      system.extraDependencies = with pkgs; [
+        curl
+        desktop-file-utils
+        docbook5
+        docbook_xsl_ns
+        grub2
+        kmod.dev
+        libarchive
+        libarchive.dev
+        libxml2.bin
+        libxslt.bin
+        python3Minimal
+        shared-mime-info
+        stdenv
+        sudo
+        xorg.lndir
+      ];
+
+      virtualisation = {
+        cores = 2;
+        memorySize = 2048;
+      };
+    };
+  };
+
+  testScript =
+    let
+      configFile = pkgs.writeText "configuration.nix" ''
+        { lib, pkgs, ... }: {
+          imports = [
+            ./hardware-configuration.nix
+            <nixpkgs/nixos/modules/testing/test-instrumentation.nix>
+          ];
+
+          boot.loader.grub = {
+            enable = true;
+            device = "/dev/vda";
+            forceInstall = true;
+          };
+
+          documentation.enable = false;
+
+          environment.systemPackages = [
+            (pkgs.writeShellScriptBin "parent" "")
+          ];
+
+          specialisation.foo = {
+            inheritParentConfig = true;
+
+            configuration = { ... }: {
+              environment.systemPackages = [
+                (pkgs.writeShellScriptBin "foo" "")
+              ];
+            };
+          };
+
+          specialisation.bar = {
+            inheritParentConfig = true;
+
+            configuration = { ... }: {
+              environment.systemPackages = [
+                (pkgs.writeShellScriptBin "bar" "")
+              ];
+            };
+          };
+        }
+      '';
+
+    in
+    ''
+      machine.start()
+      machine.succeed("udevadm settle")
+      machine.wait_for_unit("multi-user.target")
+
+      machine.succeed("nixos-generate-config")
+      machine.copy_from_host(
+          "${configFile}",
+          "/etc/nixos/configuration.nix",
+      )
+
+      with subtest("Switch to the base system"):
+          machine.succeed("nixos-rebuild switch")
+          machine.succeed("parent")
+          machine.fail("foo")
+          machine.fail("bar")
+
+      with subtest("Switch from base system into a specialization"):
+          machine.succeed("nixos-rebuild switch --specialisation foo")
+          machine.succeed("parent")
+          machine.succeed("foo")
+          machine.fail("bar")
+
+      with subtest("Switch from specialization into another specialization"):
+          machine.succeed("nixos-rebuild switch -c bar")
+          machine.succeed("parent")
+          machine.fail("foo")
+          machine.succeed("bar")
+
+      with subtest("Switch from specialization into the base system"):
+          machine.succeed("nixos-rebuild switch")
+          machine.succeed("parent")
+          machine.fail("foo")
+          machine.fail("bar")
+
+      with subtest("Switch into specialization using `nixos-rebuild test`"):
+          machine.succeed("nixos-rebuild test --specialisation foo")
+          machine.succeed("parent")
+          machine.succeed("foo")
+          machine.fail("bar")
+
+      with subtest("Make sure nonsense command combinations are forbidden"):
+          machine.fail("nixos-rebuild boot --specialisation foo")
+          machine.fail("nixos-rebuild boot -c foo")
+    '';
+})
diff --git a/nixos/tests/specialisation.nix b/nixos/tests/specialisation.nix
deleted file mode 100644
index b8d4b8279f4d..000000000000
--- a/nixos/tests/specialisation.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-import ./make-test-python.nix {
-  name = "specialisation";
-  nodes =  {
-    inheritconf = { pkgs, ... }: {
-      environment.systemPackages = [ pkgs.cowsay ];
-      specialisation.inheritconf.configuration = { pkgs, ... }: {
-        environment.systemPackages = [ pkgs.hello ];
-      };
-    };
-    noinheritconf = { pkgs, ... }: {
-      environment.systemPackages = [ pkgs.cowsay ];
-      specialisation.noinheritconf = {
-        inheritParentConfig = false;
-        configuration = { pkgs, ... }: {
-          environment.systemPackages = [ pkgs.hello ];
-        };
-      };
-    };
-  };
-  testScript = ''
-    inheritconf.wait_for_unit("default.target")
-    inheritconf.succeed("cowsay hey")
-    inheritconf.fail("hello")
-
-    with subtest("Nested clones do inherit from parent"):
-        inheritconf.succeed(
-            "/run/current-system/specialisation/inheritconf/bin/switch-to-configuration test"
-        )
-        inheritconf.succeed("cowsay hey")
-        inheritconf.succeed("hello")
-
-        noinheritconf.wait_for_unit("default.target")
-        noinheritconf.succeed("cowsay hey")
-        noinheritconf.fail("hello")
-
-    with subtest("Nested children do not inherit from parent"):
-        noinheritconf.succeed(
-            "/run/current-system/specialisation/noinheritconf/bin/switch-to-configuration test"
-        )
-        noinheritconf.fail("cowsay hey")
-        noinheritconf.succeed("hello")
-  '';
-}
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