File virt-handle-whitespaces-in-vm-names.patch of Package salt

From fbad82a38b4460260726cb3b9456cad7986eb4cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Wed, 13 Mar 2019 09:43:51 +0100
Subject: [PATCH] virt: handle whitespaces in VM names

The disk creation code is now ready to handle whitespaces in virtual
machine name.
---
 salt/modules/virt.py            |  8 +++---
 tests/unit/modules/test_virt.py | 46 ++++++++++++++++-----------------
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/salt/modules/virt.py b/salt/modules/virt.py
index 423016cd90..d160f0905f 100644
--- a/salt/modules/virt.py
+++ b/salt/modules/virt.py
@@ -760,14 +760,14 @@ def _qemu_image_create(disk, create_overlay=False, saltenv='base'):
 
         qcow2 = False
         if salt.utils.path.which('qemu-img'):
-            res = __salt__['cmd.run']('qemu-img info {}'.format(sfn))
+            res = __salt__['cmd.run']('qemu-img info "{}"'.format(sfn))
             imageinfo = salt.utils.yaml.safe_load(res)
             qcow2 = imageinfo['file format'] == 'qcow2'
         try:
             if create_overlay and qcow2:
                 log.info('Cloning qcow2 image %s using copy on write', sfn)
                 __salt__['cmd.run'](
-                    'qemu-img create -f qcow2 -o backing_file={0} {1}'
+                    'qemu-img create -f qcow2 -o backing_file="{0}" "{1}"'
                     .format(sfn, img_dest).split())
             else:
                 log.debug('Copying %s to %s', sfn, img_dest)
@@ -778,7 +778,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv='base'):
             if disk_size and qcow2:
                 log.debug('Resize qcow2 image to %sM', disk_size)
                 __salt__['cmd.run'](
-                    'qemu-img resize {0} {1}M'
+                    'qemu-img resize "{0}" {1}M'
                     .format(img_dest, disk_size)
                 )
 
@@ -800,7 +800,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv='base'):
             if disk_size:
                 log.debug('Create empty image with size %sM', disk_size)
                 __salt__['cmd.run'](
-                    'qemu-img create -f {0} {1} {2}M'
+                    'qemu-img create -f {0} "{1}" {2}M'
                     .format(disk.get('format', 'qcow2'), img_dest, disk_size)
                 )
             else:
diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py
index bbe8d813d7..cc62b67918 100644
--- a/tests/unit/modules/test_virt.py
+++ b/tests/unit/modules/test_virt.py
@@ -1106,7 +1106,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
             with patch.dict(virt.__salt__, {'cmd.run': mock_run}):  # pylint: disable=no-member
 
                 # Ensure the init() function allows creating VM without NIC and disk
-                virt.init('testvm',
+                virt.init('test vm',
                           2,
                           1234,
                           nic=None,
@@ -1120,7 +1120,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 # Test case creating disks
                 defineMock.reset_mock()
                 mock_run.reset_mock()
-                virt.init('testvm',
+                virt.init('test vm',
                           2,
                           1234,
                           nic=None,
@@ -1134,10 +1134,10 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 definition = ET.fromstring(defineMock.call_args_list[0][0][0])
                 disk_sources = [disk.find('source').get('file') if disk.find('source') is not None else None
                                 for disk in definition.findall('./devices/disk')]
-                expected_disk_path = os.path.join(root_dir, 'testvm_system.qcow2')
+                expected_disk_path = os.path.join(root_dir, 'test vm_system.qcow2')
                 self.assertEqual(disk_sources, [expected_disk_path, None])
                 self.assertEqual(mock_run.call_args[0][0],
-                                 'qemu-img create -f qcow2 {0} 10240M'.format(expected_disk_path))
+                                 'qemu-img create -f qcow2 "{0}" 10240M'.format(expected_disk_path))
                 self.assertEqual(mock_chmod.call_args[0][0], expected_disk_path)
 
     def test_update(self):
@@ -1147,7 +1147,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         root_dir = os.path.join(salt.syspaths.ROOT_DIR, 'srv', 'salt-images')
         xml = '''
             <domain type='kvm' id='7'>
-              <name>myvm</name>
+              <name>my vm</name>
               <memory unit='KiB'>1048576</memory>
               <currentMemory unit='KiB'>1048576</currentMemory>
               <vcpu placement='auto'>1</vcpu>
@@ -1157,7 +1157,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
               <devices>
                 <disk type='file' device='disk'>
                   <driver name='qemu' type='qcow2'/>
-                  <source file='{0}{1}myvm_system.qcow2'/>
+                  <source file='{0}{1}my vm_system.qcow2'/>
                   <backingStore/>
                   <target dev='vda' bus='virtio'/>
                   <alias name='virtio-disk0'/>
@@ -1165,7 +1165,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 </disk>
                 <disk type='file' device='disk'>
                   <driver name='qemu' type='qcow2'/>
-                  <source file='{0}{1}myvm_data.qcow2'/>
+                  <source file='{0}{1}my vm_data.qcow2'/>
                   <backingStore/>
                   <target dev='vdb' bus='virtio'/>
                   <alias name='virtio-disk1'/>
@@ -1198,7 +1198,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
               </devices>
             </domain>
         '''.format(root_dir, os.sep)
-        domain_mock = self.set_mock_vm('myvm', xml)
+        domain_mock = self.set_mock_vm('my vm', xml)
         domain_mock.OSType = MagicMock(return_value='hvm')
         define_mock = MagicMock(return_value=True)
         self.mock_conn.defineXML = define_mock
@@ -1211,7 +1211,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'cpu': True,
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', cpu=2))
+            }, virt.update('my vm', cpu=2))
         setxml = ET.fromstring(define_mock.call_args[0][0])
         self.assertEqual(setxml.find('vcpu').text, '2')
         self.assertEqual(setvcpus_mock.call_args[0][0], 2)
@@ -1225,7 +1225,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'mem': True,
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', mem=2048))
+            }, virt.update('my vm', mem=2048))
         setxml = ET.fromstring(define_mock.call_args[0][0])
         self.assertEqual(setxml.find('memory').text, '2048')
         self.assertEqual(setxml.find('memory').get('unit'), 'MiB')
