From 376168e251a1d4f2ee3643fed6092b8907f057ec Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Tue, 11 Jul 2017 14:28:11 -0700 Subject: tests: Enable the NoCloud KVM platform The NoCloud KVM platform includes: * Downloads daily Ubuntu images using streams and store in /srv/images * Image customization, if required, is done using mount-image-callback otherwise image is untouched * Launches KVM via the xkvm script, a wrapper around qemu-system, and sets custom port for SSH * Generation and inject an SSH (RSA 4096) key pair to use for communication with the guest to collect test artifacts * Add method to produce safe shell strings by base64 encoding the command Additional Changes: * Set default backend to use LXD * Verify not running script as root in order to prevent images from becoming owned by root * Removed extra quotes around that were added when collecting the cloud-init version from the image * Added info about each release as previously the lxd backend was able to query that information from pylxd image info, however, other backends will not be able to obtain the same information as easily --- tests/cloud_tests/platforms/__init__.py | 2 + tests/cloud_tests/platforms/nocloudkvm.py | 90 +++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 tests/cloud_tests/platforms/nocloudkvm.py (limited to 'tests/cloud_tests/platforms') diff --git a/tests/cloud_tests/platforms/__init__.py b/tests/cloud_tests/platforms/__init__.py index 443f6d44..3490fe87 100644 --- a/tests/cloud_tests/platforms/__init__.py +++ b/tests/cloud_tests/platforms/__init__.py @@ -3,8 +3,10 @@ """Main init.""" from tests.cloud_tests.platforms import lxd +from tests.cloud_tests.platforms import nocloudkvm PLATFORMS = { + 'nocloud-kvm': nocloudkvm.NoCloudKVMPlatform, 'lxd': lxd.LXDPlatform, } diff --git a/tests/cloud_tests/platforms/nocloudkvm.py b/tests/cloud_tests/platforms/nocloudkvm.py new file mode 100644 index 00000000..f1f81877 --- /dev/null +++ b/tests/cloud_tests/platforms/nocloudkvm.py @@ -0,0 +1,90 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +"""Base NoCloud KVM platform.""" +import glob +import os + +from simplestreams import filters +from simplestreams import mirrors +from simplestreams import objectstores +from simplestreams import util as s_util + +from cloudinit import util as c_util +from tests.cloud_tests.images import nocloudkvm as nocloud_kvm_image +from tests.cloud_tests.instances import nocloudkvm as nocloud_kvm_instance +from tests.cloud_tests.platforms import base +from tests.cloud_tests import util + + +class NoCloudKVMPlatform(base.Platform): + """NoCloud KVM test platform.""" + + platform_name = 'nocloud-kvm' + + def get_image(self, img_conf): + """Get image using specified image configuration. + + @param img_conf: configuration for image + @return_value: cloud_tests.images instance + """ + (url, path) = s_util.path_from_mirror_url(img_conf['mirror_url'], None) + + filter = filters.get_filters(['arch=%s' % c_util.get_architecture(), + 'release=%s' % img_conf['release'], + 'ftype=disk1.img']) + mirror_config = {'filters': filter, + 'keep_items': False, + 'max_items': 1, + 'checksumming_reader': True, + 'item_download': True + } + + def policy(content, path): + return s_util.read_signed(content, keyring=img_conf['keyring']) + + smirror = mirrors.UrlMirrorReader(url, policy=policy) + tstore = objectstores.FileStore(img_conf['mirror_dir']) + tmirror = mirrors.ObjectFilterMirror(config=mirror_config, + objectstore=tstore) + tmirror.sync(smirror, path) + + search_d = os.path.join(img_conf['mirror_dir'], '**', + img_conf['release'], '**', '*.img') + + images = [] + for fname in glob.iglob(search_d, recursive=True): + images.append(fname) + + if len(images) != 1: + raise Exception('No unique images found') + + image = nocloud_kvm_image.NoCloudKVMImage(self, img_conf, images[0]) + if img_conf.get('override_templates', False): + image.update_templates(self.config.get('template_overrides', {}), + self.config.get('template_files', {})) + return image + + def create_image(self, properties, config, features, + src_img_path, image_desc=None, use_desc=None, + user_data=None, meta_data=None): + """Create an image + + @param src_img_path: image path to launch from + @param properties: image properties + @param config: image configuration + @param features: image features + @param image_desc: description of image being launched + @param use_desc: description of container's use + @return_value: cloud_tests.instances instance + """ + name = util.gen_instance_name(image_desc=image_desc, use_desc=use_desc) + img_path = os.path.join(self.config['data_dir'], name + '.qcow2') + c_util.subp(['qemu-img', 'create', '-f', 'qcow2', + '-b', src_img_path, img_path]) + + return nocloud_kvm_instance.NoCloudKVMInstance(self, img_path, + properties, config, + features, user_data, + meta_data) + +# vi: ts=4 expandtab -- cgit v1.2.3