tests/vm: Added configuration file support

Changes to tests/vm/basevm.py to allow accepting a configuration file
as a parameter. Allows for specifying VM options such as
cpu, machine, memory, and arbitrary qemu arguments for specifying options
such as NUMA configuration.
Also added an example conf_example_aarch64.yml and conf_example_x86.yml.

Signed-off-by: Robert Foley <robert.foley@linaro.org>
Reviewed-by: Peter Puhov <peter.puhov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20200601211421.1277-4-robert.foley@linaro.org>
Message-Id: <20200701135652.1366-8-alex.bennee@linaro.org>
This commit is contained in:
Robert Foley 2020-07-01 14:56:19 +01:00 committed by Alex Bennée
parent 5d676197eb
commit 3f1e8137f2
5 changed files with 155 additions and 1 deletions

9
configure vendored
View File

@ -960,6 +960,13 @@ do
fi fi
done done
# Check for existence of python3 yaml, needed to
# import yaml config files into vm-build.
python_yaml="no"
if $(python3 -c "import yaml" 2> /dev/null); then
python_yaml="yes"
fi
: ${smbd=${SMBD-/usr/sbin/smbd}} : ${smbd=${SMBD-/usr/sbin/smbd}}
# Default objcc to clang if available, otherwise use CC # Default objcc to clang if available, otherwise use CC
@ -6868,6 +6875,7 @@ if test "$docs" != "no"; then
echo "sphinx-build $sphinx_build" echo "sphinx-build $sphinx_build"
fi fi
echo "genisoimage $genisoimage" echo "genisoimage $genisoimage"
echo "python_yaml $python_yaml"
echo "slirp support $slirp $(echo_version $slirp $slirp_version)" echo "slirp support $slirp $(echo_version $slirp $slirp_version)"
if test "$slirp" != "no" ; then if test "$slirp" != "no" ; then
echo "smbd $smbd" echo "smbd $smbd"
@ -7966,6 +7974,7 @@ echo "PYTHON=$python" >> $config_host_mak
echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
echo "PYTHON_YAML=$python_yaml" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak echo "CC=$cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then if $iasl -h > /dev/null 2>&1; then
echo "IASL=$iasl" >> $config_host_mak echo "IASL=$iasl" >> $config_host_mak

View File

@ -44,6 +44,12 @@ endif
@echo " QEMU_LOCAL=1 - Use QEMU binary local to this build." @echo " QEMU_LOCAL=1 - Use QEMU binary local to this build."
@echo " QEMU=/path/to/qemu - Change path to QEMU binary" @echo " QEMU=/path/to/qemu - Change path to QEMU binary"
@echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool" @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool"
ifeq ($(PYTHON_YAML),yes)
@echo " QEMU_CONFIG=/path/conf.yml - Change path to VM configuration .yml file."
else
@echo " (install python3-yaml to enable support for yaml file to configure a VM.)"
endif
@echo " See conf_example_*.yml for file format details."
vm-build-all: $(addprefix vm-build-, $(IMAGES)) vm-build-all: $(addprefix vm-build-, $(IMAGES))

View File

@ -481,7 +481,6 @@ class BaseVM(object):
cwd=cidir, cwd=cidir,
stdin=self._devnull, stdout=self._stdout, stdin=self._devnull, stdout=self._stdout,
stderr=self._stdout) stderr=self._stdout)
return os.path.join(cidir, "cloud-init.iso") return os.path.join(cidir, "cloud-init.iso")
def get_qemu_path(arch, build_path=None): def get_qemu_path(arch, build_path=None):
@ -497,6 +496,41 @@ def get_qemu_path(arch, build_path=None):
qemu_path = "qemu-system-" + arch qemu_path = "qemu-system-" + arch
return qemu_path return qemu_path
def parse_config(config, args):
""" Parse yaml config and populate our config structure.
The yaml config allows the user to override the
defaults for VM parameters. In many cases these
defaults can be overridden without rebuilding the VM."""
if args.config:
config_file = args.config
elif 'QEMU_CONFIG' in os.environ:
config_file = os.environ['QEMU_CONFIG']
else:
return config
if not os.path.exists(config_file):
raise Exception("config file {} does not exist".format(config_file))
# We gracefully handle importing the yaml module
# since it might not be installed.
# If we are here it means the user supplied a .yml file,
# so if the yaml module is not installed we will exit with error.
try:
import yaml
except ImportError:
print("The python3-yaml package is needed "\
"to support config.yaml files")
# Instead of raising an exception we exit to avoid
# a raft of messy (expected) errors to stdout.
exit(1)
with open(config_file) as f:
yaml_dict = yaml.safe_load(f)
if 'qemu-conf' in yaml_dict:
config.update(yaml_dict['qemu-conf'])
else:
raise Exception("config file {} is not valid"\
" missing qemu-conf".format(config_file))
return config
def parse_args(vmcls): def parse_args(vmcls):
def get_default_jobs(): def get_default_jobs():
@ -536,6 +570,9 @@ def parse_args(vmcls):
help="run tests with a snapshot") help="run tests with a snapshot")
parser.add_option("--genisoimage", default="genisoimage", parser.add_option("--genisoimage", default="genisoimage",
help="iso imaging tool") help="iso imaging tool")
parser.add_option("--config", "-c", default=None,
help="Provide config yaml for configuration. "\
"See config_example.yaml for example.")
parser.disable_interspersed_args() parser.disable_interspersed_args()
return parser.parse_args() return parser.parse_args()
@ -547,6 +584,7 @@ def main(vmcls, config=None):
if not argv and not args.build_qemu and not args.build_image: if not argv and not args.build_qemu and not args.build_image:
print("Nothing to do?") print("Nothing to do?")
return 1 return 1
config = parse_config(config, args)
logging.basicConfig(level=(logging.DEBUG if args.debug logging.basicConfig(level=(logging.DEBUG if args.debug
else logging.WARN)) else logging.WARN))
vm = vmcls(args, config=config) vm = vmcls(args, config=config)

