Merge pull request #3903 from wkennington/master.grub
Bring back grub update with fixes
This commit is contained in:
commit
3a33731e54
|
@ -20,6 +20,13 @@ sub uniq {
|
|||
return @res;
|
||||
}
|
||||
|
||||
sub runCommand {
|
||||
my ($cmd) = @_;
|
||||
open FILE, "$cmd 2>&1 |" or die "Failed to execute: $cmd\n";
|
||||
my @ret = <FILE>;
|
||||
close FILE;
|
||||
return ($?, @ret);
|
||||
}
|
||||
|
||||
# Process the command line.
|
||||
my $outDir = "/etc/nixos";
|
||||
|
@ -304,10 +311,13 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
|||
|
||||
# Maybe this is a bind-mount of a filesystem we saw earlier?
|
||||
if (defined $fsByDev{$fields[2]}) {
|
||||
my $path = $fields[3]; $path = "" if $path eq "/";
|
||||
my $base = $fsByDev{$fields[2]};
|
||||
$base = "" if $base eq "/";
|
||||
$fileSystems .= <<EOF;
|
||||
# Make sure this isn't a btrfs subvolume
|
||||
my ($status, @msg) = runCommand("btrfs subvol show $rootDir$mountPoint");
|
||||
if (join("", @msg) =~ /ERROR:/) {
|
||||
my $path = $fields[3]; $path = "" if $path eq "/";
|
||||
my $base = $fsByDev{$fields[2]};
|
||||
$base = "" if $base eq "/";
|
||||
$fileSystems .= <<EOF;
|
||||
fileSystems.\"$mountPoint\" =
|
||||
{ device = \"$base$path\";
|
||||
fsType = \"none\";
|
||||
|
@ -315,7 +325,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
|||
};
|
||||
|
||||
EOF
|
||||
next;
|
||||
next;
|
||||
}
|
||||
}
|
||||
$fsByDev{$fields[2]} = $mountPoint;
|
||||
|
||||
|
@ -337,6 +348,30 @@ EOF
|
|||
}
|
||||
}
|
||||
|
||||
# Is this a btrfs filesystem?
|
||||
if ($fsType eq "btrfs") {
|
||||
my ($status, @id_info) = runCommand("btrfs subvol show $rootDir$mountPoint");
|
||||
if ($status != 0 || join("", @msg) =~ /ERROR:/) {
|
||||
die "Failed to retreive subvolume info for $mountPoint\n";
|
||||
}
|
||||
my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
|
||||
if ($#ids > 0) {
|
||||
die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
|
||||
} elsif ($#ids == 0) {
|
||||
my ($status, @path_info) = runCommand("btrfs subvol list $rootDir$mountPoint");
|
||||
if ($status != 0) {
|
||||
die "Failed to find $mountPoint subvolume id from btrfs\n";
|
||||
}
|
||||
my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
|
||||
if ($#paths > 0) {
|
||||
die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
|
||||
} elsif ($#paths != 0) {
|
||||
die "Btrfs did not return a path for the subvolume at $mountPoint\n";
|
||||
}
|
||||
push @extraOptions, "subvol=$paths[0]";
|
||||
}
|
||||
}
|
||||
|
||||
# Emit the filesystem.
|
||||
$fileSystems .= <<EOF;
|
||||
fileSystems.\"$mountPoint\" =
|
||||
|
|
|
@ -38,6 +38,7 @@ let
|
|||
nixos-generate-config = makeProg {
|
||||
name = "nixos-generate-config";
|
||||
src = ./nixos-generate-config.pl;
|
||||
path = [ pkgs.btrfsProgs ];
|
||||
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ with lib;
|
|||
../profiles/clone-config.nix
|
||||
];
|
||||
|
||||
# FIXME: UUID detection is currently broken
|
||||
boot.loader.grub.fsIdentifier = "provided";
|
||||
|
||||
# Allow mounting of shared folders.
|
||||
users.extraUsers.demo.extraGroups = [ "vboxsf" ];
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ let
|
|||
|
||||
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 =
|
||||
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
|
||||
|
@ -25,11 +26,12 @@ let
|
|||
inherit (cfg)
|
||||
version extraConfig extraPerEntryConfig extraEntries
|
||||
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
|
||||
default devices explicitBootRoot;
|
||||
default devices fsIdentifier;
|
||||
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" [
|
||||
pkgs.mdadm
|
||||
pkgs.mdadm pkgs.utillinux
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -209,12 +211,26 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
explicitBootRoot = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
fsIdentifier = mkOption {
|
||||
default = "uuid";
|
||||
type = types.addCheck types.str
|
||||
(type: type == "uuid" || type == "label" || type == "provided");
|
||||
description = ''
|
||||
The relative path of /boot within the parent volume. Leave empty
|
||||
if /boot is not a btrfs subvolume.
|
||||
Determines how grub will identify devices when generating the
|
||||
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}"
|
||||
'') 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 warnings;
|
||||
use Class::Struct;
|
||||
use XML::LibXML;
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
|
@ -27,6 +28,14 @@ sub writeFile {
|
|||
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 $grubVersion = int(get("version"));
|
||||
my $extraConfig = get("extraConfig");
|
||||
|
@ -39,7 +48,7 @@ my $configurationLimit = int(get("configurationLimit"));
|
|||
my $copyKernels = get("copyKernels") eq "true";
|
||||
my $timeout = int(get("timeout"));
|
||||
my $defaultEntry = int(get("default"));
|
||||
my $explicitBootRoot = get("explicitBootRoot");
|
||||
my $fsIdentifier = get("fsIdentifier");
|
||||
$ENV{'PATH'} = get("path");
|
||||
|
||||
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
|
||||
|
@ -48,23 +57,115 @@ print STDERR "updating GRUB $grubVersion menu...\n";
|
|||
|
||||
mkpath("/boot/grub", 0, 0700);
|
||||
|
||||
|
||||
# Discover whether /boot is on the same filesystem as / and
|
||||
# /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
|
||||
# root of the /boot filesystem. `$bootRoot' is the path to be
|
||||
# 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) {
|
||||
# /boot.
|
||||
if (stat("/boot")->dev != stat("/nix/store")->dev) {
|
||||
$copyKernels = 1;
|
||||
}
|
||||
|
||||
if ($explicitBootRoot ne "") {
|
||||
$bootRoot = $explicitBootRoot;
|
||||
# Discover information about the location of /boot
|
||||
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, @id_info) = runCommand("btrfs subvol show @{[$fs->mount]}");
|
||||
if ($status != 0) {
|
||||
die "Failed to retreive subvolume info for @{[$fs->mount]}\n";
|
||||
}
|
||||
my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
|
||||
if ($#ids > 0) {
|
||||
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
|
||||
} elsif ($#ids == 0) {
|
||||
my ($status, @path_info) = runCommand("btrfs subvol list @{[$fs->mount]}");
|
||||
if ($status != 0) {
|
||||
die "Failed to find @{[$fs->mount]} subvolume id from btrfs\n";
|
||||
}
|
||||
my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
|
||||
if ($#paths > 0) {
|
||||
die "Btrfs returned multiple paths for a single subvolume id, mountpoint @{[$fs->mount]}\n";
|
||||
} elsif ($#paths != 0) {
|
||||
die "Btrfs did not return a path for the subvolume at @{[$fs->mount]}\n";
|
||||
}
|
||||
$path = "/$paths[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");
|
||||
# FIXME: Should be /nix/store, but this fails in the installer
|
||||
my $grubStore = GrubFs("/nix");
|
||||
|
||||
# Generate the header.
|
||||
my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n";
|
||||
|
@ -76,12 +177,17 @@ if ($grubVersion == 1) {
|
|||
";
|
||||
if ($splashImage) {
|
||||
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 {
|
||||
if ($copyKernels == 0) {
|
||||
$conf .= "
|
||||
" . $grubStore->search;
|
||||
}
|
||||
$conf .= "
|
||||
" . $grubBoot->search . "
|
||||
if [ -s \$prefix/grubenv ]; then
|
||||
load_env
|
||||
fi
|
||||
|
@ -102,7 +208,7 @@ else {
|
|||
set timeout=$timeout
|
||||
fi
|
||||
|
||||
if loadfont $bootRoot/grub/fonts/unicode.pf2; then
|
||||
if loadfont " . $grubBoot->path . "/grub/fonts/unicode.pf2; then
|
||||
set gfxmode=640x480
|
||||
insmod gfxterm
|
||||
insmod vbe
|
||||
|
@ -116,7 +222,7 @@ else {
|
|||
copy $splashImage, "/boot/background.png" or die "cannot copy $splashImage to /boot\n";
|
||||
$conf .= "
|
||||
insmod png
|
||||
if background_image $bootRoot/background.png; then
|
||||
if background_image " . $grubBoot->path . "/background.png; then
|
||||
set color_normal=white/black
|
||||
set color_highlight=black/white
|
||||
else
|
||||
|
@ -138,7 +244,7 @@ mkpath("/boot/kernels", 0, 0755) if $copyKernels;
|
|||
|
||||
sub copyToKernelsDir {
|
||||
my ($path) = @_;
|
||||
return $path unless $copyKernels;
|
||||
return $grubStore->path . substr($path, length("/nix")) unless $copyKernels;
|
||||
$path =~ /\/nix\/store\/(.*)/ or die;
|
||||
my $name = $1; $name =~ s/\//-/g;
|
||||
my $dst = "/boot/kernels/$name";
|
||||
|
@ -151,7 +257,7 @@ sub copyToKernelsDir {
|
|||
rename $tmp, $dst or die "cannot rename $tmp to $dst\n";
|
||||
}
|
||||
$copied{$dst} = 1;
|
||||
return "$bootRoot/kernels/$name";
|
||||
return $grubBoot->path . "/kernels/$name";
|
||||
}
|
||||
|
||||
sub addEntry {
|
||||
|
@ -178,6 +284,10 @@ sub addEntry {
|
|||
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n";
|
||||
} else {
|
||||
$conf .= "menuentry \"$name\" {\n";
|
||||
$conf .= $grubBoot->search . "\n";
|
||||
if ($copyKernels == 0) {
|
||||
$conf .= $grubStore->search . "\n";
|
||||
}
|
||||
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
|
||||
$conf .= " multiboot $xen $xenParams\n" if $xen;
|
||||
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
|
||||
|
@ -195,7 +305,7 @@ addEntry("NixOS - Default", $defaultConfig);
|
|||
$conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
|
||||
|
||||
# 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.
|
||||
sub addProfile {
|
||||
|
|
|
@ -133,7 +133,7 @@ in
|
|||
};
|
||||
|
||||
boot.initrd = mkIf inInitrd {
|
||||
kernelModules = [ "spl" "zfs" ] ;
|
||||
kernelModules = [ "spl" "zfs" ];
|
||||
extraUtilsCommands =
|
||||
''
|
||||
cp -v ${zfsPkg}/sbin/zfs $out/bin
|
||||
|
@ -148,6 +148,10 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
boot.loader.grub = mkIf inInitrd {
|
||||
zfsSupport = true;
|
||||
};
|
||||
|
||||
systemd.services."zpool-import" = {
|
||||
description = "Import zpools";
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
|
|
@ -52,6 +52,11 @@ in rec {
|
|||
(all nixos.tests.installer.lvm)
|
||||
(all nixos.tests.installer.separateBoot)
|
||||
(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.installer.btrfsSubvolDefault)
|
||||
(all nixos.tests.ipv6)
|
||||
(all nixos.tests.kde4)
|
||||
(all nixos.tests.login)
|
||||
|
|
|
@ -231,7 +231,8 @@ in rec {
|
|||
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.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.installer.btrfsSubvolDefault = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test);
|
||||
tests.influxdb = callTest tests/influxdb.nix {};
|
||||
tests.ipv6 = callTest tests/ipv6.nix {};
|
||||
tests.jenkins = callTest tests/jenkins.nix {};
|
||||
|
|
|
@ -35,8 +35,8 @@ let
|
|||
|
||||
|
||||
# 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, ... }:
|
||||
|
||||
{ imports =
|
||||
|
@ -54,6 +54,7 @@ let
|
|||
''}
|
||||
boot.loader.grub.device = "${grubDevice}";
|
||||
boot.loader.grub.extraConfig = "serial; terminal_output.serial";
|
||||
boot.loader.grub.fsIdentifier = "${grubIdentifier}";
|
||||
''}
|
||||
|
||||
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
||||
|
@ -93,7 +94,7 @@ let
|
|||
# disk, and then reboot from the hard disk. It's parameterized with
|
||||
# a test script fragment `createPartitions', which must create
|
||||
# partitions and filesystems.
|
||||
testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice }:
|
||||
testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
|
||||
let
|
||||
# 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";
|
||||
|
@ -161,7 +162,7 @@ let
|
|||
$machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2");
|
||||
|
||||
$machine->copyFileFromHost(
|
||||
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice; } }",
|
||||
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; } }",
|
||||
"/mnt/etc/nixos/configuration.nix");
|
||||
|
||||
# Perform the installation.
|
||||
|
@ -216,13 +217,13 @@ let
|
|||
|
||||
|
||||
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 {
|
||||
inherit iso;
|
||||
name = "installer-" + name;
|
||||
nodes = if testChannel then { inherit webserver; } else { };
|
||||
testScript = testScriptFun {
|
||||
inherit createPartitions testChannel useEFI grubVersion grubDevice;
|
||||
inherit createPartitions testChannel useEFI grubVersion grubDevice grubIdentifier;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -461,11 +462,36 @@ in {
|
|||
"mount LABEL=root /mnt",
|
||||
"btrfs subvol create /mnt/boot",
|
||||
"btrfs subvol create /mnt/nixos",
|
||||
"btrfs subvol create /mnt/nixos/default",
|
||||
"umount /mnt",
|
||||
"mount -o defaults,subvol=nixos LABEL=root /mnt",
|
||||
"mount -o defaults,subvol=nixos/default LABEL=root /mnt",
|
||||
"mkdir /mnt/boot",
|
||||
"mount -o defaults,subvol=boot LABEL=root /mnt/boot",
|
||||
);
|
||||
'';
|
||||
};
|
||||
|
||||
# Test to see if we can detect default and aux subvolumes correctly
|
||||
btrfsSubvolDefault = makeInstallerTest "btrfsSubvolDefault" {
|
||||
createPartitions = ''
|
||||
$machine->succeed(
|
||||
"sgdisk -Z /dev/vda",
|
||||
"sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
|
||||
"mkswap /dev/vda2 -L swap",
|
||||
"swapon -L swap",
|
||||
"mkfs.btrfs -L root /dev/vda3",
|
||||
"btrfs device scan",
|
||||
"mount LABEL=root /mnt",
|
||||
"btrfs subvol create /mnt/badpath",
|
||||
"btrfs subvol create /mnt/badpath/boot",
|
||||
"btrfs subvol create /mnt/nixos",
|
||||
"btrfs subvol set-default \$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt",
|
||||
"umount /mnt",
|
||||
"mount -o defaults LABEL=root /mnt",
|
||||
"mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism is actually looking up subvolumes
|
||||
"mkdir /mnt/boot",
|
||||
"mount -o defaults,subvol=badpath/boot LABEL=root /mnt/boot",
|
||||
);
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,30 +1,45 @@
|
|||
{ fetchurl, stdenv, flex, bison, gettext, ncurses, libusb, freetype, qemu
|
||||
, devicemapper, EFIsupport ? false }:
|
||||
{ stdenv, fetchurl, autogen, flex, bison, python, autoconf, automake
|
||||
, gettext, ncurses, libusb, freetype, qemu, devicemapper
|
||||
, linuxPackages ? null
|
||||
, efiSupport ? false
|
||||
, zfsSupport ? false
|
||||
}:
|
||||
|
||||
with stdenv.lib;
|
||||
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 {
|
||||
url = "http://unifoundry.com/unifont-5.1.20080820.bdf.gz";
|
||||
sha256 = "0s0qfff6n6282q28nwwblp5x295zd6n71kl43xj40vgvdqxv0fxx";
|
||||
};
|
||||
in (
|
||||
|
||||
in
|
||||
assert efiSupport -> canEfi;
|
||||
assert zfsSupport -> linuxPackages != null && linuxPackages.zfs != null;
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "${prefix}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/grub/grub-${version}.tar.xz";
|
||||
sha256 = "0n64hpmsccvicagvr0c6v0kgp2yw0kgnd3jvsyd26cnwgs7c6kkq";
|
||||
name = "grub-2.02-beta2.tar.xz";
|
||||
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 ]
|
||||
++ stdenv.lib.optional doCheck qemu;
|
||||
++ optional doCheck qemu
|
||||
++ optional zfsSupport linuxPackages.zfs;
|
||||
|
||||
preConfigure =
|
||||
'' 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>.
|
||||
sed -i "tests/util/grub-shell.in" \
|
||||
-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 =
|
||||
'' gunzip < "${unifont_bdf}" > "unifont.bdf"
|
||||
'' sh autogen.sh
|
||||
gunzip < "${unifont_bdf}" > "unifont.bdf"
|
||||
sed -i "configure" \
|
||||
-e "s|/usr/src/unifont.bdf|$PWD/unifont.bdf|g"
|
||||
'';
|
||||
|
||||
patches = [ ./fix-bash-completion.patch ];
|
||||
|
||||
configureFlags =
|
||||
let arch = if stdenv.system == "i686-linux" then "i386"
|
||||
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=" ];
|
||||
configureFlags = optional zfsSupport "--enable-libzfs"
|
||||
++ optionals efiSupport [ "--with-platform=efi" "--target=${efiSystems.${stdenv.system}.target}" "--program-prefix=" ];
|
||||
|
||||
doCheck = false;
|
||||
enableParallelBuilding = true;
|
||||
|
@ -72,7 +79,7 @@ stdenv.mkDerivation rec {
|
|||
paxmark pms $out/sbin/grub-{probe,bios-setup}
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with stdenv.lib; {
|
||||
description = "GNU GRUB, the Grand Unified Boot Loader (2.x beta)";
|
||||
|
||||
longDescription =
|
||||
|
@ -89,11 +96,8 @@ stdenv.mkDerivation rec {
|
|||
|
||||
homepage = http://www.gnu.org/software/grub/;
|
||||
|
||||
license = stdenv.lib.licenses.gpl3Plus;
|
||||
license = licenses.gpl3Plus;
|
||||
|
||||
platforms = if EFIsupport then
|
||||
[ "i686-linux" "x86_64-linux" ]
|
||||
else
|
||||
stdenv.lib.platforms.gnu;
|
||||
platforms = platforms.gnu;
|
||||
};
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1235,9 +1235,11 @@ let
|
|||
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 {
|
||||
inherit (gnome) libsoup;
|
||||
|
|
Loading…
Reference in a new issue