Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/grub: light grub by default, 150MB closure size reduction #42793

Closed
wants to merge 2 commits into from

Conversation

infinisil
Copy link
Member

@infinisil infinisil commented Jun 29, 2018

Since the default grub2 package has ZFS enabled and this was the one
that got used for NixOS and it's not being overridden, every NixOS user
gets the ZFS dependencies, even when they're not using ZFS at all.

This PR effectively removes 150MB from the system closure on a default minimal setup. Bringing the closure size for an empty configuration.nix from 1049MB to 903MB (tested with nix path-info -S of a nix-build nixos -A config.system.build.toplevel).

Can it break anything?

This switches grub2 for grub2_minimal for NixOS. Since the latter is being defined like this

grub2_light = grub2.override {
zfsSupport = false;
};

and it's being overridden with zfsSupport = true when a ZFS filesystem is being used

else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }

(grub2_light for this PR), this can only break systems who relied on ZFS support using NixOS' non-fixed grub derivation propagated through here
system.build.grub = grub;
# Common attribute for boot loaders so only one of them can be
# set at once.
system.boot.loader.id = "grub";
environment.systemPackages = optional (grub != null) grub;

Ping @aszlig @symphorien

Things done

I ran the NixOS test installer.zfsroot successfully. Also tried to run installer.simpleUefiGrub, but it failed for some unrelated networking issue.

  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

Since the default grub2 package has ZFS enabled and this was the one
that got used for NixOS and it's not being overridden, every NixOS user
gets the ZFS dependencies, even when they're not using ZFS at all.
@infinisil infinisil changed the title nixos/grub: light grub by default nixos/grub: light grub by default, 150MB closure size reduction Jun 29, 2018
@aszlig
Copy link
Member

aszlig commented Jun 30, 2018

@infinisil: The reason the installer tests now fail is because it's still referring to the previous grub derivation. It's probably a good idea to use config.system.build.grub instead there.

@infinisil
Copy link
Member Author

@aszlig Well spotted, I'll change that. Which test didn't succeed for you though? The networking issue I mentioned probably doesn't have anything to do with this

@aszlig
Copy link
Member

aszlig commented Jun 30, 2018

@infinisil: I didn't run any tests, but it seems you did:

I ran the NixOS test installer.zfsroot successfully. Also tried to run installer.simpleUefiGrub, but it failed for some unrelated networking issue.

We don't have networking access within the test VMs, so with the change
to default to grub2_light we now no longer simply add pkgs.grub2 and
pkgs.grub2_efi to the closure, because the grub NixOS module overrides
it like this (simplified):

  grubReal = pkgs.grub2_light.override { zfsSupport = ...; };
  grubEfi = grubReal.override { efiSupport = ...; };

So if we'd simply use [ pkgs.grub2_light pkgs.grub2_efi ] we would end
up with the wrong derivation in EFI tests because pkgs.grub2_efi is
actually an override of grub2 *with* ZFS but the actual installer test
would use grub2 *without* ZFS and thus will try to rebuild grub.

Tested against all the installer NixOS tests and all of them still
succeed except the grub1 test (which already failed prior to the
previous change).

Signed-off-by: aszlig <aszlig@nix.build>
@aszlig
Copy link
Member

aszlig commented Jun 30, 2018

@infinisil: Test fix added.

@infinisil
Copy link
Member Author

Ah I see now, thanks a lot @aszlig

@@ -9,12 +9,12 @@ let
efi = config.boot.loader.efi;

realGrub = if cfg.version == 1 then pkgs.grub
else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
else if cfg.zfsSupport then pkgs.grub2_light.override { zfsSupport = true; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems we should just be using regular grub in this case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

especially since:

2826  grub2_light = grub2.override {
2827    zfsSupport = false;
2828  };

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grub2 = grub2_full;
grub2_full = callPackage ../tools/misc/grub/2.0x.nix { };
grub2_efi = grub2.override {
efiSupport = true;
};
grub2_light = grub2.override {
zfsSupport = false;
};

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default grub has ZFS support enabled

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I get what you mean, overriding light with zfs = true is the same as the normal one, gotcha

Copy link
Member

@grahamc grahamc Jul 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and that is what we want here:

+ else if cfg.zfsSupport then pkgs.grub2_light.override { zfsSupport = true; }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the grub2_light variant should be the one used by the NixOS module, so that only the relevant features are enabled, because permuting all the features that might be available through the module as package definitions in all-packages.nix would be even more overkill.

Besides (and unrelated) these grub2.overrides should really be self.grub2.override so they can be overridden via overlays.

system.extraDependencies = let
# This is because the EFI version of grub overrides the base
# version of GRUB 2, so we can't just use pkgs.grub2_efi here.
grub2 = pkgs.grub2_light.override { zfsSupport = grubUseZfs; };
Copy link
Member

@grahamc grahamc Jul 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably use if grubUseZfs then pkgs.grub2 else pkgs.grub2_light, and move the comment about the EFI stuff to below this line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grahamc: It's already a bit obscure that way, doing if grubUseZfs then pkgs.grub2 else pkgs.grub2_light IMHO makes it worse because then you have to look at the actual definition in all-packages.nix to check which flags are enabled (which itself again uses .override).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my perspective is the _light variant becomes meaningless and overriding an overridden package to disable the override seems really weird.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Ideally the grub2 package should be the main package and grub2_full should be an override of grub2_light with all that stuff enabled. In the line here pkgs.grub2.override would also work, because grub2_full is just grub2_light with ZFS support.

# curl's tarball, we see what it's trying to download
curl
] ++ optional (bootLoader == "grub" && grubVersion == 1) pkgs.grub
++ optionals (bootLoader == "grub" && grubVersion == 2) [ grub2 grub2Efi ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit like much of this diff is moving code just to make the formatting slightly nicer. That can make it much more difficult to read the diff, for a minor improvement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is git diff -w which should make it way easier to follow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also GitHub has an option Hide whitespace changes, which does something similar)

@grahamc
Copy link
Member

grahamc commented Jul 7, 2018

Aside from some very minor changes, lgtm.

@infinisil
Copy link
Member Author

So, should I mess around some more to try get this to look a bit better? Not sure if worth the effort even :)

Copy link
Member

@matthewbauer matthewbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a fan of using special cased things like this. I know they exist in all-packages.nix , but IMO they shouldn't be there.

The issue with something like this is that it will break overlays settings grub2. Previously you could make an overlay with something like:

self: super: {
  grub2 = super.grub2.override {
    zfsSupport = true;
    xenSupport = false;
    efiSupport = true;
  };
}

If you think we should use the grub2 light by default, you should make grub2 in all-packages.nix point to it. Doing it this way is just kind of confusing.

@infinisil
Copy link
Member Author

While this would be very nice, I really don't feel like doing this now. Maybe I'll do it later, but until then I'm closing this. Somebody else feel free to do this.

@infinisil infinisil closed this Mar 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants