diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-07-05 11:21:29 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-07-05 11:21:29 +0100 |
commit | 0050f9978e47182270c0536906abfd3e9fa91dea (patch) | |
tree | f3e56755c749b003f8e12dabf25ec8f478cde2b9 | |
parent | c35d17cabc1e2c72ac0adfd47a0dc9ea40875069 (diff) | |
parent | 1f4abd81f7dfeb9d622b37368bef22a6481ebc66 (diff) |
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-next-050719-3' into staging
Various testing fixes:
- tests/vm updates and clean-ups
- tests/vm serial autobuild on host (-netbsd v3)
- ensure MacOS builds do "brew update"
- ensure we test --static user builds
- fix hyperv compile failure
- fix missing var warning for OpenBSD (v2)
This brings my testing back to green on all CI services. Please note
the BSD installs will throw out some warnings during the setup phase.
They shouldn't re-occur once the images are built. NetBSD has been
dropped for now given slow install issues.
# gpg: Signature made Fri 05 Jul 2019 11:15:21 BST
# gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44
* remotes/stsquad/tags/pull-testing-next-050719-3:
migration: move port_attr inside CONFIG_LINUX
target/i386: fix feature check in hyperv-stub.c
Makefile: Rename the 'vm-test' target as 'vm-help'
.travis.yml: force a brew update for MacOS builds
.travis.yml: default the --disable-system build to --static
tests/vm: ubuntu.i386: apt proxy setup
tests/vm: fedora autoinstall, using serial console
tests/vm: freebsd autoinstall, using serial console
tests/vm: openbsd autoinstall, using serial console
tests/vm: serial console support helpers
tests/vm: add vm-boot-{ssh,serial}-<guest> targets
tests/vm: proper guest shutdown
tests/vm: run test builds on snapshot
tests/vm: use ssh with pty unconditionally
tests/vm: send proxy environment variables over ssh
tests/vm: add source repos on ubuntu.i386
tests/vm: pin ubuntu.i386 image
tests/vm: avoid image presence check and removal
tests/vm: avoid extra compressed image copy
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | docs/devel/testing.rst | 4 | ||||
-rw-r--r-- | migration/rdma.c | 3 | ||||
-rw-r--r-- | target/i386/hyperv-stub.c | 2 | ||||
-rw-r--r-- | tests/vm/Makefile.include | 28 | ||||
-rwxr-xr-x | tests/vm/basevm.py | 135 | ||||
-rwxr-xr-x | tests/vm/centos | 6 | ||||
-rwxr-xr-x | tests/vm/fedora | 189 | ||||
-rwxr-xr-x | tests/vm/freebsd | 180 | ||||
-rwxr-xr-x | tests/vm/netbsd | 6 | ||||
-rwxr-xr-x | tests/vm/openbsd | 159 | ||||
-rwxr-xr-x | tests/vm/ubuntu.i386 | 11 |
13 files changed, 667 insertions, 63 deletions
diff --git a/.travis.yml b/.travis.yml index 279658b116..5d3d6ee1d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ addons: - glib - pixman - gnu-sed + update: true # The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu @@ -80,7 +81,7 @@ script: matrix: include: - env: - - CONFIG="--disable-system" + - CONFIG="--disable-system --static" # we split the system builds as it takes a while to build them all @@ -13,7 +13,7 @@ SRC_PATH=. UNCHECKED_GOALS := %clean TAGS cscope ctags dist \ html info pdf txt \ help check-help print-% \ - docker docker-% vm-test vm-build-% + docker docker-% vm-help vm-test vm-build-% print-%: @echo '$*=$($*)' @@ -1153,7 +1153,7 @@ endif @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 ' vm-help - Help about targets running tests inside VM' @echo '' @echo 'Documentation targets:' @echo ' html info pdf txt' diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index da2d0fc964..68aba3926e 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -399,12 +399,12 @@ VM testing 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``. +help which is displayed with ``make vm-help``. Quickstart ---------- -Run ``make vm-test`` to list available make targets. Invoke a specific make +Run ``make vm-help`` 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 diff --git a/migration/rdma.c b/migration/rdma.c index 74cb2aa9f9..3036221ee8 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -839,10 +839,9 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id) */ static int qemu_rdma_broken_ipv6_kernel(struct ibv_context *verbs, Error **errp) { - struct ibv_port_attr port_attr; - /* This bug only exists in linux, to our knowledge. */ #ifdef CONFIG_LINUX + struct ibv_port_attr port_attr; /* * Verbs are only NULL if management has bound to '[::]'. diff --git a/target/i386/hyperv-stub.c b/target/i386/hyperv-stub.c index fe548cbae2..0028527e79 100644 --- a/target/i386/hyperv-stub.c +++ b/target/i386/hyperv-stub.c @@ -15,7 +15,7 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) { switch (exit->type) { case KVM_EXIT_HYPERV_SYNIC: - if (!cpu->hyperv_synic) { + if (!hyperv_feat_enabled(cpu, HYPERV_FEAT_SYNIC)) { return -1; } diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index c59411bee0..3560716092 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -2,24 +2,30 @@ .PHONY: vm-build-all vm-clean-all -IMAGES := ubuntu.i386 freebsd netbsd openbsd centos +IMAGES := ubuntu.i386 freebsd netbsd openbsd centos fedora IMAGES_DIR := $(HOME)/.cache/qemu-vm/images IMAGE_FILES := $(patsubst %, $(IMAGES_DIR)/%.img, $(IMAGES)) .PRECIOUS: $(IMAGE_FILES) -vm-test: - @echo "vm-test: Test QEMU in preconfigured virtual machines" +# 'vm-help' target was historically named 'vm-test' +vm-help vm-test: + @echo "vm-help: 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" @echo " vm-build-centos - Build QEMU in CentOS VM, with Docker" + @echo " vm-build-fedora - Build QEMU in Fedora VM" @echo "" @echo " vm-build-all - Build QEMU in all VMs" @echo " vm-clean-all - Clean up VM images" @echo + @echo "For trouble-shooting:" + @echo " vm-boot-serial-<guest> - Boot guest, serial console on stdio" + @echo " vm-boot-ssh-<guest> - Boot guest and login via ssh" + @echo @echo "Special variables:" @echo " BUILD_TARGET=foo - Override the build target" @echo " TARGET_LIST=a,b,c - Override target list in builds" @@ -57,8 +63,24 @@ vm-build-%: $(IMAGES_DIR)/%.img $(if $(V),--verbose) \ --image "$<" \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ + --snapshot \ --build-qemu $(SRC_PATH) -- \ $(if $(TARGET_LIST),--target-list=$(TARGET_LIST)) \ $(if $(EXTRA_CONFIGURE_OPTS),$(EXTRA_CONFIGURE_OPTS)), \ " VM-BUILD $*") +vm-boot-serial-%: $(IMAGES_DIR)/%.img + qemu-system-x86_64 -enable-kvm -m 4G -smp 2 -nographic \ + -drive if=none,id=vblk,cache=writeback,file="$<" \ + -netdev user,id=vnet \ + -device virtio-blk-pci,drive=vblk \ + -device virtio-net-pci,netdev=vnet \ + || true + +vm-boot-ssh-%: $(IMAGES_DIR)/%.img + $(call quiet-command, \ + $(SRC_PATH)/tests/vm/$* \ + --image "$<" \ + --interactive \ + false, \ + " VM-BOOT-SSH $*") || true diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 64067c1075..b5d1479bee 100755 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -2,10 +2,11 @@ # # VM testing base class # -# Copyright 2017 Red Hat Inc. +# Copyright 2017-2019 Red Hat Inc. # # Authors: # Fam Zheng <famz@redhat.com> +# Gerd Hoffmann <kraxel@redhat.com> # # This code is licensed under the GPL version 2 or later. See # the COPYING file in the top-level directory. @@ -13,7 +14,9 @@ from __future__ import print_function import os +import re import sys +import socket import logging import time import datetime @@ -39,12 +42,21 @@ class BaseVM(object): GUEST_PASS = "qemupass" ROOT_PASS = "qemupass" + envvars = [ + "https_proxy", + "http_proxy", + "ftp_proxy", + "no_proxy", + ] + # The script to run in the guest that builds QEMU BUILD_SCRIPT = "" # The guest name, to be overridden by subclasses name = "#base" # The guest architecture, to be overridden by subclasses arch = "#arch" + # command to halt the guest, can be overridden by subclasses + poweroff = "poweroff" def __init__(self, debug=False, vcpus=None): self._guest = None self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-", @@ -71,8 +83,7 @@ class BaseVM(object): "-cpu", "max", "-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")] + "-vnc", "127.0.0.1:0,to=20"] if vcpus and vcpus > 1: self._args += ["-smp", "%d" % vcpus] if kvm_available(self.arch): @@ -101,14 +112,14 @@ class BaseVM(object): os.rename(fname + ".download", fname) return fname - def _ssh_do(self, user, cmd, check, interactive=False): - ssh_cmd = ["ssh", "-q", + def _ssh_do(self, user, cmd, check): + ssh_cmd = ["ssh", "-q", "-t", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=" + os.devnull, "-o", "ConnectTimeout=1", "-p", self.ssh_port, "-i", self._ssh_key_file] - if interactive: - ssh_cmd += ['-t'] + for var in self.envvars: + ssh_cmd += ['-o', "SendEnv=%s" % var ] assert not isinstance(cmd, str) ssh_cmd += ["%s@127.0.0.1" % user] + list(cmd) logging.debug("ssh_cmd: %s", " ".join(ssh_cmd)) @@ -120,9 +131,6 @@ class BaseVM(object): 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) @@ -157,6 +165,8 @@ class BaseVM(object): logging.debug("QEMU args: %s", " ".join(args)) qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch) guest = QEMUMachine(binary=qemu_bin, args=args) + guest.set_machine('pc') + guest.set_console() try: guest.launch() except: @@ -179,6 +189,89 @@ class BaseVM(object): raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \ usernet_info) + def console_init(self, timeout = 120): + vm = self._guest + vm.console_socket.settimeout(timeout) + + def console_log(self, text): + for line in re.split("[\r\n]", text): + # filter out terminal escape sequences + line = re.sub("\x1b\[[0-9;?]*[a-zA-Z]", "", line) + line = re.sub("\x1b\([0-9;?]*[a-zA-Z]", "", line) + # replace unprintable chars + line = re.sub("\x1b", "<esc>", line) + line = re.sub("[\x00-\x1f]", ".", line) + line = re.sub("[\x80-\xff]", ".", line) + if line == "": + continue + # log console line + sys.stderr.write("con recv: %s\n" % line) + + def console_wait(self, expect, expectalt = None): + vm = self._guest + output = "" + while True: + try: + chars = vm.console_socket.recv(1) + except socket.timeout: + sys.stderr.write("console: *** read timeout ***\n") + sys.stderr.write("console: waiting for: '%s'\n" % expect) + if not expectalt is None: + sys.stderr.write("console: waiting for: '%s' (alt)\n" % expectalt) + sys.stderr.write("console: line buffer:\n") + sys.stderr.write("\n") + self.console_log(output.rstrip()) + sys.stderr.write("\n") + raise + output += chars.decode("latin1") + if expect in output: + break + if not expectalt is None and expectalt in output: + break + if "\r" in output or "\n" in output: + lines = re.split("[\r\n]", output) + output = lines.pop() + if self.debug: + self.console_log("\n".join(lines)) + if self.debug: + self.console_log(output) + if not expectalt is None and expectalt in output: + return False + return True + + def console_send(self, command): + vm = self._guest + if self.debug: + logline = re.sub("\n", "<enter>", command) + logline = re.sub("[\x00-\x1f]", ".", logline) + sys.stderr.write("con send: %s\n" % logline) + for char in list(command): + vm.console_socket.send(char.encode("utf-8")) + time.sleep(0.01) + + def console_wait_send(self, wait, command): + self.console_wait(wait) + self.console_send(command) + + def console_ssh_init(self, prompt, user, pw): + sshkey_cmd = "echo '%s' > .ssh/authorized_keys\n" % SSH_PUB_KEY.rstrip() + self.console_wait_send("login:", "%s\n" % user) + self.console_wait_send("Password:", "%s\n" % pw) + self.console_wait_send(prompt, "mkdir .ssh\n") + self.console_wait_send(prompt, sshkey_cmd) + self.console_wait_send(prompt, "chmod 755 .ssh\n") + self.console_wait_send(prompt, "chmod 644 .ssh/authorized_keys\n") + + def console_sshd_config(self, prompt): + self.console_wait(prompt) + self.console_send("echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config\n") + for var in self.envvars: + self.console_wait(prompt) + self.console_send("echo 'AcceptEnv %s' >> /etc/ssh/sshd_config\n" % var) + + def print_step(self, text): + sys.stderr.write("### %s ...\n" % text) + def wait_ssh(self, seconds=300): starttime = datetime.datetime.now() endtime = starttime + datetime.timedelta(seconds=seconds) @@ -199,6 +292,10 @@ class BaseVM(object): def wait(self): self._guest.wait() + def graceful_shutdown(self): + self.ssh_root(self.poweroff) + self._guest.wait() + def qmp(self, *args, **kwargs): return self._guest.qmp(*args, **kwargs) @@ -275,11 +372,13 @@ def main(vmcls): 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 + exitcode = 0 + if vm.ssh(*cmd) != 0: + exitcode = 3 + if exitcode != 0 and args.interactive: + vm.ssh() + + if not args.snapshot: + vm.graceful_shutdown() + + return exitcode diff --git a/tests/vm/centos b/tests/vm/centos index 7417b50af4..53976f1c4c 100755 --- a/tests/vm/centos +++ b/tests/vm/centos @@ -66,8 +66,8 @@ class CentosVM(basevm.BaseVM): cimg = self._download_with_cache("https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1802.qcow2.xz") img_tmp = img + ".tmp" sys.stderr.write("Extracting the image...\n") - subprocess.check_call(["cp", "-f", cimg, img_tmp + ".xz"]) - subprocess.check_call(["xz", "-dvf", img_tmp + ".xz"]) + subprocess.check_call(["ln", "-f", cimg, img_tmp + ".xz"]) + subprocess.check_call(["xz", "--keep", "-dvf", img_tmp + ".xz"]) subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"]) self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()]) self.wait_ssh() @@ -77,8 +77,6 @@ class CentosVM(basevm.BaseVM): self.ssh_root_check("systemctl enable docker") self.ssh_root("poweroff") self.wait() - if os.path.exists(img): - os.remove(img) os.rename(img_tmp, img) return 0 diff --git a/tests/vm/fedora b/tests/vm/fedora new file mode 100755 index 0000000000..e8fa5bf0d2 --- /dev/null +++ b/tests/vm/fedora @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# Fedora VM image +# +# Copyright 2019 Red Hat Inc. +# +# Authors: +# Gerd Hoffmann <kraxel@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 re +import sys +import time +import socket +import subprocess +import basevm + +class FedoraVM(basevm.BaseVM): + name = "fedora" + arch = "x86_64" + + base = "http://dl.fedoraproject.org/pub/fedora/linux/releases/30/" + link = base + "Server/x86_64/iso/Fedora-Server-netinst-x86_64-30-1.2.iso" + repo = base + "Server/x86_64/os/" + full = base + "Everything/x86_64/os/" + csum = "5e4eac4566d8c572bfb3bcf54b7d6c82006ec3c6c882a2c9235c6d3494d7b100" + size = "20G" + pkgs = [ + # tools + 'git-core', + 'flex', 'bison', + 'gcc', 'binutils', 'make', + + # perl + 'perl-Test-Harness', + + # libs: usb + '"pkgconfig(libusb-1.0)"', + '"pkgconfig(libusbredirparser-0.5)"', + + # libs: crypto + '"pkgconfig(gnutls)"', + + # libs: ui + '"pkgconfig(sdl2)"', + '"pkgconfig(gtk+-3.0)"', + '"pkgconfig(ncursesw)"', + + # libs: audio + '"pkgconfig(libpulse)"', + '"pkgconfig(alsa)"', + ] + + BUILD_SCRIPT = """ + set -e; + rm -rf /home/qemu/qemu-test.* + cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); + mkdir src build; cd src; + tar -xf /dev/vdb; + cd ../build + ../src/configure --python=python3 {configure_opts}; + gmake --output-sync -j{jobs} {target} {verbose}; + """ + + def build_image(self, img): + self.print_step("Downloading install iso") + cimg = self._download_with_cache(self.link, sha256sum=self.csum) + img_tmp = img + ".tmp" + iso = img + ".install.iso" + + self.print_step("Preparing iso and disk image") + subprocess.check_call(["cp", "-f", cimg, iso]) + subprocess.check_call(["qemu-img", "create", "-f", "qcow2", + img_tmp, self.size]) + + self.print_step("Booting installer") + self.boot(img_tmp, extra_args = [ + "-bios", "pc-bios/bios-256k.bin", + "-machine", "graphics=off", + "-cdrom", iso + ]) + self.console_init(300) + self.console_wait("installation process.") + time.sleep(0.3) + self.console_send("\t") + time.sleep(0.3) + self.console_send(" console=ttyS0") + proxy = os.environ.get("http_proxy") + if not proxy is None: + self.console_send(" proxy=%s" % proxy) + self.console_send(" inst.proxy=%s" % proxy) + self.console_send(" inst.repo=%s" % self.repo) + self.console_send("\n") + + self.console_wait_send("2) Use text mode", "2\n") + + self.console_wait_send("5) [!] Installation Dest", "5\n") + self.console_wait_send("1) [x]", "c\n") + self.console_wait_send("2) [ ] Use All Space", "2\n") + self.console_wait_send("2) [x] Use All Space", "c\n") + self.console_wait_send("1) [ ] Standard Part", "1\n") + self.console_wait_send("1) [x] Standard Part", "c\n") + + self.console_wait_send("7) [!] Root password", "7\n") + self.console_wait("Password:") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait("Password (confirm):") + self.console_send("%s\n" % self.ROOT_PASS) + + self.console_wait_send("8) [ ] User creation", "8\n") + self.console_wait_send("1) [ ] Create user", "1\n") + self.console_wait_send("3) User name", "3\n") + self.console_wait_send("ENTER:", "%s\n" % self.GUEST_USER) + self.console_wait_send("4) [ ] Use password", "4\n") + self.console_wait_send("5) Password", "5\n") + self.console_wait("Password:") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait("Password (confirm):") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait_send("7) Groups", "c\n") + + while True: + good = self.console_wait("3) [x] Installation", + "3) [!] Installation") + self.console_send("r\n") + if good: + break + time.sleep(10) + + while True: + good = self.console_wait("4) [x] Software", + "4) [!] Software") + self.console_send("r\n") + if good: + break + time.sleep(10) + self.console_send("r\n" % self.GUEST_PASS) + + self.console_wait_send("'b' to begin install", "b\n") + + self.print_step("Installation started now, this will take a while") + + self.console_wait_send("Installation complete", "\n") + self.print_step("Installation finished, rebooting") + + # setup qemu user + prompt = " ~]$" + self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_wait_send(prompt, "exit\n") + + # setup root user + prompt = " ~]#" + self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_sshd_config(prompt) + + # setup virtio-blk #1 (tarfile) + self.console_wait(prompt) + self.console_send("echo 'KERNEL==\"vdb\" MODE=\"666\"' >> %s\n" % + "/etc/udev/rules.d/99-qemu.rules") + + self.print_step("Configuration finished, rebooting") + self.console_wait_send(prompt, "reboot\n") + self.console_wait("login:") + self.wait_ssh() + + self.print_step("Installing packages") + self.ssh_root_check("rm -vf /etc/yum.repos.d/fedora*.repo\n") + self.ssh_root_check("echo '[fedora]' >> /etc/yum.repos.d/qemu.repo\n") + self.ssh_root_check("echo 'baseurl=%s' >> /etc/yum.repos.d/qemu.repo\n" % self.full) + self.ssh_root_check("echo 'gpgcheck=0' >> /etc/yum.repos.d/qemu.repo\n") + self.ssh_root_check("dnf install -y %s\n" % " ".join(self.pkgs)) + + # shutdown + self.ssh_root(self.poweroff) + self.console_wait("sleep state S5") + self.wait() + + if os.path.exists(img): + os.remove(img) + os.rename(img_tmp, img) + os.remove(iso) + self.print_step("All done") + +if __name__ == "__main__": + sys.exit(basevm.main(FedoraVM)) diff --git a/tests/vm/freebsd b/tests/vm/freebsd index b0066017a6..2a19461a90 100755 --- a/tests/vm/freebsd +++ b/tests/vm/freebsd @@ -2,43 +2,203 @@ # # FreeBSD VM image # -# Copyright 2017 Red Hat Inc. +# Copyright 2017-2019 Red Hat Inc. # # Authors: # Fam Zheng <famz@redhat.com> +# Gerd Hoffmann <kraxel@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 re import sys +import time +import socket import subprocess import basevm class FreeBSDVM(basevm.BaseVM): name = "freebsd" arch = "x86_64" + + link = "https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-disc1.iso.xz" + csum = "1d40015bea89d05b8bd13e2ed80c40b522a9ec1abd8e7c8b80954fb485fb99db" + size = "20G" + pkgs = [ + # build tools + "git", + "pkgconf", + "bzip2", + + # gnu tools + "bash", + "gmake", + "gsed", + "flex", "bison", + + # libs: crypto + "gnutls", + + # libs: images + "jpeg-turbo", + "png", + + # libs: ui + "sdl2", + "gtk3", + "libxkbcommon", + + # libs: opengl + "libepoxy", + "mesa-libs", + ] + BUILD_SCRIPT = """ set -e; - rm -rf /var/tmp/qemu-test.* - cd $(mktemp -d /var/tmp/qemu-test.XXXXXX); + rm -rf /home/qemu/qemu-test.* + cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); + mkdir src build; cd src; tar -xf /dev/vtbd1; - ./configure {configure_opts}; + cd ../build + ../src/configure --python=python3.6 {configure_opts}; gmake --output-sync -j{jobs} {target} {verbose}; """ + def console_boot_serial(self): + self.console_wait_send("Autoboot", "3") + self.console_wait_send("OK", "set console=comconsole\n") + self.console_wait_send("OK", "boot\n") + 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" + self.print_step("Downloading install iso") + cimg = self._download_with_cache(self.link, sha256sum=self.csum) img_tmp = img + ".tmp" - sys.stderr.write("Extracting the image...\n") - subprocess.check_call(["cp", "-f", cimg, img_tmp_xz]) - subprocess.check_call(["xz", "-dvf", img_tmp_xz]) + iso = img + ".install.iso" + iso_xz = iso + ".xz" + + self.print_step("Preparing iso and disk image") + subprocess.check_call(["cp", "-f", cimg, iso_xz]) + subprocess.check_call(["xz", "-dvf", iso_xz]) + subprocess.check_call(["qemu-img", "create", "-f", "qcow2", + img_tmp, self.size]) + + self.print_step("Booting installer") + self.boot(img_tmp, extra_args = [ + "-bios", "pc-bios/bios-256k.bin", + "-machine", "graphics=off", + "-cdrom", iso + ]) + self.console_init() + self.console_boot_serial() + self.console_wait_send("Console type", "xterm\n") + + # pre-install configuration + self.console_wait_send("Welcome", "\n") + self.console_wait_send("Keymap Selection", "\n") + self.console_wait_send("Set Hostname", "freebsd\n") + self.console_wait_send("Distribution Select", "\n") + self.console_wait_send("Partitioning", "\n") + self.console_wait_send("Partition", "\n") + self.console_wait_send("Scheme", "\n") + self.console_wait_send("Editor", "f") + self.console_wait_send("Confirmation", "c") + + self.print_step("Installation started now, this will take a while") + + # post-install configuration + self.console_wait("New Password:") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait("Retype New Password:") + self.console_send("%s\n" % self.ROOT_PASS) + + self.console_wait_send("Network Configuration", "\n") + self.console_wait_send("IPv4", "y") + self.console_wait_send("DHCP", "y") + self.console_wait_send("IPv6", "n") + self.console_wait_send("Resolver", "\n") + + self.console_wait_send("Time Zone Selector", "a\n") + self.console_wait_send("Confirmation", "y") + self.console_wait_send("Time & Date", "\n") + self.console_wait_send("Time & Date", "\n") + + self.console_wait_send("System Configuration", "\n") + self.console_wait_send("System Hardening", "\n") + + # qemu user + self.console_wait_send("Add User Accounts", "y") + self.console_wait("Username") + self.console_send("%s\n" % self.GUEST_USER) + self.console_wait("Full name") + self.console_send("%s\n" % self.GUEST_USER) + self.console_wait_send("Uid", "\n") + self.console_wait_send("Login group", "\n") + self.console_wait_send("Login group", "\n") + self.console_wait_send("Login class", "\n") + self.console_wait_send("Shell", "\n") + self.console_wait_send("Home directory", "\n") + self.console_wait_send("Home directory perm", "\n") + self.console_wait_send("Use password", "\n") + self.console_wait_send("Use an empty password", "\n") + self.console_wait_send("Use a random password", "\n") + self.console_wait("Enter password:") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait("Enter password again:") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait_send("Lock out", "\n") + self.console_wait_send("OK", "yes\n") + self.console_wait_send("Add another user", "no\n") + + self.console_wait_send("Final Configuration", "\n") + self.console_wait_send("Manual Configuration", "\n") + self.console_wait_send("Complete", "\n") + + self.print_step("Installation finished, rebooting") + self.console_boot_serial() + + # setup qemu user + prompt = "$" + self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_wait_send(prompt, "exit\n") + + # setup root user + prompt = "root@freebsd:~ #" + self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_sshd_config(prompt) + + # setup serial console + self.console_wait(prompt) + self.console_send("echo 'console=comconsole' >> /boot/loader.conf\n") + + # setup boot delay + self.console_wait(prompt) + self.console_send("echo 'autoboot_delay=1' >> /boot/loader.conf\n") + + # setup virtio-blk #1 (tarfile) + self.console_wait(prompt) + self.console_send("echo 'chmod 666 /dev/vtbd1' >> /etc/rc.local\n") + + self.print_step("Configuration finished, rebooting") + self.console_wait_send(prompt, "reboot\n") + self.console_wait("login:") + self.wait_ssh() + + self.print_step("Installing packages") + self.ssh_root_check("pkg install -y %s\n" % " ".join(self.pkgs)) + + # shutdown + self.ssh_root(self.poweroff) + self.console_wait("Uptime:") + self.wait() + if os.path.exists(img): os.remove(img) os.rename(img_tmp, img) + os.remove(iso) + self.print_step("All done") if __name__ == "__main__": sys.exit(basevm.main(FreeBSDVM)) diff --git a/tests/vm/netbsd b/tests/vm/netbsd index 4c6624ea5e..ee9eaeab50 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -34,10 +34,8 @@ class NetBSDVM(basevm.BaseVM): img_tmp_xz = img + ".tmp.xz" img_tmp = img + ".tmp" sys.stderr.write("Extracting the image...\n") - subprocess.check_call(["cp", "-f", cimg, img_tmp_xz]) - subprocess.check_call(["xz", "-dvf", img_tmp_xz]) - if os.path.exists(img): - os.remove(img) + subprocess.check_call(["ln", "-f", cimg, img_tmp_xz]) + subprocess.check_call(["xz", "--keep", "-dvf", img_tmp_xz]) os.rename(img_tmp, img) if __name__ == "__main__": diff --git a/tests/vm/openbsd b/tests/vm/openbsd index 2105c01a26..b92c39f89a 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -2,10 +2,11 @@ # # OpenBSD VM image # -# Copyright 2017 Red Hat Inc. +# Copyright 2017-2019 Red Hat Inc. # # Authors: # Fam Zheng <famz@redhat.com> +# Gerd Hoffmann <kraxel@redhat.com> # # This code is licensed under the GPL version 2 or later. See # the COPYING file in the top-level directory. @@ -13,34 +14,166 @@ import os import sys +import socket import subprocess import basevm class OpenBSDVM(basevm.BaseVM): name = "openbsd" arch = "x86_64" + + link = "https://cdn.openbsd.org/pub/OpenBSD/6.5/amd64/install65.iso" + csum = "38d1f8cadd502f1c27bf05c5abde6cc505dd28f3f34f8a941048ff9a54f9f608" + size = "20G" + pkgs = [ + # tools + "git", + "pkgconf", + "bzip2", "xz", + + # gnu tools + "bash", + "gmake", + "gsed", + "bison", + + # libs: usb + "libusb1", + + # libs: crypto + "gnutls", + + # libs: images + "jpeg", + "png", + + # libs: ui + "sdl2", + "gtk+3", + "libxkbcommon", + ] + BUILD_SCRIPT = """ set -e; - rm -rf /var/tmp/qemu-test.* - cd $(mktemp -d /var/tmp/qemu-test.XXXXXX); + rm -rf /home/qemu/qemu-test.* + cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); + mkdir src build; cd src; tar -xf /dev/rsd1c; - ./configure --cc=x86_64-unknown-openbsd6.1-gcc-4.9.4 --python=python2.7 {configure_opts}; - gmake --output-sync -j{jobs} {verbose}; - # XXX: "gmake check" seems to always hang or fail - #gmake --output-sync -j{jobs} check {verbose}; + cd ../build + ../src/configure --cc=cc --python=python3 {configure_opts}; + gmake --output-sync -j{jobs} {target} {verbose}; """ + poweroff = "halt -p" 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" + self.print_step("Downloading install iso") + cimg = self._download_with_cache(self.link, sha256sum=self.csum) img_tmp = img + ".tmp" - sys.stderr.write("Extracting the image...\n") - subprocess.check_call(["cp", "-f", cimg, img_tmp_xz]) - subprocess.check_call(["xz", "-dvf", img_tmp_xz]) + iso = img + ".install.iso" + + self.print_step("Preparing iso and disk image") + subprocess.check_call(["cp", "-f", cimg, iso]) + subprocess.check_call(["qemu-img", "create", "-f", "qcow2", + img_tmp, self.size]) + + self.print_step("Booting installer") + self.boot(img_tmp, extra_args = [ + "-bios", "pc-bios/bios-256k.bin", + "-machine", "graphics=off", + "-cdrom", iso + ]) + self.console_init() + self.console_wait_send("boot>", "set tty com0\n") + self.console_wait_send("boot>", "\n") + + # pre-install configuration + self.console_wait_send("(I)nstall", "i\n") + self.console_wait_send("Terminal type", "xterm\n") + self.console_wait_send("System hostname", "openbsd\n") + self.console_wait_send("Which network interface", "vio0\n") + self.console_wait_send("IPv4 address", "dhcp\n") + self.console_wait_send("IPv6 address", "none\n") + self.console_wait_send("Which network interface", "done\n") + self.console_wait_send("DNS domain name", "localnet\n") + self.console_wait("Password for root account") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait("Password for root account") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait_send("Start sshd(8)", "yes\n") + self.console_wait_send("X Window System", "\n") + self.console_wait_send("xenodm", "\n") + self.console_wait_send("console to com0", "\n") + self.console_wait_send("Which speed", "\n") + + self.console_wait("Setup a user") + self.console_send("%s\n" % self.GUEST_USER) + self.console_wait("Full name") + self.console_send("%s\n" % self.GUEST_USER) + self.console_wait("Password") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait("Password") + self.console_send("%s\n" % self.GUEST_PASS) + + self.console_wait_send("Allow root ssh login", "yes\n") + self.console_wait_send("timezone", "UTC\n") + self.console_wait_send("root disk", "\n") + self.console_wait_send("(W)hole disk", "\n") + self.console_wait_send("(A)uto layout", "\n") + self.console_wait_send("Location of sets", "cd0\n") + self.console_wait_send("Pathname to the sets", "\n") + self.console_wait_send("Set name(s)", "\n") + self.console_wait_send("without verification", "yes\n") + + self.print_step("Installation started now, this will take a while") + self.console_wait_send("Location of sets", "done\n") + + self.console_wait("successfully completed") + self.print_step("Installation finished, rebooting") + self.console_wait_send("(R)eboot", "reboot\n") + + # setup qemu user + prompt = "$" + self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_wait_send(prompt, "exit\n") + + # setup root user + prompt = "openbsd#" + self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_sshd_config(prompt) + + # setup virtio-blk #1 (tarfile) + self.console_wait(prompt) + self.console_send("echo 'chmod 666 /dev/rsd1c' >> /etc/rc.local\n") + + # enable w+x for /home + self.console_wait(prompt) + self.console_send("sed -i -e '/home/s/rw,/rw,wxallowed,/' /etc/fstab\n") + + # tweak datasize limit + self.console_wait(prompt) + self.console_send("sed -i -e 's/\\(datasize[^=]*\\)=[^:]*/\\1=infinity/' /etc/login.conf\n") + + # use http (be proxy cache friendly) + self.console_wait(prompt) + self.console_send("sed -i -e 's/https/http/' /etc/installurl\n") + + self.print_step("Configuration finished, rebooting") + self.console_wait_send(prompt, "reboot\n") + self.console_wait("login:") + self.wait_ssh() + + self.print_step("Installing packages") + self.ssh_root_check("pkg_add %s\n" % " ".join(self.pkgs)) + + # shutdown + self.ssh_root(self.poweroff) + self.wait() + if os.path.exists(img): os.remove(img) os.rename(img_tmp, img) + os.remove(iso) + self.print_step("All done") if __name__ == "__main__": sys.exit(basevm.main(OpenBSDVM)) diff --git a/tests/vm/ubuntu.i386 b/tests/vm/ubuntu.i386 index a22d137e76..38f740eabf 100755 --- a/tests/vm/ubuntu.i386 +++ b/tests/vm/ubuntu.i386 @@ -51,6 +51,10 @@ class UbuntuX86VM(basevm.BaseVM): " ssh-authorized-keys:\n", " - %s\n" % basevm.SSH_PUB_KEY, "locale: en_US.UTF-8\n"]) + proxy = os.environ.get("http_proxy") + if not proxy is None: + udata.writelines(["apt:\n", + " proxy: %s" % proxy]) udata.close() subprocess.check_call(["genisoimage", "-output", "cloud-init.iso", "-volid", "cidata", "-joliet", "-rock", @@ -61,7 +65,9 @@ class UbuntuX86VM(basevm.BaseVM): 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") + cimg = self._download_with_cache( + "https://cloud-images.ubuntu.com/releases/16.04/release-20190605/ubuntu-16.04-server-cloudimg-i386-disk1.img", + sha256sum="e30091144c73483822b7c27193e9d47346dd1064229da577c3fedcf943f7cfcc") img_tmp = img + ".tmp" subprocess.check_call(["cp", "-f", cimg, img_tmp]) subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"]) @@ -75,13 +81,12 @@ class UbuntuX86VM(basevm.BaseVM): time.sleep(5) self.wait_ssh() # The previous update sometimes doesn't survive a reboot, so do it again + self.ssh_root_check("sed -ie s/^#\ deb-src/deb-src/g /etc/apt/sources.list") 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 flex bison") self.ssh_root("poweroff") self.wait() - if os.path.exists(img): - os.remove(img) os.rename(img_tmp, img) return 0 |