[PATCH 0/5] Remove code duplications for start_vm

3 views
Skip to first unread message

Anton Mikanovich

unread,
Jun 14, 2024, 7:23:33 AMJun 14
to isar-...@googlegroups.com, Anton Mikanovich
We had both shell and python APIs for running QEMU images, there is
also start_vm related functionality in testsuite itself. All this parts
duplicate each other and should be cleanup.

Anton Mikanovich (3):
start_vm: Add secureboot support
CI: Allow external usage for some APIs
start_vm: Reuse getVars API

Ilia Skochilov (2):
start_vm: Switch to python version
scripts: Remove vm_smoke_test

CONTRIBUTING.md | 50 +++----
meta-isar/conf/machine/qemuamd64-sb.conf | 2 +-
scripts/start_vm | 161 ++---------------------
scripts/vm_smoke_test | 106 ---------------
testsuite/README.md | 4 +-
testsuite/cibase.py | 6 +-
testsuite/cibuilder.py | 65 +++------
testsuite/citest.py | 4 +-
testsuite/start_vm.py | 89 +++++++++----
testsuite/utils.py | 54 ++++++++
10 files changed, 178 insertions(+), 363 deletions(-)
delete mode 100755 scripts/vm_smoke_test
create mode 100755 testsuite/utils.py

--
2.34.1

Anton Mikanovich

unread,
Jun 14, 2024, 7:23:34 AMJun 14
to isar-...@googlegroups.com, Ilia Skochilov, Anton Mikanovich
From: Ilia Skochilov <iskoc...@ilbers.de>

Remove vm_smoke_test, its functionality is now covered in the dev
testsuite. Remove mentioning of vm_smoke_test in documentation.
Add instructions about how to run the dev testsuite via avocado
framework in a kas container.

Signed-off-by: Ilia Skochilov <iskoc...@ilbers.de>
Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
CONTRIBUTING.md | 50 +++++++++++---------
scripts/vm_smoke_test | 106 ------------------------------------------
2 files changed, 28 insertions(+), 128 deletions(-)
delete mode 100755 scripts/vm_smoke_test

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9ad6bf3b..f932417b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -80,28 +80,34 @@ Plan merges to `master` so that both fit the two-week window; short extensions s
* It's highly suggested to test your patchset before submitting it to the mailing
by launching CI tests scripts. The procedure is described below:

- First, run "fast" CI
-```
- scripts/ci_build.sh -q -f
- ...
- source isar-init-build-env
- scripts/vm_smoke_test -f
-```
- Currently "fast" CI launches
- * parallel cross build of QEMU arm/arm64/amd64 Debian stretch and Raspberry Pi 1 Raspbian stretch targets
- * cross build of one of the supported boards which includes compilation of Linux kernel/U-Boot for it
- * Launches login prompt check tests for built QEMU targets
-
- Second, run standard CI
-```
- scripts/ci_build.sh -q
- ...
- source isar-init-build-env
- scripts/vm_smoke_test -q
-```
- Currently standard CI launches
- * parallel native build of QEMU arm/arm64/i386/amd64 Debian stretch/buster and Raspberry Pi 1 Raspbian stretch targets
- * Launches login prompt check tests for built QEMU targets
+ git clone https://github.com/siemens/kas
+ cat > kas.yml <<EOF
+ header:
+ version: 12
+ build_system: isar
+ repos:
+ isar:
+ url: "http://github.com:/ilbers/isar"
+ refspec: master
+ layers:
+ meta:
+ meta-isar:
+ EOF
+ kas/kas-container shell kas.yml
+
+ In kas shell:
+
+ ```
+ wget -q http://deb.isar-build.org/debian-isar.key -O- |gpg --dearmor \
+ |sudo dd of=/etc/apt/trusted.gpg.d/debian-isar.gpg
+ echo "deb [signed-by=/etc/apt/trusted.gpg.d/debian-isar.gpg] \
+ http://deb.isar-build.org/debian-isar bookworm-isar main" \
+ |sudo /etc/apt/sources.list.d/10-isar_build.list
+ sudo apt-get update
+ sudo apt-get install avocado
+ cd /work/isar/testsuite
+ avocado run citest.py -t dev --max-parallel-tasks=1
+ ```

Active developers may request from maintainers an account on isar-build.org
to analyze CI logs or to launch their own CI builds there.
diff --git a/scripts/vm_smoke_test b/scripts/vm_smoke_test
deleted file mode 100755
index f69b05c2..00000000
--- a/scripts/vm_smoke_test
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-#
-# This software is a part of ISAR.
-# Copyright (C) 2015-2018 ilbers GmbH
-
-set -e
-
-VERBOSE="--show=test"
-TIMEOUT=300
-
-# Error codes:
-ES_OK=0
-ES_FAIL=1
-ES_BUG=3
-
-RET=$ES_FAIL
-
-# Get Avocado QEMU tests path
-TESTSUITE_DIR="$(dirname "$0")/../testsuite"
-
-# Go to Isar root
-cd "$(dirname "$0")/.."
-
-BUILD_DIR=./build
-
-show_help() {
- echo "This script tests the Isar images for default targets in QEMU."
- echo
- echo "Usage:"
- echo " $0 [params]"
- echo
- echo "Parameters:"
- echo " -f,--fast test reduced set of supported targets."
- echo " -q, --quiet do not display boot logs for all the targets."
- echo " If test failed for the specific configuration,"
- echo " the respective boot log will be printed anyway."
- echo " -t,--timeout SEC specify time in seconds to wait before stop QEMU."
- echo " The default is: 300"
- echo " -h, --help display this message and exit."
- echo
- echo "Exit status:"
- echo " 0 if OK,"
- echo " 1 if test failed,"
- echo " 3 if invalid parameters are passed."
-}
-
-# Parse command line to get user configuration
-while [ $# -gt 0 ]
-do
- key="$1"
-
- case $key in
- -h|--help)
- show_help
- exit 0
- ;;
- -o|--output)
- # Deprecated option
- shift
- ;;
- -p|--pid-file)
- # Deprecated option
- shift
- ;;
- -f|--fast)
- FAST_BUILD="1"
- ;;
- -q|--quiet)
- VERBOSE=""
- ;;
- -t|--timeout)
- TIMEOUT=$2
- shift
- ;;
- *)
- echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
- exit $ES_BUG
- ;;
- esac
-
- shift
-done
-
-TAGS="full"
-if [ -n "$FAST_BUILD" ]; then
- TAGS="fast"
-fi
-
-# Provide working path
-mkdir -p .config/avocado
-cat <<EOF > .config/avocado/avocado.conf
-[datadir.paths]
-base_dir = $BUILD_DIR/
-test_dir = $BUILD_DIR/tests
-data_dir = $BUILD_DIR/data
-logs_dir = $BUILD_DIR/job-results
-EOF
-export VIRTUAL_ENV="./"
-
-if avocado $VERBOSE run "$TESTSUITE_DIR/citest.py" -t $TAGS,startvm \
- --test-runner=runner --disable-sysinfo \
- -p build_dir="$BUILD_DIR" -p time_to_wait=$TIMEOUT; then
- RET=$ES_OK
-fi
-
-exit $RET
--
2.34.1

Anton Mikanovich

