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
|
if cfg.devices == [] then
|
||||||
throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
|
throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
|
||||||
else
|
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}";
|
"${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
|
||||||
|
|
||||||
system.build.grub = grub;
|
system.build.grub = grub;
|
||||||
@ -277,7 +277,11 @@ in
|
|||||||
'') config.boot.loader.grub.extraFiles);
|
'') config.boot.loader.grub.extraFiles);
|
||||||
|
|
||||||
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
|
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::Path;
|
||||||
use File::stat;
|
use File::stat;
|
||||||
use File::Copy;
|
use File::Copy;
|
||||||
|
use File::Slurp;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use Cwd;
|
use Cwd;
|
||||||
|
|
||||||
@ -70,14 +71,48 @@ struct(Fs => {
|
|||||||
type => '$',
|
type => '$',
|
||||||
mount => '$',
|
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 {
|
sub GetFs {
|
||||||
my ($dir) = @_;
|
my ($dir) = @_;
|
||||||
my ($status, @dfOut) = runCommand("df -T $dir");
|
my $bestFs = Fs->new(device => "", type => "", mount => "");
|
||||||
if ($status != 0 || $#dfOut != 1) {
|
foreach my $fs (read_file("/proc/self/mountinfo")) {
|
||||||
die "Failed to retrieve output about $dir from `df`";
|
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 $bestFs;
|
||||||
return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]);
|
|
||||||
}
|
}
|
||||||
struct (Grub => {
|
struct (Grub => {
|
||||||
path => '$',
|
path => '$',
|
||||||
|
@ -35,7 +35,8 @@ let
|
|||||||
|
|
||||||
|
|
||||||
# The configuration to install.
|
# The configuration to install.
|
||||||
makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
|
makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier
|
||||||
|
, readOnly ? true, forceGrubReinstallCount ? 0 }:
|
||||||
pkgs.writeText "configuration.nix" ''
|
pkgs.writeText "configuration.nix" ''
|
||||||
{ config, pkgs, modulesPath, ... }:
|
{ config, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
@ -57,6 +58,10 @@ let
|
|||||||
boot.loader.grub.fsIdentifier = "${grubIdentifier}";
|
boot.loader.grub.fsIdentifier = "${grubIdentifier}";
|
||||||
''}
|
''}
|
||||||
|
|
||||||
|
boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
|
||||||
|
|
||||||
|
${optionalString (!readOnly) "nix.readOnlyStore = false;"}
|
||||||
|
|
||||||
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
@ -198,16 +203,30 @@ let
|
|||||||
$machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/
|
$machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/
|
||||||
or die "nix-env failed";
|
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.
|
# Check whether nixos-rebuild works.
|
||||||
$machine->succeed("nixos-rebuild switch >&2");
|
$machine->succeed("nixos-rebuild switch >&2");
|
||||||
|
|
||||||
# Test nixos-option.
|
# Test nixos-option.
|
||||||
$machine->succeed("nixos-option boot.initrd.kernelModules | grep virtio_console");
|
$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 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 qemu-guest.nix");
|
||||||
|
|
||||||
$machine->shutdown;
|
$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
|
# And just to be sure, check that the machine still boots after
|
||||||
# "nixos-rebuild switch".
|
# "nixos-rebuild switch".
|
||||||
$machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
|
$machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user