Accessing `/sys` in derivations

I came up with idea of implementing a grub theme which would use vendor logo. But I experienced i think all possible problems

I knew i would need to have impure derivation, but here are 2 problems:

  1. error: pure derivation '***-grub-config.xml' depends on impure derivation ***-grub-theme. Worked around with IFD (it won’t complain about impure dependency anymore)

  2. /sys is not accessible, even in impure derivation

What can I do here? I wouldn’t like to disable sandbox, or use extraInstallCommand

Nothing, dont do that. You’ll have to pull the vendor logo outside if a nix build. You cant do it during.

Well, it’s not going to work across different machines or anything, but you could do something like this for the machine on which you’re doing evaluation:

{
  runCommand,
}:
runCommand "vendor-logo.bmp" {
  # Replace this with the "got:" hash when you get an error.
  outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
} ''
  cp ${/sys/firmware/acpi/bgrt/image} $out
''

How about vendoring the logos you need for different machines into your configuration/package and then selecting which one to use based on the hostname?

3 Likes

Dont do that, that’ll break in surprising ways.

I never said it was a good idea!

2 Likes

This fails in pure evaluation, so when using flakes. And I am pretty sure in restricted eval it would also fail.

The OP opened with saying they were expecting to run things in impure mode. I’m just giving the people what they want, man.

This is a dumb trick that goes against the spirit of Nix, yes, but it’s not a tenth of the footgun that nix-ld is; now there’s a hack I won’t touch with a ten-foot pole. Where are all the don’t-do-thatters every time someone asks for help with that?

They were aware of needing impure drv, which is different from impure evaluation.

1 Like

Well spotted, I concede that point.

:raised_hand:

I guess the better question is what are you doing with this image that requires accessing /sys at buildtime? Wouldn’t it be easier to copy the file over during activation or such? Not ideal but better than this…

2 Likes

I was promised that this absolute-path is replaceable by another trick (by the way, you don’t even need fixed-output here)

Nix path:

{ runCommand }:
runCommand "vendor-logo.bmp" {} ''
  cp "${<sys-firmware-acpi/bgrt/image>}" "$out"
''

Invocation:

nix-build -I sys-firmware-acpi=/sys/firmware/acpi …
nix-build --pure \
  -I nixpkgs=/home/repos/nixpkgs \
  -I sys-firmware-acpi=/sys/firmware/acpi \
  -E 'let inherit (import <nixpkgs> {}) 
          runCommand; 
       in 
         runCommand "vendor-logo.bmp" {} 
           "cp ${<sys-firmware-acpi/bgrt/image>} $out"'

works for me.

The file is copied in eval-time, pure evaluation and full build sandboxing is preserved.

3 Likes

This is my current approach, I’m currently trying to get rid of it because I have to configure theme in 2 different attributes which is kind of confusing. My goal is to build theme entirely in grub.theme

Also, the reason I want to keep it in single derivation is PGP signatures. I used Secure Boot, which requires to sign every file used by grub. Now, files are signed in extraInstallCommand on every rebuild which leads to much longer build times, and wasting my SSD’s P/E cycles.

Upd: I forgot to mention that nix also throws error cannot operate on output ‘out’ of the unbuilt derivation, and this confuses me the most, why is it unbuilt?