unread,
Jun 14, 2024, 7:23:35 AMJun 14
to isar-...@googlegroups.com, Anton Mikanovich
Provide utilities class for external usage to be imported from outside
of Avocado framework.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/cibase.py | 6 +++--
testsuite/cibuilder.py | 50 ++++----------------------------------
testsuite/citest.py | 4 +++-
testsuite/utils.py | 54 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 48 deletions(-)
create mode 100755 testsuite/utils.py

diff --git a/testsuite/cibase.py b/testsuite/cibase.py
index 0f6997af..c257a465 100755
--- a/testsuite/cibase.py
+++ b/testsuite/cibase.py
@@ -8,6 +8,8 @@ import tempfile
import time

from cibuilder import CIBuilder, isar_root
+from utils import CIUtils
+
from avocado.utils import process

class CIBaseTest(CIBuilder):
@@ -238,13 +240,13 @@ class CIBaseTest(CIBuilder):
for target in targets:
sfiles[target] = dict()
package = target.rsplit(':', 1)[-1]
- isar_apt = self.getVars('REPO_ISAR_DB_DIR', target=target)
+ isar_apt = CIUtils.getVars('REPO_ISAR_DB_DIR', target=target)
fpath = f'{package}/{package}*.tar.gz'
targz = set(glob.glob(f'{isar_apt}/../apt/*/pool/*/*/{fpath}'))
if len(targz) < 1:
self.fail('No source packages found')
for filename in targz:
- sfiles[target][filename] = self.get_tar_content(filename)
+ sfiles[target][filename] = CIUtils.get_tar_content(filename)
return sfiles

self.configure(**kwargs)
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index a51d6f7e..4aa06ffb 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -9,11 +9,11 @@ import shutil
import signal
import subprocess
import sys
-import tarfile
import time
import tempfile

import start_vm
+from utils import CIUtils

from avocado import Test
from avocado.utils import path
@@ -22,7 +22,6 @@ from avocado.utils import process
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/../bitbake/lib')

import bb
-import bb.tinfoil

DEF_VM_TO_SEC = 600

@@ -253,38 +252,6 @@ class CIBuilder(Test):
except FileNotFoundError:
self.log.warn(path + backup_prefix + ' not exist')

- def getVars(self, *vars, target=None):
- self.check_init()
- def fixStream(stream):
- # fix stream objects to emulate _io.TextIOWrapper
- stream.isatty = lambda: False
- stream.fileno = lambda: False
- stream.encoding = sys.getdefaultencoding()
-
- sl = target is not None
- fixStream(sys.stdout)
- fixStream(sys.stderr)
-
- # wait until previous bitbake will be finished
- lockfile = os.path.join(self.build_dir, 'bitbake.lock')
- checks = 0
- while os.path.exists(lockfile) and checks < 5:
- time.sleep(1)
- checks += 1
-
- with bb.tinfoil.Tinfoil(setup_logging=sl) as tinfoil:
- values = ()
- if target:
- tinfoil.prepare(quiet=2)
- d = tinfoil.parse_recipe(target)
- for var in vars:
- values = values + (d.getVar(var, True) or 'None',)
- else:
- tinfoil.prepare(config_only=True, quiet=2)
- for var in vars:
- values = values + (tinfoil.config_data.getVar(var, True) or 'None',)
- return values if len(values) > 1 else values[0]
-
def create_tmp_layer(self):
tmp_layer_dir = os.path.join(isar_root, 'meta-tmp')

@@ -314,13 +281,6 @@ BBPATH .= ":${LAYERDIR}"\
bb.utils.edit_bblayers_conf(bblayersconf_file, None, tmp_layer_dir)
bb.utils.prunedir(tmp_layer_dir)

- def get_tar_content(self, filename):
- try:
- tar = tarfile.open(filename)
- return tar.getnames()
- except Exception:
- return []
-
def get_ssh_cmd_prefix(self, user, host, port, priv_key):
cmd_prefix = 'ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no '\
'-p %s -o IdentityFile=%s %s@%s ' \
@@ -526,10 +486,10 @@ BBPATH .= ":${LAYERDIR}"\
resize_output = None
image_fstypes, \
wks_file, \
- bbdistro = self.getVars('IMAGE_FSTYPES', \
- 'WKS_FILE', \
- 'DISTRO', \
- target=multiconfig)
+ bbdistro = CIUtils.getVars('IMAGE_FSTYPES', \
+ 'WKS_FILE', \
+ 'DISTRO', \
+ target=multiconfig)

# only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':
diff --git a/testsuite/citest.py b/testsuite/citest.py
index 42d44f6a..b84ae0e1 100755
--- a/testsuite/citest.py
+++ b/testsuite/citest.py
@@ -5,6 +5,7 @@ import os
from avocado import skipUnless
from avocado.utils import path
from cibase import CIBaseTest
+from utils import CIUtils

UMOCI_AVAILABLE = True
SKOPEO_AVAILABLE = True
@@ -17,6 +18,7 @@ try:
except path.CmdNotFoundError:
SKOPEO_AVAILABLE = False

+
class DevTest(CIBaseTest):

