Purifying an impure NixOS configuration when using Flakes

I have following configuration in my NixOS configuration repository:

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

let nginxLocation = url: dir: {
      name = url;
      value = {
        alias = dir;
        index = "index.html";
        extraConfig = ''expires 6h;'';
      };
    };
    updateIndex = newIndex : args@{name, value} :
      args // { value = args.value // { index = newIndex; }; };
    releaseOS = pkgs.callPackage (import <nixpkgs/nixos/release.nix>) {};
    releasePKGS = pkgs.callPackage (import <nixpkgs/pkgs/top-level/release.nix>) {};
    nixos-manual = "${releaseOS.manualHTML.${builtins.currentSystem}}";
    nixpkgs-manual = "${releasePKGS.manual}";
in
{
  services.nginx = {
    enable = true;
    virtualHosts = {
      localhost = {
        default = true;
        listen = [ { addr = "127.0.0.1"; port = 80; ssl = false; }
                   { addr = "[::1]"; port = 80; ssl = false; }
                 ];
        locations = (builtins.listToAttrs [
          (nginxLocation "/ghc-doc/" "${pkgs.ghc.doc}/share/doc/ghc/html/")
          (nginxLocation "/nix-doc/" "${config.nix.package.doc}/share/doc/nix/manual/")
          (nginxLocation "/nixos-doc/" "${nixos-manual}/share/doc/nixos/")
          (updateIndex "manual.html" (nginxLocation "/nixpkgs-doc/" "${nixpkgs-manual}/share/doc/nixpkgs/"))
        ]);
      };
    };
  };
}

And I’m trying to move to Nix Flake, and I’m getting following error:

warning: creating lock file '/home/user/projects/my-nixos/flake.lock'
error: --- ThrownError ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
at: (13:42) in file: /nix/store/cpa8yfd6sjmvjblcnn77vxybia16x4ss-source/web-server.nix

    12|       args // { value = args.value // { index = newIndex; }; };
    13|     releaseOS = pkgs.callPackage (import <nixpkgs/nixos/release.nix>) {};
      |                                          ^
    14|     releasePKGS = pkgs.callPackage (import <nixpkgs/pkgs/top-level/release.nix>) {};

cannot look up '<nixpkgs/nixos/release.nix>' in pure evaluation mode (use '--impure' to override)
(use '--show-trace' to show detailed location information)

I guess I need to transform <nixpkgs/nixos/...> to flakes equivalent. Any ideas how to go about this ?

I’m running nix-env (Nix) 2.4pre20201205_a5d85d0.

Thanks!

2 Likes

Many of us pass inputs into the module system, and then you could do this:

imports = [
  `${inputs.nixpkgs}/modules/virtualisation/amazon-config.nix`
];

There’s also ${modulesPath} (which is also provided to your config functions via the module system) which might be useful, depending on what you’re doing.

Thanks, although is “`” (backquote) part of Nix syntax, or did you mean to type double quotes ?

Just to confirm, did you mean something like:

{
  description = "nixOS configuration";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  outputs = { self, nixpkgs }: {
     nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
       system = "x86_64-linux";
       modules = [ ./configuration.nix ]; # configuration.nix has imports = [ ./web-server.nix ] the one in the post
       extraArgs = let flake = builtins.getFlake (builtins.toString ./.);
        in { inherit (flake) inputs; };
    };
  };
}

And then in web-server.nix:

    releaseOS = pkgs.callPackage (import "${inputs.nixpkgs}/nixos/release.nix") {};
    releasePKGS = pkgs.callPackage (import "${inputs.nixpkgs}/pkgs/top-level/release.nix") {};

Although this requires passing --impure due to following which is what I’m trying to avoid.

cannot call 'getFlake' on mutable flake reference '/nix/store/k2v9ncpjxy3q65wsba7fgsr36q24q0ks-source', at /nix/store/k2v9ncpjxy3q65wsba7fgsr36q24q0ks-source/flake.nix:9:32 (use --impure to override)

Thanks!

That’s can be replaced with self.

Another possibility is to use pkgs.path, which points to the, well, path to nixpkgs.

Thanks, self works :slight_smile: