I want to extract my machine’s hostname to it in import paths in flake.nix. I have a pc and a laptop, and I have a repo to store their configurations in one repo.
For example, my pc’s hostname is MohamedDesktop and laptop’s hostname is MohamedLaptop. In my repo, I have a folder for the device-specific configuration.
(Note the “./.” syntax for dynamically constructing a path)
If the hosts’ configuration are very close, you can reduce boilerplate like so:
nixosConfigurations =
let
hostNames = [
"MohamedDesktop"
"MohamedLaptop"
];
inherit (nixpkgs) lib; # for quick function access
commonModules = [ ./common-module-1.nix ]; # Whatever modules are common
in
lib.pipe hostNames [
(map (
hostName:
lib.nameValuePair hostName (
lib.nixosSystem {
modules =
commonModules
++ [ { networking.hostName = hostName; } ] # Sets the hostname
++ [ (./. + "/devices/${hostName}/configuration.nix") ]; # Imports the per-host configuration.nix
}
)
))
lib.listToAttrs
];
Here’s an example of my wrapper around nixosSystem that does a similar thing.
I tried to solve this problem by add the following:
That command is run in an isolated build environment that has no access to the real environment, so it’s producing stub values. While it is possible to make a pattern like that work, it’s not ideal as it breaks the pure evaluation of flakes.
If you want to access the hostname value in a module somewhere, you should refer to it as config.networking.hostName.
Note that imports does not have access to config because of the way NixOS modules are evaluated. imports are evaluated first before config is a thing.