tcurdt
December 3, 2023, 1:15am
1
I got a flake that defines a nixos configuration “foo”
outputs =
{ self
, nixpkgs
, ...
} @ inputs: {
nixosConfigurations = {
foo = nixpkgs.lib.nixosSystem {
Now I would like this into a separate file which should work like this I guess
foo = import ./machines/foo.nix { inherit nixpkgs; };
and
{ nixpkgs, ... }: # does this need to match { inherit nixpkgs; }; ?
{
nixpkgs.lib.nixosSystem {
modules = [
]
networking.hostName = "nixos";
networking.domain = "local";
system = "aarch64-linux";
system.stateVersion = "23.05";
}
}
Now I got a couple of questions:
Is there an easy way to import multiple nixosConfigurations
similar to this?
I am not sure how one would define the name/reference “foo”.
nixosConfigurations = import ./machines/*.nix { inherit nixpkgs; };
Or would I need to implement this myself?
And about this:
outputs =
{ self
, nixpkgs
, ...
} @ inputs: {
Why the self
?
What defines the number of variables? Why is it self
and nixpkgs
here?
Why the ...
?
Why the @ inputs:
Maybe I have missed the details in docs.
Either a pointer or explanation would be great.
tcurdt:
Why the self
?
Since you have ...
, you can leave it out. self
allows you to access values you are outputting.
Like if you output an overlay from your flake as overlays.default
, in other attributes you can access it as self.overlays.default
.
You always get at least self and your flake inputs. Any extra parameters you have are implicit inputs.
tcurdt:
Why the ...
?
That means that the function has at least self and nixpkgs, but more is okay. If you leave out the ...
, then you have to list all the parameters. For example if you have only the nixpkgs input, { self, nixpkgs }
would work, as well as { nixpkgs, ... }
, but { nixpkgs }
would error due to unhandled self
parameter.
tcurdt:
Why the @ inputs:
That allows you to refer to the whole set of arguments as inputs
. inputs.self
is the same as self
and inputs.nixpkgs
is the same as nixpkgs
.
tcurdt:
Is there an easy way to import multiple nixosConfigurations
similar to this?
I am not sure how one would define the name/reference “foo”.
nixosConfigurations = import ./machines/*.nix { inherit nixpkgs; };
Or would I need to implement this myself?
You could implement it by getting the directory contents, and mapping them to the values. Or use genAttrs if you are okay with listing the names.
For available functions, can see: Nix (builtins) & Nixpkgs (lib) Functions
If you want it done for you, you could use a flake library. I would recommend GitHub - nix-community/flakelight: Framework for simplifying flake setup [maintainer=@accelbread] (though I am biased as its author).
2 Likes
tcurdt
December 3, 2023, 10:50pm
3
That was really helpful input. Thank you very much.
Right now I am trying to use a function:
{
description = "my servers";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
outputs =
{ self
, nixpkgs
, ...
} @ inputs:
let
mkHost = import ./lib/mkHost.nix { inherit inputs; };
in {
nixosConfigurations.utm-arm = mkHost {
system = "aarch64-linux";
hostName = "nixos";
};
};
}
From what I understood the inherit inputs
on the import should pass in the nixpkgs
.
And with this file lib/mkHost.nix
{ nixpkgs }:
{
system,
hostName,
}: nixpkgs.lib.nixosSystem {
# specialArgs = { inherit inputs; };
# system = system;
# system.stateVersion = "23.05";
modules = [
./hosts/utm-arm/hardware-configuration.nix
];
networking.hostName = hostName;
networking.domain = "utm";
}
It should work - but I am getting
function '**anonymous lambda**' called without required argument '**nixpkgs**'
Using
mkHost = import ./lib/mkHost.nix { inherit nixpkgs; };
improves things but there I am getting
function 'anonymous lambda' called with unexpected argument 'networking'
So obviously some more inputs are missing.
Another problem that raises the question of attribute context. This cannot really work
system = system;
system.stateVersion = "23.05";
but how do I reference the one system or the other?
It seems one really is nixpkgs.lib.nixosSystem.system
and the other system.stateVersion
.
tcurdt
December 3, 2023, 11:16pm
4
Ha! Seems like I got it:
outputs =
{ self
, nixpkgs
, ...
} @ inputs:
let
mkHost = import ./lib/mkHost.nix { inherit nixpkgs; };
in {
nixosConfigurations.utm-arm = mkHost {
hostPlatform = "aarch64-linux";
hostName = "nixos";
};
};
{ nixpkgs }:
{
hostPlatform,
hostName,
}: nixpkgs.lib.nixosSystem {
modules = [
../hosts/utm-arm/hardware-configuration.nix
{
nixpkgs.hostPlatform = hostPlatform;
networking.hostName = hostName;
networking.domain = "utm";
system.stateVersion = "23.05";
}
];
}
Still not quite sure why inherit inputs
doesn’t work though.
{ inherit inputs; }
is equivalent { inputs = inputs; }
so in mkHost you’d need { inputs }:
and to use inputs.nixpkgs
.
You probably want the following instead:
outputs =
{ self
, nixpkgs
, ...
} @ inputs:
let
mkHost = import ./lib/mkHost.nix inputs;
in {
nixosConfigurations.utm-arm = mkHost {
hostPlatform = "aarch64-linux";
hostName = "nixos";
};
};
{ nixpkgs, ... }:
{
hostPlatform,
hostName,
}: nixpkgs.lib.nixosSystem {
modules = [
../hosts/utm-arm/hardware-configuration.nix
{
nixpkgs.hostPlatform = hostPlatform;
networking.hostName = hostName;
networking.domain = "utm";
system.stateVersion = "23.05";
}
];
}
1 Like