| 27 May 2024 |
nbp | Yes _module was one way to expose the internal details. | 17:12:15 |
nbp | There are multiple problems to finding the declarations of a submodule option. | 17:12:47 |
nbp | One of them is the apply function, which implies that the content would be post-processed. | 17:13:32 |
nbp | Another one, which I bet nobody noticed, is that you can add submodules at the definition site:
nix-repl> (nixosConfigurations.ouessant.extendModules { modules = [ ({...}: { fileSystems."/" = {lib, ...}: { options.color = lib.mkOption { type = lib.types.str; default = "red"; }; }; }) ]; }).config.fileSystems."/".color
"red"
| 17:19:11 |
nbp | Adding color is point-less, but for example, one could import a home-manager configuration this way. | 17:19:35 |
nbp | * Another one, which I bet nobody noticed, is that you can add submodules at the definition site:
{...}: {
fileSystems."/" = {lib, ...}: {
options.color = lib.mkOption {
type = lib.types.str;
default = "red";
};
};
}
| 17:21:05 |
nbp | {
fileSystems."/" = {...}: { imports = [ ./root.nix]; };
}
| 17:22:12 |
nbp | I will note that the former is better than
{ home-manager.users.jdoe = import ./home.nix; }
as the later will lose the file attribute associated with home.nix when reporting error messages.
| 17:31:59 |
| 28 May 2024 |
Sam Lehman | This is a pretty basic example of what I'd like to be able to do, where the import could also be another profile instead of a nixosModule.
profile1.nix:
imports = [inputs.sops-nix.nixosModules.sops];
sops.secrets.mysecret1={};
profile2.nix:
imports = [inputs.sops-nix.nixosModules.sops];
sops.secrets.mysecret2 = {}
| 12:11:12 |
Sam Lehman | In reply to @infinidoge:inx.moe Probably the easiest way to accomplish something like this would be to have all of the profiles imported, but control what gets applied with options
Something like: common:
options = {
profile1 = lib.mkOption {
type = lib.types.bool;
default = false;
};
profile2 = lib.mkOption {
type = lib.types.bool;
default = false;
};
profile3 = lib.mkOption {
type = lib.types.bool;
default = false;
};
};
config = {
# Common config here
};
profile1:
config = lib.mkIf config.profile1 {
# Profile 1 config here
};
profile2:
config = lib.mkIf config.profile2 {
# Profile 2 config here
};
And so on This is similar to something else I was considering separately, but I was also trying to make each profile fully standalone, so I could safely import and enable them without conflicts.
Can a config block contain imports? One of my issues is that I want my profiles to import their own dependencies, but also not conflict when two profiles share a dependent profile or nixosModule
I want to do something like this programmatically, where all my profiles get collected and wrapped inside a config block, and have a mkEnableOption controlling whether they get enabled.
| 12:25:21 |
nbp |
Can a config block contain imports? No, because imports are resolved in order to know what config definitions are contributing to the final configuration.
| 12:30:20 |
nbp | *
Can a config block contain imports?
No, because imports are resolved in order to know what config definitions are contributing to the final configuration.
| 12:30:28 |
nbp | You can create an option, which value is used as part of:
config = mkIf (config.profile == "profile_42") { … };
| 12:32:21 |
Sam Lehman | In reply to @nbp:mozilla.org Sam Lehman: Yes, evalModules should capture the whole tree of imports and deduplicated moduled key property. However, if you are using flakes, and define a nixosModules within the flake.nix file, then the key attribute is not initialized to any value which can safely be deduplicated. Not sure I follow.
Is key an intermediate attr of the loaded modules that doesn't make it into the resulting config? The default behavior breaks when I try to do what I described.
I'm also using https://github.com/divnix/std and I'd like to reference other profiles using cell.nixosModules.<name> before they reach my flake outputs.
| 12:34:18 |
Sam Lehman | In reply to @nbp:mozilla.org
Can a config block contain imports?
No, because imports are resolved in order to know what config definitions are contributing to the final configuration.
That's what I thought | 12:34:43 |
Sam Lehman | In reply to @nbp:mozilla.org
You can create an option, which value is used as part of:
config = mkIf (config.profile == "profile_42") { … };
I don't think this structure will work for how I'm trying to set my profiles up.
I might be able to create options.profiles and wrap each profile in their own module machinery, so the entire profile gets added to config and creates options.profiles.<name>.enable which controls activation of the profile. My only issue is handling imports.
| 12:38:48 |
nbp | If you can just import them all, and use mkIf as described above. | 12:40:43 |
nbp | I doubt the above would not work, unless you have circular dependencies, as the code above is how NixOS is written, and it work, AFAIK. | 12:41:31 |
nbp | * I doubt the above would not work, unless you have circular dependencies, as the code above is how NixOS is written, and it works, AFAIK. | 12:41:37 |
Sam Lehman | My config eval errors for me if I enable two profiles that both import the same nixosModule, and if imports can't be gated by mkIf, I think I'm stuck with that problem. | 12:45:32 |
nbp | If they error while importing the same nixosModule, this is because the module system is unable to find a unique identifier to use as a key to deduplicate the 2 imports. | 12:48:27 |
nbp | This happens with flakes which are just providing unnamed modules. | 12:48:50 |
nbp | Using the key attribute next to config would help resolve that, or by moving the module to a file, and not importing it in the flake. | 12:49:37 |
Sam Lehman | hmmm, is there a way to manually give it a key? I have no idea how this part works? | 12:49:43 |