Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import unstable and inherit config

Tags:

nix

nixos

I have a package-upgrades.nix that I use to upgrade packages from unstable or a fork.

{...}:
{
  nixpkgs.config = {
    packageOverrides = let
      pkgsUnstable = import (
        fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz
      ) { };
      pkgsMaster = import (
        fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz
      ) { };
      pkgsLocal = import (
        fetchTarball https://github.com/moaxcp/nixpkgs/archive/local.tar.gz
      ) { };
    in pkgs:
    rec {
        dropbox = pkgsUnstable.dropbox;
        jbake = pkgsUnstable.jbake;
    };
  };
}

This works well for things like windows manager.

notion = pkgsUnstable.notion;
...
windowManager.notion.enable = true;

The problem is allowUnfree does not seem to get set on the unstable import. I wanted to try something like this.

  pkgsUnstable = import (
    fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz
  ) { inherit config };

This results in an error for an undefined config.

error: undefined variable ‘config’ at /etc/nixos/package-upgrades.nix:7:10
(use ‘--show-trace’ to show detailed location information)
building Nix...
error: undefined variable ‘config’ at /etc/nixos/package-upgrades.nix:7:10
(use ‘--show-trace’ to show detailed location information)
building the system configuration...
error: undefined variable ‘config’ at /etc/nixos/package-upgrades.nix:7:10
(use ‘--show-trace’ to show detailed location information)

Is there any way to override the config in the imported nixpkgs repo?

like image 906
John Mercier Avatar asked Oct 17 '22 22:10

John Mercier


1 Answers

You're on the right track. You need to pass a config argument to the Nixpkgs function. However, it is not in scope.

A Nix module is basically a function that evaluates to an attribute set. It's written in Nix and does not get a special treatment, so if you want to reuse something you have defined in a module, you have two options.

  • Introduce a let binding and use that to reference your config
  • Use the config parameter that is passed to NixOS modules

The first option is basic use of the Nix language. The second is more specific to NixOS modules, although it will occur in other places.

When a configuration (conceptually, a set of modules) gets evaluated, the result of the evaluation is passed to all the modules. This is an example of circular programming, where values that have not been computed can be passed around thanks to laziness. It may take some getting used to the idea that the result of a function gets passed as an argument, but it is very useful.

For example, in your case you may be able to use the final value of config as determined by not just this module but all your modules, however, it doesn't work because evaluation of the NixOS configuration seems to be quite strict.

One solution is to factor out the common configuration that all Nixpkgs need to use:

{ config, ...}:
let
  baseConfig = {
    allowUnfree = true;
  };

  pkgsUnstable = import (
    fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz
  ) { config = baseConfig; };
  pkgsMaster = import (
    fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz
  ) { config = baseConfig; };
  pkgsLocal = import (
    fetchTarball https://github.com/moaxcp/nixpkgs/archive/local.tar.gz
  ) { config = baseConfig; };

in
{
  nixpkgs.config = baseConfig // {
    packageOverrides = pkgs: {
      dropbox = pkgsUnstable.dropbox;
      jbake = pkgsUnstable.jbake;
    };
  };
}

Perhaps it's a good idea to use overlays instead of packageOverrides here. Overlays let you decompose your configuration a bit more. An immediate benefit here is that you may reference your package sets in other modules, because they will be in the pkgs argument so you don't necessarily have to override the packages. Overriding them is a good idea if you want to make sure the same version is used everywhere in your system configuration, but with this you can also reference pkgs.pkgsUnstable.somePackage if you only need that version in a specific situation.

{ ...}:
let

  pkgsConfig = {
    allowUnfree = true;
  };

  packageSetsOverlay = self: super: {
    pkgsUnstable = import (
      fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz
    ) { config = pkgsConfig; };
    pkgsMaster = import (
      fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz
    ) { config = pkgsConfig; };
    pkgsLocal = import (
      fetchTarball https://github.com/moaxcp/nixpkgs/archive/local.tar.gz
    ) { config = pkgsConfig; };
  };

  upgradesOverlay = self: super: {
    dropbox = super.pkgsUnstable.dropbox;
    jbake = super.pkgsUnstable.jbake;
  };

  overlays = [ packageSetsOverlay
               upgradesOverlay
             ];
in
{
  nixpkgs.overlays = overlays;
  nixpkgs.config = pkgsConfig;
}
like image 90
Robert Hensing Avatar answered Oct 21 '22 05:10

Robert Hensing