Can I run nix-instantiate --eval --strict on my configuration.nix?

I’m just beginning to learn nix so glad to have this place to asks questions in. Thanks for reading!

I’m watching this video: https://youtu.be/61MuMY9XFNo?t=2257
At the 37min37sec mark the presenter seems to show what a configuration.nix file will be evaluated to using nix-instantiate. The command he runs is: nix-instantiate --eval configuration.nix --strict --json, and then he sees a json result. However, when I do the same locally I see this:

> nix-instantiate --eval --strict --json configuration.nix 
error: cannot convert a function to JSON
> nix-instantiate --eval --strict configuration.nix  
<LAMBDA>

Is this due to version differences of nix-instantiate? My version is:

> nix-instantiate --version
nix-instantiate (Nix) 2.3.4

How can I get the same thing done so that I can see what my configuration.nix evaluates to?

In case it matters, my configuration.nix currently looks like this:

# 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’).

{ config, pkgs, ... }:

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

  # Use the systemd-boot EFI boot loader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  boot.initrd.luks.devices = {
    nixos = {
      device="/dev/disk/by-uuid/fcd53ef1-31ef-485e-a3e4-cc5b345c14c3";
      preLVM=true;
    };
  };

  # Start dropbox automatically. From <https://discourse.nixos.org/t/using-dropbox-on-nixos/387/5>
  # this failed... 2020.05.02
  # it seems to have worked actually!
  systemd.user.services.dropbox = {
    description = "Dropbox";
    after = [ "xembedsniproxy.service" ];
    wants = [ "xembedsniproxy.service" ];
    wantedBy = [ "graphical-session.target" ];
    environment = {
      QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix;
      QML2_IMPORT_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtQmlPrefix;
    };
    serviceConfig = {
      ExecStart = "${pkgs.dropbox.out}/bin/dropbox";
      ExecReload = "${pkgs.coreutils.out}/bin/kill -HUP $MAINPID";
      KillMode = "control-group"; # upstream recommends process
      Restart = "on-failure";
      PrivateTmp = true;
      ProtectSystem = "full";
      Nice = 10;
    };
  };

  networking.hostName = "nixos-dell";
  networking.networkmanager.enable = true;

  # The global useDHCP flag is deprecated, therefore explicitly set to false here.
  # Per-interface useDHCP will be mandatory in the future, so this generated config
  # replicates the default behaviour.
  networking.useDHCP = false;
  networking.interfaces.wlp59s0.useDHCP = true;

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";
  console = {
    font = "Lat2-Terminus16";
    keyMap = "no";
  };

  # Set your time zone.
  time.timeZone = "Europe/Oslo";

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    # Terminal
    wget
    neovim
    tmux
    zsh
    oh-my-zsh
    git
    ripgrep
    yakuake
    tree
    xclip

    # Browser
    vivaldi
    firefox

    # Dev
    docker
    docker-compose
    idea.pycharm-professional

    # Other
    dropbox
    slack
    openconnect
    spectacle
    anki
  ];

  nixpkgs.config = {
    allowUnfree = true;

    # Build Vivaldi with the proprietary stuff needed to play media
    vivaldi = {
      proprietaryCodecs = true;
      enableWideVine = true;
    };
  };

  # Enable docker, ref https://github.com/NixOS/nixpkgs/issues/6616
  virtualisation.docker.enable = true;

  # Enable zsh and oh-my-zsh
  programs.zsh.enable = true;
  programs.zsh.ohMyZsh.enable = true;
  programs.zsh.interactiveShellInit = ''
    export ZSH=${pkgs.oh-my-zsh}/share/oh-my-zsh/

    # Customize your oh-my-zsh options here
    ZSH_THEME="agnoster"
    plugins=(git docker ssh-agent)

    source $ZSH/oh-my-zsh.sh
  '';
  programs.zsh.promptInit = ""; # Clear this to avoid a conflict with oh-my-zsh

  # 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;
  #   pinentryFlavor = "gnome3";
  # };

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

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

  # Enable sound.
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  # Enable the X11 windowing system.
  services.xserver.enable = true;
  services.xserver.layout = "us";
  services.xserver.xkbOptions = "eurosign:e";

  # Enable touchpad support.
  services.xserver.libinput.enable = true;

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

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.stian = {
    isNormalUser = true;
    shell = pkgs.zsh;
    extraGroups = [
      "wheel" # Enable ‘sudo’ for the user.
      "docker"
    ];
  };

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

}

Your configuration.nix is not a derivation, it’s a function. You need to instantiate <nixpkgs/nixos> instead and select the system attribute.

$ nix-instantiate --strict "<nixpkgs/nixos>" -A system

You can also specify --arg ./configuration.nix if you’d like to instantiate a different configuration than the NIXOS_CONFIG env variable or the <nixos-config> entry of NIX_PATH.

4 Likes

I was about to say that you could look at the source of nixos-rebuild https://github.com/NixOS/nixpkgs/blob/9b20a24d4d59e6563bfb0d3182c463221f16cc5d/nixos/modules/installer/tools/nixos-rebuild.sh#L416 . This confirms @ElvishJerricco’s comment!

2 Likes

To actually reproduce what you’ve seen in video, you should do

$ nix-instantiate --strict --json --eval -E '
import ./configuration.nix  {
  config = {};
  pkgs = import <nixpkgs> {};
  lib = import <nixpkgs/lib>;
}
'

However, as others suggested, this is only view of a single module. If you would ever want the --json --strict view of all modules combined together with your system definition, then I would disappoint you - it is not possible to do with nix-instantiate. There are a few infinite recursions and aborts, which prevent this:

nix-instantiate --strict --json --eval -E '
import <nixpkgs/nixos> {
  configuration = import ./configuration.nix;
}
'
....
/nix/store/jmjklnnv5iverror: Please be informed that this pseudo-package is not the only part of
Nixpkgs that fails to evaluate. You should not evaluate entire Nixpkgs
without some special measures to handle failing packages, like those taken
by Hydra.

ba3g288ppz4z25dqgrw45-vmware-guest.nix","/nix/store/yamzdblrb2qnq4ad95c18kixkxsajvqp-xen-dom0.nix","/nix/store/760irz3939zqr309d63r6x51q0icafcp-xe-guest-utilities.nix"],"extraModules":[],"modules":["/nix/store/845sqqbpwdkyhdcxjbln1pkzwzc91wzc-station.nix"],
"pkgs":{"AAAAAASomeThingsFailToEvaluate":}}}}}
4 Likes

Is there also a solution for when using flakes? I get this error when I run your command:

[I] moritz@moxps ~> nix-instantiate --strict "<nixpkgs/nixos>" -A system
error: --- ThrownError ------------------------------------------------------------------------------------------------------------------------ nix-instantiate
at: (1:60) in file: /nix/store/i5jrl45vbd2hky16zz2hbln07lb6afil-source/nixos/default.nix

     1| { configuration ? import ./lib/from-env.nix "NIXOS_CONFIG" <nixos-config>
      |                                                            ^
     2| , system ? builtins.currentSystem

file 'nixos-config' was not found in the Nix search path (add it using $NIX_PATH or -I)
(use '--show-trace' to show detailed location information)