← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~smoser/cloud-init:fix/cii-kvmimage-preserve-original into cloud-init:master

 

Scott Moser has proposed merging ~smoser/cloud-init:fix/cii-kvmimage-preserve-original into cloud-init:master.

Commit message:
tests: NoCloudKVMImage do not modify the original local cache image.

The NoCloudKVMImage.execute() would modify the image in /srv/citest
that meant that after the first time you ran a test, the image was
dirty.

The change here is to make the image operate on a qcow backed image.

Also modify Snapshot to then copy the qcow rather
than creating another chained qcow.  The reason being that the image
might go away but the snaphot stick around.

Also 
 * drop use of 'override_templates' which was only relevant to LXD.
 * NoCloudKVM.create_image() returned an instance before
   now it has create_instance which creates an instance.
 * NoCloudKVMInstance has a 'disk' attribute separate from 'name'



Requested reviews:
  cloud-init commiters (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/334147
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~smoser/cloud-init:fix/cii-kvmimage-preserve-original into cloud-init:master.
diff --git a/tests/cloud_tests/images/nocloudkvm.py b/tests/cloud_tests/images/nocloudkvm.py
index 1e7962c..8a6b8a5 100644
--- a/tests/cloud_tests/images/nocloudkvm.py
+++ b/tests/cloud_tests/images/nocloudkvm.py
@@ -4,6 +4,10 @@
 
 from cloudinit import util as c_util
 
+import os
+import shutil
+import tempfile
+
 from tests.cloud_tests.images import base
 from tests.cloud_tests.snapshots import nocloudkvm as nocloud_kvm_snapshot
 
@@ -13,7 +17,7 @@ class NoCloudKVMImage(base.Image):
 
     platform_name = "nocloud-kvm"
 
-    def __init__(self, platform, config, img_path):
+    def __init__(self, platform, config, orig_img_path):
         """Set up image.
 
         @param platform: platform object
@@ -21,7 +25,13 @@ class NoCloudKVMImage(base.Image):
         @param img_path: path to the image
         """
         self.modified = False
-        self._img_path = img_path
+        self._workd = tempfile.mkdtemp(prefix='cloud_KvmImage')
+        self._orig_img_path = orig_img_path
+        self._img_path = os.path.join(self._workd,
+                                      os.path.basename(self._orig_img_path))
+
+        c_util.subp(['qemu-img', 'create', '-f', 'qcow2',
+                    '-b', orig_img_path, self._img_path])
 
         super(NoCloudKVMImage, self).__init__(platform, config)
 
@@ -61,13 +71,9 @@ class NoCloudKVMImage(base.Image):
         if not self._img_path:
             raise RuntimeError()
 
-        instance = self.platform.create_image(
-            self.properties, self.config, self.features,
-            self._img_path, image_desc=str(self), use_desc='snapshot')
-
         return nocloud_kvm_snapshot.NoCloudKVMSnapshot(
             self.platform, self.properties, self.config,
-            self.features, instance)
+            self.features, self._img_path)
 
     def destroy(self):
         """Unset path to signal image is no longer used.
@@ -77,6 +83,8 @@ class NoCloudKVMImage(base.Image):
         framework decide whether to keep or destroy everything.
         """
         self._img_path = None
+        shutil.rmtree(self._workd)
+
         super(NoCloudKVMImage, self).destroy()
 
 # vi: ts=4 expandtab
diff --git a/tests/cloud_tests/instances/nocloudkvm.py b/tests/cloud_tests/instances/nocloudkvm.py
index cc82580..bc06a79 100644
--- a/tests/cloud_tests/instances/nocloudkvm.py
+++ b/tests/cloud_tests/instances/nocloudkvm.py
@@ -25,12 +25,13 @@ class NoCloudKVMInstance(base.Instance):
     platform_name = "nocloud-kvm"
     _ssh_client = None
 
