diff --git a/lib/build-vms.nix b/lib/build-vms.nix index e8e5885137d6..aacd0e99cb18 100644 --- a/lib/build-vms.nix +++ b/lib/build-vms.nix @@ -1,4 +1,4 @@ -{ system }: +{ system, minimal ? false }: let pkgs = import { config = {}; inherit system; }; in @@ -27,7 +27,7 @@ rec { [ ../modules/virtualisation/qemu-vm.nix ../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs { key = "no-manual"; services.nixosManual.enable = false; } - ]; + ] ++ lib.optional minimal ../modules/testing/minimal-kernel.nix; extraArgs = { inherit nodes; }; }; diff --git a/lib/testing.nix b/lib/testing.nix index 6a39df8c865d..a27f4344c6ae 100644 --- a/lib/testing.nix +++ b/lib/testing.nix @@ -1,6 +1,6 @@ -{ system }: +{ system, minimal ? false }: -with import ./build-vms.nix { inherit system; }; +with import ./build-vms.nix { inherit system minimal; }; with pkgs; rec { diff --git a/modules/config/swap.nix b/modules/config/swap.nix index 163de568d0f7..5b20f657e129 100644 --- a/modules/config/swap.nix +++ b/modules/config/swap.nix @@ -73,4 +73,10 @@ with pkgs.lib; }; + config = mkIf ((length config.swapDevices) != 0) { + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isYes "SWAP") + ]; + }; + } diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index 3bbf24bb3791..174d31c6c008 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -263,6 +263,11 @@ in ''; }; + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isEnabled "UNIX") + (isYes "INOTIFY_USER") + (isYes "NET") + ]; }; } diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 1b247a658908..62b68c560d13 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -108,6 +108,24 @@ let kernel = config.boot.kernelPackages.kernel; in apply = pkgs.aggregateModules; }; + system.requiredKernelConfig = mkOption { + default = []; + example = literalExample '' + with config.lib.kernelConfig; [ + (isYes "MODULES") + (isEnabled "FB_CON_DECOR") + (isEnabled "BLK_DEV_INITRD") + ] + ''; + internal = true; + type = types.listOf types.attrs; + description = '' + This option allows modules to specify the kernel config options that + must be set (or unset) for the module to work. Please use the + lib.kernelConfig functions to build list elements. + ''; + }; + }; @@ -173,6 +191,53 @@ let kernel = config.boot.kernelPackages.kernel; in # The Linux kernel >= 2.6.27 provides firmware. hardware.firmware = [ "${kernel}/lib/firmware" ]; - }; + lib.kernelConfig = { + isYes = option: { + assertion = config: config.isYes option; + message = "CONFIG_${option} is not yes!"; + configLine = "CONFIG_${option}=y"; + }; + isNo = option: { + assertion = config: config.isNo option; + message = "CONFIG_${option} is not no!"; + configLine = "CONFIG_${option}=n"; + }; + + isModule = option: { + assertion = config: config.isModule option; + message = "CONFIG_${option} is not built as a module!"; + configLine = "CONFIG_${option}=m"; + }; + + ### Usually you will just want to use these two + # True if yes or module + isEnabled = option: { + assertion = config: config.isEnabled option; + message = "CONFIG_${option} is not enabled!"; + configLine = "CONFIG_${option}=y"; + }; + + # True if no or omitted + isDisabled = option: { + assertion = config: config.isDisabled option; + message = "CONFIG_${option} is not disabled!"; + configLine = "CONFIG_${option}=n"; + }; + }; + + # The config options that all modules can depend upon + system.requiredKernelConfig = with config.lib.kernelConfig; [ + # !!! Should this really be needed? + (isYes "MODULES") + (isYes "BINFMT_ELF") + ]; + + # nixpkgs kernels are assumed to have all required features + assertions = if config.boot.kernelPackages.kernel ? features then [] else + let cfg = config.boot.kernelPackages.kernel.config; in map (attrs: + { assertion = attrs.assertion cfg; inherit (attrs) message; } + ) config.system.requiredKernelConfig; + + }; } diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 02a75ae21c46..01ecd839f556 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -321,4 +321,8 @@ in { system.build.initialRamdisk = initialRamdisk; system.build.extraUtils = extraUtils; + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isYes "TMPFS") + (isYes "BLK_DEV_INITRD") + ]; } diff --git a/modules/testing/minimal-kernel.nix b/modules/testing/minimal-kernel.nix new file mode 100644 index 000000000000..0ad20bbf75a2 --- /dev/null +++ b/modules/testing/minimal-kernel.nix @@ -0,0 +1,28 @@ +{ config, pkgs, ... }: + +let + configfile = builtins.storePath (builtins.toFile "config" (pkgs.lib.concatStringsSep "\n" + (map (builtins.getAttr "configLine") config.system.requiredKernelConfig)) + ); + + origKernel = pkgs.linuxManualConfig { + inherit (pkgs.linux) src version; + inherit configfile; + allowImportFromDerivation = true; + kernelPatches = [ pkgs.kernelPatches.cifs_timeout_2_6_38 ]; + }; + + kernel = origKernel // (derivation (origKernel.drvAttrs // { + configurePhase = '' + runHook preConfigure + mkdir ../build + make $makeFlags "''${makeFlagsArray[@]}" mrproper + make $makeFlags "''${makeFlagsArray[@]}" KCONFIG_ALLCONFIG=${configfile} allnoconfig + runHook postConfigure + ''; + })); + + kernelPackages = pkgs.linuxPackagesFor kernel kernelPackages; +in { + boot.kernelPackages = kernelPackages; +} diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 830f1744fa04..9d36538ea088 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -5,11 +5,18 @@ with pkgs.lib; +let + kernel = config.boot.kernelPackages.kernel; + + hasCIFSTimeout = if kernel ? features then kernel.features ? cifsTimeout + else (filter (p: p.name == "cifs-timeout") kernel.kernelPatches) != []; +in + { config = # Require a patch to the kernel to increase the 15s CIFS timeout. - mkAssert (config.boot.kernelPackages.kernel.features ? cifsTimeout) " + mkAssert hasCIFSTimeout " VM tests require that the kernel has the CIFS timeout patch. " { @@ -87,6 +94,11 @@ with pkgs.lib; system.upstartEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data"; + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isYes "SERIAL_8250_CONSOLE") + (isYes "SERIAL_8250") + (isEnabled "VIRTIO_CONSOLE") + ]; }; } diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index dd8b457d43c7..17f19537115e 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -385,4 +385,22 @@ in # Wireless won't work in the VM. networking.wireless.enable = mkOverride 50 false; + + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isEnabled "VIRTIO_BLK") + (isEnabled "VIRTIO_PCI") + (isEnabled "VIRTIO_NET") + (isEnabled "EXT3_FS") + (isEnabled "CIFS") + (isYes "BLK_DEV") + (isYes "PCI") + (isYes "EXPERIMENTAL") + (isYes "NETDEVICES") + (isYes "NET_CORE") + (isYes "INET") + (isYes "NETWORK_FILESYSTEMS") + ] ++ optional (!cfg.graphics) [ + (isYes "SERIAL_8250_CONSOLE") + (isYes "SERIAL_8250") + ]; } diff --git a/release.nix b/release.nix index 4ccbd2ef754f..10cea94881f2 100644 --- a/release.nix +++ b/release.nix @@ -1,5 +1,6 @@ { nixosSrc ? {outPath = ./.; revCount = 1234; shortRev = "abcdef"; } , nixpkgs ? {outPath = ; revCount = 5678; shortRev = "fedcba"; } +, minimal ? false }: let @@ -194,8 +195,8 @@ let tests = let - t = import ./tests { system = "i686-linux"; }; - t_64 = import ./tests { system = "x86_64-linux"; }; + t = import ./tests { system = "i686-linux"; inherit minimal; }; + t_64 = import ./tests { system = "x86_64-linux"; inherit minimal; }; in { avahi = t.avahi.test; bittorrent = t.bittorrent.test; diff --git a/tests/default.nix b/tests/default.nix index 4edcbd2f325b..0d2c3102a646 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -1,6 +1,6 @@ -{ system ? builtins.currentSystem }: +{ system ? builtins.currentSystem, minimal ? false }: -with import ../lib/testing.nix { inherit system; }; +with import ../lib/testing.nix { inherit system minimal; }; { avahi = makeTest (import ./avahi.nix);