AllowUnfree doesn't work with Flake managed system

Hi All,

I am trying to move my new laptop to a Flake managed system. I started from https://github.com/Misterio77/nix-starter-configs/tree/minimal and it works fine except when I am trying to add ‘non-free’ software.

Even though it has nixpkgs.config.allowUnfree = true; in ./nixos/configuration.nix, when I run

sudo nixos-rebuild switch --flake .#my-hostname`

It tells me the package is unfree ;).

Article: make flakes use same nixpkgs as NixOS would seem similar I wasn’t sure how to apply that to my configuration.

Flakes - NixOS Wiki Says

To use nonfree software in a flake, add nixpkgs as an input in your flake and import it with the allowUnfree option:

pkgs = import nixpkgs { config = { allowUnfree = true; }; };

I tried putting that line in the inputs block in the flake, but that gave me an error. Pretty new to Nix (and flakes!) so any help would be much appreciated.

1 Like

do you mind posting your configuration.nix?

But you should just need to add nixpkgs.config.allowUnfree = true; to your configuration. Example: https://github.com/jonringer/server-configuration/blob/c9035456fedccd196f2c01f3d1ca670b6534b6ce/configuration.nix#L21

sure thing

configuration.nix

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ inputs, lib, config, pkgs, ... }:

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

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  boot.loader.efi.efiSysMountPoint = "/boot/efi";

  networking.hostName = "sulu"; # Define your hostname.
  #networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # This will add your inputs as registries, making operations with them (such
  # as nix shell nixpkgs#name) consistent with your flake inputs.
  nix.registry = lib.mapAttrs' (n: v: lib.nameValuePair n { flake = v; }) inputs;

  # Will activate home-manager profiles for each user upon login
  # This is useful when using ephemeral installations
  environment.loginShellInit = ''
    [ -d "$HOME/.nix-profile" ] || /nix/var/nix/profiles/per-user/$USER/home-manager/activate &> /dev/null
  '';

  nix = {
    settings = {
      # Enable flakes and new 'nix' command
      experimental-features = "nix-command flakes";
      # Deduplicate and optimize nix store
      auto-optimise-store = true;
    };

    gc = {
      automatic = true;
      persistent = true;
      dates = "weekly";
      options = "--delete-older-than 7d";
    };
  };

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # Set your time zone.
  time.timeZone = "America/Vancouver";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_CA.utf8";

  # Enable the X11 windowing system.
  services.xserver.enable = true;

  # Enable the KDE Plasma Desktop Environment.
  services.xserver.displayManager.lightdm.enable = true;
  services.xserver.desktopManager.plasma5.enable = true;

  # Configure keymap in X11
  services.xserver = {
    layout = "us";
    xkbVariant = "";
  };

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  sound.enable = true;
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;
  
  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;
  #nixpkgs.config.allowUnfreePredicate = (pkg: true);  # Me trying to fix this

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [

    ### GTK Themes
    kitty-themes
    
    ### Audio & Video
    vlc

    ### Developer Tools
    emacs   # https://search.nixos.org/options?query=emacs
    micro
    vscodium 
    mg

    ### Games
    #steam
    #retroarchFull
    #zeroad
    #xonotic
    #minetest   # https://search.nixos.org/options?channel=22.05&from=0&size=50&sort=relevance&type=packages&query=minetest
    #minecraft   # https://search.nixos.org/options?channel=22.05&from=0&size=50&sort=relevance&type=packages&query=minecraft
    #endless-sky
    #flare
    #astromenace
    #redeclipse
    #superTuxKart
    #lincity
    #extremetuxracer
    #urbanterror
    #speed_dreams
    #torcs
    #bottles
    #lutris
    
    
    ### Graphics & Photography
    inkscape
    gimp
    
    ### Communication / Internet / News
    firefox
    chromium
    #signal-desktop
    #discord
    #zoom-us
    thunderbird

    ### Productivity
    libreoffice
    zathura

    ### Science / System / Utilities / Security
    curl
    dconf
    dconf2nix
    dmenu
    exa
    fd
    filezilla
    flatpak
    git
    gparted
    hddtemp
    htop
    keepassxc
    kitty
    lshw
    lsof
    macchanger
    mc
    nerdfonts
    nfs-utils # https://github.com/NixOS/nixpkgs/blob/f21492b413295ab60f538d5e1812ab908e3e3292/nixos/modules/tasks/filesystems/nfs.nix
    metasploit
    nmap
    p7zip
    procs
    proxychains
    qbittorrent
    ranger
    remmina
    ripgrep
    rsync # https://search.nixos.org/options?channel=22.05&from=0&size=50&sort=relevance&type=packages&query=rsync
    rustscan
    shotcut
    smartmontools
    socialscan
    sqlmap
    starship
    terminator
    tmux # optition = https://search.nixos.org/options?channel=22.05&from=0&size=50&sort=relevance&type=packages&query=tmux + https://github.com/tmux-plugins/tmux-resurrect
    tomb
    topgrade
    traceroute
    tre-command
    variety
    vnstat
    wget
    whatweb
    whois
    wireshark # https://search.nixos.org/options?channel=22.05&from=0&size=50&sort=relevance&type=packages&query=wireshark
    
    
    ### Programming Languages / SQL / Webserver
    #docker
    #docker-compose
  ];
  
  ### RetroArch
  services.xserver.desktopManager.retroarch.enable = true;
  
  ### Steam
  #programs.steam.enable = true;
  
  ### Dconf
  programs.dconf.enable = true;
  
  ### Starship
  programs.starship.enable = true;
  # programs.starship.settings  https://github.com/NixOS/nixpkgs/blob/f21492b413295ab60f538d5e1812ab908e3e3292/nixos/modules/programs/starship.nix
  
  ### Vim
  #programs.vim.defaultEditor = true;
  
  ### vnstat
  services.vnstat.enable = true;
  
  ### traceroute
  programs.traceroute.enable = true;
    
  ### Docker
  virtualisation.docker.enable = true;
  ## Default delivery with Kali Linux https://hub.docker.com/r/kalilinux/kali-rolling
  ## https://www.kali.org/docs/containers/official-kalilinux-docker-images/
  
  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  ### automatic upgrade
  system.autoUpgrade = {
      enable = true;
      channel = "https://nixos.org/channels/nixos-22.05";
  };


  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # 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 = "22.05"; # Did you read the comment?
}

