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.
This commit is contained in:
Eelco Dolstra 2013-10-09 19:13:26 +02:00
parent 08f8d9507a
commit e5bcb378fa
2 changed files with 52 additions and 25 deletions

View file

@ -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

View file

@ -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;
# 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;
my @links = sort
{ nrFromGen($b) <=> nrFromGen($a) }
(glob "/nix/var/nix/profiles/system-*-link");
sub nrFromGen { my ($x) = @_; $x =~ /\/\w+-(\d+)-link/; return $1; }
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);
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 "") {