[PATCH v3] [Kimchi] Replace backing image by clone when using template based on existing img

- This commit replaces the current backing image to a complete clone when using a template based on an existing template. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- model/templates.py | 26 +++++++++++++++++++++++++- tests/test_rest.py | 19 +++++++++++++++---- vmtemplate.py | 8 -------- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/model/templates.py b/model/templates.py index a02099c..1cdb99b 100644 --- a/model/templates.py +++ b/model/templates.py @@ -23,6 +23,7 @@ import magic import os import platform import psutil +import shutil import stat import urlparse @@ -378,7 +379,30 @@ class LibvirtVMTemplate(VMTemplate): for v in vol_list: pool = self._get_storage_pool(v['pool']) # outgoing text to libvirt, encode('utf-8') - pool.createXML(v['xml'].encode('utf-8'), 0) + if 'base' in v and 'path' in v['base']: + conn = self.conn.get() + try: + volume_base = conn.storageVolLookupByPath( + v['base']['path']) + + except libvirt.libvirtError as e: + image_dir = os.path.dirname(v['base']['path']) + image_name = os.path.basename(v['base']['path']) + volume_dir = os.path.dirname(v['path']) + + if image_dir != volume_dir: + shutil.copy(v['base']['path'], volume_dir) + + pool.refresh() + + volume_base = pool.storageVolLookupByName(image_name) + + pool.createXMLFrom(v['xml'].encode('utf-8'), + volume_base, + 0) + else: + pool.createXML(v['xml'].encode('utf-8'), 0) + except libvirt.libvirtError as e: raise OperationFailed("KCHVMSTOR0008E", {'error': e.message}) return vol_list diff --git a/tests/test_rest.py b/tests/test_rest.py index a009ed3..997611e 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1030,9 +1030,13 @@ class RestTests(unittest.TestCase): self.assertIn(u"KCHVM0012E", resp['reason']) def test_create_vm_with_img_based_template(self): + self._create_pool('pool-imgbs') + self.request('/plugins/kimchi/storagepools/pool-imgbs/activate', '{}', + 'POST') + resp = json.loads( self.request( - '/plugins/kimchi/storagepools/default-pool/storagevolumes' + '/plugins/kimchi/storagepools/pool-imgbs/storagevolumes' ).read() ) self.assertEquals(0, len(resp)) @@ -1040,8 +1044,15 @@ class RestTests(unittest.TestCase): # Create a Template mock_base = '/tmp/mock.img' os.system("qemu-img create -f qcow2 %s 10M" % mock_base) - req = json.dumps({'name': 'test', 'source_media': mock_base}) - resp = self.request('/plugins/kimchi/templates', req, 'POST') + + tmpl_params = { + 'name': 'test', 'source_media': mock_base, + 'disks': [{'pool': + {'name': '/plugins/kimchi/storagepools/pool-imgbs'}}]} + + resp = self.request('/plugins/kimchi/templates', + json.dumps(tmpl_params), + 'POST') self.assertEquals(201, resp.status) req = json.dumps({'template': '/plugins/kimchi/templates/test'}) @@ -1053,7 +1064,7 @@ class RestTests(unittest.TestCase): # Test storage volume created with backing store of base file resp = json.loads( self.request( - '/plugins/kimchi/storagepools/default-pool/storagevolumes' + '/plugins/kimchi/storagepools/pool-imgbs/storagevolumes' ).read() ) self.assertEquals(1, len(resp)) diff --git a/vmtemplate.py b/vmtemplate.py index a223beb..4ce5d19 100644 --- a/vmtemplate.py +++ b/vmtemplate.py @@ -264,14 +264,6 @@ class VMTemplate(object): v_tree.append(E.capacity(str(info['capacity']), unit='G')) target_fmt = info['format'] - if 'base' in d: - # target must be qcow2 in order to use a backing file - target_fmt = 'qcow2' - - v_tree.append(E.backingStore( - E.path(info['base']['path']), - E.format(type=info['base']['format']))) - target = E.target( E.format(type=target_fmt), E.path(info['path'])) v_tree.append(target) -- 1.9.1

