From 4d7e344f69825e06d2d48ab7e735f35f57311672 Mon Sep 17 00:00:00 2001 From: Marc Weber Date: Fri, 11 Dec 2009 00:51:13 +0000 Subject: [PATCH] Adding initial version of the nixos cd insallation test script using qemu_kvm. Installation doesn't take place yet. VM is started printing a remote controlled "Hello". This serves as example how to run a vm within a bulid job. svn path=/nixos/trunk/; revision=18887 --- .../installation-cd-minimal-test-insecure.nix | 54 ++++++++ modules/services/networking/openvpn.nix | 4 +- modules/services/networking/ssh/sshd.nix | 1 + .../system/activation/activation-script.nix | 2 +- release.nix | 5 + tests/test-nixos-install-from-cd-config.nix | 26 ++++ tests/test-nixos-install-from-cd.nix | 125 ++++++++++++++++++ 7 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix create mode 100644 tests/test-nixos-install-from-cd-config.nix create mode 100644 tests/test-nixos-install-from-cd.nix diff --git a/modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix b/modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix new file mode 100644 index 00000000000..e25e2e72129 --- /dev/null +++ b/modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix @@ -0,0 +1,54 @@ +# See installation-cd-minimal.nix +# it's called insecure because it allows logging in as root without password +# So don't boot this cdrom to install your system :-) + +{config, pkgs, ...}: + +let + doOverride = pkgs.lib.mkOverride 0 {}; +in + +{ + require = [ ./installation-cd-minimal.nix ]; + + installer.configModule = "./nixos/modules/installer/cd-dvd/installation-cd-minimal-test-insecure"; + + services.sshd.permitRootLogin = "yes"; + jobs.sshd = { + startOn = doOverride "started network-interfaces"; + }; + + + boot.initrd.extraKernelModules = + ["cifs" "virtio_net" "virtio_pci" "virtio_blk" "virtio_balloon" "nls_utf8"]; + + environment.systemPackages = [ pkgs.vim_configurable ]; + + boot.loader.grub.timeout = doOverride 0; + boot.loader.grub.default = 2; + + # FIXME: rewrite pam.services the to be an attr list + # I only want to override sshd + security.pam.services = doOverride + # Most of these should be moved to specific modules. + [ { name = "cups"; } + { name = "ejabberd"; } + { name = "ftp"; } + { name = "lshd"; rootOK =true; allowNullPassword =true; } + { name = "passwd"; } + { name = "samba"; } + { name = "sshd"; rootOK = true; allowNullPassword =true; } + { name = "xlock"; } + { name = "chsh"; rootOK = true; } + { name = "su"; rootOK = true; forwardXAuth = true; } + # Note: useradd, groupadd etc. aren't setuid root, so it + # doesn't really matter what the PAM config says as long as it + # lets root in. + { name = "useradd"; rootOK = true; } + # Used by groupadd etc. + { name = "shadow"; rootOK = true; } + { name = "login"; ownDevices = true; allowNullPassword = true; } + ]; + +} + diff --git a/modules/services/networking/openvpn.nix b/modules/services/networking/openvpn.nix index 78873db67fa..0d2025d9ce3 100644 --- a/modules/services/networking/openvpn.nix +++ b/modules/services/networking/openvpn.nix @@ -34,8 +34,8 @@ let in { description = "OpenVPN-${name}"; - startOn = "network-interfaces/started"; - stopOn = "network-interfaces/stop"; + startOn = "started network-interfaces"; + stopOn = "stopping network-interfaces"; environment = { PATH = "${pkgs.coreutils}/bin"; }; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 9bddba959b6..f99e871c448 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -82,6 +82,7 @@ in yes, without-password, forced-commands-only or no. + If without-password doesn't work try yes. ''; }; diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix index df3806b834b..21c52abe49f 100644 --- a/modules/system/activation/activation-script.nix +++ b/modules/system/activation/activation-script.nix @@ -2,7 +2,7 @@ {pkgs, config, ...}: let - inherit (pkgs.lib) mkOption mergeTypedOption mergeAttrs mapRecordFlatten + inherit (pkgs.lib) mkOption mergeTypedOption mergeAttrs mapAttrs addErrorContext fold id filter textClosureMap noDepEntry fullDepEntry; inherit (builtins) attrNames; diff --git a/release.nix b/release.nix index 9520ac02698..8a3b69b7261 100644 --- a/release.nix +++ b/release.nix @@ -90,6 +90,11 @@ let description = "minimal"; }; + iso_minimal_test_insecure = makeIso { + module = ./modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix; + description = "minimal-testing-only"; + }; + iso_minimal_fresh_kernel = makeIso { module = ./modules/installer/cd-dvd/installation-cd-minimal-fresh-kernel.nix; description = "minimal with 2.6.31-zen-branch"; diff --git a/tests/test-nixos-install-from-cd-config.nix b/tests/test-nixos-install-from-cd-config.nix new file mode 100644 index 00000000000..758ab2328da --- /dev/null +++ b/tests/test-nixos-install-from-cd-config.nix @@ -0,0 +1,26 @@ +# this is the configuration which will be installed. +# The configuration is prebuild before starting the vm because starting the vm +# causes some overhead. +{pkgs, config, ...}: { + + # make system boot and accessible: + require = [ ../modules/installer/cd-dvd/installation-cd-minimal-test-insecure.nix ]; + + boot.loader.grub = { + device = "/dev/sda"; + copyKernels = true; + bootDevice = "(hd0,0)"; + }; + + fileSystems = [ + { mountPoint = "/"; + device = "/dev/sda1"; + neededForBoot = true; + } + ]; + + fonts = { + enableFontConfig = false; + }; + +} diff --git a/tests/test-nixos-install-from-cd.nix b/tests/test-nixos-install-from-cd.nix new file mode 100644 index 00000000000..d654cdbd69f --- /dev/null +++ b/tests/test-nixos-install-from-cd.nix @@ -0,0 +1,125 @@ +{ nixos ? ./.. +, nixpkgs ? ../../nixpkgs +, services ? ../../nixos/services +, system ? builtins.currentSystem +, configPath ? ./test-nixos-install-from-cd.nix +}: + +let + +/* + + test nixos installation automatically using a build job (unfinished) + + run this test this way: + nix-build --no-out-link --show-trace tests/test-nixos-install-from-cd.nix + + --no-out-link is important because creating ./result will cause rebuilding of + the iso as the nixos repository is included in the iso. + + To prevent this make these paths point to another location: + nixosTarball = makeTarball "nixos.tar.bz2" (cleanSource ../../..); + nixpkgsTarball = makeTarball "nixpkgs.tar.bz2" (cleanSource pkgs.path); + +*/ + + isos = (import ../release.nix) { inherit nixpkgs; }; + + isoFile = + # passed system = systom of iso + (isos.iso_minimal_test_insecure { inherit system; }).iso; + + configuration = /pr/system_nixos_installer/nixos/tests/test-nixos-install-from-cd-config.nix; + + eval = import ../lib/eval-config.nix { + inherit system nixpkgs; + modules = [ configuration ]; + }; + + + inherit (eval) pkgs config; + + inherit (pkgs) qemu_kvm; + + # prebuild system which will be installed for two reasons: + # build derivations are in store and can be reused + # the iso is only build when this suceeds (?) + systemDerivation = builtins.addErrorContext "while building system" config.system.build.toplevel; + +in + +rec { + + test = + # FIXME: support i686 as well + # FIXME: X shouldn't be required + # Is there a way to use kvm when not running as root? + # Would using uml provide any advantages? + pkgs.runCommand "nixos-installation-test" { inherit systemDerivation; } '' + + for path in ${pkgs.socat} ${pkgs.openssh} ${qemu_kvm}; do + PATH=$path/bin:$PATH + done + + echo "creating image file" + qemu-img create -f qcow2 image 512M + + # install the system + + export DISPLAY=localhost:0.0 + + cat >> run-kvm.sh << EOF + #!/bin/sh + qemu-system-x86_64 -m 620 \ + -no-kvm-irqchip \ + -net nic -net user -smb \ + -hda image \ + -cdrom $(echo ${isoFile}/iso/*.iso) \ + "\$@" + EOF + chmod +x run-kvm.sh + + SOCKET_NAME=65535.socket + + # run qemu-kvm in a background process + { ./run-kvm.sh -boot d -redir tcp:''${SOCKET_NAME/.socket/}::22 \ + || { echo "starting kvm failed, exiting" 1>&2; pkill -9 $$; } + } & + + # check that vm is still running + checkVM(){ [ -n "$(jobs -l)" ] || { echo "kvm died!?"; exit 1; }; } + + waitTill(){ + echo $1 + while ! eval "$2"; do sleep 1; checkVM; done + } + + SSH(){ + ssh -v -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no \ + -o ProxyCommand="socat stdio ./$SOCKET_NAME" \ + root@127.0.0.1 \ + "$@"; + } + + # wait for socket + + waitTill "waiting for socket in $TMP" '[ ! -e ./$SOCKET_NAME ]' + waitTill "waiting for sshd job" "SSH 'echo Hello > /dev/tty1'" + + # INSTALLATION + echo "installation should take place" + + # REBOOT + echo "rebooting should take place" + + # CHECK + echo "verify system is up and running" + + # SHUTDOWN + SSH "shutdown -h now" + + echo waiting for kvm to shutdown.. + wait + ''; +}