Commit 65cbbc75 authored by Thomas Strobel's avatar Thomas Strobel
Browse files

grub installation: integrate trustedGRUB + fix broken equality check

parent d7869f46
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ let

  realGrub = if cfg.version == 1 then pkgs.grub
    else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
    else if cfg.enableTrustedboot then pkgs.trustedGrub
           else pkgs.grub2;

  grub =
@@ -37,6 +38,7 @@ let
      grub = f grub;
      grubTarget = f (grub.grubTarget or "");
      shell = "${pkgs.stdenv.shell}";
      fullName = (builtins.parseDrvName realGrub.name).name;
      fullVersion = (builtins.parseDrvName realGrub.name).version;
      grubEfi = f grubEfi;
      grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
@@ -367,6 +369,15 @@ in
        '';
      };

      enableTrustedboot = mkOption {
        default = false;
        type = types.bool;
        description = ''
          Enable trusted boot. Grub will measure all critical components during
          the boot process to offer TCG (TPM) support.
        '';
      };

    };

  };
@@ -429,6 +440,22 @@ in
          assertion = all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters);
          message = "You cannot have duplicated devices in mirroredBoots";
        }
        {
          assertion = !cfg.enableTrustedboot || cfg.version == 2;
          message = "Trusted GRUB is only available for GRUB 2";
        }
        {
          assertion = !cfg.efiSupport || !cfg.enableTrustedboot;
          message = "Trusted GRUB does not have EFI support";
        }
        {
          assertion = !cfg.zfsSupport || !cfg.enableTrustedboot;
          message = "Trusted GRUB does not have ZFS support";
        }
        {
          assertion = !cfg.enableTrustedboot;
          message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless.";
        }
      ] ++ flip concatMap cfg.mirroredBoots (args: [
        {
          assertion = args.devices != [ ];
+11 −6
Original line number Diff line number Diff line
@@ -433,15 +433,18 @@ foreach my $fn (glob "$bootPath/kernels/*") {
#

struct(GrubState => {
    name => '$',
    version => '$',
    efi => '$',
    devices => '$',
    efiMountPoint => '$',
});
sub readGrubState {
    my $defaultGrubState = GrubState->new(version => "", efi => "", devices => "", efiMountPoint => "" );
    my $defaultGrubState = GrubState->new(name => "", version => "", efi => "", devices => "", efiMountPoint => "" );
    open FILE, "<$bootPath/grub/state" or return $defaultGrubState;
    local $/ = "\n";
    my $name = <FILE>;
    chomp($name);
    my $version = <FILE>;
    chomp($version);
    my $efi = <FILE>;
@@ -451,7 +454,7 @@ sub readGrubState {
    my $efiMountPoint = <FILE>;
    chomp($efiMountPoint);
    close FILE;
    my $grubState = GrubState->new(version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
    my $grubState = GrubState->new(name => $name, version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
    return $grubState
}

@@ -497,10 +500,11 @@ my $prevGrubState = readGrubState();
my @prevDeviceTargets = split/:/, $prevGrubState->devices;

my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference() );
my $versionDiffer = (get("fullVersion") eq \$prevGrubState->version);
my $efiDiffer = ($efiTarget eq \$prevGrubState->efi);
my $efiMountPointDiffer = ($efiSysMountPoint eq \$prevGrubState->efiMountPoint);
my $requireNewInstall = $devicesDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");
my $nameDiffer = !(get("fullName") eq $prevGrubState->name);
my $versionDiffer = !(get("fullVersion") eq $prevGrubState->version);
my $efiDiffer = !($efiTarget eq $prevGrubState->efi);
my $efiMountPointDiffer = !($efiSysMountPoint eq $prevGrubState->efiMountPoint);
my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");

# install a symlink so that grub can detect the boot drive when set
# as the root directory
@@ -543,6 +547,7 @@ if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both"))
# update GRUB state file
if ($requireNewInstall != 0) {
    open FILE, ">$bootPath/grub/state" or die "cannot create $bootPath/grub/state: $!\n";
    print FILE get("fullName"), "\n" or die;
    print FILE get("fullVersion"), "\n" or die;
    print FILE $efiTarget, "\n" or die;
    print FILE join( ":", @deviceTargets ), "\n" or die;