"""
@@ -46,7 +48,7 @@ class DevTest(CIBaseTest):

def test_dev_rebuild(self):
self.init()
- layerdir_core = self.getVars('LAYERDIR_core')
+ layerdir_core = CIUtils.getVars('LAYERDIR_core')

dpkgbase_file = layerdir_core + '/classes/dpkg-base.bbclass'

diff --git a/testsuite/utils.py b/testsuite/utils.py
new file mode 100755
index 00000000..a3f643fa
--- /dev/null
+++ b/testsuite/utils.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import tarfile
+import time
+
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/../bitbake/lib')
+
+import bb
+import bb.tinfoil
+
+class CIUtils():
+ @staticmethod
+ def getVars(*vars, target=None):
+ def fixStream(stream):
+ # fix stream objects to emulate _io.TextIOWrapper
+ stream.isatty = lambda: False
+ stream.fileno = lambda: False
+ stream.encoding = sys.getdefaultencoding()
+
+ sl = target is not None
+ if not hasattr(sys.stdout, 'isatty'):
+ fixStream(sys.stdout)
+ if not hasattr(sys.stderr, 'isatty'):
+ fixStream(sys.stderr)
+
+ # wait until previous bitbake will be finished
+ lockfile = os.path.join(os.getcwd(), 'bitbake.lock')
+ checks = 0
+ while os.path.exists(lockfile) and checks < 5:
+ time.sleep(1)
+ checks += 1
+
+ with bb.tinfoil.Tinfoil(setup_logging=sl) as tinfoil:
+ values = ()
+ if target:
+ tinfoil.prepare(quiet=2)
+ d = tinfoil.parse_recipe(target)
+ for var in vars:
+ values = values + (d.getVar(var, True) or '',)
+ else:
+ tinfoil.prepare(config_only=True, quiet=2)
+ for var in vars:
+ values = values + (tinfoil.config_data.getVar(var, True) or '',)
+ return values if len(values) > 1 else values[0]
+
+ @staticmethod
+ def get_tar_content(filename):
+ try:
+ tar = tarfile.open(filename)
+ return tar.getnames()
+ except Exception:
+ return []
--
2.34.1

Anton Mikanovich

unread,
Jun 14, 2024, 7:23:36 AMJun 14
to isar-...@googlegroups.com, Anton Mikanovich
We already have an API to get Bitbake variable values without manual
handling of bitbake execution. This will speedup und simplify start_vm.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/start_vm.py | 47 ++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 45e509a7..ada13121 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -11,43 +11,49 @@ import sys
import shutil
import time

+from utils import CIUtils
+
OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'

-def get_bitbake_env(arch, distro, image):
+def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
- output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
- return output

-def get_bitbake_var(output, var):
- ret = ''
- for line in output.splitlines():
- if line.startswith(var + '='):
- ret = line.split('"')[1]
- return ret
-
-def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
- bb_output = get_bitbake_env(arch, distro, image).decode()
+ image_type, \
+ deploy_dir_image, \
+ kernel_image, \
+ initrd_image, \
+ serial, \
+ root_dev, \
+ qemu_arch, \
+ qemu_machine, \
+ qemu_cpu, \
+ qemu_disk_args = CIUtils.getVars('IMAGE_FSTYPES', \
+ 'DEPLOY_DIR_IMAGE', \
+ 'KERNEL_IMAGE', \
+ 'INITRD_DEPLOY_FILE', \
+ 'MACHINE_SERIAL', \
+ 'QEMU_ROOTFS_DEV', \
+ 'QEMU_ARCH', \
+ 'QEMU_MACHINE', \
+ 'QEMU_CPU', \
+ 'QEMU_DISK_ARGS', \
+ target=multiconfig)

extra_args = ''
cpu = ['']

- image_type = get_bitbake_var(bb_output, 'IMAGE_FSTYPES').split()[0]
- deploy_dir_image = get_bitbake_var(bb_output, 'DEPLOY_DIR_IMAGE')
base = 'ubuntu' if distro in ['jammy', 'focal'] else 'debian'

rootfs_image = image + '-' + base + '-' + distro + '-qemu' + arch + '.' + image_type

if image_type == 'ext4':
- kernel_image = deploy_dir_image + '/' + get_bitbake_var(bb_output, 'KERNEL_IMAGE')
- initrd_image = get_bitbake_var(bb_output, 'INITRD_DEPLOY_FILE')
+ kernel_image = deploy_dir_image + '/' + kernel_image

if not initrd_image:
initrd_image = '/dev/null'
else:
initrd_image = deploy_dir_image + '/' + initrd_image

- serial = get_bitbake_var(bb_output, 'MACHINE_SERIAL')
- root_dev = get_bitbake_var(bb_output, 'QEMU_ROOTFS_DEV')
kargs = ['-append', '"console=' + serial + ' root=/dev/' + root_dev + ' rw"']

extra_args = ['-kernel', kernel_image, '-initrd', initrd_image]
@@ -57,11 +63,6 @@ def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal
else:
raise ValueError('Invalid image type: ' + str(image_type))

- qemu_arch = get_bitbake_var(bb_output, 'QEMU_ARCH')
- qemu_machine = get_bitbake_var(bb_output, 'QEMU_MACHINE')
- qemu_cpu = get_bitbake_var(bb_output, 'QEMU_CPU')
- qemu_disk_args = get_bitbake_var(bb_output, 'QEMU_DISK_ARGS')
-
if out:
extra_args.extend(['-chardev','stdio,id=ch0,logfile=' + out])
extra_args.extend(['-serial','chardev:ch0'])
--
2.34.1

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:13 AMJun 17
to isar-...@googlegroups.com, Anton Mikanovich
We had both shell and python APIs for running QEMU images, there is
also start_vm related functionality in testsuite itself. All this parts
duplicate each other and should be cleanup.

Changes since v1:
- Fix multiple image type targets.

Anton Mikanovich (3):
start_vm: Add secureboot support
CI: Allow external usage for some APIs
start_vm: Reuse getVars API

Ilia Skochilov (2):
start_vm: Switch to python version
scripts: Remove vm_smoke_test

CONTRIBUTING.md | 50 +++----
meta-isar/conf/machine/qemuamd64-sb.conf | 2 +-
scripts/start_vm | 161 ++---------------------
scripts/vm_smoke_test | 106 ---------------
testsuite/README.md | 4 +-
testsuite/cibase.py | 6 +-
testsuite/cibuilder.py | 65 +++------
testsuite/citest.py | 4 +-
testsuite/start_vm.py | 90 +++++++++----
testsuite/utils.py | 54 ++++++++
10 files changed, 179 insertions(+), 363 deletions(-)
delete mode 100755 scripts/vm_smoke_test

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:14 AMJun 17
to isar-...@googlegroups.com, Ilia Skochilov, Anton Mikanovich
From: Ilia Skochilov <iskoc...@ilbers.de>

Remove the shell version of start_vm.
Use the python version of start_vm for both testsuite and command line.

Signed-off-by: Ilia Skochilov <iskoc...@ilbers.de>
Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
scripts/start_vm | 161 +++--------------------------------------
testsuite/README.md | 4 +-
testsuite/cibuilder.py | 2 +-
testsuite/start_vm.py | 7 +-
4 files changed, 18 insertions(+), 156 deletions(-)

diff --git a/scripts/start_vm b/scripts/start_vm
index 42899df9..b081e973 100755
--- a/scripts/start_vm
+++ b/scripts/start_vm
@@ -1,156 +1,15 @@
-#!/bin/sh
+#!/usr/bin/env python3
#
-# This software is a part of ISAR.
-# Copyright (C) 2015-2017 ilbers GmbH
+# Helper script to start QEMU with Isar image
+# Copyright (c) 2024, ilbers GmbH

-set -e
+import sys, os
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'testsuite'))

-ES_OK=0
-ES_BUG=3
+from start_vm import parse_args, start_qemu

-# Convert bitbake assignments to shell ones
-# a = b a=b
-# a ?= b a=b
-# TODO: Use bitbake to parse vars correctly (overriding in local.conf, etc.)
-bb2sh() {
- sed 's/[[:space:]]*?*=[[:space:]]*/=/'
-}
+if __name__ == "__main__":
+ args = parse_args()

-start_qemu() {
- root=`echo $QEMU_DISK_ARGS \
- | sed 's,##ROOTFS_IMAGE##,'$IMAGE_DIR/$ROOTFS_IMAGE','`
- [ -n "$KARGS$EXTRA_KARGS" ] && OPT_KERNEL_ARGS="-append $KARGS$EXTRA_KARGS"
- local had_x
- echo $- | grep -q x && had_x=1 || had_x=0
- [ $had_x -eq 0 ] && set -x
- qemu-system-$QEMU_ARCH \
- -m 1024M \
- -M $QEMU_MACHINE \
- $QCPU \
- -nographic \
- $EXTRA_ARGS \
- $OPT_KERNEL_ARGS \
- $root
- [ $had_x -eq 0 ] && set +x
-}
-
-show_help() {
- echo "This script runs ISAR image in QEMU emulator."
- echo
- echo "Usage:"
- echo " $0 [params] [BUILD_DIR]"
- echo "BUILD_DIR is your ISAR build folder. If not set, current folder"
- echo "is used."
- echo
- echo "Parameters:"
- echo " -a, --arch ARCH set isar machine architecture."
- echo " Supported: arm, i386, amd64, arm64, mipsel, riscv64."
- echo " -b, --build BUILD set path to build directory."
- echo " -d, --distro DISTRO set isar Debian distribution."
- echo " Supported: buster, bullseye, bookworm"
- echo " -o, --out FILE Route QEMU console output to"
- echo " specified file."
- echo " -p, --pid FILE Store QEMU pid to file."
- echo " -s, --secureboot Enable secureboot with default MS keys."
- echo " --help display this message and exit."
- echo
- echo "Exit status:"
- echo " 0 if OK,"
- echo " 3 if invalid parameters are passed."
-}
-
-# Set default values, that can be overwritten from command line
-ARCH=arm
-DISTRO=bookworm
-BUILD_DIR=$PWD
-
-# Parse command line to get user configuration
-while [ $# -gt 0 ]
-do
- key="$1"
-
- case $key in
- -h|--help)
- show_help
- exit 0
- ;;
- -a|--arch)
- ARCH=$2
- shift
- ;;
- -b|--build)
- BUILD_DIR=$2
- shift
- ;;
- -d|--distro)
- DISTRO=$2
- shift
- ;;
- -o|--out)
- EXTRA_ARGS="$EXTRA_ARGS -serial file:$2"
- shift
- ;;
- -p|--pid)
- EXTRA_ARGS="$EXTRA_ARGS -pidfile $2"
- shift
- ;;
- -s|--secureboot)
- OVMF_VARS_ORIG="/usr/share/OVMF/OVMF_VARS_4M.ms.fd"
- OVMF_VARS="$(basename "${OVMF_VARS_ORIG}")"
- cp "${OVMF_VARS_ORIG}" "${OVMF_VARS}"
- EXTRA_ARGS="$EXTRA_ARGS -drive if=pflash,format=raw,unit=1,file=${OVMF_VARS}"
- ;;
- *)
- echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
- exit $ES_BUG
- ;;
- esac
-
- shift
-done
-
-eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^DEPLOY_DIR_IMAGE=")
-readonly IMAGE_DIR=$DEPLOY_DIR_IMAGE
-
-readonly ISARROOT="$(dirname "$0")"/..
-
-readonly MACHINE_CONF=$ISARROOT/meta-isar/conf/machine/qemu$ARCH.conf
-eval "$(egrep 'MACHINE_SERIAL|QEMU_' $MACHINE_CONF |bb2sh)"
-
-eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "\(^IMAGE_FSTYPES=\|^IMAGE_FULLNAME=\)")
-# Take first image type for VM if there are several defined
-IMAGE_FSTYPES=$(echo "$IMAGE_FSTYPES" | awk '{print $1}')
-case "$IMAGE_FSTYPES" in
- ext4)
- readonly ROOTFS_IMAGE=$IMAGE_FULLNAME.ext4
-
- eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^KERNEL_IMAGE=")
- eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^INITRD_DEPLOY_FILE=")
- QKERNEL=$IMAGE_DIR/${KERNEL_IMAGE}
- QINITRD=/dev/null
- [ -n "$INITRD_DEPLOY_FILE" ] && QINITRD=$IMAGE_DIR/${INITRD_DEPLOY_FILE}
- if [ "$ARCH" = "riscv64" ]; then
- EXTRA_ARGS="$EXTRA_ARGS -device loader,file=$QKERNEL,addr=0x80200000"
- QKERNEL="/usr/lib/riscv64-linux-gnu/opensbi/qemu/virt/fw_jump.elf"
- fi
- EXTRA_ARGS="$EXTRA_ARGS \
- -kernel $QKERNEL \
- -initrd $QINITRD"
- KARGS="console=$MACHINE_SERIAL root=/dev/$QEMU_ROOTFS_DEV rw $QEMU_KARGS"
- ;;
- wic)
- readonly ROOTFS_IMAGE=$IMAGE_FULLNAME.wic
- EXTRA_ARGS="$EXTRA_ARGS -snapshot"
- ;;
- *)
- echo "IMAGE_FSTYPES \"$IMAGE_FSTYPES\" not supported"
- exit 1
- ;;
-esac
-
-QCPU=
-[ -n "$QEMU_CPU" ] && QCPU="-cpu $QEMU_CPU"
-
-start_qemu
-
-exit $ES_OK
+ start_qemu(args.arch, args.build, args.distro, args.image, args.out,
+ args.pid, args.pcbios)
diff --git a/testsuite/README.md b/testsuite/README.md
index 913767fc..cfcfb1bf 100644
--- a/testsuite/README.md
+++ b/testsuite/README.md
@@ -57,11 +57,11 @@ $ avocado run ../testsuite/citest.py -t startvm,full

## Manual running

-There is a tool `start_vm.py` which is the replacement for the bash script in
+There is a tool start_vm which is the replacement for the bash script in
`isar/scripts` directory. It can be used to run image previously built:

```
-./start_vm.py -a amd64 -b /build -d bullseye -i isar-image-base
+start_vm -a amd64 -b /build -d bullseye -i isar-image-base
```

# Tests for running commands under qemu images
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 227d0a96..12c48180 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -529,7 +529,7 @@ BBPATH .= ":${LAYERDIR}"\
'DISTRO', \
target=multiconfig)

- # only the first type will be tested in start_vm.py
+ # only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':
if wks_file:
# ubuntu is less verbose so we do not see the message
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index ef0dfbcb..2c07b816 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -98,7 +98,7 @@ def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
print(cmdline)
p1 = subprocess.call('exec ' + ' '.join(cmdline), shell=True)

-if __name__ == "__main__":
+def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())
@@ -107,6 +107,9 @@ if __name__ == "__main__":
parser.add_argument('-o', '--out', help='Route QEMU console output to specified file.')
parser.add_argument('-p', '--pid', help='Store QEMU pid to specified file.')
parser.add_argument('--pcbios', action="store_true", help='remove any bios options to enforce use of pc bios')
- args = parser.parse_args()
+ return parser.parse_args()
+
+if __name__ == "__main__":
+ args = parse_args()

start_qemu(args.arch, args.build, args.distro, args.image, args.out, args.pid, args.pcbios)
--
2.34.1

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:15 AMJun 17
to isar-...@googlegroups.com, Ilia Skochilov, Anton Mikanovich
From: Ilia Skochilov <iskoc...@ilbers.de>

Remove vm_smoke_test, its functionality is now covered in the dev
testsuite. Remove mentioning of vm_smoke_test in documentation.
Add instructions about how to run the dev testsuite via avocado
framework in a kas container.

Signed-off-by: Ilia Skochilov <iskoc...@ilbers.de>
Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
CONTRIBUTING.md | 50 +++++++++++---------
scripts/vm_smoke_test | 106 ------------------------------------------
2 files changed, 28 insertions(+), 128 deletions(-)
delete mode 100755 scripts/vm_smoke_test
-# This software is a part of ISAR.
-# Copyright (C) 2015-2018 ilbers GmbH
-
-set -e
-
-VERBOSE="--show=test"
-TIMEOUT=300
-
-# Error codes:
-ES_OK=0
-ES_FAIL=1
-ES_BUG=3
-
-RET=$ES_FAIL
-
-# Get Avocado QEMU tests path
-TESTSUITE_DIR="$(dirname "$0")/../testsuite"
-
-# Go to Isar root
-cd "$(dirname "$0")/.."
-
-BUILD_DIR=./build
-
-show_help() {
- echo "This script tests the Isar images for default targets in QEMU."
- echo
- echo "Usage:"
- echo " $0 [params]"
- echo
- echo "Parameters:"
- echo " -f,--fast test reduced set of supported targets."
- echo " -q, --quiet do not display boot logs for all the targets."
- echo " If test failed for the specific configuration,"
- echo " the respective boot log will be printed anyway."
- echo " -t,--timeout SEC specify time in seconds to wait before stop QEMU."
- echo " The default is: 300"
- echo " -h, --help display this message and exit."
- echo
- echo "Exit status:"
- echo " 0 if OK,"
- echo " 1 if test failed,"
- echo " 3 if invalid parameters are passed."
-}
-
-# Parse command line to get user configuration
-while [ $# -gt 0 ]
-do
- key="$1"
-
- case $key in
- -h|--help)
- show_help
- exit 0
- ;;
- -o|--output)
- # Deprecated option
- shift
- ;;
- -p|--pid-file)
- # Deprecated option
- shift
- ;;
- -f|--fast)
- FAST_BUILD="1"
- ;;
- -q|--quiet)
- VERBOSE=""
- ;;
- -t|--timeout)
- TIMEOUT=$2
- shift
- ;;
- *)
- echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
- exit $ES_BUG
- ;;
- esac
-
- shift
-done
-

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:15 AMJun 17
to isar-...@googlegroups.com, Anton Mikanovich
We already have an API to get Bitbake variable values without manual
handling of bitbake execution. This will speedup und simplify start_vm.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/start_vm.py | 48 ++++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 45e509a7..f414a194 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -11,43 +11,50 @@ import sys
import shutil
import time

+from utils import CIUtils
+
OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'

-def get_bitbake_env(arch, distro, image):
+def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
- output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
- return output

-def get_bitbake_var(output, var):
- ret = ''
- for line in output.splitlines():
- if line.startswith(var + '='):
- ret = line.split('"')[1]
- return ret
-
-def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
- bb_output = get_bitbake_env(arch, distro, image).decode()
+ image_fstypes, \
+ deploy_dir_image, \
+ kernel_image, \
+ initrd_image, \
+ serial, \
+ root_dev, \
+ qemu_arch, \
+ qemu_machine, \
+ qemu_cpu, \
+ qemu_disk_args = CIUtils.getVars('IMAGE_FSTYPES', \
+ 'DEPLOY_DIR_IMAGE', \
+ 'KERNEL_IMAGE', \
+ 'INITRD_DEPLOY_FILE', \
+ 'MACHINE_SERIAL', \
+ 'QEMU_ROOTFS_DEV', \
+ 'QEMU_ARCH', \
+ 'QEMU_MACHINE', \
+ 'QEMU_CPU', \
+ 'QEMU_DISK_ARGS', \
+ target=multiconfig)

extra_args = ''
cpu = ['']

- image_type = get_bitbake_var(bb_output, 'IMAGE_FSTYPES').split()[0]
- deploy_dir_image = get_bitbake_var(bb_output, 'DEPLOY_DIR_IMAGE')
+ image_type = image_fstypes.split()[0]
base = 'ubuntu' if distro in ['jammy', 'focal'] else 'debian'

rootfs_image = image + '-' + base + '-' + distro + '-qemu' + arch + '.' + image_type

if image_type == 'ext4':
- kernel_image = deploy_dir_image + '/' + get_bitbake_var(bb_output, 'KERNEL_IMAGE')
- initrd_image = get_bitbake_var(bb_output, 'INITRD_DEPLOY_FILE')
+ kernel_image = deploy_dir_image + '/' + kernel_image

if not initrd_image:
initrd_image = '/dev/null'
else:
initrd_image = deploy_dir_image + '/' + initrd_image

- serial = get_bitbake_var(bb_output, 'MACHINE_SERIAL')
- root_dev = get_bitbake_var(bb_output, 'QEMU_ROOTFS_DEV')
kargs = ['-append', '"console=' + serial + ' root=/dev/' + root_dev + ' rw"']

extra_args = ['-kernel', kernel_image, '-initrd', initrd_image]
@@ -57,11 +64,6 @@ def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:15 AMJun 17
to isar-...@googlegroups.com, Anton Mikanovich
Provide utilities class for external usage to be imported from outside
of Avocado framework.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/cibase.py | 6 +++--
testsuite/cibuilder.py | 50 ++++----------------------------------
testsuite/citest.py | 4 +++-
testsuite/utils.py | 54 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 48 deletions(-)
create mode 100755 testsuite/utils.py

diff --git a/testsuite/cibase.py b/testsuite/cibase.py
index 0f6997af..c257a465 100755
--- a/testsuite/cibase.py
+++ b/testsuite/cibase.py
@@ -8,6 +8,8 @@ import tempfile
import time

from cibuilder import CIBuilder, isar_root
+from utils import CIUtils
+
from avocado.utils import process

class CIBaseTest(CIBuilder):
@@ -238,13 +240,13 @@ class CIBaseTest(CIBuilder):
for target in targets:
sfiles[target] = dict()
package = target.rsplit(':', 1)[-1]
- isar_apt = self.getVars('REPO_ISAR_DB_DIR', target=target)
+ isar_apt = CIUtils.getVars('REPO_ISAR_DB_DIR', target=target)
fpath = f'{package}/{package}*.tar.gz'
targz = set(glob.glob(f'{isar_apt}/../apt/*/pool/*/*/{fpath}'))
if len(targz) < 1:
self.fail('No source packages found')
for filename in targz:
- sfiles[target][filename] = self.get_tar_content(filename)
+ sfiles[target][filename] = CIUtils.get_tar_content(filename)
return sfiles

self.configure(**kwargs)
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index a51d6f7e..4aa06ffb 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
# only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':

Anton Mikanovich

unread,
Jun 17, 2024, 11:09:15 AMJun 17
to isar-...@googlegroups.com, Anton Mikanovich
Add sb_copy_vars()/sb_cleanup() API for creation of OVMF variables file
copy in case it was declared in QEMU_DISK_ARGS value.
If OVMF_VARS_4M.ms.fd is already exists it will be reused, otherwise
created copy will be deleted after QEMU exit.

sb_copy_vars() returns True if cleanup needed.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
meta-isar/conf/machine/qemuamd64-sb.conf | 2 +-
testsuite/cibuilder.py | 13 ++++++---
testsuite/start_vm.py | 37 +++++++++++++++++++++---
3 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/meta-isar/conf/machine/qemuamd64-sb.conf b/meta-isar/conf/machine/qemuamd64-sb.conf
index 2bec553b..9ad5f8d6 100644
--- a/meta-isar/conf/machine/qemuamd64-sb.conf
+++ b/meta-isar/conf/machine/qemuamd64-sb.conf
@@ -18,4 +18,4 @@ IMAGER_INSTALL:wic += "${GRUB_DEBIAN_SB_MOK}"
IMAGE_PREINSTALL += "mokutil"

# overwrite qemu disk args for signed boot
-QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on"
+QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=OVMF_VARS_4M.ms.fd"
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 12c48180..a51d6f7e 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -477,6 +477,8 @@ BBPATH .= ":${LAYERDIR}"\
boot_log, None, enforce_pcbios)
cmdline.insert(1, '-nographic')

+ need_sb_cleanup = start_vm.sb_copy_vars(cmdline)
+
self.log.info('QEMU boot line:\n' + ' '.join(cmdline))
self.log.info('QEMU boot log:\n' + boot_log)

@@ -485,7 +487,7 @@ BBPATH .= ":${LAYERDIR}"\
universal_newlines=True)
self.log.info("Started VM with pid %s" % (p1.pid))

- return p1, cmdline, boot_log
+ return p1, cmdline, boot_log, need_sb_cleanup


def vm_wait_boot(self, p1, timeout):
@@ -564,6 +566,9 @@ BBPATH .= ":${LAYERDIR}"\
pid = self.vm_dict[vm][0]
os.kill(pid, signal.SIGKILL)

+ if self.vm_dict[vm][3]:
+ start_vm.sb_cleanup()
+
del(self.vm_dict[vm])
self.vm_dump_dict(vm)

@@ -600,7 +605,7 @@ BBPATH .= ":${LAYERDIR}"\
stderr = ""

if vm in self.vm_dict:
- pid, cmdline, boot_log = self.vm_dict[vm]
+ pid, cmdline, boot_log, need_sb_cleanup = self.vm_dict[vm]

# Check that corresponding process exists
proc = subprocess.run("ps -o cmd= %d" % (pid), shell=True, text=True,
@@ -612,8 +617,8 @@ BBPATH .= ":${LAYERDIR}"\
if run_qemu:
self.log.info("No qemu-system process for `%s` found, run new VM" % (vm))

- p1, cmdline, boot_log = self.vm_turn_on(arch, distro, image, enforce_pcbios)
- self.vm_dict[vm] = p1.pid, cmdline, boot_log
+ p1, cmdline, boot_log, need_sb_cleanup = self.vm_turn_on(arch, distro, image, enforce_pcbios)
+ self.vm_dict[vm] = p1.pid, cmdline, boot_log, need_sb_cleanup
self.vm_dump_dict(vm)

rc = self.vm_wait_boot(p1, timeout)
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 2c07b816..45e509a7 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -1,15 +1,18 @@
#!/usr/bin/env python3
#
# Helper script to start QEMU with Isar image
-# Copyright (c) 2019, ilbers GmbH
+# Copyright (c) 2019-2024, ilbers GmbH

import argparse
import os
import socket
import subprocess
import sys
+import shutil
import time

+OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'
+
def get_bitbake_env(arch, distro, image):
multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
@@ -91,16 +94,42 @@ def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal

return cmd

+def sb_copy_vars(cmdline):
+ ovmf_vars_filename = os.path.basename(OVMF_VARS_PATH)
+
+ for param in cmdline:
+ if ovmf_vars_filename in param:
+ if os.path.exists(ovmf_vars_filename):
+ break
+ if not os.path.exists(OVMF_VARS_PATH):
+ print('%s required but not found!' % OVMF_VARS_PATH, file=sys.stderr)
+ break
+ shutil.copy(OVMF_VARS_PATH, ovmf_vars_filename)
+ return True
+
+ return False
+
+def sb_cleanup():
+ os.remove(os.path.basename(OVMF_VARS_PATH))
+
def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
- cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios)
+ cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid,
+ enforce_pcbios)
cmdline.insert(1, '-nographic')

+ need_cleanup = sb_copy_vars(cmdline)
+
print(cmdline)
- p1 = subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+
+ try:
+ subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+ finally:
+ if need_cleanup:
+ sb_cleanup()

def parse_args():
parser = argparse.ArgumentParser()
- parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
+ parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'amd64-sb', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())
parser.add_argument('-d', '--distro', choices=['buster', 'bullseye', 'bookworm', 'trixie', 'focal', 'jammy'], help='set isar Debian distribution.', default='bookworm')
parser.add_argument('-i', '--image', help='set image name.', default='isar-image-base')
--
2.34.1

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:28 AMJun 21
to isar-...@googlegroups.com, Ilia Skochilov, Anton Mikanovich
From: Ilia Skochilov <iskoc...@ilbers.de>

Remove the shell version of start_vm.
Use the python version of start_vm for both testsuite and command line.

Signed-off-by: Ilia Skochilov <iskoc...@ilbers.de>
Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
scripts/start_vm | 161 +++--------------------------------------
testsuite/README.md | 4 +-
testsuite/cibuilder.py | 2 +-
testsuite/start_vm.py | 7 +-
4 files changed, 19 insertions(+), 155 deletions(-)

diff --git a/scripts/start_vm b/scripts/start_vm
index 42899df9..cc80bce5 100755
--- a/scripts/start_vm
+++ b/scripts/start_vm
@@ -1,156 +1,17 @@
-#!/bin/sh
+#!/usr/bin/env python3
#
-# This software is a part of ISAR.
-# Copyright (C) 2015-2017 ilbers GmbH
+# Helper script to start QEMU with Isar image
+# Copyright (c) 2024, ilbers GmbH

-set -e
+import os
+import sys

-ES_OK=0
-ES_BUG=3
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'testsuite'))

-# Convert bitbake assignments to shell ones
-# a = b a=b
-# a ?= b a=b
-# TODO: Use bitbake to parse vars correctly (overriding in local.conf, etc.)
-bb2sh() {
- sed 's/[[:space:]]*?*=[[:space:]]*/=/'
-}
+from start_vm import parse_args, start_qemu

-start_qemu() {
- root=`echo $QEMU_DISK_ARGS \
- | sed 's,##ROOTFS_IMAGE##,'$IMAGE_DIR/$ROOTFS_IMAGE','`
- [ -n "$KARGS$EXTRA_KARGS" ] && OPT_KERNEL_ARGS="-append $KARGS$EXTRA_KARGS"
- local had_x
- echo $- | grep -q x && had_x=1 || had_x=0
- [ $had_x -eq 0 ] && set -x
- qemu-system-$QEMU_ARCH \
- -m 1024M \
- -M $QEMU_MACHINE \
- $QCPU \
- -nographic \
- $EXTRA_ARGS \
- $OPT_KERNEL_ARGS \
- $root
- [ $had_x -eq 0 ] && set +x
-}
+if __name__ == "__main__":
+ args = parse_args()

-show_help() {
- echo "This script runs ISAR image in QEMU emulator."
- echo
- echo "Usage:"
- echo " $0 [params] [BUILD_DIR]"
- echo "BUILD_DIR is your ISAR build folder. If not set, current folder"
- echo "is used."
- echo
- echo "Parameters:"
- echo " -a, --arch ARCH set isar machine architecture."
- echo " Supported: arm, i386, amd64, arm64, mipsel, riscv64."
- echo " -b, --build BUILD set path to build directory."
- echo " -d, --distro DISTRO set isar Debian distribution."
- echo " Supported: buster, bullseye, bookworm"
- echo " -o, --out FILE Route QEMU console output to"
- echo " specified file."
- echo " -p, --pid FILE Store QEMU pid to file."
- echo " -s, --secureboot Enable secureboot with default MS keys."
- echo " --help display this message and exit."
- echo
- echo "Exit status:"
- echo " 0 if OK,"
- echo " 3 if invalid parameters are passed."
-}
-
-# Set default values, that can be overwritten from command line
-ARCH=arm
-DISTRO=bookworm
-BUILD_DIR=$PWD
-
-# Parse command line to get user configuration
-while [ $# -gt 0 ]
-do
- key="$1"
-
- case $key in
- -h|--help)
- show_help
- exit 0
- ;;
- -a|--arch)
- ARCH=$2
- shift
- ;;
- -b|--build)
- BUILD_DIR=$2
- shift
- ;;
- -d|--distro)
- DISTRO=$2
- shift
- ;;
- -o|--out)
- EXTRA_ARGS="$EXTRA_ARGS -serial file:$2"
- shift
- ;;
- -p|--pid)
- EXTRA_ARGS="$EXTRA_ARGS -pidfile $2"
- shift
- ;;
- -s|--secureboot)
- OVMF_VARS_ORIG="/usr/share/OVMF/OVMF_VARS_4M.ms.fd"
- OVMF_VARS="$(basename "${OVMF_VARS_ORIG}")"
- cp "${OVMF_VARS_ORIG}" "${OVMF_VARS}"
- EXTRA_ARGS="$EXTRA_ARGS -drive if=pflash,format=raw,unit=1,file=${OVMF_VARS}"
- ;;
- *)
- echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
- exit $ES_BUG
- ;;
- esac
-
- shift
-done
-
- ;;
- *)
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 227d0a96..12c48180 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -529,7 +529,7 @@ BBPATH .= ":${LAYERDIR}"\
'DISTRO', \
target=multiconfig)

- # only the first type will be tested in start_vm.py
+ # only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':
if wks_file:
# ubuntu is less verbose so we do not see the message
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index ef0dfbcb..2c07b816 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -98,7 +98,7 @@ def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
print(cmdline)
p1 = subprocess.call('exec ' + ' '.join(cmdline), shell=True)

-if __name__ == "__main__":
+def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:29 AMJun 21
to isar-...@googlegroups.com, Anton Mikanovich
Provide utilities class for external usage to be imported from outside
of Avocado framework.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/cibase.py | 8 +++--
testsuite/cibuilder.py | 52 ++++-----------------------------
testsuite/citest.py | 4 ++-
testsuite/repro-build-test.py | 4 ++-
testsuite/utils.py | 55 +++++++++++++++++++++++++++++++++++
5 files changed, 72 insertions(+), 51 deletions(-)
create mode 100755 testsuite/utils.py

diff --git a/testsuite/cibase.py b/testsuite/cibase.py
index 0f6997af..fd571c29 100755
--- a/testsuite/cibase.py
+++ b/testsuite/cibase.py
@@ -8,6 +8,8 @@ import tempfile
import time

from cibuilder import CIBuilder, isar_root
+from utils import CIUtils
+
from avocado.utils import process

class CIBaseTest(CIBuilder):
@@ -238,13 +240,13 @@ class CIBaseTest(CIBuilder):
for target in targets:
sfiles[target] = dict()
package = target.rsplit(':', 1)[-1]
- isar_apt = self.getVars('REPO_ISAR_DB_DIR', target=target)
+ isar_apt = CIUtils.getVars('REPO_ISAR_DB_DIR', target=target)
fpath = f'{package}/{package}*.tar.gz'
targz = set(glob.glob(f'{isar_apt}/../apt/*/pool/*/*/{fpath}'))
if len(targz) < 1:
self.fail('No source packages found')
- for filename in targz:
- sfiles[target][filename] = self.get_tar_content(filename)
+ for fname in targz:
+ sfiles[target][fname] = CIUtils.get_tar_content(fname)
return sfiles

self.configure(**kwargs)
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 87d71387..a20e88f9 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -525,11 +485,11 @@ BBPATH .= ":${LAYERDIR}"\
module_output = b'Just an example'
resize_output = None
image_fstypes, \
- wks_file, \
- bbdistro = self.getVars('IMAGE_FSTYPES', \
- 'WKS_FILE', \
- 'DISTRO', \
- target=multiconfig)
+ wks_file, \
+ bbdistro = CIUtils.getVars('IMAGE_FSTYPES',
+ 'WKS_FILE',
+ 'DISTRO',
+ target=multiconfig)

# only the first type will be tested in start_vm
if image_fstypes.split()[0] == 'wic':
diff --git a/testsuite/citest.py b/testsuite/citest.py
index 42d44f6a..b84ae0e1 100755
--- a/testsuite/citest.py
+++ b/testsuite/citest.py
@@ -5,6 +5,7 @@ import os
from avocado import skipUnless
from avocado.utils import path
from cibase import CIBaseTest
+from utils import CIUtils

UMOCI_AVAILABLE = True
SKOPEO_AVAILABLE = True
@@ -17,6 +18,7 @@ try:
except path.CmdNotFoundError:
SKOPEO_AVAILABLE = False

+
class DevTest(CIBaseTest):

"""
@@ -46,7 +48,7 @@ class DevTest(CIBaseTest):

