From afe3c77014bf54fbbfebc4ed43a58b9f85cd8622 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 24 Aug 2015 16:05:05 +0100 Subject: [PATCH] p2v: Add a test for the PXE boot path (RHBZ#1256222). Build the P2V disk image and boot it. We don't actually use PXE specifically, but we do test the whole PXE / kernel command line path much more thoroughly. This is a 'check-slow' test because it takes ages to run. --- .gitignore | 11 +++ TODO | 8 ++ p2v/Makefile.am | 68 ++++++++++++++- p2v/test-virt-p2v-pxe.sh | 120 +++++++++++++++++++++++++++ p2v/test-virt-p2v-pxe.sshd_config.in | 39 +++++++++ 5 files changed, 245 insertions(+), 1 deletion(-) create mode 100755 p2v/test-virt-p2v-pxe.sh create mode 100644 p2v/test-virt-p2v-pxe.sshd_config.in diff --git a/.gitignore b/.gitignore index fb972a7d0..e502018b0 100644 --- a/.gitignore +++ b/.gitignore @@ -345,9 +345,20 @@ Makefile.in /p2v/dependencies.redhat /p2v/dependencies.suse /p2v/launch-virt-p2v +/p2v/stamp-test-virt-p2v-pxe-hostkey +/p2v/stamp-test-virt-p2v-pxe-kernel +/p2v/stamp-test-virt-p2v-pxe-userkey /p2v/stamp-virt-p2v.pod /p2v/stamp-virt-p2v-make-disk.pod /p2v/stamp-virt-p2v-make-kickstart.pod +/p2v/test-virt-p2v-pxe.id_rsa +/p2v/test-virt-p2v-pxe.id_rsa.pub +/p2v/test-virt-p2v-pxe.img +/p2v/test-virt-p2v-pxe.initramfs +/p2v/test-virt-p2v-pxe.sshd_config +/p2v/test-virt-p2v-pxe.ssh_host_rsa_key +/p2v/test-virt-p2v-pxe.ssh_host_rsa_key.pub +/p2v/test-virt-p2v-pxe.vmlinuz /p2v/virt-p2v /p2v/virt-p2v.1 /p2v/virt-p2v-make-disk diff --git a/TODO b/TODO index 666400eff..2b865b5b2 100644 --- a/TODO +++ b/TODO @@ -576,3 +576,11 @@ Subsecond handling in virt-diff, virt-ls Handle nanoseconds properly. You should be able to specify them on the command line and display them. + +virt-p2v +-------- + +virt-p2v-make-disk and virt-p2v-make-kickstart should have +options to let you inject SSH identities, eg: + + virt-p2v-make-disk [...] --inject-ssh-identity=id_rsa diff --git a/p2v/Makefile.am b/p2v/Makefile.am index 57efd8dd3..c66a88785 100644 --- a/p2v/Makefile.am +++ b/p2v/Makefile.am @@ -163,6 +163,72 @@ TESTS += \ test-virt-p2v.sh endif ENABLE_APPLIANCE +SLOW_TESTS = \ + test-virt-p2v-pxe.sh + +check-slow: test-virt-p2v-pxe.img \ + test-virt-p2v-pxe.vmlinuz test-virt-p2v-pxe.initramfs \ + test-virt-p2v-pxe.sshd_config \ + test-virt-p2v-pxe.ssh_host_rsa_key \ + test-virt-p2v-pxe.ssh_host_rsa_key.pub \ + test-virt-p2v-pxe.id_rsa test-virt-p2v-pxe.id_rsa.pub + $(MAKE) check TESTS="$(SLOW_TESTS)" + +test-virt-p2v-pxe.img: virt-p2v-make-disk \ + virt-p2v \ + test-virt-p2v-pxe.id_rsa + $(top_builddir)/run virt-p2v-make-disk \ + --inject-ssh-identity=test-virt-p2v-pxe.id_rsa \ + -o $@-t \ + fedora-22 + mv $@-t $@ + +test-virt-p2v-pxe.vmlinuz test-virt-p2v-pxe.initramfs: stamp-test-virt-p2v-pxe-kernel + +stamp-test-virt-p2v-pxe-kernel: test-virt-p2v-pxe.img + rm -f $@ vmlinuz initramfs test-virt-p2v-pxe.vmlinuz test-virt-p2v-pxe.initramfs + $(top_builddir)/run virt-get-kernel --unversioned-names -a $< + mv vmlinuz test-virt-p2v-pxe.vmlinuz + mv initramfs test-virt-p2v-pxe.initramfs + touch $@ + +test-virt-p2v-pxe.sshd_config: test-virt-p2v-pxe.sshd_config.in + rm -f $@ $@-t + @AWK@ \ + -v "abs_builddir=$(abs_builddir)" \ + '{ \ + gsub (/__RANDOM_PORT__/, 10000 + int (1000 * rand())); \ + gsub (/__abs_builddir__/, abs_builddir); \ + print; \ + }' < $< > $@-t + chmod 0444 $@-t + mv $@-t $@ + +test-virt-p2v-pxe.ssh_host_rsa_key test-virt-p2v-pxe.ssh_host_rsa_key.pub: stamp-test-virt-p2v-pxe-hostkey + +stamp-test-virt-p2v-pxe-hostkey: + rm -f test-virt-p2v-pxe.ssh_host_rsa_key + rm -f test-virt-p2v-pxe.ssh_host_rsa_key.pub + ssh-keygen -t rsa -f test-virt-p2v-pxe.ssh_host_rsa_key -N '' + touch $@ + +test-virt-p2v-pxe.id_rsa test-virt-p2v-pxe.id_rsa.pub: stamp-test-virt-p2v-pxe-userkey + +stamp-test-virt-p2v-pxe-userkey: + rm -f test-virt-p2v-pxe.id_rsa + rm -f test-virt-p2v-pxe.id_rsa.pub + ssh-keygen -t rsa -f test-virt-p2v-pxe.id_rsa -N '' + touch $@ + +# Don't clean ssh_host_rsa_key{,.pub} or id_rsa{,.pub} since those +# consume system entropy to regenerate. +CLEANFILES += \ + stamp-test-virt-p2v-pxe-kernel \ + test-virt-p2v-pxe.img \ + test-virt-p2v-pxe.vmlinuz \ + test-virt-p2v-pxe.initramfs \ + test-virt-p2v-pxe.sshd_config + EXTRA_DIST += \ - $(TESTS) \ + $(TESTS) $(SLOW_TESTS) \ test-virt-p2v-ssh.sh diff --git a/p2v/test-virt-p2v-pxe.sh b/p2v/test-virt-p2v-pxe.sh new file mode 100755 index 000000000..f05cb9655 --- /dev/null +++ b/p2v/test-virt-p2v-pxe.sh @@ -0,0 +1,120 @@ +#!/bin/bash - +# libguestfs virt-p2v test script +# Copyright (C) 2014-2015 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test virt-p2v in non-GUI mode with something resembling the +# PXE boot code path. This tests: +# * virt-p2v-make-disk +# * systemd p2v.service +# * launch-virt-p2v +# * networking +# * virt-p2v in kernel command-line mode + +unset CDPATH +export LANG=C +set -e + +if [ -n "$SKIP_TEST_VIRT_P2V_PXE_SH" ]; then + echo "$0: test skipped because environment variable is set" + exit 77 +fi + +if [ "$(guestfish get-backend)" = "uml" ]; then + echo "$0: test skipped because UML backend does not support network" + exit 77 +fi + +if [ "$(uname -m)" != "x86_64" ]; then + echo "$0: test skipped because !x86_64" + exit 77 +fi + +qemu=qemu-system-x86_64 +if ! $qemu -help >/dev/null 2>&1; then + echo "$0: test skipped because $qemu not found" + exit 77 +fi + +img="test-virt-p2v-pxe.img" +if ! test -f $img; then + echo "$0: test skipped because $img was not created" + exit 77 +fi + +guestsdir="$(cd ../tests/guests && pwd)" +f="$guestsdir/windows.img" +if ! test -f $f; then + echo "$0: test skipped because phony Windows image was not created" + exit 77 +fi + +virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools} +if ! test -r $virt_tools_data_dir/rhsrvany.exe; then + echo "$0: test skipped because rhsrvany.exe is not installed" + exit 77 +fi + +d=test-virt-p2v-pxe.d +rm -rf $d +mkdir $d + +# Start the ssh server. Kill it if the script exits for any reason. +# Note you must use an absolute path to exec sshd. +`which sshd` -f test-virt-p2v-pxe.sshd_config -D & +sshd_pid=$! +cleanup () +{ + kill $sshd_pid +} +trap cleanup INT QUIT TERM EXIT ERR + +# Get the randomly assigned sshd port number. +port="$(grep ^Port test-virt-p2v-pxe.sshd_config | awk '{print $2}')" + +# Connect as the local user. +username="$(id -un)" + +# Output storage path. +os="$(cd $d; pwd)" + +# The Linux kernel command line. +cmdline="root=/dev/sda3 ro console=ttyS0 printk.time=1 p2v.debug p2v.server=10.0.2.2 p2v.port=$port p2v.username=$username p2v.identity=file:///var/tmp/id_rsa p2v.name=windows p2v.o=local p2v.os=$os" + +# Run virt-p2v inside qemu. +$qemu \ + -nodefconfig \ + -display none \ + -machine accel=kvm:tcg \ + -m 2048 \ + -kernel test-virt-p2v-pxe.vmlinuz \ + -initrd test-virt-p2v-pxe.initramfs \ + -append "$cmdline" \ + -boot c \ + -device virtio-scsi-pci,id=scsi \ + -drive file=$img,format=raw,snapshot=on,if=none,index=0,id=hd0 \ + -device scsi-hd,drive=hd0 \ + -drive file=$f,format=raw,snapshot=on,if=none,index=1,id=hd1 \ + -device scsi-hd,drive=hd1 \ + -netdev user,id=usernet \ + -device virtio-net-pci,netdev=usernet \ + -serial stdio + +# Test the libvirt XML metadata and a disk was created. +test -f $d/windows.xml +test -f $d/windows-sda + +rm -r $d diff --git a/p2v/test-virt-p2v-pxe.sshd_config.in b/p2v/test-virt-p2v-pxe.sshd_config.in new file mode 100644 index 000000000..d8b6203f9 --- /dev/null +++ b/p2v/test-virt-p2v-pxe.sshd_config.in @@ -0,0 +1,39 @@ +# libguestfs virt-p2v test script +# @configure_input@ +# Copyright (C) 2014-2015 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Minimal sshd_config used by test-virt-p2v-pxe.ssh when it runs +# a captive sshd. + +# Choose a random high port number. +Port __RANDOM_PORT__ + +# Only allow connections from loopback. +ListenAddress [::1] +ListenAddress 127.0.0.1 + +# Privilege separation breaks non-root usage of sshd. +UsePrivilegeSeparation no + +# Use local files instead of inaccessible global configuration. +PidFile __abs_builddir__/test-virt-p2v-pxe.sshd.pid +HostKey __abs_builddir__/test-virt-p2v-pxe.ssh_host_rsa_key + +AuthorizedKeysFile __abs_builddir__/test-virt-p2v-pxe.id_rsa.pub + +# Don't check file permissions. +StrictModes no