And flake.nix

{
  description = "You new nix config";

  inputs = {
    # Nixpkgs
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    hardware.url = "github:nixos/nixos-hardware";

    # Home manager
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";

    # TODO: Add any other flake you might need
  };

  outputs = { nixpkgs, home-manager, ... }@inputs: {
    nixosConfigurations = {
      sulu = nixpkgs.lib.nixosSystem {
        pkgs = nixpkgs.legacyPackages.x86_64-linux;

        modules = [ ./nixos/configuration.nix ];
        # Pass inputs down to our config, so that they can consume flake inputs
        specialArgs = { inherit inputs; };
      };
    };
  };
}

That’s your problem. It overrides the entire nixpkgs invocation mechanism in nixos, so of course the options related to that don’t take effect.

Okay great! How do I fix it… presumably it was put there for a reason (I did not put it there)? I’ll file a ticket on https://github.com/Misterio77/nix-starter-configs/tree/minimal so others do not have the same issue.

But just so I understand/learn a bit more about Nix (the language), How does assigning a symbol (pkgs) override anything? If assignment has that side effect, it would be seem to be bad and unpredictable… or are you saying nixpkgs.legacyPackages.x86_64-linux is a function call that has the side effect? It doesn’t look like a function call to my old imperative eyes :wink:

Just take the line out. You don’t need it there… home-manager needs a line like that, for reasons I don’t really understand, but nixos does not.

It overrides something because the nixosSystem function reacts to its presence in its attrset argument. It’s basically just a named argument.

It’s not really correct to consider that “assigning a symbol”. It’s adding an entry to an attribute set (similar to a dict in python, a hash in ruby, or an object in javascript). If the same line was inside a let construct, that would be assigning a lexically scoped variable. (Also, if you use the rec keyword before an attrset, it kind of acts like both)

1 Like

Opened an issue for that Nixpkgs module should not allow setting both pkgs and other options · Issue #191910 · NixOS/nixpkgs · GitHub

3 Likes

Okay thanks, I elided the home-manager section from the flake, but it’s moot at this point since I am not (yet) using home-manager, but I’ll cross that bridge when and if I ever do start using it.

