Why this override is not working?

I’m having a problem with k3s not being able to find iscsiadm when mounting a CSI PVC and, before submitting a patch to upstream nixpkgs, I want to test wether that’s actually a real fix.

To do so, I created an overridden package like this, to add some more packages to the binary $PATH:

(import (builtins.fetchTree {
    narHash = "sha256-ePnxG4hacRd6oZMk+YeCSYMNUnHCe+qPLI0/+VaTu48=";
    owner = "NixOS";
    repo = "nixpkgs";
    rev = "e43cf1748462c81202a32b26294e9f8eefcc3462";
    type = "github";
  }) {
    overlays = [
      (
        final: prev: {
          k3s = prev.k3s.overrideAttrs (finalAttrs: prevAttrs: {
            k3sRuntimeDeps =
              prevAttrs.k3sRuntimeDeps
              ++ [
                final.openiscsi
              ];
          });
        }
      )
    ];
  })
.k3s

I saved that to k3s.nix and ran this:

$ grep iscsi $(nix-build k3s.nix)/bin/k3s || echo "override not working :("
override not working :(

Could anybody explain to me why this override is not working? And how to fix it? Thanks!

overrideAttrs takes either a set, or a unary (single argument) function.

You want

rev.k3s.overrideAttrs (prevAttrs: {

Thanks. I tried, but that just produces the same derivation, with the same problem. According to the docs, overrideAttrs supports both signatures.

This happens because k3sRuntimeDeps are referenced via rec and overriding an attribute of a recursive set doesn’t propagate to its recursive references.

You’d either need to wrap k3s again or change the k3s derivation to make use of stdenv.mkDerivation: overlay style overridable recursive attributes by roberth · Pull Request #119942 · NixOS/nixpkgs · GitHub but I don’t know if buildGoModule supports that yet.

OK that definitely seems to be the problem, but it’s causing buffer overflow in my mind. :dizzy_face:

How would I supposedly make use of that PR?

The proper fix would likely be to split the package into an unwrapped and wrapped variant. Then just target the wrapped version of the package to cheaply modify what’s available to it at runtime without incurring the cost of rebuilding k3s each time.

Haha ^^

You’ll get used to it :slight_smile:

You make use of it by replacing rec statement in mkDerivations with a unary lambdas and use the lambda’s parameter for recursive references.

For example:

mkDerivation rec {
  foo = "bar";
  baz = [ foo ];
}

mkDerivation (finalAttrs: {
  foo = "bar";
  baz = finalAttrs.foo;
})

buildGoModule might not support that style yet though, it’s quite new.

Separating out the wrapper would also be great. It’s such a common pattern, perhaps we should have a standardised way of handling it.

1 Like