Pin unfree package in module

Hello there,

I’m writing a NixOS module which defines a package option. I’d like this option to use a given package from a specific nixpkgs commit by default.

I can’t use the pkgs attribute since this will come from the user nixpkgs version. Neither can I rely on Flake inputs as the module should support Flakes and non-Flakes setup.

In the end I made it work but the package does not come from the cache and is built instead, which takes quite some time. I’d like to avoid this if possible, but is it?

Here is a (shortened) working version:

{ pkgs, ... }:

let
  nixpkgsCommit = "1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679";
  nixpkgs = pkgs.fetchFromGitHub {
    owner = "nixos";
    repo = "nixpkgs";
    rev = nixpkgsCommit;
    hash = "sha256-MiJ11L7w18S2G5ftcoYtcrrS0JFqBaj9d5rwJFpC5Wk=";
  };
  mypkg =
    (import nixpkgs {
      system = pkgs.system;
      config.allowUnfree = true;
    }).mypkg;
in
{
  options.programs.mypkg = {
    package = lib.mkOption {
      type = lib.types.package;
      default = mypkg;
      defaultText = "pkgs.mypkg";
      example = "pkgs.unstable.mypkg";
      description = ''
        The mypkg package to use.
      '';
    };
  };
}

Plus, I think this import is evaluating the whole nixpkgs set, which is not that great. Wouldn’t callPackage be better? Something like that:

mypkg = pkgs.callPackage "${nixpkgs}/pkgs/<path-to-package>.nix" { };

But by using callPackage, I think it will be impossible to benefit from any caching source. Am I right?

Thanks for any help :slight_smile:

The nixpkgs you’re using for pinning doesn’t match a cached snapshot that has been published via https://channels.nixos.org/, so building from scratch is expected.
You can find a list of recent hashes to choose from here: flake-programs-sqlite/sources.json at afd1949edb9a0f2433c3d05a4401b95add9620aa · wamserma/flake-programs-sqlite · GitHub

edit: you should also have a look at https://www.nixhub.io/

Yes, callPackage is more suitable here since it will use the expression to build on top of pkgs instead of building an entirely new pkgs for dependencies.

But note that if other stuff on your system depends on your custom version that won’t register! In that case you’d need to add your custom element as an overlay to pkgs instead, which will require rebuilding the dependents.

1 Like

That’s what I suspected, but then I looked at Hydra builds and used the reported commit (b9d43b3fe5152d1dc5783a2ba865b2a03388b741), with the same result.

The initial commit I was using was coming from nixhub.


At one point in time, I’m pretty sure the package build has been cached. I just don’t know how to find it.

That’s my understanding too, but then if I use callPackage, I’m pretty sure no caching will be possible at all and the package will have to be built on first module install.

1 Like

OTOH this may lead to a build failure if the package relies on specific versions of its dependencies.

1 Like

Well, what happens when you do

NIXPKGS_ALLOW_UNFREE=1 nix shell --impure github:nixos/nixpkgs/1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679#mypkg

Does it build or use a cached version? If it builds, it is very likely that the specific package you are trying to use is not cached. (If you try e.g. with hello, it pulls from the cache.)

edit: an example for a package that is not cached:

NIXPKGS_ALLOW_UNFREE=1 nix shell --impure github:nixos/nixpkgs/1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679#zerotierone
1 Like

Didn’t think of using nix shell, thanks for the reminder!

Sadly, both commits I found are building the package.


I’ll try with other commits too, but this process of fail and retry seems overly complex :slightly_frowning_face:


EDIT: in fact, the commit from Hydra failed the evaluation of the package, since it is unfree. Therefore the package cannot be in cache and also I guess that means all Hydra evaluations of this package should fail and not be in cache.

Apparently, no unfree package is cached by cache.nixos.org (hence including the one I’m having trouble with).

This is somehow stated in the nixpkgs manual:

Unfree package that cannot be redistributed. You can build it yourself, but you cannot redistribute the output of the derivation. Thus it cannot be included in the Nixpkgs channel.

If I understand this sentence correctly, since such packages cannot be redistributed, they cannot be cached either.

I resorted to creating my own Cachix cache to cache the output of the derivations for this package. I just don’t know what are the legal implications of doing that, since I’m planning on making this cache public.

Thanks for the help anyway!