diff --git a/lib/kernel.nix b/lib/kernel.nix index 2ce19f8cb68..a0f986ee116 100644 --- a/lib/kernel.nix +++ b/lib/kernel.nix @@ -8,10 +8,10 @@ with lib; option = x: x // { optional = true; }; - yes = { tristate = "y"; }; - no = { tristate = "n"; }; - module = { tristate = "m"; }; - freeform = x: { freeform = x; }; + yes = { tristate = "y"; optional = false; }; + no = { tristate = "n"; optional = false; }; + module = { tristate = "m"; optional = false; }; + freeform = x: { freeform = x; optional = false; }; /* Common patterns/legacy used in common-config/hardened-config.nix diff --git a/nixos/modules/system/boot/kernel_config.nix b/nixos/modules/system/boot/kernel_config.nix index a316782dfc5..85bd420e304 100644 --- a/nixos/modules/system/boot/kernel_config.nix +++ b/nixos/modules/system/boot/kernel_config.nix @@ -22,7 +22,7 @@ let mergeFalseByDefault = locs: defs: if defs == [] then abort "This case should never happen." - else if any (x: x == false) defs then false + else if any (x: x == false) (getValues defs) then false else true; kernelItem = types.submodule { @@ -55,6 +55,7 @@ let default = false; description = '' Wether option should generate a failure when unused. + Upon merging values, mandatory wins over optional. ''; }; }; @@ -121,7 +122,7 @@ in type = types.attrsOf kernelItem; example = literalExample '' with lib.kernel; { "9P_NET" = yes; - USB = optional yes; + USB = option yes; MMC_BLOCK_MINORS = freeform "32"; }''; description = '' diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix index e6e1bd84236..a9d0cf45168 100644 --- a/pkgs/os-specific/linux/kernel/generic.nix +++ b/pkgs/os-specific/linux/kernel/generic.nix @@ -158,11 +158,8 @@ let ; }).config; - # structuredConfig = moduleStructuredConfig.settings; }; - - }; # end of configfile derivation kernel = (callPackage ./manual-config.nix {}) { diff --git a/pkgs/test/kernel.nix b/pkgs/test/kernel.nix index 86f1b8d8e9a..a4da1003033 100644 --- a/pkgs/test/kernel.nix +++ b/pkgs/test/kernel.nix @@ -1,53 +1,79 @@ +# to run these tests: +# nix-instantiate --eval --strict . -A tests.kernel-config +# +# make sure to use NON EXISTING kernel settings else they may conflict with +# common-config.nix { lib, pkgs }: -with lib.kernel; -with lib.asserts; -with lib.modules; +with lib; +with kernel; -# To test nixos/modules/system/boot/kernel_config.nix; let - # copied from release-lib.nix - assertTrue = bool: - if bool - then pkgs.runCommand "evaluated-to-true" {} "touch $out" - else pkgs.runCommand "evaluated-to-false" {} "false"; - lts_kernel = pkgs.linuxPackages.kernel; - kernelTestConfig = structuredConfig: (lts_kernel.override { - structuredExtraConfig = structuredConfig; - }).configfile.structuredConfig; + # to see the result once the module transformed the lose structured config + getConfig = structuredConfig: + (lts_kernel.override { + structuredExtraConfig = structuredConfig; + }).configfile.structuredConfig; mandatoryVsOptionalConfig = mkMerge [ - { USB_DEBUG = option yes;} - { USB_DEBUG = yes;} + { NIXOS_FAKE_USB_DEBUG = yes;} + { NIXOS_FAKE_USB_DEBUG = option yes; } ]; freeformConfig = mkMerge [ - { MMC_BLOCK_MINORS = freeform "32"; } # same as default, won't trigger any error - { MMC_BLOCK_MINORS = freeform "64"; } # will trigger an error but the message is not great: + { NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "32"; } # same as default, won't trigger any error + { NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "64"; } # will trigger an error but the message is not great: ]; yesWinsOverNoConfig = mkMerge [ - # default for "8139TOO_PIO" is no - { "8139TOO_PIO" = yes; } # yes wins over no by default - { "8139TOO_PIO" = no; } + # default for "NIXOS_TEST_BOOLEAN" is no + { "NIXOS_TEST_BOOLEAN" = yes; } # yes wins over no by default + { "NIXOS_TEST_BOOLEAN" = no; } ]; + + optionalNoWins = mkMerge [ + { NIXOS_FAKE_USB_DEBUG = option yes;} + { NIXOS_FAKE_USB_DEBUG = yes;} + ]; + + allOptionalRemainOptional = mkMerge [ + { NIXOS_FAKE_USB_DEBUG = option yes;} + { NIXOS_FAKE_USB_DEBUG = option yes;} + ]; + in -{ +runTests { + testEasy = { + expr = (getConfig { NIXOS_FAKE_USB_DEBUG = yes;}).NIXOS_FAKE_USB_DEBUG; + expected = { tristate = "y"; optional = false; freeform = null; }; + }; + # mandatory flag should win over optional - mandatoryCheck = (kernelTestConfig mandatoryVsOptionalConfig); + testMandatoryCheck = { + expr = (getConfig mandatoryVsOptionalConfig).NIXOS_FAKE_USB_DEBUG.optional; + expected = false; + }; + + testYesWinsOverNo = { + expr = (getConfig yesWinsOverNoConfig)."NIXOS_TEST_BOOLEAN".tristate; + expected = "y"; + }; + + testAllOptionalRemainOptional = { + expr = (getConfig allOptionalRemainOptional)."NIXOS_FAKE_USB_DEBUG".optional; + expected = true; + }; # check that freeform options are unique # Should trigger - # > The option `settings.MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `' and `' - freeformCheck = let - res = builtins.tryEval ( (kernelTestConfig freeformConfig).MMC_BLOCK_MINORS.freeform); - in - assertTrue (res.success == false); + # > The option `settings.NIXOS_FAKE_MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `' and `' + testTreeform = let + res = builtins.tryEval ( (getConfig freeformConfig).NIXOS_FAKE_MMC_BLOCK_MINORS.freeform); + in { + expr = res.success; + expected = false; + }; - yesVsNoCheck = let - res = kernelTestConfig yesWinsOverNoConfig; - in - assertTrue (res."8139TOO_PIO".tristate == "y"); }