Don’t try to do that in the flake.nix
. That way madness lies - if you don’t fully understand the nix language/module system yet, you will never get it to work, and if you do fully understand them, you completely lose separation of concerns and your code becomes a mess.
The style of your config comes from people reading guides on how to use various third party flakes that just show the minimum viable solution with no regards to code quality. I’d recommend a completely different approach.
Rather than this mess:
modules = [
./general
./luna/configuration.nix
home-manager.nixosModules.home-manager
({pkgs, myConfig, ... }: {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.sharedModules = [
inputs.sops-nix.homeManagerModules.sops
];
home-manager.users.kekkon = import ./general/home.nix;
# Optionally, use home-manager.extraSpecialArgs to pass
# arguments to home.nix
home-manager.extraSpecialArgs = myConfig // {
extraProfile = ''
export NIXOS_CONFIG=/home/kekkon/nix-flakes/flake.nix
'';
};
})
vscode-server.nixosModules.default
({config, pkgs, myConfig, ...}: {
services.atuin.enable = myConfig.enableAtuin or false;
services.vscode-server.enable = true;
})
disko.nixosModules.disko
sops-nix.nixosModules.sops
({...}: {
nixpkgs.config.allowUnfree = true;
})
];
Split all of that out into your NixOS modules. I’d start by moving the module imports to the imports
of general/default.nix
. Pass the various flake inputs to the module system with specialArgs
so you can do that.
Next, grab the little inline modules you wrote and just expand them into general/default.nix
. Ultimately you’ll have something like this:
# general/default.nix
{ inputs, ... }: {
imports = with inputs; [
home-manager.nixosModules.home-manager
vscode-server.nixosModules.default
disko.nixosModules.disko
sops-nix.nixosModules.sops
];
nixpkgs.config.allowUnfree = true;
# home-manager options
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.sharedModules = [
inputs.sops-nix.homeManagerModules.sops
];
home-manager.users.kekkon = import ./general/home.nix;
# Optionally, use home-manager.extraSpecialArgs to pass
# arguments to home.nix
# This obviously won't work, make it a home-manager module instead
home-manager.extraSpecialArgs = myConfig // {
extraProfile = ''
export NIXOS_CONFIG=/home/kekkon/nix-flakes/flake.nix
'';
};
# vscode options
services.atuin.enable = myConfig.enableAtuin or false;
services.vscode-server.enable = true;
# whatever other options you had in here previously
}
Besides the obvious readability improvements, this also allows you to use the NixOS module systen for DRY purposes. Importing general/default.nix
is now enough to enable all those options, you don’t need to repeat them for each nixosConfiguration
in your flake.nix
.
Break the little subsections into other modules and add them to the general imports
as you see fit, I can totally see having a separate module for your home-manager config for example.
After that, if you still want to go with your custom options approach, learn how to write a module for that and write one. You almost have one, but you need to add it to your imports
or modules
, and I suspect learn a bit about how the imports
, options
, and config
sections and such work.
That said, I’ve personally done that before and found it rather cumbersome in the long run. Learning to use the NixOS module system (and especially lib.mkForce
and lib.mkDefault
) resulted in much better code quality.
Nowadays I would just write a module that you only add to those configurations which should have that stuff enabled. So your nixosConfigurations
eventually looks like this:
nixosConfigurations = {
luna = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./general
./general/autin.nix
./luna/configuration.nix
];
specialArgs = { inherit inputs; };
};
sol = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./general
./sol/configuration.nix
];
specialArgs = { inherit inputs; };
};
titan = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./general
./general/zellij.nix
./titan/configuration.nix
];
specialArgs = { inherit inputs; };
};
};
I’d even go a step further and only import those modules in the imports
of the respective configuration.nix
es to make all that completely opaque at the flake.nix
level.