nixos/grub: add new implementation of install-grub.pl#317026
nixos/grub: add new implementation of install-grub.pl#317026pluiedev wants to merge 3 commits intoNixOS:masterfrom
install-grub.pl#317026Conversation
6327db4 to
eff29a0
Compare
|
Found a couple of (serious) bugs, fortunately there's a test I can use to catch them... :D |
339c8db to
f8e1766
Compare
|
Ready for review |
|
Should probably post this in the discourse thread of prs ready to review :P |
|
@ofborg test grub grub-ng |
f8e1766 to
c0234b2
Compare
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/4819 |
|
ThinkChaos
left a comment
There was a problem hiding this comment.
Thank you for working on this!
It's what's blocking me from going perl-less. I'll give it a try when I have time, though my setup is not likely to trigger many edge cases.
Generally it seems like we should use eyre a lot more: most code just uses ? without adding any context. That'll lead to errors users can't understand 🙁
IMO, it's fine for a prototype to do that, but the best time for error handling is when you write the code, and the second best is when there's a full review. Otherwise you end up having to go over every thing again and it's very easy to miss some places.
I haven't done a full review but already spent enough time one this now. Here's the comments I wrote for now.
Don't hesitate to tell me I'm wrong or whatever in the comments :)
There was a problem hiding this comment.
Any parent dirs will have unexpected permissions here.
There was a problem hiding this comment.
If create_dir_all creates any parent directories, they won't use the permission we set just below.
I'm not sure what's the best thing to do here.
ac96ddc to
9c7825b
Compare
37e7aea to
98ee2b7
Compare
98ee2b7 to
d6bd08b
Compare
|
(I didn't read the PR but the os prober test passes, great!) |
|
I tested this and the Example entry from this PR: Example entry from old script: I have an impermanence setup. This is my partition setup for reference: |
|
Might have missed a variable reference there when porting? (Note to self: never touch Perl ever again) |
|
So, you could say I'm one of the maintainers of grub: I use it on both EFI and non-EFI systems and I wrote the NixOS tests. As a first impression: can we try to keep it simpler? |
|
Most of the complexity is simply handling the error cases that the Perl code just skips over — more rigorous input parsing, more rigorous subprocess spawning, etc. Rust is in general a much more explicit language than Perl (which is infamous for being so terse that it's impenetrable). As to where to add the extra bootloader entries, it's aptly under src/builder/entries.rs :p |
|
What's necessary for this to move forward? |
|
Mostly to fix some bugs with the code output (see comments above). I'm a bit burnt out from Nix work at the moment but I'll come back to this in due time |
| let line = line?; | ||
|
|
||
| let mut fields = line.split(' '); | ||
| let Some(mount_point) = fields.nth(4).map(Path::new) else { |
There was a problem hiding this comment.
At least the root, mount point, and device fields in /proc/$PID/mountinfo are POSIX paths, meaning they are strings of bytes that do not contain a null byte. Given that the format of/proc/$PID/mountinfo relies on space-separated fields in line-separated records, it escapes several items in path-type fields by replacing them with a \ followed by three octal digits encoding the byte (e.g. a UTF-8 newline is replaced by \012). You'll need to decode these escapes before using the resulting OsString to construct a Path object, if you want to be robust against weird paths. install-grub.pl doesn't do this, but it's buggy overall.
Possibly some of the other fields have this kind of escaping also, not sure.
There was a problem hiding this comment.
Do they always use octal escapes and never other escape formats (e.g. hexadecimal escapes)?
There was a problem hiding this comment.
Took a look at the kernel code generating the mountinfo pseudo-files, and yep. It is also only those three fields which get this escaping/mangling, too, looks like.
| }; | ||
|
|
||
| let Some(ext) = splash_image.extension() else { | ||
| bail!("Splash image has no extension - could not decide which module to load!") |
There was a problem hiding this comment.
Given you're using eyre1 and returning its Result type already, you can avoid these rather verbose Option matches and replace them with this arguably more readable construct, converting the Option to a Result with error context and opening it with the try operator:
let ext = splash_image.extension().ok_or_eyre("Splash image has no extension - could not decide which module to load!")?;1: Also, what's the motivation for using eyre instead of just anyhow?
There was a problem hiding this comment.
I preferred eyre when I first wrote this, but I've since switched to anyhow — haven't gotten to porting this over yet.
| }; | ||
|
|
||
| // Skip the bind-mount for the Nix store. | ||
| if mount_point == store_dir && super_options.any(|s| s == "rw") { |
There was a problem hiding this comment.
I believe it should be checking mount_options rather than super_options here, as the latter is always going to contain rw, for both the bind mount and non-bind mount, at least on the systems I've checked.
That would also explain why mount_options appears to be unused in the Perl version: they accidentally used the wrong variable here. Although I guess that never mattered enough to cause a bug in practice, or at least not one that anyone tracked down...
There was a problem hiding this comment.
Ah, that makes so much sense actually. I was confused by this as well xD
Description of changes
Following in the footsteps of Perlless Activation (#270727) and Perlless
switch-to-configuration(#308801), it's now time for Perllessinstall-grub, which can be enabled by simply settingboot.loader.grub.useInstallNgtotrue.This is still a draft PR for now since I don't use GRUB myself, and I could do with some help from GRUB users who could actually test this :) The GRUB config generation logic seems to work pretty well, though.
Things done
nix.conf? (See Nix manual)sandbox = relaxedsandbox = truenix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)Add a 👍 reaction to pull requests you find important.