Revert "Revert "Merge pull request #2449 from wkennington/master.grub""
This reverts commit 94205f5f21
.
Conflicts:
nixos/modules/system/boot/loader/grub/install-grub.pl
This commit is contained in:
parent
af4c369d0a
commit
36614ff3e2
|
@ -20,6 +20,13 @@ sub uniq {
|
||||||
return @res;
|
return @res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub runCommand {
|
||||||
|
my ($cmd) = @_;
|
||||||
|
open FILE, "$cmd 2>/dev/null |" or die "Failed to execute: $cmd\n";
|
||||||
|
my @ret = <FILE>;
|
||||||
|
close FILE;
|
||||||
|
return ($?, @ret);
|
||||||
|
}
|
||||||
|
|
||||||
# Process the command line.
|
# Process the command line.
|
||||||
my $outDir = "/etc/nixos";
|
my $outDir = "/etc/nixos";
|
||||||
|
@ -337,6 +344,20 @@ EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Is this a btrfs filesystem?
|
||||||
|
if ($fsType eq "btrfs") {
|
||||||
|
my ($status, @info) = runCommand("btrfs subvol show $rootDir$mountPoint");
|
||||||
|
if ($status != 0) {
|
||||||
|
die "Failed to retreive subvolume info for $mountPoint";
|
||||||
|
}
|
||||||
|
my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/;
|
||||||
|
if ($#subvols > 0) {
|
||||||
|
die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
|
||||||
|
} elsif ($#subvols == 0) {
|
||||||
|
push @extraOptions, "subvol=$subvols[0]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Emit the filesystem.
|
# Emit the filesystem.
|
||||||
$fileSystems .= <<EOF;
|
$fileSystems .= <<EOF;
|
||||||
fileSystems.\"$mountPoint\" =
|
fileSystems.\"$mountPoint\" =
|
||||||
|
|
|
@ -38,6 +38,7 @@ let
|
||||||
nixos-generate-config = makeProg {
|
nixos-generate-config = makeProg {
|
||||||
name = "nixos-generate-config";
|
name = "nixos-generate-config";
|
||||||
src = ./nixos-generate-config.pl;
|
src = ./nixos-generate-config.pl;
|
||||||
|
path = [ pkgs.btrfsProgs ];
|
||||||
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
|
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ with lib;
|
||||||
../profiles/clone-config.nix
|
../profiles/clone-config.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# FIXME: UUID detection is currently broken
|
||||||
|
boot.loader.grub.fsIdentifier = "provided";
|
||||||
|
|
||||||
# Allow mounting of shared folders.
|
# Allow mounting of shared folders.
|
||||||
users.extraUsers.demo.extraGroups = [ "vboxsf" ];
|
users.extraUsers.demo.extraGroups = [ "vboxsf" ];
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ let
|
||||||
|
|
||||||
cfg = config.boot.loader.grub;
|
cfg = config.boot.loader.grub;
|
||||||
|
|
||||||
realGrub = if cfg.version == 1 then pkgs.grub else pkgs.grub2;
|
realGrub = if cfg.version == 1 then pkgs.grub
|
||||||
|
else pkgs.grub2.override { zfsSupport = cfg.zfsSupport; };
|
||||||
|
|
||||||
grub =
|
grub =
|
||||||
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
|
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
|
||||||
|
@ -25,11 +26,12 @@ let
|
||||||
inherit (cfg)
|
inherit (cfg)
|
||||||
version extraConfig extraPerEntryConfig extraEntries
|
version extraConfig extraPerEntryConfig extraEntries
|
||||||
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
|
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
|
||||||
default devices explicitBootRoot;
|
default devices fsIdentifier;
|
||||||
path = (makeSearchPath "bin" [
|
path = (makeSearchPath "bin" [
|
||||||
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils
|
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs
|
||||||
|
pkgs.utillinux
|
||||||
]) + ":" + (makeSearchPath "sbin" [
|
]) + ":" + (makeSearchPath "sbin" [
|
||||||
pkgs.mdadm
|
pkgs.mdadm pkgs.utillinux
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -209,12 +211,26 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
explicitBootRoot = mkOption {
|
fsIdentifier = mkOption {
|
||||||
default = "";
|
default = "uuid";
|
||||||
type = types.str;
|
type = types.addCheck types.str
|
||||||
|
(type: type == "uuid" || type == "label" || type == "provided");
|
||||||
description = ''
|
description = ''
|
||||||
The relative path of /boot within the parent volume. Leave empty
|
Determines how grub will identify devices when generating the
|
||||||
if /boot is not a btrfs subvolume.
|
configuration file. A value of uuid / label signifies that grub
|
||||||
|
will always resolve the uuid or label of the device before using
|
||||||
|
it in the configuration. A value of provided means that grub will
|
||||||
|
use the device name as show in <command>df</command> or
|
||||||
|
<command>mount</command>. Note, zfs zpools / datasets are ignored
|
||||||
|
and will always be mounted using their labels.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
zfsSupport = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether grub should be build against libzfs.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -260,6 +276,9 @@ in
|
||||||
${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}"
|
${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}"
|
||||||
'') config.boot.loader.grub.extraFiles);
|
'') config.boot.loader.grub.extraFiles);
|
||||||
|
|
||||||
|
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
|
||||||
|
message = "Only grub version 2 provides zfs support";}];
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use Class::Struct;
|
||||||
use XML::LibXML;
|
use XML::LibXML;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
@ -27,6 +28,14 @@ sub writeFile {
|
||||||
close FILE or die;
|
close FILE or die;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub runCommand {
|
||||||
|
my ($cmd) = @_;
|
||||||
|
open FILE, "$cmd 2>/dev/null |" or die "Failed to execute: $cmd\n";
|
||||||
|
my @ret = <FILE>;
|
||||||
|
close FILE;
|
||||||
|
return ($?, @ret);
|
||||||
|
}
|
||||||
|
|
||||||
my $grub = get("grub");
|
my $grub = get("grub");
|
||||||
my $grubVersion = int(get("version"));
|
my $grubVersion = int(get("version"));
|
||||||
my $extraConfig = get("extraConfig");
|
my $extraConfig = get("extraConfig");
|
||||||
|
@ -39,7 +48,7 @@ my $configurationLimit = int(get("configurationLimit"));
|
||||||
my $copyKernels = get("copyKernels") eq "true";
|
my $copyKernels = get("copyKernels") eq "true";
|
||||||
my $timeout = int(get("timeout"));
|
my $timeout = int(get("timeout"));
|
||||||
my $defaultEntry = int(get("default"));
|
my $defaultEntry = int(get("default"));
|
||||||
my $explicitBootRoot = get("explicitBootRoot");
|
my $fsIdentifier = get("fsIdentifier");
|
||||||
$ENV{'PATH'} = get("path");
|
$ENV{'PATH'} = get("path");
|
||||||
|
|
||||||
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
|
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
|
||||||
|
@ -48,22 +57,108 @@ print STDERR "updating GRUB $grubVersion menu...\n";
|
||||||
|
|
||||||
mkpath("/boot/grub", 0, 0700);
|
mkpath("/boot/grub", 0, 0700);
|
||||||
|
|
||||||
|
|
||||||
# Discover whether /boot is on the same filesystem as / and
|
# Discover whether /boot is on the same filesystem as / and
|
||||||
# /nix/store. If not, then all kernels and initrds must be copied to
|
# /nix/store. If not, then all kernels and initrds must be copied to
|
||||||
# /boot, and all paths in the GRUB config file must be relative to the
|
# /boot.
|
||||||
# root of the /boot filesystem. `$bootRoot' is the path to be
|
if (stat("/boot")->dev != stat("/nix/store")->dev) {
|
||||||
# prepended to paths under /boot.
|
|
||||||
my $bootRoot = "/boot";
|
|
||||||
if (stat("/")->dev != stat("/boot")->dev) {
|
|
||||||
$bootRoot = "";
|
|
||||||
$copyKernels = 1;
|
|
||||||
} elsif (stat("/boot")->dev != stat("/nix/store")->dev) {
|
|
||||||
$copyKernels = 1;
|
$copyKernels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($explicitBootRoot ne "") {
|
# Discover information about the location of /boot
|
||||||
$bootRoot = $explicitBootRoot;
|
struct(Fs => {
|
||||||
|
device => '$',
|
||||||
|
type => '$',
|
||||||
|
mount => '$',
|
||||||
|
});
|
||||||
|
sub GetFs {
|
||||||
|
my ($dir) = @_;
|
||||||
|
my ($status, @dfOut) = runCommand("df -T $dir");
|
||||||
|
if ($status != 0 || $#dfOut != 1) {
|
||||||
|
die "Failed to retrieve output about $dir from `df`";
|
||||||
|
}
|
||||||
|
my @boot = split(/[ \n\t]+/, $dfOut[1]);
|
||||||
|
return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]);
|
||||||
|
}
|
||||||
|
struct (Grub => {
|
||||||
|
path => '$',
|
||||||
|
search => '$',
|
||||||
|
});
|
||||||
|
my $driveid = 1;
|
||||||
|
sub GrubFs {
|
||||||
|
my ($dir) = @_;
|
||||||
|
my $fs = GetFs($dir);
|
||||||
|
my $path = "/" . substr($dir, length($fs->mount));
|
||||||
|
my $search = "";
|
||||||
|
|
||||||
|
if ($grubVersion > 1) {
|
||||||
|
# ZFS is completely separate logic as zpools are always identified by a label
|
||||||
|
# or custom UUID
|
||||||
|
if ($fs->type eq 'zfs') {
|
||||||
|
my $sid = index($fs->device, '/');
|
||||||
|
|
||||||
|
if ($sid < 0) {
|
||||||
|
$search = '--label ' . $fs->device;
|
||||||
|
$path = '/@' . $path;
|
||||||
|
} else {
|
||||||
|
$search = '--label ' . substr($fs->device, 0, $sid);
|
||||||
|
$path = '/' . substr($fs->device, $sid) . '/@' . $path;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
my %types = ('uuid' => '--fs-uuid', 'label' => '--label');
|
||||||
|
|
||||||
|
if ($fsIdentifier eq 'provided') {
|
||||||
|
# If the provided dev is identifying the partition using a label or uuid,
|
||||||
|
# we should get the label / uuid and do a proper search
|
||||||
|
my @matches = $fs->device =~ m/\/dev\/disk\/by-(label|uuid)\/(.*)/;
|
||||||
|
if ($#matches > 1) {
|
||||||
|
die "Too many matched devices"
|
||||||
|
} elsif ($#matches == 1) {
|
||||||
|
$search = "$types{$matches[0]} $matches[1]"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Determine the identifying type
|
||||||
|
$search = $types{$fsIdentifier} . ' ';
|
||||||
|
|
||||||
|
# Based on the type pull in the identifier from the system
|
||||||
|
my ($status, @devInfo) = runCommand("blkid -o export @{[$fs->device]}");
|
||||||
|
if ($status != 0) {
|
||||||
|
die "Failed to get blkid info for @{[$fs->device]}";
|
||||||
|
}
|
||||||
|
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
||||||
|
if ($#matches != 0) {
|
||||||
|
die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n"
|
||||||
|
}
|
||||||
|
$search .= $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
# BTRFS is a special case in that we need to fix the referrenced path based on subvolumes
|
||||||
|
if ($fs->type eq 'btrfs') {
|
||||||
|
my ($status, @info) = runCommand("btrfs subvol show @{[$fs->mount]}");
|
||||||
|
if ($status != 0) {
|
||||||
|
die "Failed to retreive subvolume info for @{[$fs->mount]}";
|
||||||
|
}
|
||||||
|
my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/;
|
||||||
|
if ($#subvols > 0) {
|
||||||
|
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
|
||||||
|
} elsif ($#subvols == 0) {
|
||||||
|
$path = "/$subvols[0]$path";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (not $search eq "") {
|
||||||
|
$search = "search --set=drive$driveid " . $search;
|
||||||
|
$path = "(\$drive$driveid)$path";
|
||||||
|
$driveid += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Grub->new(path => $path, search => $search);
|
||||||
|
}
|
||||||
|
my $grubBoot = GrubFs("/boot");
|
||||||
|
my $grubStore = GrubFs("/nix");
|
||||||
|
|
||||||
|
# We don't need to copy if we can read the kernels directly
|
||||||
|
if ($grubStore->search ne "") {
|
||||||
|
$copyKernels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate the header.
|
# Generate the header.
|
||||||
|
@ -76,12 +171,14 @@ if ($grubVersion == 1) {
|
||||||
";
|
";
|
||||||
if ($splashImage) {
|
if ($splashImage) {
|
||||||
copy $splashImage, "/boot/background.xpm.gz" or die "cannot copy $splashImage to /boot\n";
|
copy $splashImage, "/boot/background.xpm.gz" or die "cannot copy $splashImage to /boot\n";
|
||||||
$conf .= "splashimage $bootRoot/background.xpm.gz\n";
|
$conf .= "splashimage " . $grubBoot->path . "/background.xpm.gz\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
$conf .= "
|
$conf .= "
|
||||||
|
" . $grubBoot->search . "
|
||||||
|
" . $grubStore->search . "
|
||||||
if [ -s \$prefix/grubenv ]; then
|
if [ -s \$prefix/grubenv ]; then
|
||||||
load_env
|
load_env
|
||||||
fi
|
fi
|
||||||
|
@ -102,7 +199,7 @@ else {
|
||||||
set timeout=$timeout
|
set timeout=$timeout
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if loadfont $bootRoot/grub/fonts/unicode.pf2; then
|
if loadfont " . $grubBoot->path . "/grub/fonts/unicode.pf2; then
|
||||||
set gfxmode=640x480
|
set gfxmode=640x480
|
||||||
insmod gfxterm
|
insmod gfxterm
|
||||||
insmod vbe
|
insmod vbe
|
||||||
|
@ -116,7 +213,7 @@ else {
|
||||||
copy $splashImage, "/boot/background.png" or die "cannot copy $splashImage to /boot\n";
|
copy $splashImage, "/boot/background.png" or die "cannot copy $splashImage to /boot\n";
|
||||||
$conf .= "
|
$conf .= "
|
||||||
insmod png
|
insmod png
|
||||||
if background_image $bootRoot/background.png; then
|
if background_image " . $grubBoot->path . "/background.png; then
|
||||||
set color_normal=white/black
|
set color_normal=white/black
|
||||||
set color_highlight=black/white
|
set color_highlight=black/white
|
||||||
else
|
else
|
||||||
|
@ -138,7 +235,7 @@ mkpath("/boot/kernels", 0, 0755) if $copyKernels;
|
||||||
|
|
||||||
sub copyToKernelsDir {
|
sub copyToKernelsDir {
|
||||||
my ($path) = @_;
|
my ($path) = @_;
|
||||||
return $path unless $copyKernels;
|
return $grubStore->path . substr($path, length("/nix")) unless $copyKernels;
|
||||||
$path =~ /\/nix\/store\/(.*)/ or die;
|
$path =~ /\/nix\/store\/(.*)/ or die;
|
||||||
my $name = $1; $name =~ s/\//-/g;
|
my $name = $1; $name =~ s/\//-/g;
|
||||||
my $dst = "/boot/kernels/$name";
|
my $dst = "/boot/kernels/$name";
|
||||||
|
@ -151,7 +248,7 @@ sub copyToKernelsDir {
|
||||||
rename $tmp, $dst or die "cannot rename $tmp to $dst\n";
|
rename $tmp, $dst or die "cannot rename $tmp to $dst\n";
|
||||||
}
|
}
|
||||||
$copied{$dst} = 1;
|
$copied{$dst} = 1;
|
||||||
return "$bootRoot/kernels/$name";
|
return $grubBoot->path . "/kernels/$name";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub addEntry {
|
sub addEntry {
|
||||||
|
@ -178,6 +275,8 @@ sub addEntry {
|
||||||
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n";
|
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n";
|
||||||
} else {
|
} else {
|
||||||
$conf .= "menuentry \"$name\" {\n";
|
$conf .= "menuentry \"$name\" {\n";
|
||||||
|
$conf .= $grubBoot->search . "\n";
|
||||||
|
$conf .= $grubStore->search . "\n";
|
||||||
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
||||||
$conf .= " multiboot $xen $xenParams\n" if $xen;
|
$conf .= " multiboot $xen $xenParams\n" if $xen;
|
||||||
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
|
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
|
||||||
|
@ -195,7 +294,7 @@ addEntry("NixOS - Default", $defaultConfig);
|
||||||
$conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
|
$conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
|
||||||
|
|
||||||
# extraEntries could refer to @bootRoot@, which we have to substitute
|
# extraEntries could refer to @bootRoot@, which we have to substitute
|
||||||
$conf =~ s/\@bootRoot\@/$bootRoot/g;
|
$conf =~ s/\@bootRoot\@/$grubBoot->path/g;
|
||||||
|
|
||||||
# Emit submenus for all system profiles.
|
# Emit submenus for all system profiles.
|
||||||
sub addProfile {
|
sub addProfile {
|
||||||
|
|
|
@ -133,7 +133,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.initrd = mkIf inInitrd {
|
boot.initrd = mkIf inInitrd {
|
||||||
kernelModules = [ "spl" "zfs" ] ;
|
kernelModules = [ "spl" "zfs" ];
|
||||||
extraUtilsCommands =
|
extraUtilsCommands =
|
||||||
''
|
''
|
||||||
cp -v ${zfsPkg}/sbin/zfs $out/bin
|
cp -v ${zfsPkg}/sbin/zfs $out/bin
|
||||||
|
@ -148,6 +148,10 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boot.loader.grub = mkIf inInitrd {
|
||||||
|
zfsSupport = true;
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services."zpool-import" = {
|
systemd.services."zpool-import" = {
|
||||||
description = "Import zpools";
|
description = "Import zpools";
|
||||||
after = [ "systemd-udev-settle.service" ];
|
after = [ "systemd-udev-settle.service" ];
|
||||||
|
|
|
@ -52,6 +52,10 @@ in rec {
|
||||||
(all nixos.tests.installer.lvm)
|
(all nixos.tests.installer.lvm)
|
||||||
(all nixos.tests.installer.separateBoot)
|
(all nixos.tests.installer.separateBoot)
|
||||||
(all nixos.tests.installer.simple)
|
(all nixos.tests.installer.simple)
|
||||||
|
(all nixos.tests.installer.simpleLabels)
|
||||||
|
(all nixos.tests.installer.simpleProvided)
|
||||||
|
(all nixos.tests.installer.btrfsSimple)
|
||||||
|
(all nixos.tests.installer.btrfsSubvols)
|
||||||
(all nixos.tests.ipv6)
|
(all nixos.tests.ipv6)
|
||||||
(all nixos.tests.kde4)
|
(all nixos.tests.kde4)
|
||||||
(all nixos.tests.login)
|
(all nixos.tests.login)
|
||||||
|
|
|
@ -231,7 +231,7 @@ in rec {
|
||||||
tests.installer.simpleLabels = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleLabels.test);
|
tests.installer.simpleLabels = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleLabels.test);
|
||||||
tests.installer.simpleProvided = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleProvided.test);
|
tests.installer.simpleProvided = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleProvided.test);
|
||||||
tests.installer.btrfsSimple = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSimple.test);
|
tests.installer.btrfsSimple = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSimple.test);
|
||||||
#tests.installer.btrfsSubvols = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSubvols.test);
|
tests.installer.btrfsSubvols = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSubvols.test);
|
||||||
tests.influxdb = callTest tests/influxdb.nix {};
|
tests.influxdb = callTest tests/influxdb.nix {};
|
||||||
tests.ipv6 = callTest tests/ipv6.nix {};
|
tests.ipv6 = callTest tests/ipv6.nix {};
|
||||||
tests.jenkins = callTest tests/jenkins.nix {};
|
tests.jenkins = callTest tests/jenkins.nix {};
|
||||||
|
|
|
@ -35,8 +35,8 @@ let
|
||||||
|
|
||||||
|
|
||||||
# The configuration to install.
|
# The configuration to install.
|
||||||
makeConfig = { testChannel, useEFI, grubVersion, grubDevice }: pkgs.writeText "configuration.nix"
|
makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
|
||||||
''
|
pkgs.writeText "configuration.nix" ''
|
||||||
{ config, pkgs, modulesPath, ... }:
|
{ config, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
{ imports =
|
{ imports =
|
||||||
|
@ -54,6 +54,7 @@ let
|
||||||
''}
|
''}
|
||||||
boot.loader.grub.device = "${grubDevice}";
|
boot.loader.grub.device = "${grubDevice}";
|
||||||
boot.loader.grub.extraConfig = "serial; terminal_output.serial";
|
boot.loader.grub.extraConfig = "serial; terminal_output.serial";
|
||||||
|
boot.loader.grub.fsIdentifier = "${grubIdentifier}";
|
||||||
''}
|
''}
|
||||||
|
|
||||||
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
||||||
|
@ -93,7 +94,7 @@ let
|
||||||
# disk, and then reboot from the hard disk. It's parameterized with
|
# disk, and then reboot from the hard disk. It's parameterized with
|
||||||
# a test script fragment `createPartitions', which must create
|
# a test script fragment `createPartitions', which must create
|
||||||
# partitions and filesystems.
|
# partitions and filesystems.
|
||||||
testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice }:
|
testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
|
||||||
let
|
let
|
||||||
# FIXME: OVMF doesn't boot from virtio http://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg01501.html
|
# FIXME: OVMF doesn't boot from virtio http://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg01501.html
|
||||||
iface = if useEFI || grubVersion == 1 then "scsi" else "virtio";
|
iface = if useEFI || grubVersion == 1 then "scsi" else "virtio";
|
||||||
|
@ -161,7 +162,7 @@ let
|
||||||
$machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2");
|
$machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2");
|
||||||
|
|
||||||
$machine->copyFileFromHost(
|
$machine->copyFileFromHost(
|
||||||
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice; } }",
|
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; } }",
|
||||||
"/mnt/etc/nixos/configuration.nix");
|
"/mnt/etc/nixos/configuration.nix");
|
||||||
|
|
||||||
# Perform the installation.
|
# Perform the installation.
|
||||||
|
@ -216,13 +217,13 @@ let
|
||||||
|
|
||||||
|
|
||||||
makeInstallerTest = name:
|
makeInstallerTest = name:
|
||||||
{ createPartitions, testChannel ? false, useEFI ? false, grubVersion ? 2, grubDevice ? "/dev/vda" }:
|
{ createPartitions, testChannel ? false, useEFI ? false, grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid" }:
|
||||||
makeTest {
|
makeTest {
|
||||||
inherit iso;
|
inherit iso;
|
||||||
name = "installer-" + name;
|
name = "installer-" + name;
|
||||||
nodes = if testChannel then { inherit webserver; } else { };
|
nodes = if testChannel then { inherit webserver; } else { };
|
||||||
testScript = testScriptFun {
|
testScript = testScriptFun {
|
||||||
inherit createPartitions testChannel useEFI grubVersion grubDevice;
|
inherit createPartitions testChannel useEFI grubVersion grubDevice grubIdentifier;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,45 @@
|
||||||
{ fetchurl, stdenv, flex, bison, gettext, ncurses, libusb, freetype, qemu
|
{ stdenv, fetchurl, autogen, flex, bison, python, autoconf, automake
|
||||||
, devicemapper, EFIsupport ? false }:
|
, gettext, ncurses, libusb, freetype, qemu, devicemapper
|
||||||
|
, linuxPackages ? null
|
||||||
|
, efiSupport ? false
|
||||||
|
, zfsSupport ? false
|
||||||
|
}:
|
||||||
|
|
||||||
|
with stdenv.lib;
|
||||||
let
|
let
|
||||||
|
efiSystems = {
|
||||||
|
"i686-linux".target = "i386";
|
||||||
|
"x86_64-linux".target = "x86_64";
|
||||||
|
};
|
||||||
|
|
||||||
prefix = "grub${if EFIsupport then "-efi" else ""}";
|
canEfi = any (system: stdenv.system == system) (mapAttrsToList (name: _: name) efiSystems);
|
||||||
|
|
||||||
version = "2.00";
|
prefix = "grub${if efiSupport then "-efi" else ""}";
|
||||||
|
|
||||||
|
version = "2.02-beta2";
|
||||||
|
|
||||||
unifont_bdf = fetchurl {
|
unifont_bdf = fetchurl {
|
||||||
url = "http://unifoundry.com/unifont-5.1.20080820.bdf.gz";
|
url = "http://unifoundry.com/unifont-5.1.20080820.bdf.gz";
|
||||||
sha256 = "0s0qfff6n6282q28nwwblp5x295zd6n71kl43xj40vgvdqxv0fxx";
|
sha256 = "0s0qfff6n6282q28nwwblp5x295zd6n71kl43xj40vgvdqxv0fxx";
|
||||||
};
|
};
|
||||||
|
in (
|
||||||
|
|
||||||
in
|
assert efiSupport -> canEfi;
|
||||||
|
assert zfsSupport -> linuxPackages != null && linuxPackages.zfs != null;
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "${prefix}-${version}";
|
name = "${prefix}-${version}";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://gnu/grub/grub-${version}.tar.xz";
|
name = "grub-2.02-beta2.tar.xz";
|
||||||
sha256 = "0n64hpmsccvicagvr0c6v0kgp2yw0kgnd3jvsyd26cnwgs7c6kkq";
|
url = "http://alpha.gnu.org/gnu/grub/grub-2.02~beta2.tar.xz";
|
||||||
|
sha256 = "13a13fhc0wf473dn73zhga15mjvkg6vqp4h25dxg4n7am2r05izn";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ flex bison ];
|
nativeBuildInputs = [ autogen flex bison python autoconf automake ];
|
||||||
buildInputs = [ ncurses libusb freetype gettext devicemapper ]
|
buildInputs = [ ncurses libusb freetype gettext devicemapper ]
|
||||||
++ stdenv.lib.optional doCheck qemu;
|
++ optional doCheck qemu
|
||||||
|
++ optional zfsSupport linuxPackages.zfs;
|
||||||
|
|
||||||
preConfigure =
|
preConfigure =
|
||||||
'' for i in "tests/util/"*.in
|
'' for i in "tests/util/"*.in
|
||||||
|
@ -43,27 +58,19 @@ stdenv.mkDerivation rec {
|
||||||
# See <http://www.mail-archive.com/qemu-devel@nongnu.org/msg22775.html>.
|
# See <http://www.mail-archive.com/qemu-devel@nongnu.org/msg22775.html>.
|
||||||
sed -i "tests/util/grub-shell.in" \
|
sed -i "tests/util/grub-shell.in" \
|
||||||
-e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g'
|
-e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g'
|
||||||
|
|
||||||
# Fix for building on Glibc 2.16. Won't be needed once the
|
|
||||||
# gnulib in grub is updated.
|
|
||||||
sed -i '/gets is a security hole/d' grub-core/gnulib/stdio.in.h
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
prePatch =
|
prePatch =
|
||||||
'' gunzip < "${unifont_bdf}" > "unifont.bdf"
|
'' sh autogen.sh
|
||||||
|
gunzip < "${unifont_bdf}" > "unifont.bdf"
|
||||||
sed -i "configure" \
|
sed -i "configure" \
|
||||||
-e "s|/usr/src/unifont.bdf|$PWD/unifont.bdf|g"
|
-e "s|/usr/src/unifont.bdf|$PWD/unifont.bdf|g"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
patches = [ ./fix-bash-completion.patch ];
|
patches = [ ./fix-bash-completion.patch ];
|
||||||
|
|
||||||
configureFlags =
|
configureFlags = optional zfsSupport "--enable-libzfs"
|
||||||
let arch = if stdenv.system == "i686-linux" then "i386"
|
++ optionals efiSupport [ "--with-platform=efi" "--target=${efiSystems.${stdenv.system}.target}" "--program-prefix=" ];
|
||||||
else if stdenv.system == "x86_64-linux" then "x86_64"
|
|
||||||
else throw "unsupported EFI firmware architecture";
|
|
||||||
in
|
|
||||||
stdenv.lib.optionals EFIsupport
|
|
||||||
[ "--with-platform=efi" "--target=${arch}" "--program-prefix=" ];
|
|
||||||
|
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
@ -72,7 +79,7 @@ stdenv.mkDerivation rec {
|
||||||
paxmark pms $out/sbin/grub-{probe,bios-setup}
|
paxmark pms $out/sbin/grub-{probe,bios-setup}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = {
|
meta = with stdenv.lib; {
|
||||||
description = "GNU GRUB, the Grand Unified Boot Loader (2.x beta)";
|
description = "GNU GRUB, the Grand Unified Boot Loader (2.x beta)";
|
||||||
|
|
||||||
longDescription =
|
longDescription =
|
||||||
|
@ -89,11 +96,8 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
homepage = http://www.gnu.org/software/grub/;
|
homepage = http://www.gnu.org/software/grub/;
|
||||||
|
|
||||||
license = stdenv.lib.licenses.gpl3Plus;
|
license = licenses.gpl3Plus;
|
||||||
|
|
||||||
platforms = if EFIsupport then
|
platforms = platforms.gnu;
|
||||||
[ "i686-linux" "x86_64-linux" ]
|
|
||||||
else
|
|
||||||
stdenv.lib.platforms.gnu;
|
|
||||||
};
|
};
|
||||||
}
|
})
|
||||||
|
|
|
@ -1235,9 +1235,11 @@ let
|
||||||
buggyBiosCDSupport = config.grub.buggyBiosCDSupport or true;
|
buggyBiosCDSupport = config.grub.buggyBiosCDSupport or true;
|
||||||
};
|
};
|
||||||
|
|
||||||
grub2 = callPackage ../tools/misc/grub/2.0x.nix { libusb = libusb1; flex = flex_2_5_35; };
|
grub2 = callPackage ../tools/misc/grub/2.0x.nix { };
|
||||||
|
|
||||||
grub2_efi = grub2.override { EFIsupport = true; };
|
grub2_efi = grub2.override { efiSupport = true; };
|
||||||
|
|
||||||
|
grub2_zfs = grub2.override { zfsSupport = true; };
|
||||||
|
|
||||||
gssdp = callPackage ../development/libraries/gssdp {
|
gssdp = callPackage ../development/libraries/gssdp {
|
||||||
inherit (gnome) libsoup;
|
inherit (gnome) libsoup;
|
||||||
|
|
Loading…
Reference in New Issue