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:
parent
5d676197eb
commit
3f1e8137f2
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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: ""
|
|
@ -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
|
Loading…
Reference in New Issue