def test_dev_rebuild(self):
self.init()
- layerdir_core = self.getVars('LAYERDIR_core')
+ layerdir_core = CIUtils.getVars('LAYERDIR_core')

dpkgbase_file = layerdir_core + '/classes/dpkg-base.bbclass'

diff --git a/testsuite/repro-build-test.py b/testsuite/repro-build-test.py
index 843f3bc6..04e4ddc7 100755
--- a/testsuite/repro-build-test.py
+++ b/testsuite/repro-build-test.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

from cibuilder import CIBuilder
+from utils import CIUtils
from avocado.utils import process


@@ -29,7 +30,8 @@ class ReproBuild(CIBuilder):

def get_image_path(self, target_name):
image_dir = "tmp/deploy/images"
- machine, image_name = self.getVars("MACHINE", "IMAGE_FULLNAME", target=target_name)
+ machine, image_name = CIUtils.getVars('MACHINE', 'IMAGE_FULLNAME',
+ target=target_name)
return f"{image_dir}/{machine}/{image_name}.tar.gz"

def build_repro_image(
diff --git a/testsuite/utils.py b/testsuite/utils.py
new file mode 100755
index 00000000..ffcb5cc7
--- /dev/null
+++ b/testsuite/utils.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import tarfile
+import time
+
+sys.path.append(os.path.join(os.path.dirname(__file__), '../bitbake/lib'))
+ values = values + (tinfoil.config_data.getVar(var) or '',)

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:29 AMJun 21
to isar-...@googlegroups.com, Anton Mikanovich
Add sb_copy_vars()/sb_cleanup() API for creation of OVMF variables file
copy in case it was declared in QEMU_DISK_ARGS value.
If OVMF_VARS_4M.ms.fd is already exists it will be reused, otherwise
created copy will be deleted after QEMU exit.

sb_copy_vars() returns True if cleanup needed.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
meta-isar/conf/machine/qemuamd64-sb.conf | 2 +-
testsuite/cibuilder.py | 15 ++++++---
testsuite/start_vm.py | 41 ++++++++++++++++++++++--
3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/meta-isar/conf/machine/qemuamd64-sb.conf b/meta-isar/conf/machine/qemuamd64-sb.conf
index 2bec553b..9ad5f8d6 100644
--- a/meta-isar/conf/machine/qemuamd64-sb.conf
+++ b/meta-isar/conf/machine/qemuamd64-sb.conf
@@ -18,4 +18,4 @@ IMAGER_INSTALL:wic += "${GRUB_DEBIAN_SB_MOK}"
IMAGE_PREINSTALL += "mokutil"

# overwrite qemu disk args for signed boot
-QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on"
+QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=OVMF_VARS_4M.ms.fd"
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 12c48180..87d71387 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -612,8 +617,10 @@ BBPATH .= ":${LAYERDIR}"\
if run_qemu:
self.log.info("No qemu-system process for `%s` found, run new VM" % (vm))

- p1, cmdline, boot_log = self.vm_turn_on(arch, distro, image, enforce_pcbios)
- self.vm_dict[vm] = p1.pid, cmdline, boot_log
+ p1, cmdline, boot_log, \
+ need_sb_cleanup = self.vm_turn_on(arch, distro, image,
+ enforce_pcbios)
+ self.vm_dict[vm] = p1.pid, cmdline, boot_log, need_sb_cleanup
self.vm_dump_dict(vm)

rc = self.vm_wait_boot(p1, timeout)
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 2c07b816..0e0d7000 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -1,15 +1,18 @@
#!/usr/bin/env python3
#
# Helper script to start QEMU with Isar image
-# Copyright (c) 2019, ilbers GmbH
+# Copyright (c) 2019-2024, ilbers GmbH

import argparse
import os
import socket
import subprocess
import sys
+import shutil
import time

+OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'
+
def get_bitbake_env(arch, distro, image):
multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
@@ -91,16 +94,48 @@ def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal

return cmd

+
+def sb_copy_vars(cmdline):
+ ovmf_vars_filename = os.path.basename(OVMF_VARS_PATH)
+
+ for param in cmdline:
+ if ovmf_vars_filename in param:
+ if os.path.exists(ovmf_vars_filename):
+ break
+ if not os.path.exists(OVMF_VARS_PATH):
+ print(f'{OVMF_VARS_PATH} required but not found!',
+ file=sys.stderr)
+ break
+ shutil.copy(OVMF_VARS_PATH, ovmf_vars_filename)
+ return True
+
+ return False
+
+
+def sb_cleanup():
+ os.remove(os.path.basename(OVMF_VARS_PATH))
+
+
def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios)
cmdline.insert(1, '-nographic')

