Too dumb to use allowUnfreePredicate

Hello everyone!

(Sorry in advance for the long post, maybe it’s enough to read the TL;DR.)

In a reply to one of my previous posts @TLATER recommended to change the way I handle my pkgs configuration in my flake.nix and also suggested to use allowUnfreePredicate (mentioned in the Manual and the Wiki) for packages that need it.

Today I tried to implement the suggestions but failed.

TL;DR

My issue boils down to: where and how do I use allowUnfreePredicate precisely? For example, one of the unfree applications that I use is installed with an option programs.<app_name>.enable = true and another one is installed as part of the users.<username>.packages = [ ] list in a separate file called users.nix.
By trial and error, I know just doing the following doesn’t work: (EDIT: It works! It turns out the mistake was something else. Read the rest of this thread if your’re interested.)

nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
  "app_1"
];
programs.app_1.enable = true;

What am I doing wrong?

MORE IN-DEPTH EXPLANATION

So far, my flake.nix looked like this:

{
  description = "NixOS System Flake";
  
  outputs = inputs@{ self, nixpkgs, nixpkgs-unstable, nixos-hardware, ... }:
  let
    /* ---- GLOBAL SETTINGS ---- */
    system = "x86_64-linux";
    desktop = "gnome";
    
    /* ---- PKGS ---- */
    pkgs = import nixpkgs {
      inherit system;
      config = { allowUnfree = true; };
    };
    pkgs-unstable = import nixpkgs-unstable {
      inherit system;
      config = { allowUnfree = true; };
    };
  in {

    nixosConfigurations = {
      "Moon-Presence" = nixpkgs.lib.nixosSystem {
        inherit system;
        specialArgs = { inherit desktop pkgs pkgs-unstable; };
        modules = [
          ./hosts/Moon-Presence/configuration.nix
          nixos-hardware.nixosModules.dell-xps-13-9310
        ];
      };
      "Oceiros" = nixpkgs.lib.nixosSystem {
        inherit system;
        specialArgs = { inherit desktop pkgs pkgs-unstable; };
        modules = [
          ./hosts/Oceiros/configuration.nix
        ];
      };
    };
  };

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixos-hardware.url = "github:NixOS/nixos-hardware/master";
  };
}

The configuration.nix in turn imports several other nix files, specific to the host machine.

Now, I changed the PKGS section in the let binding to:

pkgs = nixpkgs.legacyPackages.${system};
pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};

Of course, when I try to rebuild the system with this change Nix complains about the unfree license of some programs and refuses to continue.

Now the question is, how do I pass allowUnfreePredicate correctly to these programs?

Here are two examples: One of the applications is 1Password, which is included in my configuration like this

programs._1password-gui = {
  enable = true;
  polkitPolicyOwners = [ "<username>" ];
  package = pkgs-unstable._1password-gui;
};

Another application is Spotify, which is declared in a separate users.nix file that gets imported to configuration.nix and which contains the line:

users.users.<username>.packages = with pkgs; [ spotify ];

In both cases, just prepending

nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
  "1password"
  "spotify"
];

doesn’t work. So, what do I need to do here? As always, thanks a lot for your help! (And sorry if I missed any obvious solutions.)

How about:

Then the package names should be guaranteed to be correct. Note that if these packages in turn depend on any unfree packages, you will also have to whitelist those.

If that still doesn’t work, mind sharing the exact error?

1 Like

Thanks for your super quick reply! I’ll give it a try. Where do I need to put it? In my configuration.nix or the files that contain programs._1password-gui.enable and spotify respectively?

Edit: The error I got during my previous attempts was just the regular notification about “unfree licenses”.

So, I edited my system-apps.nix file which gets imported to configuration.nix:

{ config, lib, pkgs, pkgs-unstable, ... }:

{
  /* ---- SYSTEM-WIDE APPLICATIONS ---- */
  environment.systemPackages = with pkgs; [
    gh
    gnupg
    neofetch
    lynis
    ffmpeg
    vlc    
    lf    
    distrobox   
    libreoffice-fresh
  ] ++ (with pkgs-unstable; [
    # add packages from nixpkgs-unstable
  ]);

  /* ---- PROGRAMS WITH SPECIAL OPTIONS ---- */
  nixpkgs.config.allowUnfreePredicate = let
  whitelist = map lib.getName [
    config.programs._1password-gui.package
    pkgs.spotify
  ];
  in pkg: builtins.elem (lib.getName pkg) whitelist;
  
  programs = {
    # ...
    _1password-gui = {
      enable = true;
      polkitPolicyOwners = [ "florian" ];
      package = pkgs._1password-gui; # or pkgs-unstable
    };
    # ...
  };
  # Enable udev rules for Steam hardware such as the Steam Controller 
  hardware.steam-hardware.enable = true;

  /* ---- VIRTUALISATION ---- */
  virtualisation.waydroid.enable = true;
  virtualisation.podman.enable = true;
}

