what is ${modulesPath} is configuration.nix - nix

In /etc/nixos/configuration.nix, I have this code
{ lib, pkgs, config, modulesPath, ... }:
with lib;
let
nixos-wsl = import ./nixos-wsl;
in
{
imports = [
"${modulesPath}/profiles/minimal.nix"
nixos-wsl.nixosModules.wsl
];
I would like to know what "${modulesPath} is.
I have tried in shell.
echo ${modulesPath}
nothing
I have tried to print it in a nix interpreter.
nix repl
${modulesPath}
error: syntax error, unexpected DOLLAR_CURLY
modulePath
error: undefined variable 'modulesPath'
nothing too.
Does somebody what is that and more generally how to get the value of "nix constant"
update
I missed something important:
I have to import it in nix repl like this.
nix repl
{modulesPath}: modulesPath
«lambda # (string):1:1»
It say that it is a lamdba. I thought it would give a string value.

Quoting from the nixpkgs source:
For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.
{ modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/minimal.nix")
];
}
This is performed in nixos/lib/eval-config-minimal.nix, as follows:
lib.evalModules {
inherit prefix modules;
specialArgs = {
modulesPath = builtins.toString ../modules;
} // specialArgs;
};
Because this is done in <nixpkgs>/nixos/lib, ../modules becomes <nixpkgs>/nixos/modules.
$ nix repl
Welcome to Nix 2.8.1. Type :? for help.
nix-repl> "${toString <nixpkgs>}/nixos/modules/profiles/minimal.nix"
"/nix/store/qdblsqzrzarf9am35r6nqnvlsl7dammk-source/nixos/modules/profiles/minimal.nix"
...run this on your own machine, and you'll get a directory that exists for you.

Related

NixOS: how to import some configuration from GitLab? infinite recursion encountered

I'm trying to deploy a NixOS VM while storing its configuration on a private GitLab repository.
My configuration.nix looks like this (simplified to only include the relevant bits):
{ pkgs, ... }:
let
repo = pkgs.fetchFromGitLab { owner = "hectorj"; repo = "nix-fleet"; };
in {
imports = [
./hardware-configuration.nix
"${repo}/my-server-name/host.nix"
];
}
but it is giving me this error:
error: infinite recursion encountered
at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:496:28:
495| builtins.addErrorContext (context name)
496| (args.${name} or config._module.args.${name})
| ^
497| ) (lib.functionArgs f);
I do not understand where the recursion is happening.
It doesn't seem like its even fetching the repo, as I can put any non-existing names in the args and get the same error.
I saw https://nixos.org/guides/installing-nixos-on-a-raspberry-pi.html doing something similar without issue:
imports = ["${fetchTarball "https://github.com/NixOS/nixos-hardware/archive/936e4649098d6a5e0762058cb7687be1b2d90550.tar.gz" }/raspberry-pi/4"];
And I can use that line on my VM and it will build fine.
What am I missing?
The recursion is as follows
Compute the configuration
Compute the config fixpoint of all modules
Find all modules
Compute "${repo}/my-server-name/host.nix"
Compute repo (pkgs.fetch...)
Compute pkgs
Compute config._module.args.pkgs (Nixpkgs can be configured by NixOS options)
Compute the configuration (= 1)
You can break the recursion at 6 by using builtins.fetchTarball instead.
Alternatively, you can break it around 7, by using a different "pkgs".
If you're using configuration.nix as part of a larger expression, you may be able to pass an invoked Nixpkgs to NixOS via specialArgs.pkgs2 = import nixpkgs { ... }. This creates a pkgs2 module argument that can't be configured by NixOS itself.
Otherwise, you could define pkgs2 in a let binding.
{ pkgs, ... }:
let
# pkgs2: An independent Nixpkgs that can be constructed before the NixOS
# imports are resolved.
pkgs2 = import <nixpkgs> {};
repo = pkgs2.fetchFromGitLab { owner = "hectorj"; repo = "nix-fleet"; };
in {
imports = [
./hardware-configuration.nix
"${repo}/my-server-name/host.nix"
];
}

Why is cabal building these dependencies when they should be provided by nix when using `callCabal2Nix`?

[nix-shell:~/NewProjects/TitaniumKiwi]$ cabal v2-repl titaniumkiwi
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
- QuickCheck-2.13.2 (lib) (requires build)
- blaze-builder-0.4.1.0 (lib) (requires build)
- case-insensitive-1.2.1.0 (lib) (requires build)
- comonad-5.0.5 (lib:comonad) (requires build)
- microlens-mtl-0.2.0.1 (lib) (requires build)
- microlens-th-0.4.3.2 (lib) (requires build)
...
Why does it need to build the libraries (I assume they would be handled by nix)?
When the shell.nix has:
{ sources ? import ./nix/sources.nix
} :
let
niv = import sources.nixpkgs {
overlays = [
(_ : _ : { niv = import sources.niv {}; })
] ;
config = {};
};
pkgs = niv.pkgs;
myHaskellPackages = pkgs.haskellPackages;
in
myHaskellPackages.callCabal2nix "titaniumkiwi" (./.) {}
Output of ghc-pkg list:
[nix-shell:~/NewProjects/TitaniumKiwi]$ ghc-pkg list
/nix/store/xf5zihz12kszk0xiv6c0d0psc0mj10xs-ghc-8.6.5/lib/ghc-8.6.5/package.conf.d
Cabal-2.4.0.1
array-0.5.3.0
base-4.12.0.0
binary-0.8.6.0
bytestring-0.10.8.2
containers-0.6.0.1
deepseq-1.4.4.0
directory-1.3.3.0
filepath-1.4.2.1
ghc-8.6.5
ghc-boot-8.6.5
ghc-boot-th-8.6.5
ghc-compact-0.1.0.0
ghc-heap-8.6.5
ghc-prim-0.5.3
ghci-8.6.5
haskeline-0.7.4.3
hpc-0.6.0.3
integer-gmp-1.0.2.0
libiserv-8.6.3
mtl-2.2.2
parsec-3.1.13.0
pretty-1.1.3.6
process-1.6.5.0
rts-1.0
stm-2.5.0.0
template-haskell-2.14.0.0
terminfo-0.4.1.2
text-1.2.3.1
time-1.8.0.2
transformers-0.5.6.2
unix-2.7.2.2
xhtml-3000.2.2.1
If I manually generate the shell.nix file with cabal2nix --shell . > shell.nix then it works perfectly (Cabal does no building of libraries).
callCabal2nix runs the cabal2nix command without --shell. For a shell, you need to use the pkg.env attribute.
I recommend renaming renaming shell.nix to default.nix and writing a new shell.nix:
args#{...}: (import ./default.nix args).env
Side note: some resources may suggest lib.inNixShell and haskell.lib.shellAware, but they break down when the expression is used as a dependency. Doing it safely in a single file will be possible after Nix master is released, presumably Nix 2.4.

How to build a NixOps deployment on hydra

Deploying my NixOps machines takes alot of time, as packages need to build. I want to do the building regularly on my trusted private Hydra instance.
My current approach involves this release.nix file, but it doesn't work out so well.
{ nixpkgs ? <nixpkgs>, onlySystem ? true, extraModules ? [] }:
let
nixos = import "${nixpkgs}/nixos";
buildEnv = conf: (nixos {
configuration = conf;
});
buildTarget = m: let build = buildEnv (buildConf m); in
if onlySystem then build.system else build.vm;
buildConf = module: { ... }:
{
imports = [ module ] ++ extraModules;
};
in
{
machine1 = buildTarget ./machine1/configuration.nix;
machine2 = buildTarget ./machine2/configuration.nix
machine3 = buildTarget ./machine3/configuration.nix
machine4 = buildTarget ./machine4/configuration.nix
}
I don't really understand this code, as I copied it from here.
This builds fine if I run nix-build release.nix locally, but on hydra I never get a full build. Sometimes builds don't dequeue (they just don't get build), sometimes they fail with various error messages. As nothing of the hydra problems are reproducible (beside the fact, that I never get a full build), I wonder what the best practice for building a NixOps deployment is.
Please note, that I have unfree packages in my deployment. The option nixpkgs.config.allowUnfree = true; is set on the hydra server.
This is not a question about my hydra failures, but about what would be a good way to build a NixOps deployment with Hydra CI.
As far as I know, there is no way to make this super easy. Your code looks ok, but my method is a slightly different. I only build the toplevel attribute and I construct the NixOS configuration differently.
I build NixOS 'installations' from inside Nix using something like:
let
modules = [ ./configuration.nix ];
nixosSystem = import (pkgs.path + "/nixos/lib/eval-config.nix") {
inherit (pkgs) system;
inherit modules;
};
in
nixosSystem.config.system.build.toplevel

