Merge pull request #3961 from wkennington/master.grub
nixos/install-grub: Read correct mountpoints
This commit is contained in:
commit
53fa517176
@ -260,7 +260,7 @@ in
|
||||
if cfg.devices == [] then
|
||||
throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
|
||||
else
|
||||
"PERL5LIB=${makePerlPath [ pkgs.perlPackages.XMLLibXML pkgs.perlPackages.XMLSAX ]} " +
|
||||
"PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ])} " +
|
||||
"${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
|
||||
|
||||
system.build.grub = grub;
|
||||
@ -277,7 +277,11 @@ in
|
||||
'') config.boot.loader.grub.extraFiles);
|
||||
|
||||
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
|
||||
message = "Only grub version 2 provides zfs support";}];
|
||||
message = "Only grub version 2 provides zfs support";}]
|
||||
++ flip map cfg.devices (dev: {
|
||||
assertion = hasPrefix "/" dev;
|
||||
message = "Grub devices must be absolute paths, not ${dev}";
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
@ -6,6 +6,7 @@ use File::Basename;
|
||||
use File::Path;
|
||||
use File::stat;
|
||||
use File::Copy;
|
||||
use File::Slurp;
|
||||
use POSIX;
|
||||
use Cwd;
|
||||
|
||||
@ -70,14 +71,48 @@ struct(Fs => {
|
||||
type => '$',
|
||||
mount => '$',
|
||||
});
|
||||
sub PathInMount {
|
||||
my ($path, $mount) = @_;
|
||||
my @splitMount = split /\//, $mount;
|
||||
my @splitPath = split /\//, $path;
|
||||
if ($#splitPath < $#splitMount) {
|
||||
return 0;
|
||||
}
|
||||
for (my $i = 0; $i <= $#splitMount; $i++) {
|
||||
if ($splitMount[$i] ne $splitPath[$i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
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 $bestFs = Fs->new(device => "", type => "", mount => "");
|
||||
foreach my $fs (read_file("/proc/self/mountinfo")) {
|
||||
chomp $fs;
|
||||
my @fields = split / /, $fs;
|
||||
my $mountPoint = $fields[4];
|
||||
next unless -d $mountPoint;
|
||||
my @mountOptions = split /,/, $fields[5];
|
||||
|
||||
# Skip the optional fields.
|
||||
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
|
||||
my $fsType = $fields[$n];
|
||||
my $device = $fields[$n + 1];
|
||||
my @superOptions = split /,/, $fields[$n + 2];
|
||||
|
||||
# Skip the read-only bind-mount on /nix/store.
|
||||
next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
|
||||
|
||||
# Ensure this matches the intended directory
|
||||
next unless PathInMount($dir, $mountPoint);
|
||||
|
||||
# Is it better than our current match?
|
||||
if (length($mountPoint) > length($bestFs->mount)) {
|
||||
$bestFs = Fs->new(device => $device, type => $fsType, mount => $mountPoint);
|
||||
}
|
||||
}
|
||||
my @boot = split(/[ \n\t]+/, $dfOut[1]);
|
||||
return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]);
|
||||
return $bestFs;
|
||||
}
|
||||
struct (Grub => {
|
||||
path => '$',
|
||||
|
@ -35,7 +35,8 @@ let
|
||||
|
||||
|
||||
# The configuration to install.
|
||||
makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
|
||||
makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier
|
||||
, readOnly ? true, forceGrubReinstallCount ? 0 }:
|
||||
pkgs.writeText "configuration.nix" ''
|
||||
{ config, pkgs, modulesPath, ... }:
|
||||
|
||||
@ -57,6 +58,10 @@ let
|
||||
boot.loader.grub.fsIdentifier = "${grubIdentifier}";
|
||||
''}
|
||||
|
||||
boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
|
||||
|
||||
${optionalString (!readOnly) "nix.readOnlyStore = false;"}
|
||||
|
||||
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
||||
}
|
||||
'';
|
||||
@ -198,16 +203,30 @@ let
|
||||
$machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/
|
||||
or die "nix-env failed";
|
||||
|
||||
# We need to a writable nix-store on next boot
|
||||
$machine->copyFileFromHost(
|
||||
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 1; } }",
|
||||
"/etc/nixos/configuration.nix");
|
||||
|
||||
# Check whether nixos-rebuild works.
|
||||
$machine->succeed("nixos-rebuild switch >&2");
|
||||
|
||||
# Test nixos-option.
|
||||
$machine->succeed("nixos-option boot.initrd.kernelModules | grep virtio_console");
|
||||
$machine->succeed("nixos-option -d boot.initrd.kernelModules | grep 'List of modules'");
|
||||
$machine->succeed("nixos-option -l boot.initrd.kernelModules | grep qemu-guest.nix");
|
||||
$machine->succeed("nixos-option boot.initrd.kernelModules | grep 'List of modules'");
|
||||
$machine->succeed("nixos-option boot.initrd.kernelModules | grep qemu-guest.nix");
|
||||
|
||||
$machine->shutdown;
|
||||
|
||||
# Check whether a writable store build works
|
||||
$machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
|
||||
$machine->waitForUnit("multi-user.target");
|
||||
$machine->copyFileFromHost(
|
||||
"${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 2; } }",
|
||||
"/etc/nixos/configuration.nix");
|
||||
$machine->succeed("nixos-rebuild boot >&2");
|
||||
$machine->shutdown;
|
||||
|
||||
# And just to be sure, check that the machine still boots after
|
||||
# "nixos-rebuild switch".
|
||||
$machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
|
||||
|
Loading…
Reference in New Issue
Block a user