+ need_cleanup = sb_copy_vars(cmdline)
+
print(cmdline)
- p1 = subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+
+ try:
+ subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+ finally:
+ if need_cleanup:
+ sb_cleanup()
+

def parse_args():
parser = argparse.ArgumentParser()
- parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
+ arch_names = ['arm', 'arm64', 'amd64', 'amd64-sb', 'i386', 'mipsel']
+ parser.add_argument('-a', '--arch', choices=arch_names,
+ help='set isar machine architecture.', default='arm')
parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:29 AMJun 21
to isar-...@googlegroups.com, Ilia Skochilov, Anton Mikanovich
From: Ilia Skochilov <iskoc...@ilbers.de>

Remove vm_smoke_test, its functionality is now covered in the dev
testsuite. Remove mentioning of vm_smoke_test in documentation.
Add instructions about how to run the dev testsuite via avocado
framework in a kas container.

Signed-off-by: Ilia Skochilov <iskoc...@ilbers.de>
Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
-# This software is a part of ISAR.
-# Copyright (C) 2015-2018 ilbers GmbH
-
-set -e
-
-VERBOSE="--show=test"
-TIMEOUT=300
-
-# Error codes:
-ES_OK=0
-ES_FAIL=1
-ES_BUG=3
-
-RET=$ES_FAIL
-
-# Get Avocado QEMU tests path
-TESTSUITE_DIR="$(dirname "$0")/../testsuite"
-
-# Go to Isar root
-cd "$(dirname "$0")/.."
-
-BUILD_DIR=./build
-
-show_help() {
- echo "This script tests the Isar images for default targets in QEMU."
- echo
- echo "Usage:"
- echo " $0 [params]"
- echo
- echo "Parameters:"
- echo " -f,--fast test reduced set of supported targets."
- echo " -q, --quiet do not display boot logs for all the targets."
- echo " If test failed for the specific configuration,"
- echo " the respective boot log will be printed anyway."
- echo " -t,--timeout SEC specify time in seconds to wait before stop QEMU."
- echo " The default is: 300"
- echo " -h, --help display this message and exit."
- echo
- echo "Exit status:"
- echo " 0 if OK,"
- echo " 1 if test failed,"
- echo " 3 if invalid parameters are passed."
-}
-
-# Parse command line to get user configuration
-while [ $# -gt 0 ]
-do
- key="$1"
-
- case $key in
- -h|--help)
- show_help
- exit 0
- ;;
- -o|--output)
- # Deprecated option
- shift
- ;;
- -p|--pid-file)
- # Deprecated option
- shift
- ;;
- -f|--fast)
- FAST_BUILD="1"
- ;;
- -q|--quiet)
- VERBOSE=""
- ;;
- -t|--timeout)
- TIMEOUT=$2
- shift
- ;;
- *)
- echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
- exit $ES_BUG
- ;;
- esac
-
- shift
-done
-

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:30 AMJun 21
to isar-...@googlegroups.com, Anton Mikanovich
We had both shell and python APIs for running QEMU images, there is
also start_vm related functionality in testsuite itself. All this parts
duplicate each other and should be cleanup.

