Import unstable and inherit config

别来无恙 提交于 2020-01-02 21:02:41

问题


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?


回答1:


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;
}


来源:https://stackoverflow.com/questions/48733553/import-unstable-and-inherit-config

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!