···66 ...
77}:
88let
99+ inherit (builtins) concatLists attrNames;
910 inherit (lib.options) mkOption literalExpression;
1011 inherit (lib) types;
1112···17181819 cfg = config.easyHosts;
19202020- # we really expect a list of paths but i want to accept lists of lists of lists and so on
2121- # since they will be flattened in the final function that applies the settings
2222- modulesType = types.listOf types.anything;
2121+ mkBasicParams = name: {
2222+ modules = mkOption {
2323+ # we really expect a list of paths but i want to accept lists of lists of lists and so on
2424+ # since they will be flattened in the final function that applies the settings
2525+ type = types.listOf types.anything;
2626+ default = [ ];
2727+ description = "${name} modules to be included in the system";
2828+ example = literalExpression ''
2929+ [ ./hardware-configuration.nix ./networking.nix ]
3030+ '';
3131+ };
23322424- specialArgsType = types.lazyAttrsOf types.raw;
3333+ specialArgs = mkOption {
3434+ type = types.lazyAttrsOf types.raw;
3535+ default = { };
3636+ description = "${name} special arguments to be passed to the system";
3737+ example = literalExpression ''
3838+ { foo = "bar"; }
3939+ '';
4040+ };
4141+ };
2542in
2643{
2744 options = {
···4057 example = literalExpression "aarch64-darwin";
4158 };
42594343- shared = {
4444- modules = mkOption {
4545- type = modulesType;
4646- default = [ ];
4747- };
4848-4949- specialArgs = mkOption {
5050- type = specialArgsType;
5151- default = { };
5252- };
5353- };
6060+ shared = mkBasicParams "Shared";
54615562 perClass = mkOption {
5663 default = _: {
···5966 };
6067 type = types.functionTo (
6168 types.submodule {
6262- options = {
6363- modules = mkOption {
6464- type = modulesType;
6565- default = [ ];
6666- };
6767-6868- specialArgs = mkOption {
6969- type = specialArgsType;
7070- default = { };
7171- };
7272- };
6969+ options = mkBasicParams "Per class";
7370 }
7471 );
7572 };
···9794 in
9895 {
9996 options = {
9797+ # keep this up to date with
9898+ # https://github.com/NixOS/nixpkgs/blob/75a43236cfd40adbc6138029557583eb77920afd/lib/systems/flake-systems.nix#L1
10099 arch = mkOption {
101101- type = types.str;
100100+ type = types.enum [
101101+ "x86_64"
102102+ "aarch64"
103103+ "armv6l"
104104+ "armv7l"
105105+ "i686"
106106+ "powerpc64le"
107107+ "riscv64"
108108+ ];
102109 default = "x86_64";
110110+ example = "aarch64";
103111 };
104112105113 class = mkOption {
106106- type = types.str;
114114+ type = types.enum (concatLists [
115115+ [
116116+ "nixos"
117117+ "darwin"
118118+ "iso"
119119+ ]
120120+121121+ (attrNames cfg.additionalClasses)
122122+ ]);
107123 default = "nixos";
124124+ example = "darwin";
108125 };
109126110127 system = mkOption {
111128 type = types.str;
112129 default = constructSystem cfg self.class self.arch;
130130+ example = "aarch64-darwin";
113131 };
114132115133 path = mkOption {
···122140 type = types.bool;
123141 default = false;
124142 };
125125-126126- modules = mkOption {
127127- type = modulesType;
128128- default = [ ];
129129- };
130130-131131- specialArgs = mkOption {
132132- type = specialArgsType;
133133- default = { };
134134- };
135135- };
143143+ } // (mkBasicParams name);
136144 }
137145 )
138146 );
+126-118
lib.nix
···2323 filterAttrs
2424 ;
2525 inherit (lib.modules) mkDefault evalModules;
2626+ inherit (lib.trivial) mergeAttrs;
26272728 classToOS = class: if (class == "darwin") then "darwin" else "linux";
2829 classToND = class: if (class == "darwin") then "darwin" else "nixos";
···9091 specialArgs ? { },
9192 ...
9293 }:
9393- withSystem system (
9494- { self', inputs', ... }:
9595- let
9696- darwinInput =
9797- if (inputs ? darwin) then
9898- inputs.darwin
9999- else if (inputs ? nix-darwin) then
100100- inputs.nix-darwin
101101- else
102102- throw "cannot find nix-darwin input";
9494+ let
9595+ darwinInput = inputs.darwin or inputs.nix-darwin or (throw "cannot find nix-darwin input");
9696+ nixpkgs = inputs.nixpkgs or (throw "cannot find nixpkgs input");
10397104104- # create the modulesPath based on the system, we need
105105- modulesPath =
106106- if class == "darwin" then "${darwinInput}/modules" else "${inputs.nixpkgs}/nixos/modules";
9898+ # create the modulesPath based on the system, we need
9999+ modulesPath = if class == "darwin" then "${darwinInput}/modules" else "${nixpkgs}/nixos/modules";
107100108108- # we need to import the module list for our system
109109- # this is either the nixos modules list provided by nixpkgs
110110- # or the darwin modules list provided by nix darwin
111111- baseModules = import "${modulesPath}/module-list.nix";
101101+ # we need to import the module list for our system
102102+ # this is either the nixos modules list provided by nixpkgs
103103+ # or the darwin modules list provided by nix darwin
104104+ baseModules = import "${modulesPath}/module-list.nix";
112105113113- eval = evalModules {
114114- # we use recursiveUpdate such that users can "override" the specialArgs
115115- #
116116- # This should only be used for special arguments that need to be evaluated
117117- # when resolving module structure (like in imports).
118118- specialArgs = recursiveUpdate {
119119- inherit
120120- # these are normal args that people expect to be passed
121121- lib
122122- self # even though self is just the same as `inputs.self`
123123- inputs
106106+ eval = evalModules {
107107+ # we use recursiveUpdate such that users can "override" the specialArgs
108108+ #
109109+ # This should only be used for special arguments that need to be evaluated
110110+ # when resolving module structure (like in imports).
111111+ specialArgs = recursiveUpdate {
112112+ inherit
113113+ # these are normal args that people expect to be passed,
114114+ # but we expect to be evaulated when resolving module structure
115115+ inputs
124116125125- # these come from flake-parts
126126- self'
127127- inputs'
117117+ # even though self is just the same as `inputs.self`
118118+ # we still pass this as some people will use this
119119+ self
128120129129- # we need to set this beacuse some modules require it sadly
130130- # you may also recall `modulesPath + /installer/scan/not-detected.nix`
131131- modulesPath
132132- ;
133133- } specialArgs;
121121+ # we need to set this beacuse some modules require it sadly
122122+ # you may also recall `modulesPath + /installer/scan/not-detected.nix`
123123+ modulesPath
124124+ ;
125125+ } specialArgs;
134126135135- # A nominal type for modules. When set and non-null, this adds a check to
136136- # make sure that only compatible modules are imported.
137137- class = classToND class;
127127+ # A nominal type for modules. When set and non-null, this adds a check to
128128+ # make sure that only compatible modules are imported.
129129+ class = classToND class;
138130139139- modules = flatten [
140140- # bring in all of our base modules
141141- baseModules
131131+ modules = flatten [
132132+ # bring in all of our base modules
133133+ baseModules
142134143143- # import our host system paths
144144- (
145145- if path != null then
146146- path
147147- else
148148- (filter pathExists [
149149- # if the previous path does not exist then we will try to import some paths with some assumptions
150150- "${self}/hosts/${name}/default.nix"
151151- "${self}/systems/${name}/default.nix"
152152- ])
153153- )
135135+ # import our host system paths
136136+ (
137137+ if path != null then
138138+ path
139139+ else
140140+ (filter pathExists [
141141+ # if the previous path does not exist then we will try to import some paths with some assumptions
142142+ "${self}/hosts/${name}/default.nix"
143143+ "${self}/systems/${name}/default.nix"
144144+ ])
145145+ )
154146155155- # get an installer profile from nixpkgs to base the Isos off of
156156- # this is useful because it makes things alot easier
157157- (optionals (class == "iso") [
158158- "${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix"
159159- ])
147147+ # get an installer profile from nixpkgs to base the Isos off of
148148+ # this is useful because it makes things alot easier
149149+ (optionals (class == "iso") [
150150+ "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix"
151151+ ])
160152161161- (singleton {
162162- # some modules to have these arguments, like documentation.nix
163163- # <https://github.com/NixOS/nixpkgs/blob/9692553cb583e8dca46b66ab76c0eb2ada1a4098/nixos/modules/misc/documentation.nix>
164164- _module.args = {
165165- inherit baseModules;
153153+ # the next 3 singleton's are split up to make it easier to understand as they do things diffrent things
166154167167- # this should in the future be the modules that the user added without baseModules
168168- modules = [ ];
155155+ # recall `specialArgs` would take be prefered when resolving module structure
156156+ # well this is how we do it use it for all args that don't need to rosolve module structure
157157+ (singleton {
158158+ _module.args = withSystem system (
159159+ { self', inputs', ... }:
160160+ {
161161+ inherit self' inputs';
162162+ }
163163+ );
164164+ })
169165170170- # TODO: remove in 25.05
171171- # https://github.com/NixOS/nixpkgs/blob/9692553cb583e8dca46b66ab76c0eb2ada1a4098/nixos/lib/eval-config.nix#L38
172172- extraModules = [ ];
173173- };
166166+ # some modules to have these arguments, like documentation.nix
167167+ # <https://github.com/NixOS/nixpkgs/blob/9692553cb583e8dca46b66ab76c0eb2ada1a4098/nixos/modules/misc/documentation.nix>
168168+ (singleton {
169169+ _module.args = {
170170+ inherit baseModules;
174171175175- # we set the systems hostname based on the host value
176176- # which should be a string that is the hostname of the system
177177- networking.hostName = name;
172172+ # this should in the future be the modules that the user added without baseModules
173173+ modules = [ ];
178174179179- nixpkgs = {
180180- # you can also do this as `inherit system;` with the normal `lib.nixosSystem`
181181- # however for evalModules this will not work, so we do this instead
182182- hostPlatform = mkDefault system;
175175+ # TODO: remove in 25.05
176176+ # https://github.com/NixOS/nixpkgs/blob/9692553cb583e8dca46b66ab76c0eb2ada1a4098/nixos/lib/eval-config.nix#L38
177177+ extraModules = [ ];
178178+ };
179179+ })
183180184184- # The path to the nixpkgs sources used to build the system.
185185- # This is automatically set up to be the store path of the nixpkgs flake used to build
186186- # the system if using lib.nixosSystem, and is otherwise null by default.
187187- # so that means that we should set it to our nixpkgs flake output path
188188- flake.source = inputs.nixpkgs.outPath;
189189- };
190190- })
181181+ # here we make some basic assumptions about the system the person is using
182182+ # like the system type and the hostname
183183+ (singleton {
184184+ # we set the systems hostname based on the host value
185185+ # which should be a string that is the hostname of the system
186186+ networking.hostName = mkDefault name;
191187192192- # if we are on darwin we need to import the nixpkgs source, its used in some
193193- # modules, if this is not set then you will get an error
194194- (optionals (class == "darwin") (singleton {
195195- # without supplying an upstream nixpkgs source, nix-darwin will not be able to build
196196- # and will complain and log an error demanding that you must set this value
197197- nixpkgs.source = mkDefault inputs.nixpkgs;
188188+ nixpkgs = {
189189+ # you can also do this as `inherit system;` with the normal `lib.nixosSystem`
190190+ # however for evalModules this will not work, so we do this instead
191191+ hostPlatform = mkDefault system;
198192199199- system = {
200200- # i don't quite know why this is set but upstream does it so i will too
201201- checks.verifyNixPath = false;
193193+ # The path to the nixpkgs sources used to build the system.
194194+ # This is automatically set up to be the store path of the nixpkgs flake used to build
195195+ # the system if using lib.nixosSystem, and is otherwise null by default.
196196+ # so that means that we should set it to our nixpkgs flake output path
197197+ flake.source = nixpkgs.outPath;
198198+ };
199199+ })
202200203203- # we use these values to keep track of what upstream revision we are on, this also
204204- # prevents us from recreating docs for the same configuration build if nothing has changed
205205- darwinVersionSuffix = ".${darwinInput.shortRev or darwinInput.dirtyShortRev or "dirty"}";
206206- darwinRevision = darwinInput.rev or darwinInput.dirtyRev or "dirty";
207207- };
208208- }))
201201+ # if we are on darwin we need to import the nixpkgs source, its used in some
202202+ # modules, if this is not set then you will get an error
203203+ (optionals (class == "darwin") (singleton {
204204+ # without supplying an upstream nixpkgs source, nix-darwin will not be able to build
205205+ # and will complain and log an error demanding that you must set this value
206206+ nixpkgs.source = mkDefault nixpkgs;
207207+208208+ system = {
209209+ # i don't quite know why this is set but upstream does it so i will too
210210+ checks.verifyNixPath = false;
211211+212212+ # we use these values to keep track of what upstream revision we are on, this also
213213+ # prevents us from recreating docs for the same configuration build if nothing has changed
214214+ darwinVersionSuffix = ".${darwinInput.shortRev or darwinInput.dirtyShortRev or "dirty"}";
215215+ darwinRevision = darwinInput.rev or darwinInput.dirtyRev or "dirty";
216216+ };
217217+ }))
209218210210- # import any additional modules that the user has provided
211211- modules
212212- ];
219219+ # import any additional modules that the user has provided
220220+ modules
221221+ ];
222222+ };
223223+ in
224224+ if ((classToND class) == "nixos") then
225225+ { nixosConfigurations.${name} = eval; }
226226+ else
227227+ {
228228+ darwinConfigurations.${name} = eval // {
229229+ system = eval.config.system.build.toplevel;
213230 };
214214- in
215215- if ((classToND class) == "nixos") then
216216- { nixosConfigurations.${name} = eval; }
217217- else
218218- {
219219- darwinConfigurations.${name} = eval // {
220220- system = eval.config.system.build.toplevel;
221221- };
222222- }
223223- );
231231+ };
224232225233 foldAttrsReccursive = foldl' (acc: attrs: recursiveUpdate acc attrs) { };
226234227235 mkHosts =
228236 easyHostsConfig:
229229- foldAttrs (host: acc: host // acc) { } (
237237+ foldAttrs mergeAttrs { } (
230238 attrValues (
231239 mapAttrs (
232240 name: hostConfig:
···239247240248 # merging is handled later
241249 modules = [
242242- (hostConfig.modules or [ ])
243243- (easyHostsConfig.shared.modules or [ ])
244244- ((easyHostsConfig.perClass hostConfig.class).modules or [ ])
250250+ hostConfig.modules
251251+ easyHostsConfig.shared.modules
252252+ (easyHostsConfig.perClass hostConfig.class).modules
245253 ];
246254247255 specialArgs = foldAttrsReccursive [
248248- (hostConfig.specialArgs or { })
249249- (easyHostsConfig.shared.specialArgs or { })
250250- ((easyHostsConfig.perClass hostConfig.class).specialArgs or { })
256256+ hostConfig.specialArgs
257257+ easyHostsConfig.shared.specialArgs
258258+ (easyHostsConfig.perClass hostConfig.class).specialArgs
251259 ];
252260 }
253261 ) easyHostsConfig.hosts