Commit e5bcb378 authored by Eelco Dolstra's avatar Eelco Dolstra
Browse files

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.
parent 08f8d950
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ Options:
                           building NixOS
  --rollback             restore the previous NixOS configuration (only
                           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
+34 −19
Original line number Diff line number Diff line
@@ -193,14 +193,18 @@ $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;
# Emit submenus for all system profiles.
sub addProfile {
    my ($profile, $description) = @_;

sub nrFromGen { my ($x) = @_; $x =~ /system-(.*)-link/; return $1; }
    # 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 "/nix/var/nix/profiles/system-*-link");
        (glob "$profile-*-link");

    my $curEntry = 0;
    foreach my $link (@links) {
@@ -214,6 +218,17 @@ foreach my $link (@links) {
    }

    $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 "") {