nixos/README.md: relax the requirement of providing option defaults (#334509)
[NixPkgs.git] / nixos / modules / system / boot / kernel_config.nix
blob8ca9c96006a486e8339999dbe0293e28bf7e600c
1 { lib, config, ... }:
3 with lib;
4 let
5   mergeFalseByDefault =
6     locs: defs:
7     if defs == [ ] then
8       abort "This case should never happen."
9     else if any (x: x == false) (getValues defs) then
10       false
11     else
12       true;
14   kernelItem = types.submodule {
15     options = {
16       tristate = mkOption {
17         type = types.enum [
18           "y"
19           "m"
20           "n"
21           null
22         ];
23         default = null;
24         internal = true;
25         visible = true;
26         description = ''
27           Use this field for tristate kernel options expecting a "y" or "m" or "n".
28         '';
29       };
31       freeform = mkOption {
32         type = types.nullOr types.str // {
33           merge = mergeEqualOption;
34         };
35         default = null;
36         example = ''MMC_BLOCK_MINORS.freeform = "32";'';
37         description = ''
38           Freeform description of a kernel configuration item value.
39         '';
40       };
42       optional = mkOption {
43         type = types.bool // {
44           merge = mergeFalseByDefault;
45         };
46         default = false;
47         description = ''
48           Whether option should generate a failure when unused.
49           Upon merging values, mandatory wins over optional.
50         '';
51       };
52     };
53   };
55   mkValue =
56     with lib;
57     val:
58     let
59       isNumber =
60         c:
61         elem c [
62           "0"
63           "1"
64           "2"
65           "3"
66           "4"
67           "5"
68           "6"
69           "7"
70           "8"
71           "9"
72         ];
74     in
75     if (val == "") then
76       "\"\""
77     else if val == "y" || val == "m" || val == "n" then
78       val
79     else if all isNumber (stringToCharacters val) then
80       val
81     else if substring 0 2 val == "0x" then
82       val
83     else
84       val; # FIXME: fix quoting one day
86   # generate nix intermediate kernel config file of the form
87   #
88   #       VIRTIO_MMIO m
89   #       VIRTIO_BLK y
90   #       VIRTIO_CONSOLE n
91   #       NET_9P_VIRTIO? y
92   #
93   # Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
94   # returns a string, expr should be an attribute set
95   # Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa
96   # use the identity if you don't want to override the configured values
97   generateNixKConf =
98     exprs:
99     let
100       mkConfigLine =
101         key: item:
102         let
103           val = if item.freeform != null then item.freeform else item.tristate;
104         in
105         optionalString (val != null) (
106           if (item.optional) then "${key}? ${mkValue val}\n" else "${key} ${mkValue val}\n"
107         );
109       mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
110     in
111     mkConf exprs;
116   options = {
118     intermediateNixConfig = mkOption {
119       readOnly = true;
120       type = types.lines;
121       example = ''
122         USB? y
123         DEBUG n
124       '';
125       description = ''
126         The result of converting the structured kernel configuration in settings
127         to an intermediate string that can be parsed by generate-config.pl to
128         answer the kernel `make defconfig`.
129       '';
130     };
132     settings = mkOption {
133       type = types.attrsOf kernelItem;
134       example = literalExpression ''
135         with lib.kernel; {
136                "9P_NET" = yes;
137                USB = option yes;
138                MMC_BLOCK_MINORS = freeform "32";
139              }'';
140       description = ''
141         Structured kernel configuration.
142       '';
143     };
144   };
146   config = {
147     intermediateNixConfig = generateNixKConf config.settings;
148   };