Skip to content

Commit

Permalink
Merge pull request #156503 from hercules-ci/nixos-add-system.build-op…
Browse files Browse the repository at this point in the history
…tions

nixos: Add `system.build.`{`toplevel`,`installBootLoader`}, improve error message
  • Loading branch information
roberth authored Jan 25, 2022
2 parents 25dc5a5 + 48dbe26 commit 8919495
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 20 deletions.
5 changes: 3 additions & 2 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ let
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption getValues
getFiles optionAttrSetToDocList optionAttrSetToDocList'
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
getValues getFiles
optionAttrSetToDocList optionAttrSetToDocList'
scrubOptionValue literalExpression literalExample literalDocBook
showOption showFiles unknownModule mkOption;
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
Expand Down
12 changes: 7 additions & 5 deletions lib/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ rec {
else if all isInt list && all (x: x == head list) list then head list
else throw "Cannot merge definitions of `${showOption loc}'. Definition values:${showDefs defs}";

mergeOneOption = loc: defs:
if defs == [] then abort "This case should never happen."
else if length defs != 1 then
throw "The unique option `${showOption loc}' is defined multiple times. Definition values:${showDefs defs}"
else (head defs).value;
mergeOneOption = mergeUniqueOption { message = ""; };

mergeUniqueOption = { message }: loc: defs:
if length defs == 1
then (head defs).value
else assert length defs > 1;
throw "The option `${showOption loc}' is defined multiple times.\n${message}\nDefinition values:${showDefs defs}";

/* "Merge" option definitions by checking that they all have the same value. */
mergeEqualOption = loc: defs:
Expand Down
15 changes: 14 additions & 1 deletion lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ let
last
length
tail
unique
;
inherit (lib.attrsets)
attrNames
Expand All @@ -48,6 +47,7 @@ let
mergeDefaultOption
mergeEqualOption
mergeOneOption
mergeUniqueOption
showFiles
showOption
;
Expand Down Expand Up @@ -470,6 +470,18 @@ rec {
nestedTypes.elemType = elemType;
};

unique = { message }: type: mkOptionType rec {
name = "unique";
inherit (type) description check;
merge = mergeUniqueOption { inherit message; };
emptyValue = type.emptyValue;
getSubOptions = type.getSubOptions;
getSubModules = type.getSubModules;
substSubModules = m: uniq (type.substSubModules m);
functor = (defaultFunctor name) // { wrapped = type; };
nestedTypes.elemType = type;
};

# Null or value of ...
nullOr = elemType: mkOptionType rec {
name = "nullOr";
Expand Down Expand Up @@ -599,6 +611,7 @@ rec {
# A value from a set of allowed ones.
enum = values:
let
inherit (lib.lists) unique;
show = v:
if builtins.isString v then ''"${v}"''
else if builtins.isInt v then builtins.toString v
Expand Down
6 changes: 6 additions & 0 deletions nixos/doc/manual/development/option-types.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ Composed types are types that take a type as parameter. `listOf
: Ensures that type *`t`* cannot be merged. It is used to ensure option
definitions are declared only once.

`types.unique` `{ message = m }` *`t`*

: Ensures that type *`t`* cannot be merged. Prints the message *`m`*, after
the line `The option <option path> is defined multiple times.` and before
a list of definition locations.

`types.either` *`t1 t2`*

: Type *`t1`* or type *`t2`*, e.g. `with types; either int str`.
Expand Down
16 changes: 16 additions & 0 deletions nixos/doc/manual/from_md/development/option-types.section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,22 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>types.unique</literal>
<literal>{ message = m }</literal>
<emphasis><literal>t</literal></emphasis>
</term>
<listitem>
<para>
Ensures that type <emphasis><literal>t</literal></emphasis>
cannot be merged. Prints the message
<emphasis><literal>m</literal></emphasis>, after the line
<literal>The option &lt;option path&gt; is defined multiple times.</literal>
and before a list of definition locations.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>types.either</literal>
Expand Down
57 changes: 45 additions & 12 deletions nixos/modules/system/activation/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ let
utillinux = pkgs.util-linux;

kernelParams = config.boot.kernelParams;
installBootLoader =
config.system.build.installBootLoader
or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
installBootLoader = config.system.build.installBootLoader;
activationScript = config.system.activationScripts.script;
dryActivationScript = config.system.dryActivationScript;
nixosLabel = config.system.nixos.label;
Expand All @@ -135,25 +133,27 @@ let
pkgs.replaceDependency { inherit oldDependency newDependency drv; }
) baseSystemAssertWarn config.system.replaceRuntimeDependencies;

/* Workaround until https://github.com/NixOS/nixpkgs/pull/156533
Call can be replaced by argument when that's merged.
*/
tmpFixupSubmoduleBoundary = subopts:
lib.mkOption {
type = lib.types.submoduleWith {
modules = [ { options = subopts; } ];
};
};

in

{
imports = [
../build.nix
(mkRemovedOptionModule [ "nesting" "clone" ] "Use `specialisation.«name» = { inheritParentConfig = true; configuration = { ... }; }` instead.")
(mkRemovedOptionModule [ "nesting" "children" ] "Use `specialisation.«name».configuration = { ... }` instead.")
];

options = {

system.build = mkOption {
internal = true;
default = {};
type = with types; lazyAttrsOf (uniq unspecified);
description = ''
Attribute set of derivations used to setup the system.
'';
};

specialisation = mkOption {
default = {};
example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.buildCores = 0; nix.maxJobs = 1; }; }";
Expand Down Expand Up @@ -224,6 +224,39 @@ in
'';
};

system.build = tmpFixupSubmoduleBoundary {
installBootLoader = mkOption {
internal = true;
# "; true" => make the `$out` argument from switch-to-configuration.pl
# go to `true` instead of `echo`, hiding the useless path
# from the log.
default = "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
description = ''
A program that writes a bootloader installation script to the path passed in the first command line argument.
See <literal>nixos/modules/system/activation/switch-to-configuration.pl</literal>.
'';
type = types.unique {
message = ''
Only one bootloader can be enabled at a time. This requirement has not
been checked until NixOS 22.05. Earlier versions defaulted to the last
definition. Change your configuration to enable only one bootloader.
'';
} (types.either types.str types.package);
};

toplevel = mkOption {
type = types.package;
readOnly = true;
description = ''
This option contains the store path that typically represents a NixOS system.
You can read this path in a custom deployment tool for example.
'';
};
};


system.copySystemConfiguration = mkOption {
type = types.bool;
default = false;
Expand Down
21 changes: 21 additions & 0 deletions nixos/modules/system/build.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{ lib, ... }:
let
inherit (lib) mkOption types;
in
{
options = {

system.build = mkOption {
default = {};
description = ''
Attribute set of derivations used to set up the system.
'';
type = types.submoduleWith {
modules = [{
freeformType = with types; lazyAttrsOf (uniq unspecified);
}];
};
};

};
}

0 comments on commit 8919495

Please sign in to comment.