-    def __init__(self, platform, name, properties, config, features,
-                 user_data, meta_data):
+    def __init__(self, platform, name, image_path, properties, config,
+                 features, user_data, meta_data):
         """Set up instance.
 
         @param platform: platform object
         @param name: image path
+        @param image_path: path to disk image to boot.
         @param properties: dictionary of properties
         @param config: dictionary of configuration values
         @param features: dictionary of supported feature flags
@@ -43,6 +44,7 @@ class NoCloudKVMInstance(base.Instance):
         self.pid = None
         self.pid_file = None
         self.console_file = None
+        self.disk = image_path
 
         super(NoCloudKVMInstance, self).__init__(
             platform, name, properties, config, features)
@@ -145,7 +147,7 @@ class NoCloudKVMInstance(base.Instance):
         self.ssh_port = self.get_free_port()
 
         cmd = ['./tools/xkvm',
-               '--disk', '%s,cache=unsafe' % self.name,
+               '--disk', '%s,cache=unsafe' % self.disk,
                '--disk', '%s,cache=unsafe' % seed,
                '--netdev', ','.join(['user',
                                      'hostfwd=tcp::%s-:22' % self.ssh_port,
diff --git a/tests/cloud_tests/platforms/nocloudkvm.py b/tests/cloud_tests/platforms/nocloudkvm.py
index f1f8187..12ffae3 100644
--- a/tests/cloud_tests/platforms/nocloudkvm.py
+++ b/tests/cloud_tests/platforms/nocloudkvm.py
@@ -58,16 +58,14 @@ class NoCloudKVMPlatform(base.Platform):
         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', {}))
+        image = nocloud_kvm_image.NoCloudKVMImage(self, img_conf,
+                                                  sorted(images)[0])
         return image
 
-    def create_image(self, properties, config, features,
+    def create_instance(self, properties, config, features,
                      src_img_path, image_desc=None, use_desc=None,
                      user_data=None, meta_data=None):
-        """Create an image
+        """Create an instance
 
         @param src_img_path: image path to launch from
         @param properties: image properties
@@ -82,7 +80,7 @@ class NoCloudKVMPlatform(base.Platform):
         c_util.subp(['qemu-img', 'create', '-f', 'qcow2',
                     '-b', src_img_path, img_path])
 
-        return nocloud_kvm_instance.NoCloudKVMInstance(self, img_path,
+        return nocloud_kvm_instance.NoCloudKVMInstance(self, name, img_path,
                                                        properties, config,
                                                        features, user_data,
                                                        meta_data)
diff --git a/tests/cloud_tests/snapshots/nocloudkvm.py b/tests/cloud_tests/snapshots/nocloudkvm.py
index 0999834..5872fb5 100644
--- a/tests/cloud_tests/snapshots/nocloudkvm.py
+++ b/tests/cloud_tests/snapshots/nocloudkvm.py
@@ -2,6 +2,8 @@
 
 """Base NoCloud KVM snapshot."""
 import os
+import shutil
+import tempfile
 
 from tests.cloud_tests.snapshots import base
 
@@ -11,16 +13,19 @@ class NoCloudKVMSnapshot(base.Snapshot):
 
     platform_name = "nocloud-kvm"
 
-    def __init__(self, platform, properties, config, features,
-                 instance):
+    def __init__(self, platform, properties, config, features, image_path):
         """Set up snapshot.
 
         @param platform: platform object
         @param properties: image properties
         @param config: image config
         @param features: supported feature flags
+        @param image_path: image file to snapshot.
         """
-        self.instance = instance
+        self._workd = tempfile.mkdtemp(prefix='cloud_KvmImage')
+        snapshot = os.path.join(self._workd, 'snapshot')
+        shutil.copyfile(image_path, snapshot)
+        self._image_path = snapshot
 
         super(NoCloudKVMSnapshot, self).__init__(
             platform, properties, config, features)
@@ -40,9 +45,9 @@ class NoCloudKVMSnapshot(base.Snapshot):
                                 self.platform.config['public_key'])
         user_data = self.inject_ssh_key(user_data, key_file)
 
-        instance = self.platform.create_image(
+        instance = self.platform.create_instance(
             self.properties, self.config, self.features,
-            self.instance.name, image_desc=str(self), use_desc=use_desc,
+            self._image_path, image_desc=str(self), use_desc=use_desc,
             user_data=user_data, meta_data=meta_data)
 
         if start:
@@ -68,7 +73,7 @@ class NoCloudKVMSnapshot(base.Snapshot):
 
     def destroy(self):
         """Clean up snapshot data."""
-        self.instance.destroy()
+        shutil.rmtree(self._workd)
         super(NoCloudKVMSnapshot, self).destroy()
 
 # vi: ts=4 expandtab

Follow ups