| |
@@ -22,6 +22,7 @@
|
| |
import logging
|
| |
import argparse
|
| |
import tempfile
|
| |
+ import platform
|
| |
import functools
|
| |
import subprocess
|
| |
import distutils.util
|
| |
@@ -137,12 +138,19 @@
|
| |
sys.stdout.write(json.dumps(bad_inv, indent=4, separators=(',', ': ')))
|
| |
|
| |
|
| |
+ # See https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python/377028#377028
|
| |
def which(executable, default=None):
|
| |
- for path in os.environ['PATH'].split(os.pathsep):
|
| |
- path = path.strip('"')
|
| |
- fpath = os.path.join(path, executable)
|
| |
- if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
|
| |
- return fpath
|
| |
+ def is_exe(fpath):
|
| |
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
| |
+ fpath, _ = os.path.split(executable)
|
| |
+ if fpath:
|
| |
+ if is_exe(executable):
|
| |
+ return executable
|
| |
+ else:
|
| |
+ for path in os.environ['PATH'].split(os.pathsep):
|
| |
+ exe_file = os.path.join(path, executable)
|
| |
+ if is_exe(exe_file):
|
| |
+ return exe_file
|
| |
return default
|
| |
|
| |
|
| |
@@ -284,22 +292,106 @@
|
| |
# Parameters from FMF:
|
| |
param_m = str(fmf_get(['qemu', 'm'], "1024"))
|
| |
param_net_nic_model = str(fmf_get(['qemu', 'net_nic', 'model'], 'virtio'))
|
| |
- # Use -cpu host and -smp by default.
|
| |
- path_lookups = ["/usr/bin/qemu-system-x86_64", "/usr/libexec/qemu-kvm"]
|
| |
- for qemu_path in path_lookups:
|
| |
- if os.path.exists(qemu_path):
|
| |
+ # QEMU -M param.
|
| |
+ # Most architectures do not need a -M flag, defaults are fine
|
| |
+ qemu_M_param = []
|
| |
+ # List of firmwares QEMU needs to work.
|
| |
+ qemu_firmwares = []
|
| |
+ # Common QEMU parameters used both to run VM and virtio-rng probing.
|
| |
+ qemu_common_params = [
|
| |
+ # Pass through CPU model of host
|
| |
+ "-cpu", "host",
|
| |
+ # Enable KVM full virtualization support
|
| |
+ "-enable-kvm",
|
| |
+ # Do not display video output
|
| |
+ "-display", "none",
|
| |
+ # Disable VGA card to avoid crash on ppc with PR
|
| |
+ # https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg07070.html
|
| |
+ "-vga", "none"
|
| |
+ ]
|
| |
+ # Add platform specific settings:
|
| |
+ if platform.machine() == "aarch64":
|
| |
+ # Emulate the same generic interrupt controller as the host system has
|
| |
+ qemu_M_param = ["-M", "virt,gic_version=host"]
|
| |
+ # Add AAVMF firmware (without this, qemu-kvm will not work on ARM)
|
| |
+ qemu_firmwares.extend([
|
| |
+ "-drive", "%s,%s,%s,%s,%s" % (
|
| |
+ "file=/usr/share/AAVMF/AAVMF_CODE.fd",
|
| |
+ "if=pflash",
|
| |
+ "format=raw",
|
| |
+ "unit=0",
|
| |
+ "readonly=on"
|
| |
+ )
|
| |
+ ])
|
| |
+ # Include -M param and firmwares to common params:
|
| |
+ qemu_common_params.extend(qemu_M_param)
|
| |
+ qemu_common_params.extend(qemu_firmwares)
|
| |
+ # Lookup for qemu:
|
| |
+ qemu_env = os.environ.get("QEMU_CMD")
|
| |
+ if qemu_env:
|
| |
+ path_lookups = [qemu_env]
|
| |
+ else:
|
| |
+ path_lookups = []
|
| |
+ path_lookups.extend([
|
| |
+ "qemu-kvm", "/usr/libexec/qemu-kvm", "/usr/bin/qemu-system-x86_64"
|
| |
+ ])
|
| |
+ for qemu_cmd in path_lookups:
|
| |
+ qemu_path = which(qemu_cmd)
|
| |
+ if qemu_path:
|
| |
break
|
| |
+ # Try to probe virtio-rng device:
|
| |
# virtio-rng-pci: https://wiki.qemu.org/Features/VirtIORNG
|
| |
- qemu_cmd = [qemu_path,
|
| |
- "-cpu", "host", "-smp", get_qemu_smp_arg(),
|
| |
- "-m", param_m, image, "-enable-kvm", "-snapshot", "-cdrom", cloudinit,
|
| |
- "-net", "nic,model=%s" % param_net_nic_model, "-net", "user,hostfwd=tcp:127.0.0.3:{0}-:22".format(port),
|
| |
- "-device", "virtio-rng-pci", "-rtc", "base=utc",
|
| |
- "-device", "isa-serial,chardev=pts2", "-chardev", "file,id=pts2,path=" + log_guest,
|
| |
- "-display", "none"]
|
| |
+ virtio_rng = []
|
| |
+ cmd_tmpl = "echo quit | %s -device %%s -S -monitor stdio" % (
|
| |
+ " ".join([qemu_path] + qemu_common_params)
|
| |
+ )
|
| |
+ for x in ["virtio-rng", "virtio-rng-pci", "virtio-rng-ccw"]:
|
| |
+ try:
|
| |
+ subprocess.check_call(
|
| |
+ cmd_tmpl % x,
|
| |
+ stdout=subprocess.DEVNULL,
|
| |
+ stderr=subprocess.DEVNULL,
|
| |
+ shell=True
|
| |
+ )
|
| |
+ virtio_rng = ["-device", x]
|
| |
+ break
|
| |
+ except subprocess.CalledProcessError:
|
| |
+ pass
|
| |
+ if virtio_rng:
|
| |
+ logger.info("qemu-kvm is using %s device" % virtio_rng[1])
|
| |
+ # Assemble QEMU command with its parameters:
|
| |
+ qemu_cmd = [
|
| |
+ qemu_path
|
| |
+ # Add common parameters
|
| |
+ ] + qemu_common_params + [
|
| |
+ # Simulate SMP system with get_qemu_smp_arg() CPUs
|
| |
+ "-smp", get_qemu_smp_arg(),
|
| |
+ # Set startup RAM size
|
| |
+ "-m", param_m,
|
| |
+ # Add image with RHEL as drive (if=virtio is important for newer
|
| |
+ # RHEL 8 images)
|
| |
+ "-drive", "file={0},if=virtio".format(image),
|
| |
+ # Write to temporary files instead of disk image files
|
| |
+ "-snapshot",
|
| |
+ # Use `cloudinit` as CD-ROM image
|
| |
+ "-cdrom", cloudinit,
|
| |
+ # Configure/create an on-board (or machine default) NIC
|
| |
+ "-net", "nic,model=%s" % param_net_nic_model,
|
| |
+ # Configure a host network backend
|
| |
+ "-net", "user,hostfwd=tcp:127.0.0.3:{0}-:22".format(port)
|
| |
+ # Add a source of randomness
|
| |
+ ] + virtio_rng + [
|
| |
+ # Let the RTC start at the current UTC
|
| |
+ "-rtc", "base=utc",
|
| |
+ # Connect the virtual serial port with pts2
|
| |
+ "-serial", "chardev:pts2",
|
| |
+ # Log all traffic received from the guest to log_quest
|
| |
+ "-chardev", "file,id=pts2,path=" + log_guest
|
| |
+ ]
|
| |
qemu_cmd += AdditionalDrives.generate()
|
| |
if diagnose:
|
| |
qemu_cmd += ["-vnc", DEF_HOST + ":1,to=4095"]
|
| |
+ # Launch QEMU:
|
| |
qemu_proc = subprocess.Popen(qemu_cmd, stdout=open(log_qemu, 'a'), stderr=subprocess.STDOUT)
|
| |
time.sleep(5)
|
| |
if qemu_proc and diagnose:
|
| |
@@ -350,7 +442,7 @@
|
| |
if proc is None:
|
| |
raise RuntimeError("Could not launch VM for qcow2 image"
|
| |
" '{0}':{1}".format(image, cpe.output))
|
| |
- for _ in range(0, 30):
|
| |
+ for _ in range(0, 600):
|
| |
try:
|
| |
# The variables
|
| |
variables = {
|
| |
With these changes, it can be possible to use
standard-inventory-qcow2
for running tests on multiple architectures. The proposed changes were tested on RHEL 8 and all its supported architectures:x86_64
,aarch64
,ppc64le
, ands390x
.The purpose of these changes was the requirement of Quality Engineering to test
rhel-system-roles
on all supported architectures.How
standard-inventory-qcow2
was tested?First, the Beaker machines were reserved:
(a) for
x86_64
:in
job.xml
, between<hostRequires><and>...</and></hostRequires>
:(b) for
aarch64
:(c) for
ppc64le
:in
job.xml
:(d) for
s390x
:in
job.xml
:Second, the beaker machines were prepared:
Finally, the test was run: