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.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAl0fIzkACgkQ+9DbCVqe
 KkQ5rggAivGftiInedQmF0M8F+vBHSQNUSVrB19e/mBgA/Z4WopFrZNUltAMry84
 HwvQFmzAkq9OwqkOxeGcM3ABSa4Eum6lyxURg767TxK5NswKknEacgpt83FsXAJU
 nckTJPdeIGWIWntyBhu4TdREGVvYR1hk3aDBcb81V5Y5ZVkNaOp//td0eMDHuP0/
 EIGFfZt78kCgxs3Yblhen8ayx4XiEF2oICMZi+jZZnjcmOfHsYzHASq7saWDS+ne
 2fPgYLl6E/q5VgrUa4mziNu1bUPSfdidp8028Kc8FrpY/vVqvkU3TANDrTP8ag8w
 MwvRpyOrm9zC1Oe+diBk+uAfI7GmcA==
 =4Lin
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2019-07-05 11:21:29 +01:00
commit 0050f9978e
13 changed files with 667 additions and 63 deletions

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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 '[::]'.

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

189
tests/vm/fedora Executable file
View File

@ -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))

View File

@ -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))

View File

@ -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__":

View File

@ -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))

View File

@ -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