When I try to rebuild I get:

$ sudo nixos-rebuild boot --flake .#Moon-Presence
Legen Sie Ihren Finger auf den Fingerabdruckleser
building the system configuration...
error:
       … while calling the 'head' builtin

         at /nix/store/pfi7ix6c1vma70s9bbz94rj0555z5lwk-source/lib/attrsets.nix:922:11:

          921|         || pred here (elemAt values 1) (head values) then
          922|           head values
             |           ^
          923|         else

       … while evaluating the attribute 'value'

         at /nix/store/pfi7ix6c1vma70s9bbz94rj0555z5lwk-source/lib/modules.nix:807:9:

          806|     in warnDeprecation opt //
          807|       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          808|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: Package ‘1password-8.10.24’ in /nix/store/pfi7ix6c1vma70s9bbz94rj0555z5lwk-source/pkgs/applications/misc/1password-gui/default.nix:58 has an unfree license (‘unfree’), refusing to evaluate.

       a) To temporarily allow unfree packages, you can use an environment variable
          for a single invocation of the nix tools.

            $ export NIXPKGS_ALLOW_UNFREE=1

          Note: When using `nix shell`, `nix build`, `nix develop`, etc with a flake,
                then pass `--impure` in order to allow use of environment variables.

       b) For `nixos-rebuild` you can set
         { nixpkgs.config.allowUnfree = true; }
       in configuration.nix to override this.

       Alternatively you can configure a predicate to allow specific packages:
         { nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
             "1password"
           ];
         }

       c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
         { allowUnfree = true; }
       to ~/.config/nixpkgs/config.nix.

Hm, this looks completely correct to me. The error even tells you that this is the correct way to do it:

Are you sure your configuration is actually set? Are you taking that package from unstable?

1 Like

I copy-pasted the contents of the file system-apps.nix and just edited out some of the programs that are irrelevant here. 1Password should be pulled from stable:

package = pkgs._1password-gui;

I think there is currently no way to allow unfree with flake in pure evaluation mode, unless you import nixpkgs { config = ... }. This is why this exists:

1 Like

No, there definitely is, I do it in my config too: https://github.com/TLATER/dotfiles/blob/e2559cf35e4556b5be430b010952d231d292f974/nixos-config/yui/default.nix#L24

nixpkgs.config will configure the pkgs instance used for the system config, feel free to follow the module eval to see how that works.

nixpkgs-unfree solves this problem for when you do not have nixpkgs config to fix it for you.

1 Like

So, after all, should I keep it like it was before?

let
  /* ---- PKGS ---- */
  pkgs = import nixpkgs {
    inherit system;
    config = { allowUnfree = true; };
  };
  pkgs-unstable = import nixpkgs-unstable {
    inherit system;
    config = { allowUnfree = true; };
  };