It’s not really correct to consider that “assigning a symbol”. It’s adding an entry to an attribute set (similar to a dict in python, a hash in ruby, or an object in javascript). If the same line was inside a let construct, that would be assigning a lexically scoped variable. (Also, if you use the rec keyword before an attrset, it kind of acts like both)

Thank you, that helps.

Hey,

Take a look at the standard template - it shows how to set overlays and options while instantiating nixpkgs in the flake.

presumably it was put there for a reason

It’s a little wonky, but (in the context of an opinionated starter template) this tends to works nicely - it ensures your package set on NixOS and standalone home-manager is identical and makes nixosSystem and homeManagerConfiguration function calls a bit more similar.

If you prefer to set nixpkgs configs modularly, (as you found out) just removing pkgs should make things work. To use standalone home-manager through your flake, you’ll have to instantiate nixpkgs (using the same stuff you have set through nixpkgs.config). Alternatively, you can use home-manager as a NixOS module and set the option home-manager.useGlobalPkgs = true.

I should document this somewhere, thanks for the inputs!

Thanks all for the help, after removing the line, it’s working now.

Take a look at the standard template - it shows how to set overlays and options while instantiating nixpkgs in the flake.

Ultimately I want to manage a few machines so I started with the standard template but I am not sure (yet) of the differences between imports, modules and overlays, etc and how best to organize my code/configs so it was quickly turning into spaghetti, so I dropped back to the simpler example for now.

1 Like

Glad you got it working.

In other news, the minimal (similarly to the standard) template now also instantiates nixpkgs i.e. you can set allowUnfree in the flake: https://github.com/Misterio77/nix-starter-configs/blob/2e4b816bd6702621417c6a2ede9be3a4d019e0aa/minimal/flake.nix#L31

No, no, no!

You do not want to pass pkgs to nixosSystem!

Only to HM, and then you want to pass it as nixpkgs.legacyPackages.${system}.

If you do it like this, then you can use the respective nixpkgs.* options of nixos or HM.

1 Like

I don’t think I understand why is passing pkgs bad? Isn’t almost the same as setting nixpkgs.pkgs modularly? I don’t see why sharing nixpkgs instances would be a problem (if you use the same package set on all hosts, that is).

In the standard template my goal is to expose the overlays, overlaye’d packages instance (for nix building), and also apply the same overlays to both nixosConfigurations and homeConfigurations while avoiding boilerplate code that would make it too hard to understand. I could use nixpkgs.pkgs, sure, but then I’d have to pass a nixpkgs instance anyway to HM, and repeat the overlay code again (as HM does not have a nixpkgs.pkgs option), why not pass the same overlayed instance? Seems a lot more straightforward.

Inlining nixpkgs.* configs on the flake looks awful, abstracting it to a function is just hiding the complexity, passing overlays as specialArgs does not seem nice either, importing overlays.nix both on configurations and on the flake seem redundant.

I’m really just making minimal examples of what I do with my systems today. Is there a better way to provide a flake with all of these outputs while avoiding boilerplate code? I would sincerely appreciate suggestions on how to make my templates folllow best practices!

Which I advice against as well, as that as well disables the nixpkgs.* option hirarchy.

As you can see, passing pkgs to nixosSystem or a preconfigured nixpkgs instance to homeConfiguration causes regular confusion.

Questions like this pop up every day in the matrix and the discord.

It’s obvious that your approach is not easier to understand.

I would agree if indeed we would avoid multiple instantiation, but the system and home configuration are never really built together here. So it has to be evaluated twice anyway.

Also why do you want to add overlays that are only related to the system to the user instance? Why put overlays only necessary on the user also in the system?

Not even talking about, why overlays at all?

Why is boilerplate bad?

Yes, I agree the wrong abstraction is usually worse than no abstraction.

But disabling parts of the module system without even telling the users of your template about this, does not fall under this credo.

Best practice is to get the inputs into the module system and configuring and overlaying the nixpkgs to be used there.

2 Likes

Agreed. Dis-integrations like this need to be something the final user knows about and understands the consequences of. Otherwise they see documentation telling them a feature should work, it doesn’t, and they don’t even have any clue why, as happened here.

2 Likes

Thanks for the feedback, folks! I’ve added a notice about this, will see what I can do to migrate away from that strategy.

1 Like

That could be just as well solved by adding an assertion to the nixpkgs module as suggested in Nixpkgs module should not allow setting both pkgs and other options · Issue #191910 · NixOS/nixpkgs · GitHub.

1 Like