Trying to use Lua module fails on the command line

I'm trying to learn how to use Lua modules. I've been reading the following manual:
http://lua-users.org/wiki/ModulesTutorial
Unfortunately, I can't even get the first example working! I've done the following:
Created a "mymodule.lua" file which looks like this:
local mymodule = {}
function mymodule.foo()
print("Hello World!")
end
return mymodule
Then from the command line, within the folder where the mymodule.lua file resides, I tried to do the following:
mymodule = require "mymodule"
But I get the following error message:
myserver:/usr/share/x/research/# mymodule = require "mymodule"
-ash: mymodule: not found
This works:
myserver:/usr/share/x/research/# local mymodule = require "mymodule"
But then when I try to run the foo() method it fails like so:
myserver:/usr/share/x/research/# mymodule.foo()
-ash: syntax error: bad function name
myserver:/usr/share/x/research/#
And I guess this makes sense because I declared mymodule as local instead of global on the command line.
I guess my question is why can't I declare the module globally on the command line.
The manual says that I should be running this from an "interactive interpreter". I am using a standard commandline / terminal window in linux... could this be the issue? I usually have to prefix all lua commands with "lua ".
Any suggestions would be appreciated.
lua is not your shell. You need to run that code from inside the lua interpeter not at your shell prompt.
myserver:/usr/share/x/research/# lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> mymodule = require "mymodule"
> mymodule.foo()

Access to user environment variable

In my .bashrc file:
export DART_SDK=/home/nicolas/dart/dart-sdk
In command line, it works when I "echo" it. But I cannot see this user variable from dart with, I just see system variable but not mine:
var env = Platform.environment;
env.forEach((k,v) => print("Key=$k Value=$v"));
I tried:
on windows and it works
on mac but doesn't work
Is my user variable is not well defined? Is my code is bad? It's a bug?
Using the following code:
import 'dart:io'; // Server side / command line only package.
main() {
Map<String, String> env = Platform.environment;
env.forEach((k, v) => print("Key=$k Value=$v"));
}
I was able to override environment variables on both Windows and Mac. On Mac I had to add the line to .bash_profile (.bashrc is not loaded on my Mac).
John
Here is the link to dart docs: https://api.dartlang.org/1.13.0/dart-io/Platform-class.html

Resources