CANCELLED This approach didn't work as expected, I'll work on another solution to improve the backing image instead. On 19-04-2016 00:12, Jose Ricardo Ziviani wrote:
- This commit replaces the current backing image to a complete clone when using a template based on an existing template.
Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- model/templates.py | 26 +++++++++++++++++++++++++- tests/test_rest.py | 19 +++++++++++++++---- vmtemplate.py | 8 -------- 3 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/model/templates.py b/model/templates.py index a02099c..1cdb99b 100644 --- a/model/templates.py +++ b/model/templates.py @@ -23,6 +23,7 @@ import magic import os import platform import psutil +import shutil import stat import urlparse
@@ -378,7 +379,30 @@ class LibvirtVMTemplate(VMTemplate): for v in vol_list: pool = self._get_storage_pool(v['pool']) # outgoing text to libvirt, encode('utf-8') - pool.createXML(v['xml'].encode('utf-8'), 0) + if 'base' in v and 'path' in v['base']: + conn = self.conn.get() + try: + volume_base = conn.storageVolLookupByPath( + v['base']['path']) + + except libvirt.libvirtError as e: + image_dir = os.path.dirname(v['base']['path']) + image_name = os.path.basename(v['base']['path']) + volume_dir = os.path.dirname(v['path']) + + if image_dir != volume_dir: + shutil.copy(v['base']['path'], volume_dir) + + pool.refresh() + + volume_base = pool.storageVolLookupByName(image_name) + + pool.createXMLFrom(v['xml'].encode('utf-8'), + volume_base, + 0) + else: + pool.createXML(v['xml'].encode('utf-8'), 0) + except libvirt.libvirtError as e: raise OperationFailed("KCHVMSTOR0008E", {'error': e.message}) return vol_list diff --git a/tests/test_rest.py b/tests/test_rest.py index a009ed3..997611e 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1030,9 +1030,13 @@ class RestTests(unittest.TestCase): self.assertIn(u"KCHVM0012E", resp['reason'])
def test_create_vm_with_img_based_template(self): + self._create_pool('pool-imgbs') + self.request('/plugins/kimchi/storagepools/pool-imgbs/activate', '{}', + 'POST') + resp = json.loads( self.request( - '/plugins/kimchi/storagepools/default-pool/storagevolumes' + '/plugins/kimchi/storagepools/pool-imgbs/storagevolumes' ).read() ) self.assertEquals(0, len(resp)) @@ -1040,8 +1044,15 @@ class RestTests(unittest.TestCase): # Create a Template mock_base = '/tmp/mock.img' os.system("qemu-img create -f qcow2 %s 10M" % mock_base) - req = json.dumps({'name': 'test', 'source_media': mock_base}) - resp = self.request('/plugins/kimchi/templates', req, 'POST') + + tmpl_params = { + 'name': 'test', 'source_media': mock_base, + 'disks': [{'pool': + {'name': '/plugins/kimchi/storagepools/pool-imgbs'}}]} + + resp = self.request('/plugins/kimchi/templates', + json.dumps(tmpl_params), + 'POST') self.assertEquals(201, resp.status)
req = json.dumps({'template': '/plugins/kimchi/templates/test'}) @@ -1053,7 +1064,7 @@ class RestTests(unittest.TestCase): # Test storage volume created with backing store of base file resp = json.loads( self.request( - '/plugins/kimchi/storagepools/default-pool/storagevolumes' + '/plugins/kimchi/storagepools/pool-imgbs/storagevolumes' ).read() ) self.assertEquals(1, len(resp)) diff --git a/vmtemplate.py b/vmtemplate.py index a223beb..4ce5d19 100644 --- a/vmtemplate.py +++ b/vmtemplate.py @@ -264,14 +264,6 @@ class VMTemplate(object): v_tree.append(E.capacity(str(info['capacity']), unit='G'))
target_fmt = info['format'] - if 'base' in d: - # target must be qcow2 in order to use a backing file - target_fmt = 'qcow2' - - v_tree.append(E.backingStore( - E.path(info['base']['path']), - E.format(type=info['base']['format']))) - target = E.target( E.format(type=target_fmt), E.path(info['path'])) v_tree.append(target)
-- Jose Ricardo Ziviani ----------------------------- Software Engineer Linux Technology Center - IBM
participants (1)
-
Jose Ricardo Ziviani