Changes since v2:
- Fix getVars usage in repro-build-test.
- Fix coding style.

Changes since v1:
- Fix multiple image type targets.

Anton Mikanovich (3):
start_vm: Add secureboot support
CI: Allow external usage for some APIs
start_vm: Reuse getVars API

Ilia Skochilov (2):
start_vm: Switch to python version
scripts: Remove vm_smoke_test

CONTRIBUTING.md | 50 +++----
meta-isar/conf/machine/qemuamd64-sb.conf | 2 +-
scripts/start_vm | 161 ++---------------------
scripts/vm_smoke_test | 106 ---------------
testsuite/README.md | 4 +-
testsuite/cibase.py | 8 +-
testsuite/cibuilder.py | 69 +++-------
testsuite/citest.py | 4 +-
testsuite/repro-build-test.py | 4 +-
testsuite/start_vm.py | 94 +++++++++----
testsuite/utils.py | 55 ++++++++
11 files changed, 193 insertions(+), 364 deletions(-)
delete mode 100755 scripts/vm_smoke_test

Anton Mikanovich

unread,
Jun 21, 2024, 11:08:30 AMJun 21
to isar-...@googlegroups.com, Anton Mikanovich
We already have an API to get Bitbake variable values without manual
handling of bitbake execution. This will speedup und simplify start_vm.

