]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Do not use qemu-img --backing-chain or --output=json
authorEric Harney <eharney@redhat.com>
Sat, 7 Sep 2013 03:26:46 +0000 (23:26 -0400)
committerEric Harney <eharney@redhat.com>
Mon, 16 Sep 2013 15:53:29 +0000 (11:53 -0400)
Initial code for GlusterFS snapshot support in Havana
used qemu-img arguments which are too new to run in many
environments.  Run qemu-img using only arguments which
will exist on older platforms.

Partial-Bug: #1224030
Change-Id: I5155dac492da67a951ede978c2c46a54c239eb04

cinder/tests/test_glusterfs.py
cinder/volume/drivers/glusterfs.py

index 0141c2501498c580ac9b93451b921cbfa1653a79..70ed9ce8c9e9845ae98f9479a58d95f6a56730f5 100644 (file)
@@ -808,7 +808,6 @@ class GlusterFsDriverTestCase(test.TestCase):
         """
         (mox, drv) = self._mox, self._driver
 
-        #volume = DumbVolume()
         volume = self._simple_volume()
 
         hashed = drv._get_hash_str(self.TEST_EXPORT1)
@@ -873,7 +872,8 @@ class GlusterFsDriverTestCase(test.TestCase):
                             'backing-filename': volume_file}]
 
         drv.get_active_image_from_info(volume).AndReturn(snap_file_2)
-        drv._get_backing_chain_for_path(snap_path_2).AndReturn(snap_path_chain)
+        drv._get_backing_chain_for_path(volume, snap_path_2).\
+            AndReturn(snap_path_chain)
 
         drv._read_info_file(info_path).AndReturn(info_file_dict)
 
@@ -1375,3 +1375,46 @@ class GlusterFsDriverTestCase(test.TestCase):
         self.assertRaises(exception.GlusterfsException,
                           drv.delete_snapshot,
                           snap_ref)
+
+    def test_get_backing_chain_for_path(self):
+        (mox, drv) = self._mox, self._driver
+
+        glusterfs.CONF.glusterfs_mount_point_base = self.TEST_MNT_POINT_BASE
+
+        volume = self._simple_volume()
+        vol_filename = volume['name']
+        vol_filename_2 = volume['name'] + '.asdfjkl'
+        vol_filename_3 = volume['name'] + 'qwertyuiop'
+        hashed = drv._get_hash_str(self.TEST_EXPORT1)
+        vol_dir = '%s/%s' % (self.TEST_MNT_POINT_BASE, hashed)
+        vol_path = '%s/%s' % (vol_dir, vol_filename)
+        vol_path_2 = '%s/%s' % (vol_dir, vol_filename_2)
+        vol_path_3 = '%s/%s' % (vol_dir, vol_filename_3)
+
+        mox.StubOutWithMock(drv, '_execute')
+        mox.StubOutWithMock(drv, '_local_volume_dir')
+
+        qemu_img_output_base = """image: %s
+        file format: qcow2
+        virtual size: 1.0G (1073741824 bytes)
+        disk size: 173K
+        """
+        qemu_img_output = qemu_img_output_base + 'backing file: %s\n'
+
+        qemu_img_output_1 = qemu_img_output % (vol_filename, vol_filename_2)
+        qemu_img_output_2 = qemu_img_output % (vol_filename_2, vol_filename_3)
+        qemu_img_output_3 = qemu_img_output_base % (vol_filename_3)
+
+        drv._local_volume_dir(volume).AndReturn(vol_dir)
+        drv._execute('qemu-img', 'info', vol_path).\
+            AndReturn((qemu_img_output_1, None))
+        drv._local_volume_dir(volume).AndReturn(vol_dir)
+        drv._execute('qemu-img', 'info', vol_path_2).\
+            AndReturn((qemu_img_output_2, None))
+        drv._local_volume_dir(volume).AndReturn(vol_dir)
+        drv._execute('qemu-img', 'info', vol_path_3).\
+            AndReturn((qemu_img_output_3, None))
+
+        mox.ReplayAll()
+
+        drv._get_backing_chain_for_path(volume, vol_path)
index 6f46d2f06f15417c6591e5716f7bc9190ab17fe1..6384a25d8cfdf6a43cbb01611ac5e0de7fd7a36f 100644 (file)
@@ -603,7 +603,8 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
             #  exist, not   |                | exist, being   |needs ptr update
             #  used here)   |                | committed down)|     if so)
 
-            backing_chain = self._get_backing_chain_for_path(active_file_path)
+            backing_chain = self._get_backing_chain_for_path(
+                snapshot['volume'], active_file_path)
             # This file is guaranteed to exist since we aren't operating on
             # the active file.
             higher_file = next((os.path.basename(f['filename'])
@@ -781,19 +782,43 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
                                    run_as_root=True)
         return self._get_file_format(out)
 
-    def _get_backing_chain_for_path(self, path):
-        """Returns dict containing backing-chain information."""
+    def _get_backing_chain_for_path(self, volume, path):
+        """Returns list of dicts containing backing-chain information.
 
-        # TODO(eharney): these args aren't available on el6.4's qemu-img
-        #  Need to rewrite
-        #  --backing-chain added in qemu 1.3.0
-        #  --output=json added in qemu 1.5.0
+        Includes 'filename', and 'backing-filename' for each
+        applicable entry.
 
-        (out, err) = self._execute('qemu-img', 'info',
-                                   '--backing-chain',
-                                   '--output=json',
-                                   path)
-        return json.loads(out)
+        Consider converting this to use --backing-chain and --output=json
+        when environment supports qemu-img 1.5.0.
+
+        :param volume: volume reference
+        :param path: path to image file at top of chain
+
+        """
+
+        output = []
+
+        (out, _err) = self._execute('qemu-img', 'info', path)
+        new_info = {}
+        new_info['filename'] = os.path.basename(path)
+        new_info['backing-filename'] = self._get_backing_file(out)
+
+        output.append(new_info)
+
+        while True:
+            filename = new_info['backing-filename']
+            path = os.path.join(self._local_volume_dir(volume), filename)
+            (out, _err) = self._execute('qemu-img', 'info', path)
+            backing_filename = self._get_backing_file(out)
+            if backing_filename is None:
+                break
+            new_info = {}
+            new_info['filename'] = filename
+            new_info['backing-filename'] = backing_filename
+
+            output.append(new_info)
+
+        return output
 
     def _get_file_format(self, output):
         for line in output.split('\n'):