tweag / nix-hour

Questions for the weekly Nix Hour
MIT License
77 stars 3 forks source link

Tricky package overrides #69

Open nebulorum opened 5 months ago

nebulorum commented 5 months ago

I'm trying to understand how overriding works. I installed Nixos on a VirtualBox VM, version 7.0.14. However Nixos 23.11has the guest for 7.0.12 which does not work. There has been a recent PR to fix this, but its only on unstable. I've spent a week trying to get this to work, have read tons of Nix Pills, tickets, Reddit, etc and created a discourse thread and I'm still lost.

For what I can understand I can get the main package replaced, but the internal derivations show the old code and hashes. I suspect that my override is somewhat shallow, but don't understand how the options are adding old references. I watched several videos on the Nixos Hour, and I like the approach. Not sure this is the right way to ask here.

infinisil commented 1 month ago

We will focus on this topic this week at Wednesday 16:00 CEST! If anybody has any specific requests, either:

nebulorum commented 3 weeks ago

I'd like to thank for the video and regret not being there live. NixOS feel like these "get good" games, you suffer to pass the first box only to get hit by another challenge. Hard but never boring. Using the video and a lot of trying I managed to build the package in my VM. One boss down! But the next are is harder. This issue name is perfect.

So what have I learned, you can create a simple default.nix to play around the challenge. You can pick channel by using the github commit id. Overlays are nice (I avoided the callPackage or patching. May need the skill. So with the correct package building (had to try several and increase my VM disk) I decided to move the code to my configuration.nix. Unfortunately it did not suffice.

I can clearly see that the override package is there on the REPL, but the moment I activate this option virtualisation.virtualbox.guest.enable = true; the build fails.

My <nixos/nixpkgs> is using commit 205fd4226592cc83fd4c0885a3e4c9c400efabb5 (23.11):

{ config, pkgs, ... }:

  let
        nixpkgs-unstable = fetchTarball {
                url = "https://github.com/NixOS/nixpkgs/archive/61c1d282153dbfcb5fe413c2
28d172d0fe7c2a7e.tar.gz";
                sha256= "00f4chqjy9i5j6prn6qj8n3pnh50wk8inbli54zs8l8jj7jkfzyr";
        };
        unstablePkgs = import nixpkgs-unstable { };

  in  
{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

 nixpkgs.overlays = [
     (final: prev: { 
       virtualbox= unstablePkgs.virtualbox;
     })
   ];

  virtualisation.virtualbox.guest.enable = true;

So when working with default.nix:

$ nix-build -A virtualbox
/nix/store/3y43d17hr23r1r0mzbs4dy6rfg23sis8-virtualbox-7.0.14
$ nix-instantiate -A virtualbox
/nix/store/n26yjgv2mdx1h9pvdkyddfmyyh25r5jr-virtualbox-7.0.14.drv

And in the config it seems the package is correctly overridden:

nix-repl> pkgs.virtualbox                                    
«derivation /nix/store/n26yjgv2mdx1h9pvdkyddfmyyh25r5jr-virtualbox-7.0.14.drv»

But after looking at the modules it seem the guest option loads something else. I even follow Replace Modules from nixos manula, but then I get other issues. Without

nix-repl> :l <nixpkgs/nixos> 
nix-repl> config.environment.systemPackages                   
[ «derivation /nix/store/0xvz1xry5y2lkkd8fp9dzdafmxgdnlvp-VirtualBox-GuestAdditions-7.0.14-6.9.7.drv»

So it seem this is indeed tricker. This systemPackage is only there when ...guest.enable=true. Not sure it's worth keeping this open. But you asked what we don't know, and to me these relation between Nix, Nixpkgs, Modules are not super clear despite reading a ton of thing. Fell me like the monad curse, once you get it, you can't explain it to others.

nebulorum commented 3 weeks ago

Still looking at this a bit, seem the definition gets done top-level/linux-kernels.nix.

nebulorum commented 3 weeks ago

I kind of feel dumb, after a lot of search this solved the problem:

  nixpkgs.overlays = [
     (final: prev: { 
       virtualbox= unstablePkgs.virtualbox;
       kernelPackages = unstablePkgs.kernelPackages;
     })
   ];

With this I can see the version are correct. But if I understood, I'm actually replacing all kernelPackages with the ones on the unstable branch. I wonder if there is a way to replace only the one package.