diff options
author | Silvan Mosberger <infinisil@icloud.com> | 2019-01-28 10:38:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-28 10:38:00 +0100 |
commit | 51d2eed83b4787e167e59871380433c02c033c42 (patch) | |
tree | 2905fac4fc39c732be9369f075db977cff493e12 /nixos | |
parent | 8c2aaf37fde021717d7ca7b2ec651a628f9ae38b (diff) | |
parent | 045e1332d97d0db7c09265d2c2041fbca906286c (diff) | |
download | nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar.gz nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar.bz2 nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar.lz nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar.xz nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.tar.zst nixpkgs-51d2eed83b4787e167e59871380433c02c033c42.zip |
Merge pull request #42838 from teto/kernel_autoconf
[RFC] add ability to merge structured configs
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/system/boot/kernel_config.nix | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/nixos/modules/system/boot/kernel_config.nix b/nixos/modules/system/boot/kernel_config.nix new file mode 100644 index 00000000000..fbbd0982b2c --- /dev/null +++ b/nixos/modules/system/boot/kernel_config.nix @@ -0,0 +1,137 @@ +{ lib, config, ... }: + +with lib; +let + findWinner = candidates: winner: + any (x: x == winner) candidates; + + # winners is an ordered list where first item wins over 2nd etc + mergeAnswer = winners: locs: defs: + let + values = map (x: x.value) defs; + freeformAnswer = intersectLists values winners; + inter = intersectLists values winners; + winner = head winners; + in + if defs == [] then abort "This case should never happen." + else if winner == [] then abort "Give a valid list of winner" + else if inter == [] then mergeOneOption locs defs + else if findWinner values winner then + winner + else + mergeAnswer (tail winners) locs defs; + + mergeFalseByDefault = locs: defs: + if defs == [] then abort "This case should never happen." + else if any (x: x == false) defs then false + else true; + + kernelItem = types.submodule { + options = { + tristate = mkOption { + type = types.enum [ "y" "m" "n" null ] // { + merge = mergeAnswer [ "y" "m" "n" ]; + }; + default = null; + internal = true; + visible = true; + description = '' + Use this field for tristate kernel options expecting a "y" or "m" or "n". + ''; + }; + + freeform = mkOption { + type = types.nullOr types.str // { + merge = mergeEqualOption; + }; + default = null; + example = ''MMC_BLOCK_MINORS.freeform = "32";''; + description = '' + Freeform description of a kernel configuration item value. + ''; + }; + + optional = mkOption { + type = types.bool // { merge = mergeFalseByDefault; }; + default = false; + description = '' + Wether option should generate a failure when unused. + ''; + }; + }; + }; + + mkValue = with lib; val: + let + isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"]; + + in + if (val == "") then "\"\"" + else if val == "y" || val == "m" || val == "n" then val + else if all isNumber (stringToCharacters val) then val + else if substring 0 2 val == "0x" then val + else val; # FIXME: fix quoting one day + + + # generate nix intermediate kernel config file of the form + # + # VIRTIO_MMIO m + # VIRTIO_BLK y + # VIRTIO_CONSOLE n + # NET_9P_VIRTIO? y + # + # Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158 + # returns a string, expr should be an attribute set + # Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa + # use the identity if you don't want to override the configured values + generateNixKConf = exprs: + let + mkConfigLine = key: item: + let + val = if item.freeform != null then item.freeform else item.tristate; + in + if val == null + then "" + else if (item.optional) + then "${key}? ${mkValue val}\n" + else "${key} ${mkValue val}\n"; + + mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg); + in mkConf exprs; + +in +{ + + options = { + + intermediateNixConfig = mkOption { + readOnly = true; + type = types.lines; + example = '' + USB? y + DEBUG n + ''; + description = '' + The result of converting the structured kernel configuration in settings + to an intermediate string that can be parsed by generate-config.pl to + answer the kernel `make defconfig`. + ''; + }; + + settings = mkOption { + type = types.attrsOf kernelItem; + example = literalExample '' with lib.kernel; { + "9P_NET" = yes; + USB = optional yes; + MMC_BLOCK_MINORS = freeform "32"; + }''; + description = '' + Structured kernel configuration. + ''; + }; + }; + + config = { + intermediateNixConfig = generateNixKConf config.settings; + }; +} |