-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module system improvements for NixOS as a submodule #75031
Conversation
This will be useful for doing more complicated module evaluations
Because why not
8384fe7
to
7f9a0ef
Compare
I wonder if this changes #70638 |
@domenkozar Very relevant issue indeed! While this PR doesn't change that behavior, it does allow you to turn it off for specific submodules by replacing This |
Some more documentation will be helpful. |
This is nice. Finally a coment left by @nbp makes sense. Here I've tried to apply this
I've also made the needed adjustments to As for performance, everything is not better than before. I've collected stats, and found out that instantiation is worse than before:
Maybe I made a mistake somewhere? |
@danbst After investigating, it seems to have to do with the manual. Before your change with defaulting
After your change also with
Patch to disable documentation: diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix
index deecb005270..28f686e2ad8 100644
--- a/nixos/modules/misc/documentation.nix
+++ b/nixos/modules/misc/documentation.nix
@@ -74,7 +74,7 @@ in
enable = mkOption {
type = types.bool;
- default = true;
+ default = false;
description = ''
Whether to install documentation of packages from
<option>environment.systemPackages</option> into the generated system path. Also, trying to actually build the manual with the changes, I get
This probably comes from the fact that the
mkOption { default = pkgs.foo; } to not refer to pkgs.foo ), and that module seems to cause the slowdown in general too. I have a feeling that potentially also all NixOS options are duplicated in the manual in containers.<name?>.* .
|
@infinisil However it is still of same performance as previous approach. It uses same amount of memory. I doubt now if it had previously used O(n²) time to instantiate n machines. From my experiments it seems to be linear, with both approaches. Though it is much cleaner API (for containers example), which is nice! |
@danbst Ah yeah, the |
@danbst Looking it into your container rewrite a bit more, I figured out some problems:
You can then do something like this to get it to work with the same performance as before (the first xml docs patch shouldn't be necessary anymore once the second point above is done): diff --git a/nixos/doc/manual/administration/declarative-containers.xml b/nixos/doc/manual/administration/declarative-containers.xml
index d03dbc4d705..8cff2c97c3a 100644
--- a/nixos/doc/manual/administration/declarative-containers.xml
+++ b/nixos/doc/manual/administration/declarative-containers.xml
@@ -33,9 +33,9 @@ containers.database =
follows:
<programlisting>
containers.database = {
- <link linkend="opt-containers._name_.privateNetwork">privateNetwork</link> = true;
- <link linkend="opt-containers._name_.hostAddress">hostAddress</link> = "192.168.100.10";
- <link linkend="opt-containers._name_.localAddress">localAddress</link> = "192.168.100.11";
+ privateNetwork = true;
+ hostAddress = "192.168.100.10";
+ localAddress = "192.168.100.11";
};
</programlisting>
This gives the container a private virtual Ethernet interface with IP address
diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix
index deecb005270..8445b75f6bb 100644
--- a/nixos/modules/misc/documentation.nix
+++ b/nixos/modules/misc/documentation.nix
@@ -20,7 +20,10 @@ let
options =
let
scrubbedEval = evalModules {
- modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ manualModules;
+ modules = [ {
+ nixpkgs.localSystem = config.nixpkgs.localSystem;
+ documentation.isDocumentationEval = true;
+ } ] ++ manualModules;
args = (config._module.args) // { modules = [ ]; };
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
};
@@ -84,6 +87,15 @@ in
# which is at ../../../doc/multiple-output.xml
};
+ isDocumentationEval = mkOption {
+ type = types.bool;
+ default = false;
+ internal = true;
+ description = ''
+ Whether this module system evaluation is purely to get an options listing
+ '';
+ };
+
man.enable = mkOption {
type = types.bool;
default = true;
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index bbeebdb9db8..8a755e872ff 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -635,6 +635,7 @@ in
type = types.attrsOf (types.fullSubmodule {
modules = [ containerDefaults containerParamsModule ] ++ baseModules;
specialArgs.modulesPath = builtins.toString ../.;
+ hideSubOptions = config.documentation.isDocumentationEval;
});
default = {};
example = literalExample Edit: Instead of 571c7da, it would also be possible to inline this type modification into the container module, but that gets ugly because of |
@infinisil what about this danbst@cd74159 ? This solves the containers options problems. I have just verified that generated manual includes only extra options. BTW, I've just recalled that submodule types are mergeable. #24653 (comment) for insights. I wonder if |
@danbst I think separating the container options from NixOS options is cleaner, because they're like on a higher level than just a standard NixOS configuration. Similarly I'd like for nixops to not use |
093768c
to
6e521fa
Compare
Pushed code with @roberth's suggestions and rebased for a clean history. I'll do some final tests with this and if it looks good to both of you too, this should be ready to merge. |
Great work! |
This has the beneficial side effect of allowing paths to be used as modules in types.{submodule,submoduleWith}
ea7ef12
to
a2e42df
Compare
Changes:
From my side this is ready to be merged now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a documentation improvement (see review comment) and a question/idea.
I was thinking about the difference between options.x = submoduleWith { modules }
and config.x = modules
.
Did you or @danbst try hiding option docs by adding them through a config
definition instead of the modules
parameter?
I haven't checked this, but assuming you can use option priority (mkForce
etc) to override the set of config
modules, that may be a reason to pick the one or the other.
Perhaps these questions can also be addressed in the documentation.
Ah yes that does work, confirmed with this: { lib, ... }: {
options.test = lib.mkOption {
type = lib.types.submoduleWith {
modules = [{
options.foo = lib.mkOption {};
}];
};
};
config = {
test.options.bar = lib.mkOption {};
documentation.nixos.includeAllModules = true;
boot.loader.grub.device = "nodev";
fileSystems."/".device = "test";
};
} $ cat $(nix-build nixos --arg configuration ./config.nix -A config.system.build.manual.optionsJSON)/share/doc/nixos/options.json | grep test.bar But yeah the fact that modules defined in the |
Module arguments should be taken from the arguments directly. This allows evalModule's specialArgs to override them if necessary
a2e42df
to
cc81320
Compare
@roberth Done did that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
This fixes the dhcpcd issue in NixOS#76969, which was exposed by NixOS#75031 introducing changes in the module ordering and therefore option ordering too. The dhcpcd issue would also be fixable by explicitly putting dhcpcd's paths before others, however it makes more sense for systemd's default paths to be after all others by default, since they should only be a fallback, which is how binary finding will work if they come after.
This fixes the dhcpcd issue in NixOS#76969, which was exposed by NixOS#75031 introducing changes in the module ordering and therefore option ordering too. The dhcpcd issue would also be fixable by explicitly putting dhcpcd's paths before others, however it makes more sense for systemd's default paths to be after all others by default, since they should only be a fallback, which is how binary finding will work if they come after. (cherry picked from commit 9327e1c)
Motivation for this change
All these changes are there to allow NixOS to be used as submodule, which I'm doing tests with right now. This will allow things like:
Ping @Profpatsch @rycee @kreisys @nbp @edolstra @oxij @danbst @roberth
Best reviewed commit by commit
Things done
submoduleWith
fullSubmodule
-> Now namedsubmoduleWith
configDefault
-> Now namedshorthandOnlyDefinesConfig
shorthandOnlyDefinesConfig
does -> It's in the docsFor idempotentNothing needs this behavior directly, so no tests necessaryunifyModuleSyntax
submoduleWith
tested
set gives smaller numbers for all valuesMaybe deprecateRemoving them seems fine, it's really just an artifact from the module system implementation, there never should've been a need to expose this anyways.packSubmodule
andunpackSubmodule
instead of removing, though they very very likely aren't used in the wild, so probably not worth keeping them aroundtested
set evaluates still