summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-09 19:13:26 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-09 19:13:26 +0200
commite5bcb378fae0e38379b0b365ab2a2431ae5d6c07 (patch)
treee7e6a8d17b52a80d9cf63c727f2e0389fedf11c1
parent08f8d9507a8ae6958543929965f928164ad789b7 (diff)
downloadnixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar.gz
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar.bz2
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar.lz
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar.xz
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.tar.zst
nixlib-e5bcb378fae0e38379b0b365ab2a2431ae5d6c07.zip
Add support for multiple system profiles
‘nixos-rebuild’ now accepts an argument ‘--profile-name’ (or ‘-p’),
denoting the name of a system profile to use.  The default is
‘system’, which maps to /nix/var/nix/profiles/system.  Any other value
maps to /nix/var/nix/profiles/system-profiles/<name>.  The GRUB menu
generator makes all system profiles available as submenus.  For
instance, doing

  $ nixos-rebuild boot -p test

will cause a menu named ‘NixOS - Profile 'test'’ to be added to the
GRUB boot menu, leaving the default system profile unaffected.

This is only supported for GRUB 2.
-rw-r--r--modules/installer/tools/nixos-rebuild.sh30
-rw-r--r--modules/system/boot/loader/grub/install-grub.pl53
2 files changed, 55 insertions, 28 deletions
diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh
index 8597cf165b15..8734cb273d49 100644
--- a/modules/installer/tools/nixos-rebuild.sh
+++ b/modules/installer/tools/nixos-rebuild.sh
@@ -24,10 +24,10 @@ Options:
   --upgrade              fetch the latest version of NixOS before rebuilding
   --install-grub         (re-)install the Grub bootloader
   --no-build-nix         don't build the latest Nix from Nixpkgs before
-                         building NixOS
+                           building NixOS
   --rollback             restore the previous NixOS configuration (only
-                         with switch, boot, test, build)
-
+                           with switch, boot, test, build)
+  --profile-name / -p    install in the specified system profile
   --fast                 same as --no-build-nix --show-trace
 
 Various nix-build options are also accepted, in particular:
@@ -50,6 +50,7 @@ buildNix=1
 rollback=
 upgrade=
 repair=
+profile=/nix/var/nix/profiles/system
 
 while [ "$#" -gt 0 ]; do
     i="$1"; shift 1
@@ -92,6 +93,17 @@ while [ "$#" -gt 0 ]; do
         buildNix=
         extraBuildFlags+=(--show-trace)
         ;;
+      --profile-name|-p)
+        if [ -z "$1" ]; then
+            echo "$0: ‘--profile-name’ requires an argument"
+            exit 1
+        fi
+        if [ "$1" != system ]; then
+            profile="/nix/var/nix/profiles/system-profiles/$1"
+            mkdir -p -m 0755 "$(dirname "$profile")"
+        fi
+        shift 1
+        ;;
       *)
         echo "$0: unknown option \`$i'"
         exit 1
@@ -164,8 +176,8 @@ fi
 if [ -z "$rollback" ]; then
     echo "building the system configuration..." >&2
     if [ "$action" = switch -o "$action" = boot ]; then
-        nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '<nixos>' --set -A system
-        pathToConfig=/nix/var/nix/profiles/system
+        nix-env "${extraBuildFlags[@]}" -p "$profile" -f '<nixos>' --set -A system
+        pathToConfig="$profile"
     elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then
         nix-build '<nixos>' -A system -K -k "${extraBuildFlags[@]}" > /dev/null
         pathToConfig=./result
@@ -180,14 +192,14 @@ if [ -z "$rollback" ]; then
     fi
 else # [ -n "$rollback" ]
     if [ "$action" = switch -o "$action" = boot ]; then
-        nix-env --rollback -p /nix/var/nix/profiles/system
-        pathToConfig=/nix/var/nix/profiles/system
+        nix-env --rollback -p "$profile"
+        pathToConfig="$profile"
     elif [ "$action" = test -o "$action" = build ]; then
         systemNumber=$(
-            nix-env -p /nix/var/nix/profiles/system --list-generations |
+            nix-env -p "$profile" --list-generations |
             sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
         )
-        ln -sT /nix/var/nix/profiles/system-${systemNumber}-link ./result
+        ln -sT "$profile"-${systemNumber}-link ./result
         pathToConfig=./result
     else
         showSyntax
diff --git a/modules/system/boot/loader/grub/install-grub.pl b/modules/system/boot/loader/grub/install-grub.pl
index 738714ba7148..a83733db63b0 100644
--- a/modules/system/boot/loader/grub/install-grub.pl
+++ b/modules/system/boot/loader/grub/install-grub.pl
@@ -193,27 +193,42 @@ $conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
 # extraEntries could refer to @bootRoot@, which we have to substitute
 $conf =~ s/\@bootRoot\@/$bootRoot/g;
 
-# Add entries for all previous generations of the system profile.
-$conf .= "submenu \"NixOS - All configurations\" {\n" if $grubVersion == 2;
-
-sub nrFromGen { my ($x) = @_; $x =~ /system-(.*)-link/; return $1; }
-
-my @links = sort
-    { nrFromGen($b) <=> nrFromGen($a) }
-    (glob "/nix/var/nix/profiles/system-*-link");
-
-my $curEntry = 0;
-foreach my $link (@links) {
-    last if $curEntry++ >= $configurationLimit;
-    my $date = strftime("%F", localtime(lstat($link)->mtime));
-    my $version =
-        -e "$link/nixos-version"
-        ? readFile("$link/nixos-version")
-        : basename((glob(dirname(Cwd::abs_path("$link/kernel")) . "/lib/modules/*"))[0]);
-    addEntry("NixOS - Configuration " . nrFromGen($link) . " ($date - $version)", $link);
+# Emit submenus for all system profiles.
+sub addProfile {
+    my ($profile, $description) = @_;
+
+    # Add entries for all generations of this profile.
+    $conf .= "submenu \"$description\" {\n" if $grubVersion == 2;
+
+    sub nrFromGen { my ($x) = @_; $x =~ /\/\w+-(\d+)-link/; return $1; }
+
+    my @links = sort
+        { nrFromGen($b) <=> nrFromGen($a) }
+        (glob "$profile-*-link");
+
+    my $curEntry = 0;
+    foreach my $link (@links) {
+        last if $curEntry++ >= $configurationLimit;
+        my $date = strftime("%F", localtime(lstat($link)->mtime));
+        my $version =
+            -e "$link/nixos-version"
+            ? readFile("$link/nixos-version")
+            : basename((glob(dirname(Cwd::abs_path("$link/kernel")) . "/lib/modules/*"))[0]);
+        addEntry("NixOS - Configuration " . nrFromGen($link) . " ($date - $version)", $link);
+    }
+
+    $conf .= "}\n" if $grubVersion == 2;
 }
 
-$conf .= "}\n" if $grubVersion == 2;
+addProfile "/nix/var/nix/profiles/system", "NixOS - All configurations";
+
+if ($grubVersion == 2) {
+    for my $profile (glob "/nix/var/nix/profiles/system-profiles/*") {
+        my $name = basename($profile);
+        next unless $name =~ /^\w+$/;
+        addProfile $profile, "NixOS - Profile '$name'";
+    }
+}
 
 # Run extraPrepareConfig in sh
 if ($extraPrepareConfig ne "") {