View File

@ -0,0 +1,51 @@
#
# Example yaml for use by any of the scripts in tests/vm.
# Can be provided as an environment variable QEMU_CONFIG
#
qemu-conf:
# If any of the below are not provided, we will just use the qemu defaults.
# Login username and password(has to be sudo enabled)
guest_user: qemu
guest_pass: "qemupass"
# Password for root user can be different from guest.
root_pass: "qemupass"
# If one key is provided, both must be provided.
#ssh_key: /complete/path/of/your/keyfile/id_rsa
#ssh_pub_key: /complete/path/of/your/keyfile/id_rsa.pub
cpu: max
machine: virt,gic-version=max
memory: 16G
# The below is a example for how to configure NUMA topology with
# 4 NUMA nodes and 2 different NUMA distances.
qemu_args: "-smp cpus=16,sockets=2,cores=8
-numa node,cpus=0-3,nodeid=0 -numa node,cpus=4-7,nodeid=1
-numa node,cpus=8-11,nodeid=2 -numa node,cpus=12-15,nodeid=3
-numa dist,src=0,dst=1,val=15 -numa dist,src=2,dst=3,val=15
-numa dist,src=0,dst=2,val=20 -numa dist,src=0,dst=3,val=20
-numa dist,src=1,dst=2,val=20 -numa dist,src=1,dst=3,val=20"
# By default we do not set the DNS.
# You override the defaults by setting the below.
#dns: 1.234.567.89
# By default we will use a "block" device, but
# you can also boot from a "scsi" device.
# Just keep in mind your scripts might need to change
# As you will have /dev/sda instead of /dev/vda (for block device)
boot_dev_type: "block"
# By default the ssh port is not fixed.
# A fixed ssh port makes it easier for automated tests.
#ssh_port: 5555
# To install a different set of packages, provide a command to issue
#install_cmds: "apt-get update ; apt-get build-dep -y qemu"
# Or to skip the install entirely, just provide ""
#install_cmds: ""

View File

@ -0,0 +1,50 @@
#
# Example yaml for use by any of the x86 based scripts in tests/vm.
# Can be provided as an environment variable QEMU_CONFIG
#
qemu-conf:
# If any of the below are not provided, we will just use the qemu defaults.
# Login username and password(has to be sudo enabled)
guest_user: "qemu"
guest_pass: "qemupass"
# Password for root user can be different from guest.
root_pass: "qemupass"
# Provide default ssh keys of current user.
# You need to edit the below for your user.
#ssh_key_file: /home/<user>/.ssh/id_rsa
#ssh_pub_key_file: /home/<user>/.ssh/id_rsa.pub
cpu: max
machine: pc
memory: 8G
# The below is a example for how to configure NUMA topology with
# 4 NUMA nodes and 2 different NUMA distances.
qemu_args: "-smp cpus=8,sockets=2,cores=4
-object memory-backend-ram,size=4G,policy=bind,host-nodes=0,id=ram-node0
-object memory-backend-ram,size=4G,policy=bind,host-nodes=0,id=ram-node1
-object memory-backend-ram,size=4G,policy=bind,host-nodes=1,id=ram-node2
-object memory-backend-ram,size=4G,policy=bind,host-nodes=1,id=ram-node3
-numa node,cpus=0-1,nodeid=0 -numa node,cpus=2-3,nodeid=1
-numa node,cpus=4-5,nodeid=2 -numa node,cpus=6-7,nodeid=3
-numa dist,src=0,dst=1,val=15 -numa dist,src=2,dst=3,val=15
-numa dist,src=0,dst=2,val=20 -numa dist,src=0,dst=3,val=20
-numa dist,src=1,dst=2,val=20 -numa dist,src=1,dst=3,val=20"
# By default we do not set the DNS.
# You override the defaults by setting the below.
#dns: "1.234.567.89"
# By default we will use a "block" device, but
# you can also boot from a "scsi" device.
# Just keep in mind your scripts might need to change
# As you will have /dev/sda instead of /dev/vda (for block device)
boot_dev_type: "block"
# By default the ssh port is not fixed.
# A fixed ssh port makes it easier for automated tests.
ssh_port: 5555