Skip to content

Commit

Permalink
Add support for multiple system profiles
Browse files Browse the repository at this point in the history
‘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.
  • Loading branch information
edolstra committed Oct 9, 2013
1 parent 08f8d95 commit e5bcb37
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 28 deletions.
30 changes: 21 additions & 9 deletions modules/installer/tools/nixos-rebuild.sh
Expand Up @@ -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:
Expand All @@ -50,6 +50,7 @@ buildNix=1
rollback=
upgrade=
repair=
profile=/nix/var/nix/profiles/system

while [ "$#" -gt 0 ]; do
i="$1"; shift 1
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
53 changes: 34 additions & 19 deletions modules/system/boot/loader/grub/install-grub.pl
Expand Up @@ -193,27 +193,42 @@ sub addEntry {
# 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 "") {
Expand Down

0 comments on commit e5bcb37

Please sign in to comment.