in {

Oh interesting! Then I don’t know what is happening…

1 Like

I’m even more puzzled now…

Yep, me too. Maybe for the sake of argument try:

nixpkgs.config.allowUnfree = true;

Just to confirm the nixpkgs configuration is actually working.

1 Like

Purely speculative: try not passing pkgs in specialArgs and see if unfree packages under pkgs work? I am guessing that the passed pkgs here shadows the module configuration. If this works, then it solves the problem of pkgs but not pkgs-unstable though…

3 Likes

Edited system-apps.nix to include the line nixpkgs.config.allowUnfree = true; like this:

{ config, lib, pkgs, pkgs-unstable, ... }:

{
  /* ---- SYSTEM-WIDE APPLICATIONS ---- */
  environment.systemPackages = with pkgs; [
    gh
    gnupg
    neofetch
    lynis
    ffmpeg
    vlc    
    lf    
    distrobox   
    libreoffice-fresh
  ] ++ (with pkgs-unstable; [
    # add packages from nixpkgs-unstable
  ]);

  /* ---- PROGRAMS WITH SPECIAL OPTIONS ---- */
  nixpkgs.config.allowUnfree = true;
  programs = {
    git = {
      enable = true;
      config = {
        init = {
	  defaultBranch = "main";
	};
      };
    };
    fish = {
      enable = true;
      interactiveShellInit = ''
        set -U fish_greeting # disable greeting
      '';
    };
    kdeconnect = {
      enable = true;
      package = pkgs.gnomeExtensions.gsconnect;
    };
    neovim = {
      enable = true;
      defaultEditor = true;
      configure = {
        customRC = ''
          set relativenumber
        '';
      };
    };
    dconf.enable = true;
    _1password-gui = {
      enable = true;
      polkitPolicyOwners = [ "florian" ];
      package = pkgs._1password-gui; # or pkgs-unstable
    };
    ausweisapp = {
      enable = true;
      openFirewall = true;
    };
    steam.enable = true;
  };
  # Enable udev rules for Steam hardware such as the Steam Controller 
  hardware.steam-hardware.enable = true;

  /* ---- VIRTUALISATION ---- */
  virtualisation.waydroid.enable = true;
  virtualisation.podman.enable = true;
}

And again I get the error

error: Package ‘1password-8.10.24’ in /nix/store/pfi7ix6c1vma70s9bbz94rj0555z5lwk-source/pkgs/applications/misc/1password-gui/default.nix:58 has an unfree license (‘unfree’), refusing to evaluate

I’m lost…

Yep, that will probably be it, missed the fact that you’re putting pkgs in specialArgs.

pkgs-unstable will need to come from nixpkgs-unfree, indeed, as I mentioned in the previous post.

1 Like

That seems to be it! Thanks! Just tried to rebuild with specialArgs = { inherit desktop pkgs-unstable; }; and nixpkgs.config.allowUnfree = true; and it worked. Will investigate allowUnfreePredicate now…

1 Like

Awesome, now it works as expected! Thank you both very much! I would never have found this error on my own…

Now, I edited my configuration.nix which is located in ~/nixconfig/hosts/Moon-Presence to this

{ config, lib, pkgs, pkgs-unstable, desktop, ... }:

{
  /* ---- NixOS SYSTEM CONFIG ---- */
  imports = [
    ./hardware-configuration.nix
    ./boot.nix
    ./fprintd.nix
    ./networking.nix
    ../../common/system/nix-settings.nix
    ../../common/system/system-maintenance.nix
    ../../common/system/users.nix
    ../../common/system/printing.nix
    ../../common/system/bluetooth.nix
    ../../common/system/sound.nix
    ../../common/system/locale.nix
    ../../common/desktops/${desktop}.nix
    ../../common/desktops/fonts.nix
    ../../common/apps/system-apps.nix
    ../../common/apps/firefox.nix
  ];
  
  # Allow certain unfree software
  nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
    "1password"
    "steam"
    "steam-original"
    "steam-run"
    "geogebra"
    "spotify"
    "libfprint-2-tod1-goodix"
  ];
 
  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "23.05"; # Did you read the comment?
}

and now it builds with no errors! Yay!

I’ll dig into nixpkgs-unfree (and might need help again) later. Since everything is pulled from the stable branch at the moment, I am content with what I’ve got right now. Thanks again for your help!

2 Likes

Wait, what’s the fix here? I noticed that some of the packages I put in allowUnfreePredicate have started requiring the version suffix, which is annoying for obvious reasons. But I’m not understanding if that’s expected or if it means I’ve introduced some issue in my config?

The fix here is to correct a mistake I made in my flake.nix, namely to remove pkgs from specialArgs. Originally it looked like this

nixosConfigurations = {
      "Moon-Presence" = nixpkgs.lib.nixosSystem {
        inherit system;
        specialArgs = { inherit desktop pkgs pkgs-unstable; };
        modules = [
          ./hosts/Moon-Presence/configuration.nix
          nixos-hardware.nixosModules.dell-xps-13-9310
        ];
      };

and that’s what caused the issue, because it overshadowed the nixpkgs.config.allowUnfreePredicate.
It should read specialArgs = { inherit desktop pkgs-unstable; }; .

Sounds like your predicate is wrong, given you would literally need to add functionality to require the version yourself? Maybe you match against .name instead of using lib.getName?