nixpkgs/nixos/modules/testing/test-instrumentation.nix
Andreas Rammhold f4d7493162
nixos/tests: only apply qemu parameters if the options are defined
This fixes an eval error that occurred on hydra with the small channel
and the `nixos.tests.boot.biosCdrom.x86_64-linux` attribute:

> $ nix-instantiate nixos/release-small.nix -A nixos.tests.boot.biosCdrom.x86_64-linux
> warning: unknown setting 'experimental-features'
> error: The option `virtualisation.qemu' does not exist. Definition values:
> - In `/home/andi/dev/nixos/nixpkgs/nixos/modules/testing/test-instrumentation.nix':
>     {
>       consoles = [ ];
>       package = {
> 	_type = "override";
> 	content = <derivation /nix/store/q72h2cdcb9zjgiay5gdgzwddjkbjr7xq-qemu-host-cpu-only-for-vm-tests-5.1.0.drv>;
>     ...
> (use '--show-trace' to show detailed location information)

In bc2188b we changed test test-instrumentation to also set the QEMU
package that is being used. That change unfortunately caused us to
always assing values to the virtualisation.qemu.package option even when
the option is not defined. The original code was explicitly testing for
the consoles case but the then newly extended version did not adjust the
check as the intention was probably not clear.

With this commit we are always ensuring the entire virtualisation.qemu
section exists and can thus drop the individual tests for each of the
sections since the QEMU module always defines both the package and the
consoles option when it's root is defined..
2020-10-25 13:42:01 +01:00

135 lines
4.6 KiB
Nix

# This module allows the test driver to connect to the virtual machine
# via a root shell attached to port 514.
{ options, config, lib, pkgs, ... }:
with lib;
with import ../../lib/qemu-flags.nix { inherit pkgs; };
{
config = {
systemd.services.backdoor =
{ wantedBy = [ "multi-user.target" ];
requires = [ "dev-hvc0.device" "dev-${qemuSerialDevice}.device" ];
after = [ "dev-hvc0.device" "dev-${qemuSerialDevice}.device" ];
script =
''
export USER=root
export HOME=/root
export DISPLAY=:0.0
source /etc/profile
# Don't use a pager when executing backdoor
# actions. Because we use a tty, commands like systemctl
# or nix-store get confused into thinking they're running
# interactively.
export PAGER=
cd /tmp
exec < /dev/hvc0 > /dev/hvc0
while ! exec 2> /dev/${qemuSerialDevice}; do sleep 0.1; done
echo "connecting to host..." >&2
stty -F /dev/hvc0 raw -echo # prevent nl -> cr/nl conversion
echo
PS1= exec /bin/sh
'';
serviceConfig.KillSignal = "SIGHUP";
};
# Prevent agetty from being instantiated on the serial device, since it
# interferes with the backdoor (writes to it will randomly fail
# with EIO). Likewise for hvc0.
systemd.services."serial-getty@${qemuSerialDevice}".enable = false;
systemd.services."serial-getty@hvc0".enable = false;
# Only set these settings when the options exist. Some tests (e.g. those
# that do not specify any nodes, or an empty attr set as nodes) will not
# have the QEMU module loaded and thuse these options can't and should not
# be set.
virtualisation = lib.optionalAttrs (options ? virtualisation.qemu) {
qemu = {
# Only use a serial console, no TTY.
# NOTE: optionalAttrs
# test-instrumentation.nix appears to be used without qemu-vm.nix, so
# we avoid defining consoles if not possible.
# TODO: refactor such that test-instrumentation can import qemu-vm
# or declare virtualisation.qemu.console option in a module that's always imported
consoles = [ qemuSerialDevice ];
package = lib.mkDefault pkgs.qemu_test;
};
};
boot.initrd.preDeviceCommands =
''
echo 600 > /proc/sys/kernel/hung_task_timeout_secs
'';
boot.initrd.postDeviceCommands =
''
# Using acpi_pm as a clock source causes the guest clock to
# slow down under high host load. This is usually a bad
# thing, but for VM tests it should provide a bit more
# determinism (e.g. if the VM runs at lower speed, then
# timeouts in the VM should also be delayed).
echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
'';
boot.postBootCommands =
''
# Panic on out-of-memory conditions rather than letting the
# OOM killer randomly get rid of processes, since this leads
# to failures that are hard to diagnose.
echo 2 > /proc/sys/vm/panic_on_oom
'';
# Panic if an error occurs in stage 1 (rather than waiting for
# user intervention).
boot.kernelParams =
[ "console=${qemuSerialDevice}" "panic=1" "boot.panic_on_fail" ];
# `xwininfo' is used by the test driver to query open windows.
environment.systemPackages = [ pkgs.xorg.xwininfo ];
# Log everything to the serial console.
services.journald.extraConfig =
''
ForwardToConsole=yes
MaxLevelConsole=debug
'';
systemd.extraConfig = ''
# Don't clobber the console with duplicate systemd messages.
ShowStatus=no
# Allow very slow start
DefaultTimeoutStartSec=300
'';
boot.consoleLogLevel = 7;
# Prevent tests from accessing the Internet.
networking.defaultGateway = mkOverride 150 "";
networking.nameservers = mkOverride 150 [ ];
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
(isEnabled "VIRTIO_CONSOLE")
];
networking.usePredictableInterfaceNames = false;
# Make it easy to log in as root when running the test interactively.
users.users.root.initialHashedPassword = mkOverride 150 "";
services.xserver.displayManager.job.logToJournal = true;
# Make sure we use the Guest Agent from the QEMU package for testing
# to reduce the closure size required for the tests.
services.qemuGuest.package = pkgs.qemu_test.ga;
};
}