Signed-off-by: Anton Mikanovich <ami...@ilbers.de>
---
testsuite/start_vm.py | 50 ++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 0e0d7000..d6e04049 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -11,43 +11,50 @@ import sys
import shutil
import time

-OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'
-
-def get_bitbake_env(arch, distro, image):
- multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
- output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
- return output
+from utils import CIUtils

-def get_bitbake_var(output, var):
- ret = ''
- for line in output.splitlines():
- if line.startswith(var + '='):
- ret = line.split('"')[1]
- return ret
+OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'

def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=False):
- bb_output = get_bitbake_env(arch, distro, image).decode()
+ multiconfig = f'mc:qemu{arch}-{distro}:{image}'
+
+ image_fstypes, \
+ deploy_dir_image, \
+ kernel_image, \
+ initrd_image, \
+ serial, \
+ root_dev, \
+ qemu_arch, \
+ qemu_machine, \
+ qemu_cpu, \
+ qemu_disk_args = CIUtils.getVars('IMAGE_FSTYPES',

Uladzimir Bely

unread,
Jun 26, 2024, 2:32:37 AM (10 days ago) Jun 26
to Anton Mikanovich, isar-...@googlegroups.com

Applied to next.

--
Best regards,
Uladzimir.

Reply all
Reply to author
Forward
0 new messages