diff --git a/salt/modules/virt.py b/salt/modules/virt.py index f670703aa667..8f1426827374 100644 --- a/salt/modules/virt.py +++ b/salt/modules/virt.py @@ -458,7 +458,7 @@ def _get_disks(dom): if driver is not None and driver.get('type') == 'qcow2': try: stdout = subprocess.Popen( - ['qemu-img', 'info', '--output', 'json', '--backing-chain', disk['file']], + ['qemu-img', 'info', '-U', '--output', 'json', '--backing-chain', disk['file']], shell=False, stdout=subprocess.PIPE).communicate()[0] qemu_output = salt.utils.stringutils.to_str(stdout) diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py index 2c01fa1c954c..333df1d23a49 100644 --- a/tests/unit/modules/test_virt.py +++ b/tests/unit/modules/test_virt.py @@ -62,15 +62,16 @@ def setup_loader_modules(self): self.addCleanup(delattr, self, 'mock_libvirt') self.addCleanup(delattr, self, 'mock_conn') self.addCleanup(delattr, self, 'mock_popen') - mock_subprocess = MagicMock() - mock_subprocess.Popen.return_value = self.mock_popen # pylint: disable=no-member + self.mock_subprocess = MagicMock() + self.mock_subprocess.return_value = self.mock_subprocess # pylint: disable=no-member + self.mock_subprocess.Popen.return_value = self.mock_popen # pylint: disable=no-member loader_globals = { '__salt__': { 'config.get': config.get, 'config.option': config.option, }, 'libvirt': self.mock_libvirt, - 'subprocess': mock_subprocess + 'subprocess': self.mock_subprocess } return {virt: loader_globals, config: loader_globals} @@ -84,7 +85,9 @@ def set_mock_vm(self, name, xml): mock_domain.XMLDesc.return_value = xml # pylint: disable=no-member # Return state as shutdown - mock_domain.info.return_value = [4, 0, 0, 0] # pylint: disable=no-member + mock_domain.info.return_value = [4, 2048 * 1024, 1024 * 1024, 2, 1234] # pylint: disable=no-member + mock_domain.ID.return_value = 1 + mock_domain.name.return_value = name return mock_domain def test_disk_profile_merge(self): @@ -1397,49 +1400,6 @@ def test_mixed_dict_and_list_as_profile_objects(self): re.match('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$', interface_attrs['mac'], re.I)) - def test_get_graphics(self): - ''' - Test virt.get_graphics() - ''' - xml = ''' - test-vm - - - - - - - ''' - self.set_mock_vm("test-vm", xml) - - graphics = virt.get_graphics('test-vm') - self.assertEqual('vnc', graphics['type']) - self.assertEqual('5900', graphics['port']) - self.assertEqual('0.0.0.0', graphics['listen']) - - def test_get_nics(self): - ''' - Test virt.get_nics() - ''' - xml = ''' - test-vm - - - - - -
- - - - ''' - self.set_mock_vm("test-vm", xml) - - nics = virt.get_nics('test-vm') - nic = nics[list(nics)[0]] - self.assertEqual('bridge', nic['type']) - self.assertEqual('ac:de:48:b6:8b:59', nic['mac']) - def test_get_xml(self): ''' Test virt.get_xml() @@ -1578,77 +1538,6 @@ def test_parse_qemu_img_info(self): ], }, virt._parse_qemu_img_info(qemu_infos)) - def test_get_disks(self): - ''' - Test virt.get_disks() - ''' - xml = ''' - test-vm - - - - - - - - - - - - - - - ''' - self.set_mock_vm("test-vm", xml) - - qemu_infos = '''[{ - "virtual-size": 25769803776, - "filename": "/disks/test.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/disks/mybacking.qcow2", - "backing-filename": "mybacking.qcow2", - "dirty-flag": false - }, - { - "virtual-size": 25769803776, - "filename": "/disks/mybacking.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 393744384, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }]''' - - self.mock_popen.communicate.return_value = [qemu_infos] # pylint: disable=no-member - disks = virt.get_disks('test-vm') - disk = disks.get('vda') - self.assertEqual('/disks/test.qcow2', disk['file']) - self.assertEqual('disk', disk['type']) - self.assertEqual('/disks/mybacking.qcow2', disk['backing file']['file']) - cdrom = disks.get('hda') - self.assertEqual('/disks/test-cdrom.iso', cdrom['file']) - self.assertEqual('cdrom', cdrom['type']) - self.assertFalse('backing file' in cdrom.keys()) - @patch('salt.modules.virt.stop', return_value=True) @patch('salt.modules.virt.undefine') @patch('os.remove') @@ -2693,3 +2582,132 @@ def test_pool_delete(self): # Shouldn't be called with another parameter so far since those are not implemented # and thus throwing exceptions. mock_pool.delete.assert_called_once_with(self.mock_libvirt.VIR_STORAGE_POOL_DELETE_NORMAL) + + def test_full_info(self): + ''' + Test virt.full_info + ''' + xml = ''' + 28deee33-4859-4f23-891c-ee239cffec94 + test-vm + destroy + restart + destroy + + + + + + + + + + + + + + + + +
+ + + + + + + ''' + self.set_mock_vm("test-vm", xml) + + qemu_infos = '''[{ + "virtual-size": 25769803776, + "filename": "/disks/test.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 217088, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/disks/mybacking.qcow2", + "backing-filename": "mybacking.qcow2", + "dirty-flag": false + }, + { + "virtual-size": 25769803776, + "filename": "/disks/mybacking.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 393744384, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false + }]''' + + self.mock_popen.communicate.return_value = [qemu_infos] # pylint: disable=no-member + + self.mock_conn.getInfo = MagicMock(return_value=['x86_64', 4096, 8, 2712, 1, 2, 4, 2]) + + actual = virt.full_info() + + # Check that qemu-img was called with the proper parameters + qemu_img_call = [call for call in self.mock_subprocess.Popen.call_args_list if 'qemu-img' in call[0][0]][0] + self.assertIn('info', qemu_img_call[0][0]) + self.assertIn('-U', qemu_img_call[0][0]) + + # Test the hypervisor infos + self.assertEqual(2816, actual['freemem']) + self.assertEqual(6, actual['freecpu']) + self.assertEqual(4, actual['node_info']['cpucores']) + self.assertEqual(2712, actual['node_info']['cpumhz']) + self.assertEqual('x86_64', actual['node_info']['cpumodel']) + self.assertEqual(8, actual['node_info']['cpus']) + self.assertEqual(2, actual['node_info']['cputhreads']) + self.assertEqual(1, actual['node_info']['numanodes']) + self.assertEqual(4096, actual['node_info']['phymemory']) + self.assertEqual(2, actual['node_info']['sockets']) + + # Test the vm_info output: + self.assertEqual(2, actual['vm_info']['test-vm']['cpu']) + self.assertEqual(1234, actual['vm_info']['test-vm']['cputime']) + self.assertEqual(1024 * 1024, actual['vm_info']['test-vm']['mem']) + self.assertEqual(2048 * 1024, actual['vm_info']['test-vm']['maxMem']) + self.assertEqual('shutdown', actual['vm_info']['test-vm']['state']) + self.assertEqual('28deee33-4859-4f23-891c-ee239cffec94', actual['vm_info']['test-vm']['uuid']) + self.assertEqual('destroy', actual['vm_info']['test-vm']['on_crash']) + self.assertEqual('restart', actual['vm_info']['test-vm']['on_reboot']) + self.assertEqual('destroy', actual['vm_info']['test-vm']['on_poweroff']) + + # Test the nics + nic = actual['vm_info']['test-vm']['nics']['ac:de:48:b6:8b:59'] + self.assertEqual('bridge', nic['type']) + self.assertEqual('ac:de:48:b6:8b:59', nic['mac']) + + # Test the disks + disks = actual['vm_info']['test-vm']['disks'] + disk = disks.get('vda') + self.assertEqual('/disks/test.qcow2', disk['file']) + self.assertEqual('disk', disk['type']) + self.assertEqual('/disks/mybacking.qcow2', disk['backing file']['file']) + cdrom = disks.get('hda') + self.assertEqual('/disks/test-cdrom.iso', cdrom['file']) + self.assertEqual('cdrom', cdrom['type']) + self.assertFalse('backing file' in cdrom.keys()) + + # Test the graphics + graphics = actual['vm_info']['test-vm']['graphics'] + self.assertEqual('vnc', graphics['type']) + self.assertEqual('5900', graphics['port']) + self.assertEqual('0.0.0.0', graphics['listen'])