@@ -1240,21 +1240,21 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         mock_run = MagicMock()
         with patch.dict(os.__dict__, {'chmod': mock_chmod, 'makedirs': MagicMock()}):  # pylint: disable=no-member
             with patch.dict(virt.__salt__, {'cmd.run': mock_run}):  # pylint: disable=no-member
-                ret = virt.update('myvm', disk_profile='default', disks=[
+                ret = virt.update('my vm', disk_profile='default', disks=[
                     {'name': 'cddrive', 'device': 'cdrom', 'source_file': None, 'model': 'ide'},
                     {'name': 'added', 'size': 2048}])
                 added_disk_path = os.path.join(
-                        virt.__salt__['config.get']('virt:images'), 'myvm_added.qcow2')  # pylint: disable=no-member
+                        virt.__salt__['config.get']('virt:images'), 'my vm_added.qcow2')  # pylint: disable=no-member
                 self.assertEqual(mock_run.call_args[0][0],
-                                 'qemu-img create -f qcow2 {0} 2048M'.format(added_disk_path))
+                                 'qemu-img create -f qcow2 "{0}" 2048M'.format(added_disk_path))
                 self.assertEqual(mock_chmod.call_args[0][0], added_disk_path)
                 self.assertListEqual(
-                    [None, os.path.join(root_dir, 'myvm_added.qcow2')],
+                    [None, os.path.join(root_dir, 'my vm_added.qcow2')],
                     [ET.fromstring(disk).find('source').get('file') if str(disk).find('<source') > -1 else None
                      for disk in ret['disk']['attached']])
 
                 self.assertListEqual(
-                    [os.path.join(root_dir, 'myvm_data.qcow2')],
+                    [os.path.join(root_dir, 'my vm_data.qcow2')],
                     [ET.fromstring(disk).find('source').get('file') for disk in ret['disk']['detached']])
                 self.assertEqual(devattach_mock.call_count, 2)
                 devdetach_mock.assert_called_once()
@@ -1271,7 +1271,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         devattach_mock.reset_mock()
         devdetach_mock.reset_mock()
         with patch.dict(salt.modules.config.__opts__, mock_config):  # pylint: disable=no-member
-            ret = virt.update('myvm', nic_profile='myprofile',
+            ret = virt.update('my vm', nic_profile='myprofile',
                               interfaces=[{'name': 'eth0', 'type': 'network', 'source': 'default',
                                            'mac': '52:54:00:39:02:b1'},
                                           {'name': 'eth1', 'type': 'network', 'source': 'newnet'}])
@@ -1285,7 +1285,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         # Remove nics case
         devattach_mock.reset_mock()
         devdetach_mock.reset_mock()
-        ret = virt.update('myvm', nic_profile=None, interfaces=[])
+        ret = virt.update('my vm', nic_profile=None, interfaces=[])
         self.assertEqual([], ret['interface']['attached'])
         self.assertEqual(2, len(ret['interface']['detached']))
         devattach_mock.assert_not_called()
@@ -1294,7 +1294,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         # Remove disks case (yeah, it surely is silly)
         devattach_mock.reset_mock()
         devdetach_mock.reset_mock()
-        ret = virt.update('myvm', disk_profile=None, disks=[])
+        ret = virt.update('my vm', disk_profile=None, disks=[])
         self.assertEqual([], ret['disk']['attached'])
         self.assertEqual(2, len(ret['disk']['detached']))
         devattach_mock.assert_not_called()
@@ -1305,7 +1305,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'definition': True,
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', graphics={'type': 'vnc'}))
+            }, virt.update('my vm', graphics={'type': 'vnc'}))
         setxml = ET.fromstring(define_mock.call_args[0][0])
         self.assertEqual('vnc', setxml.find('devices/graphics').get('type'))
 
@@ -1314,7 +1314,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'definition': False,
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', cpu=1, mem=1024,
+            }, virt.update('my vm', cpu=1, mem=1024,
                            disk_profile='default', disks=[{'name': 'data', 'size': 2048}],
                            nic_profile='myprofile',
                            interfaces=[{'name': 'eth0', 'type': 'network', 'source': 'default',
@@ -1328,7 +1328,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
         self.mock_conn.defineXML.side_effect = self.mock_libvirt.libvirtError("Test error")
         setmem_mock.reset_mock()
         with self.assertRaises(self.mock_libvirt.libvirtError):
-            virt.update('myvm', mem=2048)
+            virt.update('my vm', mem=2048)
 
         # Failed single update failure case
         self.mock_conn.defineXML = MagicMock(return_value=True)
@@ -1338,7 +1338,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'errors': ['Failed to live change memory'],
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', mem=2048))
+            }, virt.update('my vm', mem=2048))
 
         # Failed multiple updates failure case
         self.assertEqual({
@@ -1347,7 +1347,7 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
                 'cpu': True,
                 'disk': {'attached': [], 'detached': []},
                 'interface': {'attached': [], 'detached': []}
-            }, virt.update('myvm', cpu=4, mem=2048))
+            }, virt.update('my vm', cpu=4, mem=2048))
 
     def test_mixed_dict_and_list_as_profile_objects(self):
         '''
-- 
2.21.0