mirror of https://github.com/xemu-project/xemu.git
-----BEGIN PGP SIGNATURE-----
iQFEBAABCAAuFiEEUAN8t5cGD3bwIa1WyjViTGqRccYFAlnEu6YQHGZhbXpAcmVk aGF0LmNvbQAKCRDKNWJMapFxxgsDCACLtd8/TW9qsZaz+rti3Eb8f5JYwGMSFoFO +EnCNybB8uFwl2ITYZ19JkKLJ3FIJFo0pFC63hKqTMEKIemDVv376mkAlhrx0YO9 gbr2qCXE8XZ7KXZ4EPsZUFc+330SkHtrfHGFkUmJLB9Ny2RndSf38Eb/rsQ2fVtn RiaJIYGOu08vAyIz2cys6NwO2Ft7NB0hQbeBaWfNz97XnwrN18S3TWH7BlUE0jZQ SFeIZQgr3cnyuVK4smvGVpeFeaaQNrwoCbXiinJZN/2hVVUng3JX4qOm41NidQ5B jO8kGuSAn1mZ+L9iKhQBv+h6XoNOyNsGVT5+6xgiWWMrNI+nEEoT =gd2x -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/famz/tags/build-and-test-automation-pull-request' into staging # gpg: Signature made Fri 22 Sep 2017 08:28:38 BST # gpg: using RSA key 0xCA35624C6A9171C6 # gpg: Good signature from "Fam Zheng <famz@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 5003 7CB7 9706 0F76 F021 AD56 CA35 624C 6A91 71C6 * remotes/famz/tags/build-and-test-automation-pull-request: (36 commits) docker: Drop 'set -e' from run script docker: Use archive-source.py tests: Add README for vm tests MAINTAINERS: Add tests/vm entry Makefile: Add rules to run vm tests tests: Add OpenBSD image tests: Add NetBSD image tests: Add FreeBSD image tests: Add ubuntu.i386 image tests: Add vm test lib tests: Add a test key pair scripts: Add archive-source.sh qemu.py: Add "wait()" method gitignore: Ignore vm test images MAINTAINERS: Fix subsystem name for "Build and test automation" buildsys: Move rdma libs to per object buildsys: Move brlapi libs to per object buildsys: Move usb redir cflags/libs to per object buildsys: Move libusb cflags/libs to per object buildsys: Move libcacard cflags/libs to per object ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a664607440
|
@ -52,6 +52,7 @@
|
|||
/vscclient
|
||||
/vhost-user-scsi
|
||||
/fsdev/virtfs-proxy-helper
|
||||
*.tmp
|
||||
*.[1-9]
|
||||
*.a
|
||||
*.aux
|
||||
|
|
|
@ -1896,6 +1896,7 @@ F: docs/block-replication.txt
|
|||
|
||||
Build and test automation
|
||||
-------------------------
|
||||
Build and test automation
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
M: Fam Zheng <famz@redhat.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
|
@ -1904,6 +1905,7 @@ S: Maintained
|
|||
F: .travis.yml
|
||||
F: .shippable.yml
|
||||
F: tests/docker/
|
||||
F: tests/vm/
|
||||
W: https://travis-ci.org/qemu/qemu
|
||||
W: https://app.shippable.com/github/qemu/qemu
|
||||
W: http://patchew.org/QEMU/
|
||||
|
|
2
Makefile
2
Makefile
|
@ -811,6 +811,7 @@ endif
|
|||
-include $(wildcard *.d tests/*.d)
|
||||
|
||||
include $(SRC_PATH)/tests/docker/Makefile.include
|
||||
include $(SRC_PATH)/tests/vm/Makefile.include
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
|
@ -834,6 +835,7 @@ help:
|
|||
@echo 'Test targets:'
|
||||
@echo ' check - Run all tests (check-help for details)'
|
||||
@echo ' docker - Help about targets running tests inside Docker containers'
|
||||
@echo ' vm-test - Help about targets running tests inside VM'
|
||||
@echo ''
|
||||
@echo 'Documentation targets:'
|
||||
@echo ' html info pdf txt'
|
||||
|
|
|
@ -11,3 +11,9 @@ common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
|
|||
common-obj-y += wavcapture.o
|
||||
|
||||
sdlaudio.o-cflags := $(SDL_CFLAGS)
|
||||
sdlaudio.o-libs := $(SDL_LIBS)
|
||||
alsaaudio.o-libs := $(ALSA_LIBS)
|
||||
paaudio.o-libs := $(PULSE_LIBS)
|
||||
coreaudio.o-libs := $(COREAUDIO_LIBS)
|
||||
dsoundaudio.o-libs := $(DSOUND_LIBS)
|
||||
ossaudio.o-libs := $(OSS_LIBS)
|
||||
|
|
|
@ -20,5 +20,6 @@ chardev-obj-$(CONFIG_WIN32) += char-win-stdio.o
|
|||
common-obj-y += msmouse.o wctablet.o testdev.o
|
||||
common-obj-$(CONFIG_BRLAPI) += baum.o
|
||||
baum.o-cflags := $(SDL_CFLAGS)
|
||||
baum.o-libs := $(BRLAPI_LIBS)
|
||||
|
||||
common-obj-$(CONFIG_SPICE) += spice.o
|
||||
|
|
|
@ -2788,7 +2788,6 @@ EOF
|
|||
sdl_cflags="$sdl_cflags $x11_cflags"
|
||||
sdl_libs="$sdl_libs $x11_libs"
|
||||
fi
|
||||
libs_softmmu="$sdl_libs $libs_softmmu"
|
||||
fi
|
||||
|
||||
##########################################
|
||||
|
@ -2801,7 +2800,6 @@ EOF
|
|||
rdma_libs="-lrdmacm -libverbs"
|
||||
if compile_prog "" "$rdma_libs" ; then
|
||||
rdma="yes"
|
||||
libs_softmmu="$libs_softmmu $rdma_libs"
|
||||
else
|
||||
if test "$rdma" = "yes" ; then
|
||||
error_exit \
|
||||
|
@ -2946,8 +2944,6 @@ int main(void)
|
|||
EOF
|
||||
if compile_prog "" "$vde_libs" ; then
|
||||
vde=yes
|
||||
libs_softmmu="$vde_libs $libs_softmmu"
|
||||
libs_tools="$vde_libs $libs_tools"
|
||||
else
|
||||
if test "$vde" = "yes" ; then
|
||||
feature_not_found "vde" "Install vde (Virtual Distributed Ethernet) devel"
|
||||
|
@ -3035,13 +3031,13 @@ for drv in $audio_drv_list; do
|
|||
alsa)
|
||||
audio_drv_probe $drv alsa/asoundlib.h -lasound \
|
||||
"return snd_pcm_close((snd_pcm_t *)0);"
|
||||
libs_softmmu="-lasound $libs_softmmu"
|
||||
alsa_libs="-lasound"
|
||||
;;
|
||||
|
||||
pa)
|
||||
audio_drv_probe $drv pulse/pulseaudio.h "-lpulse" \
|
||||
"pa_context_set_source_output_volume(NULL, 0, NULL, NULL, NULL); return 0;"
|
||||
libs_softmmu="-lpulse $libs_softmmu"
|
||||
pulse_libs="-lpulse"
|
||||
audio_pt_int="yes"
|
||||
;;
|
||||
|
||||
|
@ -3052,16 +3048,16 @@ for drv in $audio_drv_list; do
|
|||
;;
|
||||
|
||||
coreaudio)
|
||||
libs_softmmu="-framework CoreAudio $libs_softmmu"
|
||||
coreaudio_libs="-framework CoreAudio"
|
||||
;;
|
||||
|
||||
dsound)
|
||||
libs_softmmu="-lole32 -ldxguid $libs_softmmu"
|
||||
dsound_libs="-lole32 -ldxguid"
|
||||
audio_win_int="yes"
|
||||
;;
|
||||
|
||||
oss)
|
||||
libs_softmmu="$oss_lib $libs_softmmu"
|
||||
oss_libs="$oss_lib"
|
||||
;;
|
||||
|
||||
wav)
|
||||
|
@ -3089,7 +3085,6 @@ int main( void ) { return brlapi__openConnection (NULL, NULL, NULL); }
|
|||
EOF
|
||||
if compile_prog "" "$brlapi_libs" ; then
|
||||
brlapi=yes
|
||||
libs_softmmu="$brlapi_libs $libs_softmmu"
|
||||
else
|
||||
if test "$brlapi" = "yes" ; then
|
||||
feature_not_found "brlapi" "Install brlapi devel"
|
||||
|
@ -4209,8 +4204,6 @@ if test "$smartcard" != "no"; then
|
|||
if $pkg_config libcacard; then
|
||||
libcacard_cflags=$($pkg_config --cflags libcacard)
|
||||
libcacard_libs=$($pkg_config --libs libcacard)
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags"
|
||||
libs_softmmu="$libs_softmmu $libcacard_libs"
|
||||
smartcard="yes"
|
||||
else
|
||||
if test "$smartcard" = "yes"; then
|
||||
|
@ -4226,8 +4219,6 @@ if test "$libusb" != "no" ; then
|
|||
libusb="yes"
|
||||
libusb_cflags=$($pkg_config --cflags libusb-1.0)
|
||||
libusb_libs=$($pkg_config --libs libusb-1.0)
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $libusb_cflags"
|
||||
libs_softmmu="$libs_softmmu $libusb_libs"
|
||||
else
|
||||
if test "$libusb" = "yes"; then
|
||||
feature_not_found "libusb" "Install libusb devel >= 1.0.13"
|
||||
|
@ -4242,8 +4233,6 @@ if test "$usb_redir" != "no" ; then
|
|||
usb_redir="yes"
|
||||
usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5)
|
||||
usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5)
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
|
||||
libs_softmmu="$libs_softmmu $usb_redir_libs"
|
||||
else
|
||||
if test "$usb_redir" = "yes"; then
|
||||
feature_not_found "usb-redir" "Install usbredir devel"
|
||||
|
@ -5499,6 +5488,7 @@ if test "$slirp" = "yes" ; then
|
|||
fi
|
||||
if test "$vde" = "yes" ; then
|
||||
echo "CONFIG_VDE=y" >> $config_host_mak
|
||||
echo "VDE_LIBS=$vde_libs" >> $config_host_mak
|
||||
fi
|
||||
if test "$netmap" = "yes" ; then
|
||||
echo "CONFIG_NETMAP=y" >> $config_host_mak
|
||||
|
@ -5514,6 +5504,11 @@ for drv in $audio_drv_list; do
|
|||
def=CONFIG_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]')
|
||||
echo "$def=y" >> $config_host_mak
|
||||
done
|
||||
echo "ALSA_LIBS=$alsa_libs" >> $config_host_mak
|
||||
echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak
|
||||
echo "COREAUDIO_LIBS=$coreaudio_libs" >> $config_host_mak
|
||||
echo "DSOUND_LIBS=$dsound_libs" >> $config_host_mak
|
||||
echo "OSS_LIBS=$oss_libs" >> $config_host_mak
|
||||
if test "$audio_pt_int" = "yes" ; then
|
||||
echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak
|
||||
fi
|
||||
|
@ -5558,6 +5553,7 @@ if test "$sdl" = "yes" ; then
|
|||
echo "CONFIG_SDL=y" >> $config_host_mak
|
||||
echo "CONFIG_SDLABI=$sdlabi" >> $config_host_mak
|
||||
echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak
|
||||
echo "SDL_LIBS=$sdl_libs" >> $config_host_mak
|
||||
fi
|
||||
if test "$cocoa" = "yes" ; then
|
||||
echo "CONFIG_COCOA=y" >> $config_host_mak
|
||||
|
@ -5647,6 +5643,7 @@ if test "$curl" = "yes" ; then
|
|||
fi
|
||||
if test "$brlapi" = "yes" ; then
|
||||
echo "CONFIG_BRLAPI=y" >> $config_host_mak
|
||||
echo "BRLAPI_LIBS=$brlapi_libs" >> $config_host_mak
|
||||
fi
|
||||
if test "$bluez" = "yes" ; then
|
||||
echo "CONFIG_BLUEZ=y" >> $config_host_mak
|
||||
|
@ -5781,14 +5778,20 @@ fi
|
|||
|
||||
if test "$smartcard" = "yes" ; then
|
||||
echo "CONFIG_SMARTCARD=y" >> $config_host_mak
|
||||
echo "SMARTCARD_CFLAGS=$libcacard_cflags" >> $config_host_mak
|
||||
echo "SMARTCARD_LIBS=$libcacard_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libusb" = "yes" ; then
|
||||
echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak
|
||||
echo "LIBUSB_CFLAGS=$libusb_cflags" >> $config_host_mak
|
||||
echo "LIBUSB_LIBS=$libusb_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$usb_redir" = "yes" ; then
|
||||
echo "CONFIG_USB_REDIR=y" >> $config_host_mak
|
||||
echo "USB_REDIR_CFLAGS=$usb_redir_cflags" >> $config_host_mak
|
||||
echo "USB_REDIR_LIBS=$usb_redir_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$opengl" = "yes" ; then
|
||||
|
@ -5984,6 +5987,7 @@ echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
|
|||
|
||||
if test "$rdma" = "yes" ; then
|
||||
echo "CONFIG_RDMA=y" >> $config_host_mak
|
||||
echo "RDMA_LIBS=$rdma_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$have_rtnetlink" = "yes" ; then
|
||||
|
@ -6505,7 +6509,7 @@ if test "$ccache_cpp2" = "yes"; then
|
|||
fi
|
||||
|
||||
# build tree in object directory in case the source is not in the current directory
|
||||
DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
|
||||
DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
|
||||
DIRS="$DIRS docs docs/interop fsdev"
|
||||
DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
|
||||
DIRS="$DIRS roms/seabios roms/vgabios"
|
||||
|
|
|
@ -26,8 +26,10 @@ common-obj-$(CONFIG_USB_BLUETOOTH) += dev-bluetooth.o
|
|||
|
||||
ifeq ($(CONFIG_USB_SMARTCARD),y)
|
||||
common-obj-y += dev-smartcard-reader.o
|
||||
common-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o
|
||||
common-obj-$(CONFIG_SMARTCARD) += ccid-card-emulated.o
|
||||
common-obj-$(CONFIG_SMARTCARD) += smartcard.mo
|
||||
smartcard.mo-objs := ccid-card-passthru.o ccid-card-emulated.o
|
||||
smartcard.mo-cflags := $(SMARTCARD_CFLAGS)
|
||||
smartcard.mo-libs := $(SMARTCARD_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_POSIX),y)
|
||||
|
@ -36,6 +38,8 @@ endif
|
|||
|
||||
# usb redirection
|
||||
common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
|
||||
redirect.o-cflags = $(USB_REDIR_CFLAGS)
|
||||
redirect.o-libs = $(USB_REDIR_LIBS)
|
||||
|
||||
# usb pass-through
|
||||
ifeq ($(CONFIG_LIBUSB)$(CONFIG_USB),yy)
|
||||
|
@ -44,6 +48,11 @@ else
|
|||
common-obj-y += host-stub.o
|
||||
endif
|
||||
|
||||
host-libusb.o-cflags := $(LIBUSB_CFLAGS)
|
||||
host-libusb.o-libs := $(LIBUSB_LIBS)
|
||||
|
||||
ifeq ($(CONFIG_USB_LIBUSB),y)
|
||||
common-obj-$(CONFIG_XEN) += xen-usb.o
|
||||
xen-usb.o-cflags := $(LIBUSB_CFLAGS)
|
||||
xen-usb.o-libs := $(LIBUSB_LIBS)
|
||||
endif
|
||||
|
|
|
@ -11,3 +11,4 @@ common-obj-$(CONFIG_RDMA) += rdma.o
|
|||
|
||||
common-obj-$(CONFIG_LIVE_BLOCK_MIGRATION) += block.o
|
||||
|
||||
rdma.o-libs := $(RDMA_LIBS)
|
||||
|
|
|
@ -21,3 +21,5 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o
|
|||
tap-obj-y ?= tap-stub.o
|
||||
common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
|
||||
common-obj-$(CONFIG_WIN32) += tap-win32.o
|
||||
|
||||
vde.o-libs = $(VDE_LIBS)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Author: Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# Archive source tree, including submodules. This is created for test code to
|
||||
# export the source files, in order to be built in a different environment,
|
||||
# such as in a docker instance or VM.
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
|
||||
error() {
|
||||
printf %s\\n "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if test $# -lt 1; then
|
||||
error "Usage: $0 <output tarball>"
|
||||
fi
|
||||
|
||||
tar_file="$1"
|
||||
list_file="$1.list"
|
||||
submodules=$(git submodule foreach --recursive --quiet 'echo $name')
|
||||
|
||||
if test $? -ne 0; then
|
||||
error "git submodule command failed"
|
||||
fi
|
||||
|
||||
trap "status=$?; rm -f \"$list_file\"; exit \$status" 0 1 2 3 15
|
||||
|
||||
if test -n "$submodules"; then
|
||||
{
|
||||
git ls-files || error "git ls-files failed"
|
||||
for sm in $submodules; do
|
||||
(cd $sm; git ls-files) | sed "s:^:$sm/:"
|
||||
if test "${PIPESTATUS[*]}" != "0 0"; then
|
||||
error "git ls-files in submodule $sm failed"
|
||||
fi
|
||||
done
|
||||
} | grep -x -v $(for sm in $submodules; do echo "-e $sm"; done) > "$list_file"
|
||||
else
|
||||
git ls-files > "$list_file"
|
||||
fi
|
||||
|
||||
if test $? -ne 0; then
|
||||
error "failed to generate list file"
|
||||
fi
|
||||
|
||||
tar -cf "$tar_file" -T "$list_file" || error "failed to create tar file"
|
||||
|
||||
exit 0
|
|
@ -215,6 +215,13 @@ class QEMUMachine(object):
|
|||
LOG.debug('Output: %r', self._iolog)
|
||||
raise
|
||||
|
||||
def wait(self):
|
||||
'''Wait for the VM to power off'''
|
||||
self._popen.wait()
|
||||
self._qmp.close()
|
||||
self._load_io_log()
|
||||
self._post_shutdown()
|
||||
|
||||
def shutdown(self):
|
||||
'''Terminate the VM and clean up'''
|
||||
if self.is_running():
|
||||
|
|
|
@ -95,3 +95,4 @@ test-filter-mirror
|
|||
test-filter-redirector
|
||||
*-test
|
||||
qapi-schema/*.test.*
|
||||
vm/*.img
|
||||
|
|
|
@ -17,23 +17,13 @@ DOCKER_TOOLS := travis
|
|||
TESTS ?= %
|
||||
IMAGES ?= %
|
||||
|
||||
# Make archive from git repo $1 to tar.gz $2
|
||||
make-archive-maybe = $(if $(wildcard $1/*), \
|
||||
$(call quiet-command, \
|
||||
(cd $1; if git diff-index --quiet HEAD -- &>/dev/null; then \
|
||||
git archive -1 HEAD --format=tar.gz; \
|
||||
else \
|
||||
git archive -1 $$(git stash create) --format=tar.gz; \
|
||||
fi) > $2, \
|
||||
"ARCHIVE","$(notdir $2)"))
|
||||
|
||||
CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$)
|
||||
DOCKER_SRC_COPY := docker-src.$(CUR_TIME)
|
||||
|
||||
$(DOCKER_SRC_COPY):
|
||||
@mkdir $@
|
||||
$(call make-archive-maybe, $(SRC_PATH), $@/qemu.tgz)
|
||||
$(call make-archive-maybe, $(SRC_PATH)/dtc, $@/dtc.tgz)
|
||||
$(call quiet-command, $(SRC_PATH)/scripts/archive-source.sh $@/qemu.tar, \
|
||||
"GEN", "$@/qemu.tar")
|
||||
$(call quiet-command, cp $(SRC_PATH)/tests/docker/run $@/run, \
|
||||
"COPY","RUNNER")
|
||||
|
||||
|
@ -70,6 +60,7 @@ docker-image-debian-ppc64el-cross: docker-image-debian9
|
|||
docker-image-debian-s390x-cross: docker-image-debian9
|
||||
docker-image-debian-win32-cross: docker-image-debian8-mxe
|
||||
docker-image-debian-win64-cross: docker-image-debian8-mxe
|
||||
docker-image-travis: NOUSER=1
|
||||
|
||||
# Expand all the pre-requistes for each docker image and test combination
|
||||
$(foreach i,$(DOCKER_IMAGES), \
|
||||
|
@ -144,6 +135,7 @@ docker-run: docker-qemu-src
|
|||
$(call quiet-command, \
|
||||
$(SRC_PATH)/tests/docker/docker.py run \
|
||||
$(if $(NOUSER),,-u $(shell id -u)) -t \
|
||||
--security-opt seccomp=unconfined \
|
||||
$(if $V,,--rm) \
|
||||
$(if $(DEBUG),-i,) \
|
||||
$(if $(NETWORK),$(if $(subst $(NETWORK),,1),--net=$(NETWORK)),--net=none) \
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
# or (at your option) any later version. See the COPYING file in
|
||||
# the top-level directory.
|
||||
|
||||
BUILD_DIR=/var/tmp/qemu-build
|
||||
mkdir $BUILD_DIR
|
||||
|
||||
requires()
|
||||
{
|
||||
for c in $@; do
|
||||
|
@ -28,11 +25,22 @@ build_qemu()
|
|||
{
|
||||
config_opts="--enable-werror \
|
||||
${TARGET_LIST:+--target-list=${TARGET_LIST}} \
|
||||
--prefix=$PWD/install \
|
||||
--prefix=$INSTALL_DIR \
|
||||
$QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS \
|
||||
$@"
|
||||
echo "Configure options:"
|
||||
echo $config_opts
|
||||
$QEMU_SRC/configure $config_opts
|
||||
make $MAKEFLAGS
|
||||
$QEMU_SRC/configure $config_opts && make $MAKEFLAGS
|
||||
}
|
||||
|
||||
test_fail()
|
||||
{
|
||||
echo "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
prep_fail()
|
||||
{
|
||||
echo "$@"
|
||||
exit 2
|
||||
}
|
||||
|
|
|
@ -263,7 +263,8 @@ class BuildCommand(SubCommand):
|
|||
tag = args.tag
|
||||
|
||||
dkr = Docker()
|
||||
if dkr.image_matches_dockerfile(tag, dockerfile):
|
||||
if "--no-cache" not in argv and \
|
||||
dkr.image_matches_dockerfile(tag, dockerfile):
|
||||
if not args.quiet:
|
||||
print "Image is up to date."
|
||||
else:
|
||||
|
|
|
@ -3,6 +3,7 @@ ENV PACKAGES \
|
|||
ccache git tar PyYAML sparse flex bison python2 bzip2 hostname \
|
||||
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
|
||||
gcc gcc-c++ clang make perl which bc findutils libaio-devel \
|
||||
nettle-devel \
|
||||
mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
|
||||
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
|
||||
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
FROM quay.io/travisci/travis-ruby
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
RUN apt-get update
|
||||
RUN apt-get -y build-dep qemu
|
||||
RUN apt-get -y build-dep device-tree-compiler
|
||||
RUN apt-get -y install python2.7 python-yaml dh-autoreconf gdb strace lsof net-tools
|
||||
RUN apt-get -y install device-tree-compiler python2.7 python-yaml dh-autoreconf gdb strace lsof net-tools
|
||||
ENV FEATURES pyyaml
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
FROM ubuntu:14.04
|
||||
FROM ubuntu:16.04
|
||||
RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \
|
||||
/etc/apt/sources.list
|
||||
RUN apt-get update
|
||||
ENV PACKAGES flex bison \
|
||||
libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev \
|
||||
libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev libncursesw5-dev \
|
||||
libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev \
|
||||
libspice-protocol-dev libnss3-dev libfdt-dev \
|
||||
libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \
|
||||
libgtk-3-dev libvte-2.91-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \
|
||||
libvdeplug-dev liblzo2-dev libsnappy-dev libbz2-dev libxen-dev librdmacm-dev libibverbs-dev \
|
||||
libsasl2-dev libjpeg-turbo8-dev xfslibs-dev libcap-ng-dev libbrlapi-dev libcurl4-gnutls-dev \
|
||||
libbluetooth-dev librbd-dev libaio-dev glusterfs-common libnuma-dev libepoxy-dev libdrm-dev libgbm-dev \
|
||||
libjemalloc-dev libcacard-dev libusbredirhost-dev libnfs-dev libcap-dev libattr1-dev \
|
||||
texinfo \
|
||||
git make ccache python-yaml gcc clang sparse
|
||||
RUN apt-get -y install $PACKAGES
|
||||
RUN dpkg -l $PACKAGES | sort > /packages.txt
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash -e
|
||||
#!/bin/bash
|
||||
#
|
||||
# Docker test runner
|
||||
#
|
||||
|
@ -11,8 +11,6 @@
|
|||
# or (at your option) any later version. See the COPYING file in
|
||||
# the top-level directory.
|
||||
|
||||
set -e
|
||||
|
||||
if test -n "$V"; then
|
||||
set -x
|
||||
fi
|
||||
|
@ -20,7 +18,7 @@ fi
|
|||
BASE="$(dirname $(readlink -e $0))"
|
||||
|
||||
# Prepare the environment
|
||||
. /etc/profile || true
|
||||
. /etc/profile
|
||||
export PATH=/usr/lib/ccache:$PATH
|
||||
|
||||
if test -n "$J"; then
|
||||
|
@ -32,13 +30,7 @@ export TEST_DIR=/tmp/qemu-test
|
|||
mkdir -p $TEST_DIR/{src,build,install}
|
||||
|
||||
# Extract the source tarballs
|
||||
tar -C $TEST_DIR/src -xzf $BASE/qemu.tgz
|
||||
for p in dtc pixman; do
|
||||
if test -f $BASE/$p.tgz; then
|
||||
tar -C $TEST_DIR/src/$p -xzf $BASE/$p.tgz
|
||||
export FEATURES="$FEATURES $p"
|
||||
fi
|
||||
done
|
||||
tar -C $TEST_DIR/src -xf $BASE/qemu.tar || prep_fail "Failed to untar source"
|
||||
|
||||
if test -n "$SHOW_ENV"; then
|
||||
if test -f /packages.txt; then
|
||||
|
@ -52,10 +44,12 @@ if test -n "$SHOW_ENV"; then
|
|||
fi
|
||||
|
||||
export QEMU_SRC="$TEST_DIR/src"
|
||||
export BUILD_DIR="$TEST_DIR/build"
|
||||
export INSTALL_DIR="$TEST_DIR/install"
|
||||
|
||||
cd "$QEMU_SRC/tests/docker"
|
||||
|
||||
CMD="$QEMU_SRC/tests/docker/$@"
|
||||
CMD="./$@"
|
||||
|
||||
if test -z "$DEBUG"; then
|
||||
exec $CMD
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Run block test cases
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
|
||||
. ./common.rc
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
build_qemu --target-list=x86_64-softmmu
|
||||
cd tests/qemu-iotests
|
||||
for t in raw qcow2 nbd luks; do
|
||||
./check -g quick -$t || test_fail "Test failed: iotests $t"
|
||||
done
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/bash -e
|
||||
#!/bin/bash
|
||||
#
|
||||
# Compile all the targets.
|
||||
# Compile all the targets with as many features enabled as possible
|
||||
#
|
||||
# Copyright (c) 2016 Red Hat Inc.
|
||||
# Copyright 2016, 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
|
@ -13,7 +13,77 @@
|
|||
|
||||
. common.rc
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
cd "$BUILD_DIR" || exit 1
|
||||
|
||||
build_qemu
|
||||
make check $MAKEFLAGS
|
||||
build_qemu \
|
||||
--enable-attr \
|
||||
--enable-bluez \
|
||||
--enable-brlapi \
|
||||
--enable-bsd-user \
|
||||
--enable-bzip2 \
|
||||
--enable-cap-ng \
|
||||
--enable-coroutine-pool \
|
||||
--enable-crypto-afalg \
|
||||
--enable-curl \
|
||||
--enable-curses \
|
||||
--enable-debug \
|
||||
--enable-debug-info \
|
||||
--enable-debug-tcg \
|
||||
--enable-docs \
|
||||
--enable-fdt \
|
||||
--enable-gcrypt \
|
||||
--enable-glusterfs \
|
||||
--enable-gnutls \
|
||||
--enable-gprof \
|
||||
--enable-gtk \
|
||||
--enable-guest-agent \
|
||||
--enable-jemalloc \
|
||||
--enable-kvm \
|
||||
--enable-libiscsi \
|
||||
--enable-libnfs \
|
||||
--enable-libssh2 \
|
||||
--enable-libusb \
|
||||
--enable-linux-aio \
|
||||
--enable-linux-user \
|
||||
--enable-live-block-migration \
|
||||
--enable-lzo \
|
||||
--enable-modules \
|
||||
--enable-numa \
|
||||
--enable-opengl \
|
||||
--enable-pie \
|
||||
--enable-profiler \
|
||||
--enable-qom-cast-debug \
|
||||
--enable-rbd \
|
||||
--enable-rdma \
|
||||
--enable-replication \
|
||||
--enable-sdl \
|
||||
--enable-seccomp \
|
||||
--enable-smartcard \
|
||||
--enable-snappy \
|
||||
--enable-spice \
|
||||
--enable-stack-protector \
|
||||
--enable-system \
|
||||
--enable-tcg \
|
||||
--enable-tcg-interpreter \
|
||||
--enable-tools \
|
||||
--enable-tpm \
|
||||
--enable-trace-backend=ftrace \
|
||||
--enable-usb-redir \
|
||||
--enable-user \
|
||||
--enable-vde \
|
||||
--enable-vhost-net \
|
||||
--enable-vhost-scsi \
|
||||
--enable-vhost-user \
|
||||
--enable-vhost-vsock \
|
||||
--enable-virtfs \
|
||||
--enable-vnc \
|
||||
--enable-vnc-jpeg \
|
||||
--enable-vnc-png \
|
||||
--enable-vnc-sasl \
|
||||
--enable-vte \
|
||||
--enable-werror \
|
||||
--enable-xen \
|
||||
--enable-xen-pci-passthrough \
|
||||
--enable-xen-pv-domain-build \
|
||||
--enable-xfsctl \
|
||||
&& make check $MAKEFLAGS
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
This folder contains a well-known ssh key pair used in QEMU tests.
|
||||
|
||||
Some guests require the key to exist prior to provisioning the guest; also,
|
||||
reusing a pre-built key avoids consuming entropy every time the testsuite is
|
||||
run. Because the private key is well-known, care must be taken to use the key
|
||||
ONLY in situations that cannot be compromised by external network clients.
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAopAuOlmLV6LVHdFBj8/eeOwI9CqguIJPp7eAQSZvOiB4Ag/R
|
||||
coEhl/RBbrV5Yc/SmSD4PTpJO/iM10RwliNjDb4a3I8q3sykRJu9c9PI/YsH8WN9
|
||||
+NH2NjKPtJIcKTu287IM5JYxyB6nDoOzILbTyJ1TDR/xH6qYEfBAyiblggdjcvhA
|
||||
RTf93QIn39F/xLypXvT1K2O9BJEsnJ8lEUvB2UXhKo/JTfSeZF8wPBeowaP9EONk
|
||||
7b+nuJOWHGg68Ji6wVi62tjwl2Szch6lxIhZBpnV7QNRKMfYHP6eIyF4pusazzZq
|
||||
Telsq6xI2ghecWLzb/MF5A+rklsGx2FNuJSAJwIDAQABAoIBAHHi4o/8VZNivz0x
|
||||
cWXn8erzKV6tUoWQvW85Lj/2RiwJvSlsnYZDkx5af1CpEE2HA/pFT8PNRqsd+MWC
|
||||
7AEy710cVsM4BYerBFYQaYxwzblaoojo88LSjVPw3h5Z0iLM8+IMVd36nwuc9dpE
|
||||
R8TecMZ1+U4Tl6BgqkK+9xToZRdPKdjS8L5MoFhGN+xY0vRbbJbGaV9Q0IHxLBkB
|
||||
rEBV7T1mUynneCHRUQlJQEwJmKpT8MH3IjsUXlG5YvnuuvcQJSNTaW2iDLxuOKp8
|
||||
cxW8+qL88zpb1D5dppoIu6rlrugN0azSq70ruFJQPc/A8GQrDKoGgRQiagxNY3u+
|
||||
vHZzXlECgYEA0dKO3gfkSxsDBb94sQwskMScqLhcKhztEa8kPxTx6Yqh+x8/scx3
|
||||
XhJyOt669P8U1v8a/2Al+s81oZzzfQSzO1Q7gEwSrgBcRMSIoRBUw9uYcy02ngb/
|
||||
j/ng3DGivfJztjjiSJwb46FHkJ2JR8mF2UisC6UMXk3NgFY/3vWQx78CgYEAxlcG
|
||||
T3hfSWSmTgKRczMJuHQOX9ULfTBIqwP5VqkkkiavzigGRirzb5lgnmuTSPTpF0LB
|
||||
XVPjR2M4q+7gzP0Dca3pocrvLEoxjwIKnCbYKnyyvnUoE9qHv4Kr+vDbgWpa2LXG
|
||||
JbLmE7tgTCIp20jOPPT4xuDvlbzQZBJ5qCQSoZkCgYEAgrotSSihlCnAOFSTXbu4
|
||||
CHp3IKe8xIBBNENq0eK61kcJpOxTQvOha3sSsJsU4JAM6+cFaxb8kseHIqonCj1j
|
||||
bhOM/uJmwQJ4el/4wGDsbxriYOBKpyq1D38gGhDS1IW6kk3erl6VAb36WJ/OaGum
|
||||
eTpN9vNeQWM4Jj2WjdNx4QECgYAwTdd6mU1TmZCrJRL5ZG+0nYc2rbMrnQvFoqUi
|
||||
BvWiJovggHzur90zy73tNzPaq9Ls2FQxf5G1vCN8NCRJqEEjeYCR59OSDMu/EXc2
|
||||
CnvQ9SevHOdS1oEDEjcCWZCMFzPi3XpRih1gptzQDe31uuiHjf3cqcGPzTlPdfRt
|
||||
D8P92QKBgC4UaBvIRwREVJsdZzpIzm224Bpe8LOmA7DeTnjlT0b3lkGiBJ36/Q0p
|
||||
VhYh/6cjX4/iuIs7gJbGon7B+YPB8scmOi3fj0+nkJAONue1mMfBNkba6qQTc6Y2
|
||||
5mEKw2/O7/JpND7ucU3OK9plcw/qnrWDgHxl0Iz95+OzUIIagxne
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCikC46WYtXotUd0UGPz9547Aj0KqC4gk+nt4BBJm86IHgCD9FygSGX9EFutXlhz9KZIPg9Okk7+IzXRHCWI2MNvhrcjyrezKREm71z08j9iwfxY3340fY2Mo+0khwpO7bzsgzkljHIHqcOg7MgttPInVMNH/EfqpgR8EDKJuWCB2Ny+EBFN/3dAiff0X/EvKle9PUrY70EkSycnyURS8HZReEqj8lN9J5kXzA8F6jBo/0Q42Ttv6e4k5YcaDrwmLrBWLra2PCXZLNyHqXEiFkGmdXtA1Eox9gc/p4jIXim6xrPNmpN6WyrrEjaCF5xYvNv8wXkD6uSWwbHYU24lIAn well-known key for qemu-test, do not use on any machine exposed to an external network
|
|
@ -0,0 +1,42 @@
|
|||
# Makefile for VM tests
|
||||
|
||||
.PHONY: vm-build-all
|
||||
|
||||
IMAGES := ubuntu.i386 freebsd netbsd openbsd
|
||||
IMAGE_FILES := $(patsubst %, tests/vm/%.img, $(IMAGES))
|
||||
|
||||
.PRECIOUS: $(IMAGE_FILES)
|
||||
|
||||
vm-test:
|
||||
@echo "vm-test: Test QEMU in preconfigured virtual machines"
|
||||
@echo
|
||||
@echo " vm-build-ubuntu.i386 - Build QEMU in ubuntu i386 VM"
|
||||
@echo " vm-build-freebsd - Build QEMU in FreeBSD VM"
|
||||
@echo " vm-build-netbsd - Build QEMU in NetBSD VM"
|
||||
@echo " vm-build-openbsd - Build QEMU in OpenBSD VM"
|
||||
|
||||
vm-build-all: $(addprefix vm-build-, $(IMAGES))
|
||||
|
||||
tests/vm/%.img: $(SRC_PATH)/tests/vm/% \
|
||||
$(SRC_PATH)/tests/vm/basevm.py \
|
||||
$(SRC_PATH)/tests/vm/Makefile.include
|
||||
$(call quiet-command, \
|
||||
$< \
|
||||
$(if $(V)$(DEBUG), --debug) \
|
||||
--image "$@" \
|
||||
--force \
|
||||
--build-image $@, \
|
||||
" VM-IMAGE $*")
|
||||
|
||||
|
||||
# Build in VM $(IMAGE)
|
||||
vm-build-%: tests/vm/%.img
|
||||
$(call quiet-command, \
|
||||
$(SRC_PATH)/tests/vm/$* \
|
||||
$(if $(V)$(DEBUG), --debug) \
|
||||
$(if $(DEBUG), --interactive) \
|
||||
$(if $(J),--jobs $(J)) \
|
||||
--image "$<" \
|
||||
--build-qemu $(SRC_PATH), \
|
||||
" VM-BUILD $*")
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
=== VM test suite to run build in guests ===
|
||||
|
||||
== Intro ==
|
||||
|
||||
This test suite contains scripts that bootstrap various guest images that have
|
||||
necessary packages to build QEMU. The basic usage is documented in Makefile
|
||||
help which is displayed with "make vm-test".
|
||||
|
||||
== Quick start ==
|
||||
|
||||
Run "make vm-test" to list available make targets. Invoke a specific make
|
||||
command to run build test in an image. For example, "make vm-build-freebsd"
|
||||
will build the source tree in the FreeBSD image. The command can be executed
|
||||
from either the source tree or the build dir; if the former, ./configure is not
|
||||
needed. The command will then generate the test image in ./tests/vm/ under the
|
||||
working directory.
|
||||
|
||||
Note: images created by the scripts accept a well-known RSA key pair for SSH
|
||||
access, so they SHOULD NOT be exposed to external interfaces if you are
|
||||
concerned about attackers taking control of the guest and potentially
|
||||
exploiting a QEMU security bug to compromise the host.
|
||||
|
||||
== QEMU binary ==
|
||||
|
||||
By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there
|
||||
isn't one, or if it is older than 2.10, the test won't work. In this case,
|
||||
provide the QEMU binary in env var: QEMU=/path/to/qemu-2.10+.
|
||||
|
||||
== Make jobs ==
|
||||
|
||||
The "-j$X" option in the make command line is not propagated into the VM,
|
||||
specify "J=$X" to control the make jobs in the guest.
|
||||
|
||||
== Debugging ==
|
||||
|
||||
Add "DEBUG=1" and/or "V=1" to the make command to allow interactive debugging
|
||||
and verbose output. If this is not enough, see the next section.
|
||||
|
||||
== Manual invocation ==
|
||||
|
||||
Each guest script is an executable script with the same command line options.
|
||||
For example to work with the netbsd guest, use $QEMU_SRC/tests/vm/netbsd:
|
||||
|
||||
$ cd $QEMU_SRC/tests/vm
|
||||
|
||||
# To bootstrap the image
|
||||
$ ./netbsd --build-image --image /var/tmp/netbsd.img
|
||||
<...>
|
||||
|
||||
# To run an arbitrary command in guest (the output will not be echoed unless
|
||||
# --debug is added)
|
||||
$ ./netbsd --debug --image /var/tmp/netbsd.img uname -a
|
||||
|
||||
# To build QEMU in guest
|
||||
$ ./netbsd --debug --image /var/tmp/netbsd.img --build-qemu $QEMU_SRC
|
||||
|
||||
# To get to an interactive shell
|
||||
$ ./netbsd --interactive --image /var/tmp/netbsd.img sh
|
||||
|
||||
== Adding new guests ==
|
||||
|
||||
Please look at existing guest scripts for how to add new guests.
|
||||
|
||||
Most importantly, create a subclass of BaseVM and implement build_image()
|
||||
method and define BUILD_SCRIPT, then finally call basevm.main() from the
|
||||
script's main().
|
||||
|
||||
- Usually in build_image(), a template image is downloaded from a predefined
|
||||
URL. BaseVM._download_with_cache() takes care of the cache and the
|
||||
checksum, so consider using it.
|
||||
|
||||
- Once the image is downloaded, users, SSH server and QEMU build deps should
|
||||
be set up:
|
||||
|
||||
* Root password set to BaseVM.ROOT_PASS
|
||||
* User BaseVM.GUEST_USER is created, and password set to BaseVM.GUEST_PASS
|
||||
* SSH service is enabled and started on boot,
|
||||
$QEMU_SRC/tests/keys/id_rsa.pub is added to ssh's "authorized_keys" file
|
||||
of both root and the normal user
|
||||
* DHCP client service is enabled and started on boot, so that it can
|
||||
automatically configure the virtio-net-pci NIC and communicate with QEMU
|
||||
user net (10.0.2.2)
|
||||
* Necessary packages are installed to untar the source tarball and build
|
||||
QEMU
|
||||
|
||||
- Write a proper BUILD_SCRIPT template, which should be a shell script that
|
||||
untars a raw virtio-blk block device, which is the tarball data blob of the
|
||||
QEMU source tree, then configure/build it. Running "make check" is also
|
||||
recommended.
|
|
@ -0,0 +1,262 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# VM testing base class
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import time
|
||||
import datetime
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
|
||||
from qemu import QEMUMachine
|
||||
import subprocess
|
||||
import hashlib
|
||||
import optparse
|
||||
import atexit
|
||||
import tempfile
|
||||
import shutil
|
||||
import multiprocessing
|
||||
import traceback
|
||||
|
||||
SSH_KEY = open(os.path.join(os.path.dirname(__file__),
|
||||
"..", "keys", "id_rsa")).read()
|
||||
SSH_PUB_KEY = open(os.path.join(os.path.dirname(__file__),
|
||||
"..", "keys", "id_rsa.pub")).read()
|
||||
|
||||
class BaseVM(object):
|
||||
GUEST_USER = "qemu"
|
||||
GUEST_PASS = "qemupass"
|
||||
ROOT_PASS = "qemupass"
|
||||
|
||||
# The script to run in the guest that builds QEMU
|
||||
BUILD_SCRIPT = ""
|
||||
# The guest name, to be overridden by subclasses
|
||||
name = "#base"
|
||||
def __init__(self, debug=False, vcpus=None):
|
||||
self._guest = None
|
||||
self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
|
||||
suffix=".tmp",
|
||||
dir="."))
|
||||
atexit.register(shutil.rmtree, self._tmpdir)
|
||||
|
||||
self._ssh_key_file = os.path.join(self._tmpdir, "id_rsa")
|
||||
open(self._ssh_key_file, "w").write(SSH_KEY)
|
||||
subprocess.check_call(["chmod", "600", self._ssh_key_file])
|
||||
|
||||
self._ssh_pub_key_file = os.path.join(self._tmpdir, "id_rsa.pub")
|
||||
open(self._ssh_pub_key_file, "w").write(SSH_PUB_KEY)
|
||||
|
||||
self.debug = debug
|
||||
self._stderr = sys.stderr
|
||||
self._devnull = open(os.devnull, "w")
|
||||
if self.debug:
|
||||
self._stdout = sys.stdout
|
||||
else:
|
||||
self._stdout = self._devnull
|
||||
self._args = [ \
|
||||
"-nodefaults", "-m", "2G",
|
||||
"-cpu", "host",
|
||||
"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
|
||||
"-device", "virtio-net-pci,netdev=vnet",
|
||||
"-vnc", "127.0.0.1:0,to=20",
|
||||
"-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
|
||||
if vcpus:
|
||||
self._args += ["-smp", str(vcpus)]
|
||||
if os.access("/dev/kvm", os.R_OK | os.W_OK):
|
||||
self._args += ["-enable-kvm"]
|
||||
else:
|
||||
logging.info("KVM not available, not using -enable-kvm")
|
||||
self._data_args = []
|
||||
|
||||
def _download_with_cache(self, url, sha256sum=None):
|
||||
def check_sha256sum(fname):
|
||||
if not sha256sum:
|
||||
return True
|
||||
checksum = subprocess.check_output(["sha256sum", fname]).split()[0]
|
||||
return sha256sum == checksum
|
||||
|
||||
cache_dir = os.path.expanduser("~/.cache/qemu-vm/download")
|
||||
if not os.path.exists(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
fname = os.path.join(cache_dir, hashlib.sha1(url).hexdigest())
|
||||
if os.path.exists(fname) and check_sha256sum(fname):
|
||||
return fname
|
||||
logging.debug("Downloading %s to %s...", url, fname)
|
||||
subprocess.check_call(["wget", "-c", url, "-O", fname + ".download"],
|
||||
stdout=self._stdout, stderr=self._stderr)
|
||||
os.rename(fname + ".download", fname)
|
||||
return fname
|
||||
|
||||
def _ssh_do(self, user, cmd, check, interactive=False):
|
||||
ssh_cmd = ["ssh", "-q",
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"-o", "UserKnownHostsFile=" + os.devnull,
|
||||
"-o", "ConnectTimeout=1",
|
||||
"-p", self.ssh_port, "-i", self._ssh_key_file]
|
||||
if interactive:
|
||||
ssh_cmd += ['-t']
|
||||
assert not isinstance(cmd, str)
|
||||
ssh_cmd += ["%s@127.0.0.1" % user] + list(cmd)
|
||||
logging.debug("ssh_cmd: %s", " ".join(ssh_cmd))
|
||||
r = subprocess.call(ssh_cmd,
|
||||
stdin=sys.stdin if interactive else self._devnull,
|
||||
stdout=sys.stdout if interactive else self._stdout,
|
||||
stderr=sys.stderr if interactive else self._stderr)
|
||||
if check and r != 0:
|
||||
raise Exception("SSH command failed: %s" % cmd)
|
||||
return r
|
||||
|
||||
def ssh(self, *cmd):
|
||||
return self._ssh_do(self.GUEST_USER, cmd, False)
|
||||
|
||||
def ssh_interactive(self, *cmd):
|
||||
return self._ssh_do(self.GUEST_USER, cmd, False, True)
|
||||
|
||||
def ssh_root(self, *cmd):
|
||||
return self._ssh_do("root", cmd, False)
|
||||
|
||||
def ssh_check(self, *cmd):
|
||||
self._ssh_do(self.GUEST_USER, cmd, True)
|
||||
|
||||
def ssh_root_check(self, *cmd):
|
||||
self._ssh_do("root", cmd, True)
|
||||
|
||||
def build_image(self, img):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_source_dir(self, src_dir):
|
||||
name = "data-" + hashlib.sha1(src_dir).hexdigest()[:5]
|
||||
tarfile = os.path.join(self._tmpdir, name + ".tar")
|
||||
logging.debug("Creating archive %s for src_dir dir: %s", tarfile, src_dir)
|
||||
subprocess.check_call(["./scripts/archive-source.sh", tarfile],
|
||||
cwd=src_dir, stdin=self._devnull,
|
||||
stdout=self._stdout, stderr=self._stderr)
|
||||
self._data_args += ["-drive",
|
||||
"file=%s,if=none,id=%s,cache=writeback,format=raw" % \
|
||||
(tarfile, name),
|
||||
"-device",
|
||||
"virtio-blk,drive=%s,serial=%s,bootindex=1" % (name, name)]
|
||||
|
||||
def boot(self, img, extra_args=[]):
|
||||
args = self._args + [
|
||||
"-device", "VGA",
|
||||
"-drive", "file=%s,if=none,id=drive0,cache=writeback" % img,
|
||||
"-device", "virtio-blk,drive=drive0,bootindex=0"]
|
||||
args += self._data_args + extra_args
|
||||
logging.debug("QEMU args: %s", " ".join(args))
|
||||
qemu_bin = os.environ.get("QEMU", "qemu-system-x86_64")
|
||||
guest = QEMUMachine(binary=qemu_bin, args=args)
|
||||
try:
|
||||
guest.launch()
|
||||
except:
|
||||
logging.error("Failed to launch QEMU, command line:")
|
||||
logging.error(" ".join([qemu_bin] + args))
|
||||
logging.error("Log:")
|
||||
logging.error(guest.get_log())
|
||||
logging.error("QEMU version >= 2.10 is required")
|
||||
raise
|
||||
atexit.register(self.shutdown)
|
||||
self._guest = guest
|
||||
usernet_info = guest.qmp("human-monitor-command",
|
||||
command_line="info usernet")
|
||||
self.ssh_port = None
|
||||
for l in usernet_info["return"].splitlines():
|
||||
fields = l.split()
|
||||
if "TCP[HOST_FORWARD]" in fields and "22" in fields:
|
||||
self.ssh_port = l.split()[3]
|
||||
if not self.ssh_port:
|
||||
raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
|
||||
usernet_info)
|
||||
|
||||
def wait_ssh(self, seconds=120):
|
||||
starttime = datetime.datetime.now()
|
||||
guest_up = False
|
||||
while (datetime.datetime.now() - starttime).total_seconds() < seconds:
|
||||
if self.ssh("exit 0") == 0:
|
||||
guest_up = True
|
||||
break
|
||||
time.sleep(1)
|
||||
if not guest_up:
|
||||
raise Exception("Timeout while waiting for guest ssh")
|
||||
|
||||
def shutdown(self):
|
||||
self._guest.shutdown()
|
||||
|
||||
def wait(self):
|
||||
self._guest.wait()
|
||||
|
||||
def qmp(self, *args, **kwargs):
|
||||
return self._guest.qmp(*args, **kwargs)
|
||||
|
||||
def parse_args(vm_name):
|
||||
parser = optparse.OptionParser(
|
||||
description="VM test utility. Exit codes: "
|
||||
"0 = success, "
|
||||
"1 = command line error, "
|
||||
"2 = environment initialization failed, "
|
||||
"3 = test command failed")
|
||||
parser.add_option("--debug", "-D", action="store_true",
|
||||
help="enable debug output")
|
||||
parser.add_option("--image", "-i", default="%s.img" % vm_name,
|
||||
help="image file name")
|
||||
parser.add_option("--force", "-f", action="store_true",
|
||||
help="force build image even if image exists")
|
||||
parser.add_option("--jobs", type=int, default=multiprocessing.cpu_count() / 2,
|
||||
help="number of virtual CPUs")
|
||||
parser.add_option("--build-image", "-b", action="store_true",
|
||||
help="build image")
|
||||
parser.add_option("--build-qemu",
|
||||
help="build QEMU from source in guest")
|
||||
parser.add_option("--interactive", "-I", action="store_true",
|
||||
help="Interactively run command")
|
||||
parser.disable_interspersed_args()
|
||||
return parser.parse_args()
|
||||
|
||||
def main(vmcls):
|
||||
try:
|
||||
args, argv = parse_args(vmcls.name)
|
||||
if not argv and not args.build_qemu and not args.build_image:
|
||||
print "Nothing to do?"
|
||||
return 1
|
||||
if args.debug:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
vm = vmcls(debug=args.debug, vcpus=args.jobs)
|
||||
if args.build_image:
|
||||
if os.path.exists(args.image) and not args.force:
|
||||
sys.stderr.writelines(["Image file exists: %s\n" % args.image,
|
||||
"Use --force option to overwrite\n"])
|
||||
return 1
|
||||
return vm.build_image(args.image)
|
||||
if args.build_qemu:
|
||||
vm.add_source_dir(args.build_qemu)
|
||||
cmd = [vm.BUILD_SCRIPT.format(
|
||||
configure_opts = " ".join(argv),
|
||||
jobs=args.jobs)]
|
||||
else:
|
||||
cmd = argv
|
||||
vm.boot(args.image + ",snapshot=on")
|
||||
vm.wait_ssh()
|
||||
except Exception as e:
|
||||
if isinstance(e, SystemExit) and e.code == 0:
|
||||
return 0
|
||||
sys.stderr.write("Failed to prepare guest environment\n")
|
||||
traceback.print_exc()
|
||||
return 2
|
||||
|
||||
if args.interactive:
|
||||
if vm.ssh_interactive(*cmd) == 0:
|
||||
return 0
|
||||
vm.ssh_interactive()
|
||||
return 3
|
||||
else:
|
||||
if vm.ssh(*cmd) != 0:
|
||||
return 3
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# FreeBSD VM image
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import basevm
|
||||
|
||||
class FreeBSDVM(basevm.BaseVM):
|
||||
name = "freebsd"
|
||||
BUILD_SCRIPT = """
|
||||
set -e;
|
||||
cd $(mktemp -d /var/tmp/qemu-test.XXXXXX);
|
||||
tar -xf /dev/vtbd1;
|
||||
./configure {configure_opts};
|
||||
gmake -j{jobs};
|
||||
gmake check;
|
||||
"""
|
||||
|
||||
def build_image(self, img):
|
||||
cimg = self._download_with_cache("http://download.patchew.org/freebsd-11.1-amd64.img.xz",
|
||||
sha256sum='adcb771549b37bc63826c501f05121a206ed3d9f55f49145908f7e1432d65891')
|
||||
img_tmp_xz = img + ".tmp.xz"
|
||||
img_tmp = img + ".tmp"
|
||||
subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
|
||||
subprocess.check_call(["xz", "-df", img_tmp_xz])
|
||||
if os.path.exists(img):
|
||||
os.remove(img)
|
||||
os.rename(img_tmp, img)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(basevm.main(FreeBSDVM))
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# NetBSD VM image
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import basevm
|
||||
|
||||
class NetBSDVM(basevm.BaseVM):
|
||||
name = "netbsd"
|
||||
BUILD_SCRIPT = """
|
||||
set -e;
|
||||
cd $(mktemp -d /var/tmp/qemu-test.XXXXXX);
|
||||
tar -xf /dev/rld1a;
|
||||
./configure --python=python2.7 {configure_opts};
|
||||
gmake -j{jobs};
|
||||
gmake check;
|
||||
"""
|
||||
|
||||
def build_image(self, img):
|
||||
cimg = self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz",
|
||||
sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
|
||||
img_tmp_xz = img + ".tmp.xz"
|
||||
img_tmp = img + ".tmp"
|
||||
subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
|
||||
subprocess.check_call(["xz", "-df", img_tmp_xz])
|
||||
if os.path.exists(img):
|
||||
os.remove(img)
|
||||
os.rename(img_tmp, img)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(basevm.main(NetBSDVM))
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# OpenBSD VM image
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import basevm
|
||||
|
||||
class OpenBSDVM(basevm.BaseVM):
|
||||
name = "openbsd"
|
||||
BUILD_SCRIPT = """
|
||||
set -e;
|
||||
cd $(mktemp -d /var/tmp/qemu-test.XXXXXX);
|
||||
tar -xf /dev/rsd1c;
|
||||
./configure --cc=x86_64-unknown-openbsd6.1-gcc-4.9.4 --python=python2.7 {configure_opts};
|
||||
gmake -j{jobs};
|
||||
# XXX: "gmake check" seems to always hang or fail
|
||||
#gmake check;
|
||||
"""
|
||||
|
||||
def build_image(self, img):
|
||||
cimg = self._download_with_cache("http://download.patchew.org/openbsd-6.1-amd64.img.xz",
|
||||
sha256sum='8c6cedc483e602cfee5e04f0406c64eb99138495e8ca580bc0293bcf0640c1bf')
|
||||
img_tmp_xz = img + ".tmp.xz"
|
||||
img_tmp = img + ".tmp"
|
||||
subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
|
||||
subprocess.check_call(["xz", "-df", img_tmp_xz])
|
||||
if os.path.exists(img):
|
||||
os.remove(img)
|
||||
os.rename(img_tmp, img)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(basevm.main(OpenBSDVM))
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Ubuntu i386 image
|
||||
#
|
||||
# Copyright 2017 Red Hat Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Fam Zheng <famz@redhat.com>
|
||||
#
|
||||
# This code is licensed under the GPL version 2 or later. See
|
||||
# the COPYING file in the top-level directory.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import basevm
|
||||
import time
|
||||
|
||||
class UbuntuX86VM(basevm.BaseVM):
|
||||
name = "ubuntu.i386"
|
||||
BUILD_SCRIPT = """
|
||||
set -e;
|
||||
cd $(mktemp -d);
|
||||
sudo chmod a+r /dev/vdb;
|
||||
tar -xf /dev/vdb;
|
||||
./configure {configure_opts};
|
||||
make -j{jobs};
|
||||
make check;
|
||||
"""
|
||||
|
||||
def _gen_cloud_init_iso(self):
|
||||
cidir = self._tmpdir
|
||||
mdata = open(os.path.join(cidir, "meta-data"), "w")
|
||||
mdata.writelines(["instance-id: ubuntu-vm-0\n",
|
||||
"local-hostname: ubuntu-guest\n"])
|
||||
mdata.close()
|
||||
udata = open(os.path.join(cidir, "user-data"), "w")
|
||||
udata.writelines(["#cloud-config\n",
|
||||
"chpasswd:\n",
|
||||
" list: |\n",
|
||||
" root:%s\n" % self.ROOT_PASS,
|
||||
" %s:%s\n" % (self.GUEST_USER, self.GUEST_PASS),
|
||||
" expire: False\n",
|
||||
"users:\n",
|
||||
" - name: %s\n" % self.GUEST_USER,
|
||||
" sudo: ALL=(ALL) NOPASSWD:ALL\n",
|
||||
" ssh-authorized-keys:\n",
|
||||
" - %s\n" % basevm.SSH_PUB_KEY,
|
||||
" - name: root\n",
|
||||
" ssh-authorized-keys:\n",
|
||||
" - %s\n" % basevm.SSH_PUB_KEY,
|
||||
"locale: en_US.UTF-8\n"])
|
||||
udata.close()
|
||||
subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
|
||||
"-volid", "cidata", "-joliet", "-rock",
|
||||
"user-data", "meta-data"],
|
||||
cwd=cidir,
|
||||
stdin=self._devnull, stdout=self._stdout,
|
||||
stderr=self._stdout)
|
||||
return os.path.join(cidir, "cloud-init.iso")
|
||||
|
||||
def build_image(self, img):
|
||||
cimg = self._download_with_cache("https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-i386-disk1.img")
|
||||
img_tmp = img + ".tmp"
|
||||
subprocess.check_call(["cp", "-f", cimg, img_tmp])
|
||||
subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"])
|
||||
self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()])
|
||||
self.wait_ssh()
|
||||
self.ssh_root_check("touch /etc/cloud/cloud-init.disabled")
|
||||
self.ssh_root_check("apt-get update")
|
||||
self.ssh_root_check("apt-get install -y cloud-initramfs-growroot")
|
||||
# Don't check the status in case the guest hang up too quickly
|
||||
self.ssh_root("sync && reboot")
|
||||
time.sleep(5)
|
||||
self.wait_ssh()
|
||||
# The previous update sometimes doesn't survive a reboot, so do it again
|
||||
self.ssh_root_check("apt-get update")
|
||||
self.ssh_root_check("apt-get build-dep -y qemu")
|
||||
self.ssh_root_check("apt-get install -y libfdt-dev")
|
||||
self.ssh_root("poweroff")
|
||||
self.wait()
|
||||
if os.path.exists(img):
|
||||
os.remove(img)
|
||||
os.rename(img_tmp, img)
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(basevm.main(UbuntuX86VM))
|
|
@ -27,6 +27,7 @@ sdl.mo-objs += sdl2-gl.o
|
|||
endif
|
||||
endif
|
||||
sdl.mo-cflags := $(SDL_CFLAGS)
|
||||
sdl.mo-libs := $(SDL_LIBS)
|
||||
|
||||
ifeq ($(CONFIG_OPENGL),y)
|
||||
common-obj-y += shader.o
|
||||
|
|
Loading…
Reference in New Issue