diff --git a/nova/tests/unit/virt/hyperv/test_basevolumeutils.py b/nova/tests/unit/virt/hyperv/test_basevolumeutils.py
deleted file mode 100644
index 75c24afa1b..0000000000
--- a/nova/tests/unit/virt/hyperv/test_basevolumeutils.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-#
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import test
-from nova.virt.hyperv import basevolumeutils
-
-
-def _exception_thrower():
- raise Exception("Testing exception handling.")
-
-
-class BaseVolumeUtilsTestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V BaseVolumeUtils class."""
-
- _FAKE_COMPUTER_NAME = "fake_computer_name"
- _FAKE_DOMAIN_NAME = "fake_domain_name"
- _FAKE_INITIATOR_NAME = "fake_initiator_name"
- _FAKE_INITIATOR_IQN_NAME = "iqn.1991-05.com.microsoft:fake_computer_name"
- _FAKE_DISK_PATH = 'fake_path DeviceID="123\\\\2"'
- _FAKE_MOUNT_DEVICE = '/dev/fake/mount'
- _FAKE_DEVICE_NAME = '/dev/fake/path'
- _FAKE_SWAP = {'device_name': _FAKE_DISK_PATH}
-
- def setUp(self):
- self._volutils = basevolumeutils.BaseVolumeUtils()
- self._volutils._conn_wmi = mock.MagicMock()
- self._volutils._conn_cimv2 = mock.MagicMock()
-
- super(BaseVolumeUtilsTestCase, self).setUp()
-
- def test_get_iscsi_initiator_ok(self):
- self._check_get_iscsi_initiator(
- mock.MagicMock(return_value=mock.sentinel.FAKE_KEY),
- self._FAKE_INITIATOR_NAME)
-
- def test_get_iscsi_initiator_exception(self):
- initiator_name = "%(iqn)s.%(domain)s" % {
- 'iqn': self._FAKE_INITIATOR_IQN_NAME,
- 'domain': self._FAKE_DOMAIN_NAME
- }
-
- self._check_get_iscsi_initiator(_exception_thrower, initiator_name)
-
- def _check_get_iscsi_initiator(self, winreg_method, expected):
- mock_computer = mock.MagicMock()
- mock_computer.name = self._FAKE_COMPUTER_NAME
- mock_computer.Domain = self._FAKE_DOMAIN_NAME
- self._volutils._conn_cimv2.Win32_ComputerSystem.return_value = [
- mock_computer]
-
- with mock.patch.object(basevolumeutils,
- '_winreg', create=True) as mock_winreg:
- mock_winreg.OpenKey = winreg_method
- mock_winreg.QueryValueEx = mock.MagicMock(return_value=[expected])
-
- initiator_name = self._volutils.get_iscsi_initiator()
- self.assertEqual(expected, initiator_name)
-
- @mock.patch.object(basevolumeutils, 'driver')
- def test_volume_in_mapping(self, mock_driver):
- mock_driver.block_device_info_get_mapping.return_value = [
- {'mount_device': self._FAKE_MOUNT_DEVICE}]
- mock_driver.block_device_info_get_swap = mock.MagicMock(
- return_value=self._FAKE_SWAP)
- mock_driver.block_device_info_get_ephemerals = mock.MagicMock(
- return_value=[{'device_name': self._FAKE_DEVICE_NAME}])
-
- mock_driver.swap_is_usable = mock.MagicMock(return_value=True)
-
- self.assertTrue(self._volutils.volume_in_mapping(
- self._FAKE_MOUNT_DEVICE, mock.sentinel.FAKE_BLOCK_DEVICE_INFO))
-
- def test_get_drive_number_from_disk_path(self):
- fake_disk_path = (
- '\\\\WIN-I5BTVHOIFGK\\root\\virtualization\\v2:Msvm_DiskDrive.'
- 'CreationClassName="Msvm_DiskDrive",DeviceID="Microsoft:353B3BE8-'
- '310C-4cf4-839E-4E1B14616136\\\\1",SystemCreationClassName='
- '"Msvm_ComputerSystem",SystemName="WIN-I5BTVHOIFGK"')
- expected_disk_number = 1
-
- ret_val = self._volutils._get_drive_number_from_disk_path(
- fake_disk_path)
-
- self.assertEqual(expected_disk_number, ret_val)
-
- def test_get_drive_number_not_found(self):
- fake_disk_path = 'fake_disk_path'
-
- ret_val = self._volutils._get_drive_number_from_disk_path(
- fake_disk_path)
-
- self.assertFalse(ret_val)
-
- @mock.patch.object(basevolumeutils.BaseVolumeUtils,
- "_get_drive_number_from_disk_path")
- def test_get_session_id_from_mounted_disk(self, mock_get_session_id):
- mock_get_session_id.return_value = mock.sentinel.FAKE_DEVICE_NUMBER
- mock_initiator_session = self._create_initiator_session()
- mock_ses_class = self._volutils._conn_wmi.MSiSCSIInitiator_SessionClass
- mock_ses_class.return_value = [mock_initiator_session]
-
- session_id = self._volutils.get_session_id_from_mounted_disk(
- self._FAKE_DISK_PATH)
-
- self.assertEqual(mock.sentinel.FAKE_SESSION_ID, session_id)
-
- def test_get_devices_for_target(self):
- init_session = self._create_initiator_session()
- mock_ses_class = self._volutils._conn_wmi.MSiSCSIInitiator_SessionClass
- mock_ses_class.return_value = [init_session]
- devices = self._volutils._get_devices_for_target(
- mock.sentinel.FAKE_IQN)
-
- self.assertEqual(init_session.Devices, devices)
-
- def test_get_devices_for_target_not_found(self):
- mock_ses_class = self._volutils._conn_wmi.MSiSCSIInitiator_SessionClass
- mock_ses_class.return_value = []
- devices = self._volutils._get_devices_for_target(
- mock.sentinel.FAKE_IQN)
-
- self.assertEqual(0, len(devices))
-
- @mock.patch.object(basevolumeutils.BaseVolumeUtils,
- '_get_devices_for_target')
- def test_get_device_number_for_target(self, fake_get_devices):
- init_session = self._create_initiator_session()
- fake_get_devices.return_value = init_session.Devices
- mock_ses_class = self._volutils._conn_wmi.MSiSCSIInitiator_SessionClass
- mock_ses_class.return_value = [init_session]
- device_number = self._volutils.get_device_number_for_target(
- mock.sentinel.FAKE_IQN, mock.sentinel.FAKE_LUN)
-
- self.assertEqual(mock.sentinel.FAKE_DEVICE_NUMBER, device_number)
-
- @mock.patch.object(basevolumeutils.BaseVolumeUtils,
- '_get_devices_for_target')
- def test_get_target_lun_count(self, fake_get_devices):
- init_session = self._create_initiator_session()
- # Only disk devices are being counted.
- disk_device = mock.Mock(DeviceType=self._volutils._FILE_DEVICE_DISK)
- init_session.Devices.append(disk_device)
- fake_get_devices.return_value = init_session.Devices
-
- lun_count = self._volutils.get_target_lun_count(
- mock.sentinel.FAKE_IQN)
-
- self.assertEqual(1, lun_count)
-
- @mock.patch.object(basevolumeutils.BaseVolumeUtils,
- "_get_drive_number_from_disk_path")
- def test_get_target_from_disk_path(self, mock_get_session_id):
- mock_get_session_id.return_value = mock.sentinel.FAKE_DEVICE_NUMBER
- init_sess = self._create_initiator_session()
- mock_ses_class = self._volutils._conn_wmi.MSiSCSIInitiator_SessionClass
- mock_ses_class.return_value = [init_sess]
-
- (target_name, scsi_lun) = self._volutils.get_target_from_disk_path(
- self._FAKE_DISK_PATH)
-
- self.assertEqual(mock.sentinel.FAKE_TARGET_NAME, target_name)
- self.assertEqual(mock.sentinel.FAKE_LUN, scsi_lun)
-
- def _create_initiator_session(self):
- device = mock.MagicMock()
- device.ScsiLun = mock.sentinel.FAKE_LUN
- device.DeviceNumber = mock.sentinel.FAKE_DEVICE_NUMBER
- device.TargetName = mock.sentinel.FAKE_TARGET_NAME
- init_session = mock.MagicMock()
- init_session.Devices = [device]
- init_session.SessionId = mock.sentinel.FAKE_SESSION_ID
-
- return init_session
diff --git a/nova/tests/unit/virt/hyperv/test_hostutils.py b/nova/tests/unit/virt/hyperv/test_hostutils.py
deleted file mode 100644
index 0d6b641cf7..0000000000
--- a/nova/tests/unit/virt/hyperv/test_hostutils.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import test
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import hostutils
-
-
-class FakeCPUSpec(object):
- """Fake CPU Spec for unit tests."""
-
- Architecture = mock.sentinel.cpu_arch
- Name = mock.sentinel.cpu_name
- Manufacturer = mock.sentinel.cpu_man
- NumberOfCores = mock.sentinel.cpu_cores
- NumberOfLogicalProcessors = mock.sentinel.cpu_procs
-
-
-class HostUtilsTestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V hostutils class."""
-
- _FAKE_MEMORY_TOTAL = 1024
- _FAKE_MEMORY_FREE = 512
- _FAKE_DISK_SIZE = 1024
- _FAKE_DISK_FREE = 512
- _FAKE_VERSION_GOOD = '6.2.0'
- _FAKE_VERSION_BAD = '6.1.9'
-
- def setUp(self):
- self._hostutils = hostutils.HostUtils()
- self._hostutils._conn_cimv2 = mock.MagicMock()
-
- super(HostUtilsTestCase, self).setUp()
-
- @mock.patch('nova.virt.hyperv.hostutils.ctypes')
- def test_get_host_tick_count64(self, mock_ctypes):
- tick_count64 = "100"
- mock_ctypes.windll.kernel32.GetTickCount64.return_value = tick_count64
- response = self._hostutils.get_host_tick_count64()
- self.assertEqual(tick_count64, response)
-
- def test_get_cpus_info(self):
- cpu = mock.MagicMock(spec=FakeCPUSpec)
- self._hostutils._conn_cimv2.query.return_value = [cpu]
- cpu_list = self._hostutils.get_cpus_info()
- self.assertEqual([cpu._mock_children], cpu_list)
-
- def test_get_memory_info(self):
- memory = mock.MagicMock()
- type(memory).TotalVisibleMemorySize = mock.PropertyMock(
- return_value=self._FAKE_MEMORY_TOTAL)
- type(memory).FreePhysicalMemory = mock.PropertyMock(
- return_value=self._FAKE_MEMORY_FREE)
-
- self._hostutils._conn_cimv2.query.return_value = [memory]
- total_memory, free_memory = self._hostutils.get_memory_info()
-
- self.assertEqual(self._FAKE_MEMORY_TOTAL, total_memory)
- self.assertEqual(self._FAKE_MEMORY_FREE, free_memory)
-
- def test_get_volume_info(self):
- disk = mock.MagicMock()
- type(disk).Size = mock.PropertyMock(return_value=self._FAKE_DISK_SIZE)
- type(disk).FreeSpace = mock.PropertyMock(
- return_value=self._FAKE_DISK_FREE)
-
- self._hostutils._conn_cimv2.query.return_value = [disk]
- (total_memory, free_memory) = self._hostutils.get_volume_info(
- mock.sentinel.FAKE_DRIVE)
-
- self.assertEqual(self._FAKE_DISK_SIZE, total_memory)
- self.assertEqual(self._FAKE_DISK_FREE, free_memory)
-
- def test_check_min_windows_version_true(self):
- self._test_check_min_windows_version(self._FAKE_VERSION_GOOD, True)
-
- def test_check_min_windows_version_false(self):
- self._test_check_min_windows_version(self._FAKE_VERSION_BAD, False)
-
- def _test_check_min_windows_version(self, version, expected):
- os = mock.MagicMock()
- os.Version = version
- self._hostutils._conn_cimv2.Win32_OperatingSystem.return_value = [os]
- self.assertEqual(expected,
- self._hostutils.check_min_windows_version(6, 2))
-
- def _test_host_power_action(self, action):
- fake_win32 = mock.MagicMock()
- fake_win32.Win32Shutdown = mock.MagicMock()
-
- self._hostutils._conn_cimv2.Win32_OperatingSystem.return_value = [
- fake_win32]
-
- if action == constants.HOST_POWER_ACTION_SHUTDOWN:
- self._hostutils.host_power_action(action)
- fake_win32.Win32Shutdown.assert_called_with(
- self._hostutils._HOST_FORCED_SHUTDOWN)
- elif action == constants.HOST_POWER_ACTION_REBOOT:
- self._hostutils.host_power_action(action)
- fake_win32.Win32Shutdown.assert_called_with(
- self._hostutils._HOST_FORCED_REBOOT)
- else:
- self.assertRaises(NotImplementedError,
- self._hostutils.host_power_action, action)
-
- def test_host_shutdown(self):
- self._test_host_power_action(constants.HOST_POWER_ACTION_SHUTDOWN)
-
- def test_host_reboot(self):
- self._test_host_power_action(constants.HOST_POWER_ACTION_REBOOT)
-
- def test_host_startup(self):
- self._test_host_power_action(constants.HOST_POWER_ACTION_STARTUP)
-
- def test_get_supported_vm_types_2012_r2(self):
- with mock.patch.object(self._hostutils,
- 'check_min_windows_version') as mock_check_win:
- mock_check_win.return_value = True
- result = self._hostutils.get_supported_vm_types()
- self.assertEqual([constants.IMAGE_PROP_VM_GEN_1,
- constants.IMAGE_PROP_VM_GEN_2], result)
-
- def test_get_supported_vm_types(self):
- with mock.patch.object(self._hostutils,
- 'check_min_windows_version') as mock_check_win:
- mock_check_win.return_value = False
- result = self._hostutils.get_supported_vm_types()
- self.assertEqual([constants.IMAGE_PROP_VM_GEN_1], result)
diff --git a/nova/tests/unit/virt/hyperv/test_hostutilsv2.py b/nova/tests/unit/virt/hyperv/test_hostutilsv2.py
deleted file mode 100644
index b2e426bf71..0000000000
--- a/nova/tests/unit/virt/hyperv/test_hostutilsv2.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import test
-from nova.virt.hyperv import hostutilsv2
-
-
-class HostUtilsV2TestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V hostutilsv2 class."""
-
- def setUp(self):
- self._hostutils = hostutilsv2.HostUtilsV2()
- self._hostutils._conn_cimv2 = mock.MagicMock()
- self._hostutils._conn_virt = mock.MagicMock()
-
- super(HostUtilsV2TestCase, self).setUp()
diff --git a/nova/tests/unit/virt/hyperv/test_ioutils.py b/nova/tests/unit/virt/hyperv/test_ioutils.py
deleted file mode 100644
index b412ed4331..0000000000
--- a/nova/tests/unit/virt/hyperv/test_ioutils.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.import mock
-
-import mock
-
-import os
-
-from nova import test
-from nova.virt.hyperv import ioutils
-
-
-class IOThreadTestCase(test.NoDBTestCase):
- _FAKE_SRC = r'fake_source_file'
- _FAKE_DEST = r'fake_dest_file'
- _FAKE_MAX_BYTES = 1
-
- def setUp(self):
- self._iothread = ioutils.IOThread(
- self._FAKE_SRC, self._FAKE_DEST, self._FAKE_MAX_BYTES)
- super(IOThreadTestCase, self).setUp()
-
- @mock.patch('__builtin__.open')
- @mock.patch('os.rename')
- @mock.patch('os.path.exists')
- @mock.patch('os.remove')
- def test_copy(self, fake_remove, fake_exists, fake_rename, fake_open):
- fake_data = 'a'
- fake_src = mock.Mock()
- fake_dest = mock.Mock()
-
- fake_src.read.return_value = fake_data
- fake_dest.tell.return_value = 0
- fake_exists.return_value = True
-
- mock_context_manager = mock.MagicMock()
- fake_open.return_value = mock_context_manager
- mock_context_manager.__enter__.side_effect = [fake_src, fake_dest]
- self._iothread._stopped.isSet = mock.Mock(side_effect=[False, True])
-
- self._iothread._copy()
-
- fake_dest.seek.assert_called_once_with(0, os.SEEK_END)
- fake_dest.write.assert_called_once_with(fake_data)
- fake_dest.close.assert_called_once_with()
- fake_rename.assert_called_once_with(
- self._iothread._dest, self._iothread._dest_archive)
- fake_remove.assert_called_once_with(
- self._iothread._dest_archive)
- self.assertEqual(3, fake_open.call_count)
diff --git a/nova/tests/unit/virt/hyperv/test_livemigrationutils.py b/nova/tests/unit/virt/hyperv/test_livemigrationutils.py
deleted file mode 100644
index 65e2bbb0d7..0000000000
--- a/nova/tests/unit/virt/hyperv/test_livemigrationutils.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import exception
-from nova import test
-from nova.virt.hyperv import livemigrationutils
-from nova.virt.hyperv import vmutils
-
-
-class LiveMigrationUtilsTestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V LiveMigrationUtils class."""
-
- _FAKE_VM_NAME = 'fake_vm_name'
- _FAKE_RET_VAL = 0
-
- _RESOURCE_TYPE_VHD = 31
- _RESOURCE_TYPE_DISK = 17
- _RESOURCE_SUB_TYPE_VHD = 'Microsoft:Hyper-V:Virtual Hard Disk'
- _RESOURCE_SUB_TYPE_DISK = 'Microsoft:Hyper-V:Physical Disk Drive'
-
- def setUp(self):
- self.liveutils = livemigrationutils.LiveMigrationUtils()
- self.liveutils._vmutils = mock.MagicMock()
- self.liveutils._volutils = mock.MagicMock()
-
- self._conn = mock.MagicMock()
- self.liveutils._get_conn_v2 = mock.MagicMock(return_value=self._conn)
-
- super(LiveMigrationUtilsTestCase, self).setUp()
-
- def test_check_live_migration_config(self):
- mock_migr_svc = self._conn.Msvm_VirtualSystemMigrationService()[0]
-
- vsmssd = mock.MagicMock()
- vsmssd.EnableVirtualSystemMigration = True
- mock_migr_svc.associators.return_value = [vsmssd]
- mock_migr_svc.MigrationServiceListenerIPAdressList.return_value = [
- mock.sentinel.FAKE_HOST]
-
- self.liveutils.check_live_migration_config()
- self.assertTrue(mock_migr_svc.associators.called)
-
- def test_get_vm(self):
- expected_vm = mock.MagicMock()
- mock_conn_v2 = mock.MagicMock()
- mock_conn_v2.Msvm_ComputerSystem.return_value = [expected_vm]
-
- found_vm = self.liveutils._get_vm(mock_conn_v2, self._FAKE_VM_NAME)
-
- self.assertEqual(expected_vm, found_vm)
-
- def test_get_vm_duplicate(self):
- mock_vm = mock.MagicMock()
- mock_conn_v2 = mock.MagicMock()
- mock_conn_v2.Msvm_ComputerSystem.return_value = [mock_vm, mock_vm]
-
- self.assertRaises(vmutils.HyperVException, self.liveutils._get_vm,
- mock_conn_v2, self._FAKE_VM_NAME)
-
- def test_get_vm_not_found(self):
- mock_conn_v2 = mock.MagicMock()
- mock_conn_v2.Msvm_ComputerSystem.return_value = []
-
- self.assertRaises(exception.InstanceNotFound, self.liveutils._get_vm,
- mock_conn_v2, self._FAKE_VM_NAME)
-
- @mock.patch.object(livemigrationutils.LiveMigrationUtils,
- '_destroy_planned_vm')
- def test_check_existing_planned_vm_found(self, mock_destroy_planned_vm):
- mock_vm = mock.MagicMock()
- mock_v2 = mock.MagicMock()
- mock_v2.Msvm_PlannedComputerSystem.return_value = [mock_vm]
- self.liveutils._check_existing_planned_vm(mock_v2, mock_vm)
-
- mock_destroy_planned_vm.assert_called_once_with(mock_v2, mock_vm)
-
- @mock.patch.object(livemigrationutils.LiveMigrationUtils,
- '_destroy_planned_vm')
- def test_check_existing_planned_vm_none(self, mock_destroy_planned_vm):
- mock_v2 = mock.MagicMock()
- mock_v2.Msvm_PlannedComputerSystem.return_value = []
- self.liveutils._check_existing_planned_vm(mock_v2, mock.MagicMock())
-
- self.assertFalse(mock_destroy_planned_vm.called)
-
- def test_create_remote_planned_vm(self):
- mock_vsmsd = self._conn.query()[0]
- mock_vm = mock.MagicMock()
- mock_v2 = mock.MagicMock()
- mock_v2.Msvm_PlannedComputerSystem.return_value = [mock_vm]
-
- migr_svc = self._conn.Msvm_VirtualSystemMigrationService()[0]
- migr_svc.MigrateVirtualSystemToHost.return_value = (
- self._FAKE_RET_VAL, mock.sentinel.FAKE_JOB_PATH)
-
- resulted_vm = self.liveutils._create_remote_planned_vm(
- self._conn, mock_v2, mock_vm, [mock.sentinel.FAKE_REMOTE_IP_ADDR],
- mock.sentinel.FAKE_HOST)
-
- self.assertEqual(mock_vm, resulted_vm)
-
- migr_svc.MigrateVirtualSystemToHost.assert_called_once_with(
- ComputerSystem=mock_vm.path_.return_value,
- DestinationHost=mock.sentinel.FAKE_HOST,
- MigrationSettingData=mock_vsmsd.GetText_.return_value)
-
- def test_get_physical_disk_paths(self):
- ide_path = {mock.sentinel.IDE_PATH: mock.sentinel.IDE_HOST_RESOURCE}
- scsi_path = {mock.sentinel.SCSI_PATH: mock.sentinel.SCSI_HOST_RESOURCE}
- ide_ctrl = self.liveutils._vmutils.get_vm_ide_controller.return_value
- scsi_ctrl = self.liveutils._vmutils.get_vm_scsi_controller.return_value
- mock_get_controller_paths = (
- self.liveutils._vmutils.get_controller_volume_paths)
-
- mock_get_controller_paths.side_effect = [ide_path, scsi_path]
-
- result = self.liveutils._get_physical_disk_paths(mock.sentinel.VM_NAME)
-
- expected = dict(ide_path)
- expected.update(scsi_path)
- self.assertDictContainsSubset(expected, result)
- calls = [mock.call(ide_ctrl), mock.call(scsi_ctrl)]
- mock_get_controller_paths.assert_has_calls(calls)
-
- def test_get_physical_disk_paths_no_ide(self):
- scsi_path = {mock.sentinel.SCSI_PATH: mock.sentinel.SCSI_HOST_RESOURCE}
- scsi_ctrl = self.liveutils._vmutils.get_vm_scsi_controller.return_value
- mock_get_controller_paths = (
- self.liveutils._vmutils.get_controller_volume_paths)
-
- self.liveutils._vmutils.get_vm_ide_controller.return_value = None
- mock_get_controller_paths.return_value = scsi_path
-
- result = self.liveutils._get_physical_disk_paths(mock.sentinel.VM_NAME)
-
- self.assertEqual(scsi_path, result)
- mock_get_controller_paths.assert_called_once_with(scsi_ctrl)
-
- @mock.patch.object(livemigrationutils.volumeutilsv2, 'VolumeUtilsV2')
- def test_get_remote_disk_data(self, mock_vol_utils_class):
- mock_vol_utils_remote = mock_vol_utils_class.return_value
- mock_vm_utils = mock.MagicMock()
- disk_paths = {
- mock.sentinel.FAKE_RASD_PATH: mock.sentinel.FAKE_DISK_PATH}
- self.liveutils._volutils.get_target_from_disk_path.return_value = (
- mock.sentinel.FAKE_IQN, mock.sentinel.FAKE_LUN)
- mock_vol_utils_remote.get_device_number_for_target.return_value = (
- mock.sentinel.FAKE_DEV_NUM)
- mock_vm_utils.get_mounted_disk_by_drive_number.return_value = (
- mock.sentinel.FAKE_DISK_PATH)
-
- disk_paths = self.liveutils._get_remote_disk_data(
- mock_vm_utils, disk_paths, mock.sentinel.FAKE_HOST)
-
- self.liveutils._volutils.get_target_from_disk_path.assert_called_with(
- mock.sentinel.FAKE_DISK_PATH)
- mock_vol_utils_remote.get_device_number_for_target.assert_called_with(
- mock.sentinel.FAKE_IQN, mock.sentinel.FAKE_LUN)
- mock_vm_utils.get_mounted_disk_by_drive_number.assert_called_once_with(
- mock.sentinel.FAKE_DEV_NUM)
-
- self.assertEqual(
- {mock.sentinel.FAKE_RASD_PATH: mock.sentinel.FAKE_DISK_PATH},
- disk_paths)
-
- def test_update_planned_vm_disk_resources(self):
- mock_vm_utils = mock.MagicMock()
-
- self._prepare_vm_mocks(self._RESOURCE_TYPE_DISK,
- self._RESOURCE_SUB_TYPE_DISK)
- mock_vm = self._conn.Msvm_ComputerSystem.return_value[0]
- sasd = mock_vm.associators()[0].associators()[0]
-
- mock_vsmsvc = self._conn.Msvm_VirtualSystemManagementService()[0]
-
- self.liveutils._update_planned_vm_disk_resources(
- mock_vm_utils, self._conn, mock_vm, mock.sentinel.FAKE_VM_NAME,
- {sasd.path.return_value.RelPath: mock.sentinel.FAKE_RASD_PATH})
-
- mock_vsmsvc.ModifyResourceSettings.assert_called_once_with(
- ResourceSettings=[sasd.GetText_.return_value])
-
- def test_get_vhd_setting_data(self):
- self._prepare_vm_mocks(self._RESOURCE_TYPE_VHD,
- self._RESOURCE_SUB_TYPE_VHD)
- mock_vm = self._conn.Msvm_ComputerSystem.return_value[0]
- mock_sasd = mock_vm.associators()[0].associators()[0]
-
- vhd_sds = self.liveutils._get_vhd_setting_data(mock_vm)
- self.assertEqual([mock_sasd.GetText_.return_value], vhd_sds)
-
- def test_live_migrate_vm_helper(self):
- mock_conn_local = mock.MagicMock()
- mock_vm = mock.MagicMock()
- mock_vsmsd = mock_conn_local.query()[0]
-
- mock_vsmsvc = mock_conn_local.Msvm_VirtualSystemMigrationService()[0]
- mock_vsmsvc.MigrateVirtualSystemToHost.return_value = (
- self._FAKE_RET_VAL, mock.sentinel.FAKE_JOB_PATH)
-
- self.liveutils._live_migrate_vm(
- mock_conn_local, mock_vm, None,
- [mock.sentinel.FAKE_REMOTE_IP_ADDR],
- mock.sentinel.FAKE_RASD_PATH, mock.sentinel.FAKE_HOST)
-
- mock_vsmsvc.MigrateVirtualSystemToHost.assert_called_once_with(
- ComputerSystem=mock_vm.path_.return_value,
- DestinationHost=mock.sentinel.FAKE_HOST,
- MigrationSettingData=mock_vsmsd.GetText_.return_value,
- NewResourceSettingData=mock.sentinel.FAKE_RASD_PATH)
-
- @mock.patch.object(livemigrationutils, 'vmutilsv2')
- def test_live_migrate_vm(self, mock_vm_utils):
- mock_vm_utils_remote = mock_vm_utils.VMUtilsV2.return_value
- mock_vm = self._get_vm()
-
- mock_migr_svc = self._conn.Msvm_VirtualSystemMigrationService()[0]
- mock_migr_svc.MigrationServiceListenerIPAddressList = [
- mock.sentinel.FAKE_REMOTE_IP_ADDR]
-
- # patches, call and assertions.
- with mock.patch.multiple(
- self.liveutils,
- _destroy_planned_vm=mock.DEFAULT,
- _get_physical_disk_paths=mock.DEFAULT,
- _get_remote_disk_data=mock.DEFAULT,
- _create_remote_planned_vm=mock.DEFAULT,
- _update_planned_vm_disk_resources=mock.DEFAULT,
- _get_vhd_setting_data=mock.DEFAULT,
- _live_migrate_vm=mock.DEFAULT):
-
- disk_paths = {
- mock.sentinel.FAKE_IDE_PATH: mock.sentinel.FAKE_SASD_RESOURCE}
- self.liveutils._get_physical_disk_paths.return_value = disk_paths
-
- mock_disk_paths = [mock.sentinel.FAKE_DISK_PATH]
- self.liveutils._get_remote_disk_data.return_value = (
- mock_disk_paths)
-
- self.liveutils._create_remote_planned_vm.return_value = mock_vm
-
- self.liveutils.live_migrate_vm(mock.sentinel.FAKE_VM_NAME,
- mock.sentinel.FAKE_HOST)
-
- self.liveutils._get_remote_disk_data.assert_called_once_with(
- mock_vm_utils_remote, disk_paths, mock.sentinel.FAKE_HOST)
-
- self.liveutils._create_remote_planned_vm.assert_called_once_with(
- self._conn, self._conn, mock_vm,
- [mock.sentinel.FAKE_REMOTE_IP_ADDR], mock.sentinel.FAKE_HOST)
-
- mocked_method = self.liveutils._update_planned_vm_disk_resources
- mocked_method.assert_called_once_with(
- mock_vm_utils_remote, self._conn, mock_vm,
- mock.sentinel.FAKE_VM_NAME, mock_disk_paths)
-
- self.liveutils._live_migrate_vm.assert_called_once_with(
- self._conn, mock_vm, mock_vm,
- [mock.sentinel.FAKE_REMOTE_IP_ADDR],
- self.liveutils._get_vhd_setting_data.return_value,
- mock.sentinel.FAKE_HOST)
-
- def _prepare_vm_mocks(self, resource_type, resource_sub_type):
- mock_vm_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- vm = self._get_vm()
- self._conn.Msvm_PlannedComputerSystem.return_value = [vm]
- mock_vm_svc.DestroySystem.return_value = (mock.sentinel.FAKE_JOB_PATH,
- self._FAKE_RET_VAL)
- mock_vm_svc.ModifyResourceSettings.return_value = (
- None, mock.sentinel.FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- sasd = mock.MagicMock()
- other_sasd = mock.MagicMock()
- sasd.ResourceType = resource_type
- sasd.ResourceSubType = resource_sub_type
- sasd.HostResource = [mock.sentinel.FAKE_SASD_RESOURCE]
- sasd.path.return_value.RelPath = mock.sentinel.FAKE_DISK_PATH
-
- vm_settings = mock.MagicMock()
- vm.associators.return_value = [vm_settings]
- vm_settings.associators.return_value = [sasd, other_sasd]
-
- def _get_vm(self):
- mock_vm = mock.MagicMock()
- self._conn.Msvm_ComputerSystem.return_value = [mock_vm]
- mock_vm.path_.return_value = mock.sentinel.FAKE_VM_PATH
- return mock_vm
diff --git a/nova/tests/unit/virt/hyperv/test_networkutils.py b/nova/tests/unit/virt/hyperv/test_networkutils.py
deleted file mode 100644
index 281df29833..0000000000
--- a/nova/tests/unit/virt/hyperv/test_networkutils.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import test
-from nova.virt.hyperv import networkutils
-from nova.virt.hyperv import vmutils
-
-
-class NetworkUtilsTestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V NetworkUtils class."""
-
- _FAKE_PORT = {'Name': mock.sentinel.FAKE_PORT_NAME}
- _FAKE_RET_VALUE = 0
-
- _MSVM_VIRTUAL_SWITCH = 'Msvm_VirtualSwitch'
-
- def setUp(self):
- self._networkutils = networkutils.NetworkUtils()
- self._networkutils._conn = mock.MagicMock()
-
- super(NetworkUtilsTestCase, self).setUp()
-
- def test_get_external_vswitch(self):
- mock_vswitch = mock.MagicMock()
- mock_vswitch.path_.return_value = mock.sentinel.FAKE_VSWITCH_PATH
- getattr(self._networkutils._conn,
- self._MSVM_VIRTUAL_SWITCH).return_value = [mock_vswitch]
-
- switch_path = self._networkutils.get_external_vswitch(
- mock.sentinel.FAKE_VSWITCH_NAME)
-
- self.assertEqual(mock.sentinel.FAKE_VSWITCH_PATH, switch_path)
-
- def test_get_external_vswitch_not_found(self):
- self._networkutils._conn.Msvm_VirtualEthernetSwitch.return_value = []
-
- self.assertRaises(vmutils.HyperVException,
- self._networkutils.get_external_vswitch,
- mock.sentinel.FAKE_VSWITCH_NAME)
-
- def test_get_external_vswitch_no_name(self):
- mock_vswitch = mock.MagicMock()
- mock_vswitch.path_.return_value = mock.sentinel.FAKE_VSWITCH_PATH
-
- mock_ext_port = self._networkutils._conn.Msvm_ExternalEthernetPort()[0]
- self._prepare_external_port(mock_vswitch, mock_ext_port)
-
- switch_path = self._networkutils.get_external_vswitch(None)
- self.assertEqual(mock.sentinel.FAKE_VSWITCH_PATH, switch_path)
-
- def _prepare_external_port(self, mock_vswitch, mock_ext_port):
- mock_lep = mock_ext_port.associators()[0]
- mock_lep.associators.return_value = [mock_vswitch]
-
- def test_create_vswitch_port(self):
- svc = self._networkutils._conn.Msvm_VirtualSwitchManagementService()[0]
- svc.CreateSwitchPort.return_value = (
- self._FAKE_PORT, self._FAKE_RET_VALUE)
-
- port = self._networkutils.create_vswitch_port(
- mock.sentinel.FAKE_VSWITCH_PATH, mock.sentinel.FAKE_PORT_NAME)
-
- svc.CreateSwitchPort.assert_called_once_with(
- Name=mock.ANY, FriendlyName=mock.sentinel.FAKE_PORT_NAME,
- ScopeOfResidence="", VirtualSwitch=mock.sentinel.FAKE_VSWITCH_PATH)
- self.assertEqual(self._FAKE_PORT, port)
-
- def test_vswitch_port_needed(self):
- self.assertTrue(self._networkutils.vswitch_port_needed())
diff --git a/nova/tests/unit/virt/hyperv/test_networkutilsv2.py b/nova/tests/unit/virt/hyperv/test_networkutilsv2.py
deleted file mode 100644
index 1038e88682..0000000000
--- a/nova/tests/unit/virt/hyperv/test_networkutilsv2.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova.tests.unit.virt.hyperv import test_networkutils
-from nova.virt.hyperv import networkutilsv2
-
-
-class NetworkUtilsV2TestCase(test_networkutils.NetworkUtilsTestCase):
- """Unit tests for the Hyper-V NetworkUtilsV2 class."""
-
- _MSVM_VIRTUAL_SWITCH = 'Msvm_VirtualEthernetSwitch'
-
- def setUp(self):
- super(NetworkUtilsV2TestCase, self).setUp()
- self._networkutils = networkutilsv2.NetworkUtilsV2()
- self._networkutils._conn = mock.MagicMock()
-
- def _prepare_external_port(self, mock_vswitch, mock_ext_port):
- mock_lep = mock_ext_port.associators()[0]
- mock_lep1 = mock_lep.associators()[0]
- mock_esw = mock_lep1.associators()[0]
- mock_esw.associators.return_value = [mock_vswitch]
-
- def test_create_vswitch_port(self):
- self.assertRaises(
- NotImplementedError,
- self._networkutils.create_vswitch_port,
- mock.sentinel.FAKE_VSWITCH_PATH,
- mock.sentinel.FAKE_PORT_NAME)
-
- def test_vswitch_port_needed(self):
- self.assertFalse(self._networkutils.vswitch_port_needed())
diff --git a/nova/tests/unit/virt/hyperv/test_rdpconsoleutils.py b/nova/tests/unit/virt/hyperv/test_rdpconsoleutils.py
deleted file mode 100644
index 98d4484b61..0000000000
--- a/nova/tests/unit/virt/hyperv/test_rdpconsoleutils.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from nova import test
-from nova.virt.hyperv import rdpconsoleutils
-
-
-class RDPConsoleUtilsTestCase(test.NoDBTestCase):
- def setUp(self):
- self._rdpconsoleutils = rdpconsoleutils.RDPConsoleUtils()
- super(RDPConsoleUtilsTestCase, self).setUp()
-
- def test_get_rdp_console_port(self):
- listener_port = self._rdpconsoleutils.get_rdp_console_port()
-
- self.assertEqual(self._rdpconsoleutils._DEFAULT_HYPERV_RDP_PORT,
- listener_port)
diff --git a/nova/tests/unit/virt/hyperv/test_rdpconsoleutilsv2.py b/nova/tests/unit/virt/hyperv/test_rdpconsoleutilsv2.py
deleted file mode 100644
index bcdfaf92f0..0000000000
--- a/nova/tests/unit/virt/hyperv/test_rdpconsoleutilsv2.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova import test
-from nova.virt.hyperv import rdpconsoleutilsv2
-
-
-class RDPConsoleUtilsV2TestCase(test.NoDBTestCase):
- _FAKE_RDP_PORT = 1000
-
- def setUp(self):
- self._rdpconsoleutils = rdpconsoleutilsv2.RDPConsoleUtilsV2()
- self._rdpconsoleutils._conn = mock.MagicMock()
-
- super(RDPConsoleUtilsV2TestCase, self).setUp()
-
- def test_get_rdp_console_port(self):
- conn = self._rdpconsoleutils._conn
- mock_rdp_setting_data = conn.Msvm_TerminalServiceSettingData()[0]
- mock_rdp_setting_data.ListenerPort = self._FAKE_RDP_PORT
-
- listener_port = self._rdpconsoleutils.get_rdp_console_port()
-
- self.assertEqual(self._FAKE_RDP_PORT, listener_port)
diff --git a/nova/tests/unit/virt/hyperv/test_utilsfactory.py b/nova/tests/unit/virt/hyperv/test_utilsfactory.py
deleted file mode 100644
index b13913bd19..0000000000
--- a/nova/tests/unit/virt/hyperv/test_utilsfactory.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2014 Cloudbase Solutions SRL
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Unit tests for the Hyper-V utils factory.
-"""
-
-import mock
-from oslo_config import cfg
-
-from nova import test
-from nova.virt.hyperv import utilsfactory
-from nova.virt.hyperv import volumeutils
-from nova.virt.hyperv import volumeutilsv2
-
-CONF = cfg.CONF
-
-
-class TestHyperVUtilsFactory(test.NoDBTestCase):
- def test_get_volumeutils_v2(self):
- self._test_returned_class(expected_class=volumeutilsv2.VolumeUtilsV2,
- os_supports_v2=True)
-
- def test_get_volumeutils_v1(self):
- self._test_returned_class(expected_class=volumeutils.VolumeUtils)
-
- def test_get_volumeutils_force_v1_and_not_min_version(self):
- self._test_returned_class(expected_class=volumeutils.VolumeUtils,
- force_v1=True)
-
- @mock.patch.object(utilsfactory, 'CONF')
- def _test_returned_class(self, mock_CONF, expected_class, force_v1=False,
- os_supports_v2=False):
- # NOTE(claudiub): temporary change, in order for unit tests to pass.
- # force_hyperv_utils_v1 CONF flag does not exist anymore.
- # utilsfactory and its test cases will be removed next commit.
- mock_CONF.hyperv.force_volumeutils_v1 = force_v1
- with mock.patch.object(
- utilsfactory.utils,
- 'check_min_windows_version') as mock_check_min_windows_version:
- mock_check_min_windows_version.return_value = os_supports_v2
-
- actual_class = type(utilsfactory.get_volumeutils())
- self.assertEqual(actual_class, expected_class)
diff --git a/nova/tests/unit/virt/hyperv/test_vhdutils.py b/nova/tests/unit/virt/hyperv/test_vhdutils.py
deleted file mode 100644
index 659dd5ef22..0000000000
--- a/nova/tests/unit/virt/hyperv/test_vhdutils.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-from oslo_utils import units
-
-from nova import test
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vhdutils
-from nova.virt.hyperv import vmutils
-
-
-class VHDUtilsBaseTestCase(test.NoDBTestCase):
- "Base Class unit test classes of Hyper-V VHD Utils classes."
-
- _FAKE_VHD_PATH = "C:\\fake_path.vhdx"
- _FAKE_PARENT_PATH = "C:\\fake_parent_path.vhdx"
- _FAKE_FORMAT = 3
- _FAKE_TYPE = 3
- _FAKE_MAX_INTERNAL_SIZE = units.Gi
- _FAKE_DYNAMIC_BLK_SIZE = 2097152
- _FAKE_BAD_TYPE = 5
-
- _FAKE_JOB_PATH = 'fake_job_path'
- _FAKE_RET_VAL = 0
- _FAKE_VHD_INFO_XML = (
- """
-
-33554432
-
-
-Virtual Hard Disk Setting Data
-
-
-Setting Data for a Virtual Hard Disk.
-
-
-fake_path.vhdx
-
-
-%(format)s
-
-
-52794B89-AC06-4349-AC57-486CAAD52F69
-
-
-4096
-
-
-%(max_internal_size)s
-
-
-%(parent_path)s
-
-
-%(path)s
-
-
-4096
-
-
-%(type)s
-
-""" % {'path': _FAKE_VHD_PATH,
- 'parent_path': _FAKE_PARENT_PATH,
- 'format': _FAKE_FORMAT,
- 'max_internal_size': _FAKE_MAX_INTERNAL_SIZE,
- 'type': _FAKE_TYPE})
-
-
-class VHDUtilsTestCase(VHDUtilsBaseTestCase):
- """Unit tests for the Hyper-V VHDUtils class."""
-
- def setUp(self):
- super(VHDUtilsTestCase, self).setUp()
- self._vhdutils = vhdutils.VHDUtils()
- self._vhdutils._conn = mock.MagicMock()
- self._vhdutils._vmutils = mock.MagicMock()
-
- self._fake_vhd_info = {
- 'ParentPath': self._FAKE_PARENT_PATH,
- 'MaxInternalSize': self._FAKE_MAX_INTERNAL_SIZE,
- 'Type': self._FAKE_TYPE}
-
- def test_validate_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.ValidateVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.validate_vhd(self._FAKE_VHD_PATH)
- mock_img_svc.ValidateVirtualHardDisk.assert_called_once_with(
- Path=self._FAKE_VHD_PATH)
-
- def test_get_vhd_info(self):
- self._mock_get_vhd_info()
- vhd_info = self._vhdutils.get_vhd_info(self._FAKE_VHD_PATH)
- self.assertEqual(self._fake_vhd_info, vhd_info)
-
- def _mock_get_vhd_info(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.GetVirtualHardDiskInfo.return_value = (
- self._FAKE_VHD_INFO_XML, self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- def test_create_dynamic_vhd(self):
- self._vhdutils.get_vhd_info = mock.MagicMock(
- return_value={'Format': self._FAKE_FORMAT})
-
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.CreateDynamicVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.create_dynamic_vhd(self._FAKE_VHD_PATH,
- self._FAKE_MAX_INTERNAL_SIZE,
- constants.DISK_FORMAT_VHD)
-
- mock_img_svc.CreateDynamicVirtualHardDisk.assert_called_once_with(
- Path=self._FAKE_VHD_PATH,
- MaxInternalSize=self._FAKE_MAX_INTERNAL_SIZE)
- self._vhdutils._vmutils.check_ret_val.assert_called_once_with(
- self._FAKE_RET_VAL, self._FAKE_JOB_PATH)
-
- def test_reconnect_parent_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.ReconnectParentVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.reconnect_parent_vhd(self._FAKE_VHD_PATH,
- self._FAKE_PARENT_PATH)
- mock_img_svc.ReconnectParentVirtualHardDisk.assert_called_once_with(
- ChildPath=self._FAKE_VHD_PATH,
- ParentPath=self._FAKE_PARENT_PATH,
- Force=True)
- self._vhdutils._vmutils.check_ret_val.assert_called_once_with(
- self._FAKE_RET_VAL, self._FAKE_JOB_PATH)
-
- def test_merge_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.MergeVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.merge_vhd(self._FAKE_VHD_PATH, self._FAKE_VHD_PATH)
-
- mock_img_svc.MergeVirtualHardDisk.assert_called_once_with(
- SourcePath=self._FAKE_VHD_PATH,
- DestinationPath=self._FAKE_VHD_PATH)
- self._vhdutils._vmutils.check_ret_val.assert_called_once_with(
- self._FAKE_RET_VAL, self._FAKE_JOB_PATH)
-
- def test_resize_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.ExpandVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.get_internal_vhd_size_by_file_size = mock.MagicMock(
- return_value=self._FAKE_MAX_INTERNAL_SIZE)
-
- self._vhdutils.resize_vhd(self._FAKE_VHD_PATH,
- self._FAKE_MAX_INTERNAL_SIZE)
-
- mock_img_svc.ExpandVirtualHardDisk.assert_called_once_with(
- Path=self._FAKE_VHD_PATH,
- MaxInternalSize=self._FAKE_MAX_INTERNAL_SIZE)
- self._vhdutils._vmutils.check_ret_val.assert_called_once_with(
- self._FAKE_RET_VAL, self._FAKE_JOB_PATH)
-
- def _mocked_get_internal_vhd_size(self, root_vhd_size, vhd_type):
- mock_get_vhd_info = mock.MagicMock(return_value={'Type': vhd_type})
- mock_get_blk_size = mock.MagicMock(
- return_value=self._FAKE_DYNAMIC_BLK_SIZE)
- with mock.patch.multiple(self._vhdutils,
- get_vhd_info=mock_get_vhd_info,
- _get_vhd_dynamic_blk_size=mock_get_blk_size):
-
- return self._vhdutils.get_internal_vhd_size_by_file_size(
- None, root_vhd_size)
-
- def test_create_differencing_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.CreateDifferencingVirtualHardDisk.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.create_differencing_vhd(self._FAKE_VHD_PATH,
- self._FAKE_PARENT_PATH)
-
- mock_img_svc.CreateDifferencingVirtualHardDisk.assert_called_once_with(
- Path=self._FAKE_VHD_PATH,
- ParentPath=self._FAKE_PARENT_PATH)
-
- def test_get_internal_vhd_size_by_file_size_fixed(self):
- root_vhd_size = 1 * 1024 ** 3
- real_size = self._mocked_get_internal_vhd_size(
- root_vhd_size, constants.VHD_TYPE_FIXED)
-
- expected_vhd_size = 1 * 1024 ** 3 - 512
- self.assertEqual(expected_vhd_size, real_size)
-
- def test_get_internal_vhd_size_by_file_size_dynamic(self):
- root_vhd_size = 20 * 1024 ** 3
- real_size = self._mocked_get_internal_vhd_size(
- root_vhd_size, constants.VHD_TYPE_DYNAMIC)
-
- expected_vhd_size = 20 * 1024 ** 3 - 43008
- self.assertEqual(expected_vhd_size, real_size)
-
- def test_get_internal_vhd_size_by_file_size_differencing(self):
- # For differencing images, the internal size of the parent vhd
- # is returned
- vhdutil = vhdutils.VHDUtils()
- root_vhd_size = 20 * 1024 ** 3
- vhdutil.get_vhd_info = mock.MagicMock()
- vhdutil.get_vhd_parent_path = mock.MagicMock()
- vhdutil.get_vhd_parent_path.return_value = self._FAKE_VHD_PATH
- vhdutil.get_vhd_info.side_effect = [
- {'Type': 4}, {'Type': constants.VHD_TYPE_DYNAMIC}]
-
- vhdutil._get_vhd_dynamic_blk_size = mock.MagicMock()
- vhdutil._get_vhd_dynamic_blk_size.return_value = 2097152
-
- real_size = vhdutil.get_internal_vhd_size_by_file_size(None,
- root_vhd_size)
- expected_vhd_size = 20 * 1024 ** 3 - 43008
- self.assertEqual(expected_vhd_size, real_size)
-
- def test_get_vhd_format_vhdx(self):
- with mock.patch('nova.virt.hyperv.vhdutils.open',
- mock.mock_open(read_data=vhdutils.VHDX_SIGNATURE),
- create=True):
-
- format = self._vhdutils.get_vhd_format(self._FAKE_VHD_PATH)
-
- self.assertEqual(constants.DISK_FORMAT_VHDX, format)
-
- def test_get_vhd_format_vhd(self):
- with mock.patch('nova.virt.hyperv.vhdutils.open',
- mock.mock_open(),
- create=True) as mock_open:
- f = mock_open.return_value
- f.tell.return_value = 1024
- readdata = ['notthesig', vhdutils.VHD_SIGNATURE]
-
- def read(*args):
- for content in readdata:
- yield content
-
- f.read.side_effect = read()
-
- format = self._vhdutils.get_vhd_format(self._FAKE_VHD_PATH)
-
- self.assertEqual(constants.DISK_FORMAT_VHD, format)
-
- def test_get_vhd_format_invalid_format(self):
- with mock.patch('nova.virt.hyperv.vhdutils.open',
- mock.mock_open(read_data='invalid'),
- create=True) as mock_open:
- f = mock_open.return_value
- f.tell.return_value = 1024
-
- self.assertRaises(vmutils.HyperVException,
- self._vhdutils.get_vhd_format,
- self._FAKE_VHD_PATH)
-
- def test_get_vhd_format_zero_length_file(self):
- with mock.patch('nova.virt.hyperv.vhdutils.open',
- mock.mock_open(read_data=''),
- create=True) as mock_open:
- f = mock_open.return_value
- f.tell.return_value = 0
-
- self.assertRaises(vmutils.HyperVException,
- self._vhdutils.get_vhd_format,
- self._FAKE_VHD_PATH)
-
- f.seek.assert_called_once_with(0, 2)
-
- def test_get_supported_vhd_format(self):
- fmt = self._vhdutils.get_best_supported_vhd_format()
- self.assertEqual(constants.DISK_FORMAT_VHD, fmt)
diff --git a/nova/tests/unit/virt/hyperv/test_vhdutilsv2.py b/nova/tests/unit/virt/hyperv/test_vhdutilsv2.py
deleted file mode 100644
index 765d1ddb78..0000000000
--- a/nova/tests/unit/virt/hyperv/test_vhdutilsv2.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova.tests.unit.virt.hyperv import test_vhdutils
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vhdutilsv2
-from nova.virt.hyperv import vmutils
-
-
-class VHDUtilsV2TestCase(test_vhdutils.VHDUtilsBaseTestCase):
- """Unit tests for the Hyper-V VHDUtilsV2 class."""
-
- _FAKE_BLOCK_SIZE = 33554432
- _FAKE_LOG_SIZE = 1048576
- _FAKE_LOGICAL_SECTOR_SIZE = 4096
- _FAKE_METADATA_SIZE = 1048576
- _FAKE_PHYSICAL_SECTOR_SIZE = 4096
-
- def setUp(self):
- super(VHDUtilsV2TestCase, self).setUp()
- self._vhdutils = vhdutilsv2.VHDUtilsV2()
- self._vhdutils._conn = mock.MagicMock()
- self._vhdutils._vmutils = mock.MagicMock()
-
- self._fake_file_handle = mock.MagicMock()
-
- self._fake_vhd_info = {
- 'Path': self._FAKE_VHD_PATH,
- 'ParentPath': self._FAKE_PARENT_PATH,
- 'Format': self._FAKE_FORMAT,
- 'MaxInternalSize': self._FAKE_MAX_INTERNAL_SIZE,
- 'Type': self._FAKE_TYPE,
- 'BlockSize': self._FAKE_BLOCK_SIZE,
- 'LogicalSectorSize': self._FAKE_LOGICAL_SECTOR_SIZE,
- 'PhysicalSectorSize': self._FAKE_PHYSICAL_SECTOR_SIZE}
-
- def _mock_get_vhd_info(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.GetVirtualHardDiskSettingData.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL, self._FAKE_VHD_INFO_XML)
-
- def test_get_vhd_info(self):
- self._mock_get_vhd_info()
- vhd_info = self._vhdutils.get_vhd_info(self._FAKE_VHD_PATH)
-
- self.assertEqual(self._FAKE_VHD_PATH, vhd_info['Path'])
- self.assertEqual(self._FAKE_PARENT_PATH, vhd_info['ParentPath'])
- self.assertEqual(self._FAKE_FORMAT, vhd_info['Format'])
- self.assertEqual(self._FAKE_MAX_INTERNAL_SIZE,
- vhd_info['MaxInternalSize'])
- self.assertEqual(self._FAKE_TYPE, vhd_info['Type'])
-
- def test_get_vhd_info_no_parent(self):
- fake_vhd_xml_no_parent = self._FAKE_VHD_INFO_XML.replace(
- self._FAKE_PARENT_PATH, "")
-
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.GetVirtualHardDiskSettingData.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL, fake_vhd_xml_no_parent)
-
- vhd_info = self._vhdutils.get_vhd_info(self._FAKE_VHD_PATH)
-
- self.assertEqual(self._FAKE_VHD_PATH, vhd_info['Path'])
- self.assertIsNone(vhd_info['ParentPath'])
- self.assertEqual(self._FAKE_FORMAT, vhd_info['Format'])
- self.assertEqual(self._FAKE_MAX_INTERNAL_SIZE,
- vhd_info['MaxInternalSize'])
- self.assertEqual(self._FAKE_TYPE, vhd_info['Type'])
-
- def test_create_dynamic_vhd(self):
- self._vhdutils.get_vhd_info = mock.MagicMock(
- return_value={'Format': self._FAKE_FORMAT})
-
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.CreateVirtualHardDisk.return_value = (self._FAKE_JOB_PATH,
- self._FAKE_RET_VAL)
-
- self._vhdutils.create_dynamic_vhd(self._FAKE_VHD_PATH,
- self._FAKE_MAX_INTERNAL_SIZE,
- constants.DISK_FORMAT_VHDX)
-
- self.assertTrue(mock_img_svc.CreateVirtualHardDisk.called)
-
- def test_create_differencing_vhd(self):
- self._vhdutils.get_vhd_info = mock.MagicMock(
- return_value={'ParentPath': self._FAKE_PARENT_PATH,
- 'Format': self._FAKE_FORMAT})
-
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.CreateVirtualHardDisk.return_value = (self._FAKE_JOB_PATH,
- self._FAKE_RET_VAL)
-
- self._vhdutils.create_differencing_vhd(self._FAKE_VHD_PATH,
- self._FAKE_PARENT_PATH)
-
- self.assertTrue(mock_img_svc.CreateVirtualHardDisk.called)
-
- def test_reconnect_parent_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- fake_new_parent_path = 'fake_new_parent_path'
-
- self._vhdutils._get_vhd_info_xml = mock.MagicMock(
- return_value=self._FAKE_VHD_INFO_XML)
-
- mock_img_svc.SetVirtualHardDiskSettingData.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vhdutils.reconnect_parent_vhd(self._FAKE_VHD_PATH,
- fake_new_parent_path)
-
- expected_virt_disk_data = self._FAKE_VHD_INFO_XML.replace(
- self._FAKE_PARENT_PATH, fake_new_parent_path)
- mock_img_svc.SetVirtualHardDiskSettingData.assert_called_once_with(
- VirtualDiskSettingData=expected_virt_disk_data)
-
- def test_reconnect_parent_vhd_exception(self):
- # Test that reconnect_parent_vhd raises an exception if the
- # vhd info XML does not contain the ParentPath property.
- fake_vhd_info_xml = self._FAKE_VHD_INFO_XML.replace('ParentPath',
- 'FakeParentPath')
- self._vhdutils._get_vhd_info_xml = mock.Mock(
- return_value=fake_vhd_info_xml)
-
- self.assertRaises(vmutils.HyperVException,
- self._vhdutils.reconnect_parent_vhd,
- self._FAKE_VHD_PATH,
- mock.sentinel.new_parent_path)
-
- def test_resize_vhd(self):
- mock_img_svc = self._vhdutils._conn.Msvm_ImageManagementService()[0]
- mock_img_svc.ResizeVirtualHardDisk.return_value = (self._FAKE_JOB_PATH,
- self._FAKE_RET_VAL)
- self._vhdutils.get_internal_vhd_size_by_file_size = mock.MagicMock(
- return_value=self._FAKE_MAX_INTERNAL_SIZE)
-
- self._vhdutils.resize_vhd(self._FAKE_VHD_PATH,
- self._FAKE_MAX_INTERNAL_SIZE)
-
- mock_img_svc.ResizeVirtualHardDisk.assert_called_once_with(
- Path=self._FAKE_VHD_PATH,
- MaxInternalSize=self._FAKE_MAX_INTERNAL_SIZE)
-
- self.mock_get = self._vhdutils.get_internal_vhd_size_by_file_size
- self.mock_get.assert_called_once_with(self._FAKE_VHD_PATH,
- self._FAKE_MAX_INTERNAL_SIZE)
-
- def _test_get_vhdx_internal_size(self, vhd_type):
- self._vhdutils.get_vhd_info = mock.MagicMock()
- self._vhdutils.get_vhd_parent_path = mock.Mock(
- return_value=self._FAKE_PARENT_PATH)
-
- if vhd_type == 4:
- self._vhdutils.get_vhd_info.side_effect = [
- {'Type': vhd_type}, self._fake_vhd_info]
- else:
- self._vhdutils.get_vhd_info.return_value = self._fake_vhd_info
-
- @mock.patch('nova.virt.hyperv.vhdutils.VHDUtils.get_vhd_format')
- def test_get_vhdx_internal_size(self, mock_get_vhd_format):
- mock_get_vhd_format.return_value = constants.DISK_FORMAT_VHDX
- self._mock_get_vhd_info()
- self._vhdutils._get_vhdx_log_size = mock.MagicMock(
- return_value=self._FAKE_LOG_SIZE)
- self._vhdutils._get_vhdx_metadata_size_and_offset = mock.MagicMock(
- return_value=(self._FAKE_METADATA_SIZE, 1024))
- self._vhdutils._get_vhdx_block_size = mock.MagicMock(
- return_value=self._FAKE_BLOCK_SIZE)
-
- file_mock = mock.MagicMock()
- with mock.patch('__builtin__.open', file_mock):
- internal_size = (
- self._vhdutils.get_internal_vhd_size_by_file_size(
- self._FAKE_VHD_PATH, self._FAKE_MAX_INTERNAL_SIZE))
-
- self.assertEqual(self._FAKE_MAX_INTERNAL_SIZE - self._FAKE_BLOCK_SIZE,
- internal_size)
-
- def test_get_vhdx_internal_size_dynamic(self):
- self._test_get_vhdx_internal_size(3)
-
- def test_get_vhdx_internal_size_differencing(self):
- self._test_get_vhdx_internal_size(4)
-
- def test_get_vhdx_current_header(self):
- VHDX_HEADER_OFFSETS = [64 * 1024, 128 * 1024]
- fake_sequence_numbers = ['\x01\x00\x00\x00\x00\x00\x00\x00',
- '\x02\x00\x00\x00\x00\x00\x00\x00']
- self._fake_file_handle.read = mock.MagicMock(
- side_effect=fake_sequence_numbers)
-
- offset = self._vhdutils._get_vhdx_current_header_offset(
- self._fake_file_handle)
- self.assertEqual(offset, VHDX_HEADER_OFFSETS[1])
-
- def test_get_vhdx_metadata_size(self):
- fake_metadata_offset = '\x01\x00\x00\x00\x00\x00\x00\x00'
- fake_metadata_size = '\x01\x00\x00\x00'
- self._fake_file_handle.read = mock.MagicMock(
- side_effect=[fake_metadata_offset, fake_metadata_size])
-
- metadata_size, metadata_offset = (
- self._vhdutils._get_vhdx_metadata_size_and_offset(
- self._fake_file_handle))
- self.assertEqual(metadata_size, 1)
- self.assertEqual(metadata_offset, 1)
-
- def test_get_block_size(self):
- self._vhdutils._get_vhdx_metadata_size_and_offset = mock.MagicMock(
- return_value=(self._FAKE_METADATA_SIZE, 1024))
- fake_block_size = '\x01\x00\x00\x00'
- self._fake_file_handle.read = mock.MagicMock(
- return_value=fake_block_size)
-
- block_size = self._vhdutils._get_vhdx_block_size(
- self._fake_file_handle)
- self.assertEqual(block_size, 1)
-
- def test_get_log_size(self):
- fake_current_header_offset = 64 * 1024
- self._vhdutils._get_vhdx_current_header_offset = mock.MagicMock(
- return_value=fake_current_header_offset)
- fake_log_size = '\x01\x00\x00\x00'
- self._fake_file_handle.read = mock.MagicMock(
- return_value=fake_log_size)
-
- log_size = self._vhdutils._get_vhdx_log_size(self._fake_file_handle)
- self.assertEqual(log_size, 1)
-
- def test_get_supported_vhd_format(self):
- fmt = self._vhdutils.get_best_supported_vhd_format()
- self.assertEqual(constants.DISK_FORMAT_VHDX, fmt)
diff --git a/nova/tests/unit/virt/hyperv/test_vmutils.py b/nova/tests/unit/virt/hyperv/test_vmutils.py
deleted file mode 100644
index eac39c1705..0000000000
--- a/nova/tests/unit/virt/hyperv/test_vmutils.py
+++ /dev/null
@@ -1,918 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from six.moves import range
-
-from nova import exception
-from nova import test
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vmutils
-
-
-class VMUtilsTestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V VMUtils class."""
-
- _FAKE_VM_NAME = 'fake_vm'
- _FAKE_MEMORY_MB = 2
- _FAKE_VCPUS_NUM = 4
- _FAKE_JOB_PATH = 'fake_job_path'
- _FAKE_RET_VAL = 0
- _FAKE_RET_VAL_BAD = -1
- _FAKE_PATH = "fake_path"
- _FAKE_CTRL_PATH = 'fake_ctrl_path'
- _FAKE_CTRL_ADDR = 0
- _FAKE_DRIVE_ADDR = 0
- _FAKE_MOUNTED_DISK_PATH = 'fake_mounted_disk_path'
- _FAKE_VM_PATH = "fake_vm_path"
- _FAKE_VHD_PATH = "fake_vhd_path"
- _FAKE_DVD_PATH = "fake_dvd_path"
- _FAKE_VOLUME_DRIVE_PATH = "fake_volume_drive_path"
- _FAKE_VM_UUID = "04e79212-39bc-4065-933c-50f6d48a57f6"
- _FAKE_INSTANCE = {"name": _FAKE_VM_NAME,
- "uuid": _FAKE_VM_UUID}
- _FAKE_SNAPSHOT_PATH = "fake_snapshot_path"
- _FAKE_RES_DATA = "fake_res_data"
- _FAKE_HOST_RESOURCE = "fake_host_resource"
- _FAKE_CLASS = "FakeClass"
- _FAKE_RES_PATH = "fake_res_path"
- _FAKE_RES_NAME = 'fake_res_name'
- _FAKE_ADDRESS = "fake_address"
- _FAKE_JOB_STATUS_DONE = 7
- _FAKE_JOB_STATUS_BAD = -1
- _FAKE_JOB_DESCRIPTION = "fake_job_description"
- _FAKE_ERROR = "fake_error"
- _FAKE_ELAPSED_TIME = 0
- _CONCRETE_JOB = "Msvm_ConcreteJob"
- _FAKE_DYNAMIC_MEMORY_RATIO = 1.0
-
- _FAKE_SUMMARY_INFO = {'NumberOfProcessors': 4,
- 'EnabledState': 2,
- 'MemoryUsage': 2,
- 'UpTime': 1}
-
- _DEFINE_SYSTEM = 'DefineVirtualSystem'
- _DESTROY_SYSTEM = 'DestroyVirtualSystem'
- _DESTROY_SNAPSHOT = 'RemoveVirtualSystemSnapshot'
- _ADD_RESOURCE = 'AddVirtualSystemResources'
- _REMOVE_RESOURCE = 'RemoveVirtualSystemResources'
- _SETTING_TYPE = 'SettingType'
- _VM_GEN = constants.VM_GEN_1
-
- _VIRTUAL_SYSTEM_TYPE_REALIZED = 3
-
- def setUp(self):
- self._vmutils = vmutils.VMUtils()
- self._vmutils._conn = mock.MagicMock()
-
- super(VMUtilsTestCase, self).setUp()
-
- def test_enable_vm_metrics_collection(self):
- self.assertRaises(NotImplementedError,
- self._vmutils.enable_vm_metrics_collection,
- self._FAKE_VM_NAME)
-
- def test_get_vm_summary_info(self):
- self._lookup_vm()
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
-
- mock_summary = mock.MagicMock()
- mock_svc.GetSummaryInformation.return_value = (self._FAKE_RET_VAL,
- [mock_summary])
-
- for (key, val) in self._FAKE_SUMMARY_INFO.items():
- setattr(mock_summary, key, val)
-
- summary = self._vmutils.get_vm_summary_info(self._FAKE_VM_NAME)
- self.assertEqual(self._FAKE_SUMMARY_INFO, summary)
-
- def _lookup_vm(self):
- mock_vm = mock.MagicMock()
- self._vmutils._lookup_vm_check = mock.MagicMock(
- return_value=mock_vm)
- mock_vm.path_.return_value = self._FAKE_VM_PATH
- return mock_vm
-
- def test_lookup_vm_ok(self):
- mock_vm = mock.MagicMock()
- self._vmutils._conn.Msvm_ComputerSystem.return_value = [mock_vm]
- vm = self._vmutils._lookup_vm_check(self._FAKE_VM_NAME)
- self.assertEqual(mock_vm, vm)
-
- def test_lookup_vm_multiple(self):
- mockvm = mock.MagicMock()
- self._vmutils._conn.Msvm_ComputerSystem.return_value = [mockvm, mockvm]
- self.assertRaises(vmutils.HyperVException,
- self._vmutils._lookup_vm_check,
- self._FAKE_VM_NAME)
-
- def test_lookup_vm_none(self):
- self._vmutils._conn.Msvm_ComputerSystem.return_value = []
- self.assertRaises(exception.InstanceNotFound,
- self._vmutils._lookup_vm_check,
- self._FAKE_VM_NAME)
-
- def test_set_vm_memory_static(self):
- self._test_set_vm_memory_dynamic(1.0)
-
- def test_set_vm_memory_dynamic(self):
- self._test_set_vm_memory_dynamic(2.0)
-
- def _test_set_vm_memory_dynamic(self, dynamic_memory_ratio):
- mock_vm = self._lookup_vm()
-
- mock_s = self._vmutils._conn.Msvm_VirtualSystemSettingData()[0]
- mock_s.SystemType = 3
-
- mock_vmsetting = mock.MagicMock()
- mock_vmsetting.associators.return_value = [mock_s]
-
- self._vmutils._modify_virt_resource = mock.MagicMock()
-
- self._vmutils._set_vm_memory(mock_vm, mock_vmsetting,
- self._FAKE_MEMORY_MB,
- dynamic_memory_ratio)
-
- self._vmutils._modify_virt_resource.assert_called_with(
- mock_s, self._FAKE_VM_PATH)
-
- if dynamic_memory_ratio > 1:
- self.assertTrue(mock_s.DynamicMemoryEnabled)
- else:
- self.assertFalse(mock_s.DynamicMemoryEnabled)
-
- def test_soft_shutdown_vm(self):
- mock_vm = self._lookup_vm()
- mock_shutdown = mock.MagicMock()
- mock_shutdown.InitiateShutdown.return_value = (self._FAKE_RET_VAL, )
- mock_vm.associators.return_value = [mock_shutdown]
-
- with mock.patch.object(self._vmutils, 'check_ret_val') as mock_check:
- self._vmutils.soft_shutdown_vm(self._FAKE_VM_NAME)
-
- mock_shutdown.InitiateShutdown.assert_called_once_with(
- Force=False, Reason=mock.ANY)
- mock_check.assert_called_once_with(self._FAKE_RET_VAL, None)
-
- def test_soft_shutdown_vm_no_component(self):
- mock_vm = self._lookup_vm()
- mock_vm.associators.return_value = []
-
- with mock.patch.object(self._vmutils, 'check_ret_val') as mock_check:
- self._vmutils.soft_shutdown_vm(self._FAKE_VM_NAME)
- self.assertFalse(mock_check.called)
-
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils._get_vm_disks')
- def test_get_vm_storage_paths(self, mock_get_vm_disks):
- self._lookup_vm()
- mock_rasds = self._create_mock_disks()
- mock_get_vm_disks.return_value = ([mock_rasds[0]], [mock_rasds[1]])
-
- storage = self._vmutils.get_vm_storage_paths(self._FAKE_VM_NAME)
- (disk_files, volume_drives) = storage
-
- self.assertEqual([self._FAKE_VHD_PATH], disk_files)
- self.assertEqual([self._FAKE_VOLUME_DRIVE_PATH], volume_drives)
-
- def test_get_vm_disks(self):
- mock_vm = self._lookup_vm()
- mock_vmsettings = [mock.MagicMock()]
- mock_vm.associators.return_value = mock_vmsettings
-
- mock_rasds = self._create_mock_disks()
- mock_vmsettings[0].associators.return_value = mock_rasds
-
- (disks, volumes) = self._vmutils._get_vm_disks(mock_vm)
-
- mock_vm.associators.assert_called_with(
- wmi_result_class=self._vmutils._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- mock_vmsettings[0].associators.assert_called_with(
- wmi_result_class=self._vmutils._RESOURCE_ALLOC_SETTING_DATA_CLASS)
- self.assertEqual([mock_rasds[0]], disks)
- self.assertEqual([mock_rasds[1]], volumes)
-
- def _create_mock_disks(self):
- mock_rasd1 = mock.MagicMock()
- mock_rasd1.ResourceSubType = self._vmutils._HARD_DISK_RES_SUB_TYPE
- mock_rasd1.HostResource = [self._FAKE_VHD_PATH]
- mock_rasd1.Connection = [self._FAKE_VHD_PATH]
- mock_rasd1.Parent = self._FAKE_CTRL_PATH
- mock_rasd1.Address = self._FAKE_ADDRESS
- mock_rasd1.HostResource = [self._FAKE_VHD_PATH]
-
- mock_rasd2 = mock.MagicMock()
- mock_rasd2.ResourceSubType = self._vmutils._PHYS_DISK_RES_SUB_TYPE
- mock_rasd2.HostResource = [self._FAKE_VOLUME_DRIVE_PATH]
-
- return [mock_rasd1, mock_rasd2]
-
- @mock.patch.object(vmutils.VMUtils, '_set_vm_vcpus')
- @mock.patch.object(vmutils.VMUtils, '_set_vm_memory')
- @mock.patch.object(vmutils.VMUtils, '_get_wmi_obj')
- def test_create_vm(self, mock_get_wmi_obj, mock_set_mem, mock_set_vcpus):
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- getattr(mock_svc, self._DEFINE_SYSTEM).return_value = (
- None, self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- mock_vm = mock_get_wmi_obj.return_value
- self._vmutils._conn.Msvm_ComputerSystem.return_value = [mock_vm]
-
- mock_s = mock.MagicMock()
- setattr(mock_s,
- self._SETTING_TYPE,
- self._VIRTUAL_SYSTEM_TYPE_REALIZED)
- mock_vm.associators.return_value = [mock_s]
-
- self._vmutils.create_vm(self._FAKE_VM_NAME, self._FAKE_MEMORY_MB,
- self._FAKE_VCPUS_NUM, False,
- self._FAKE_DYNAMIC_MEMORY_RATIO,
- self._VM_GEN,
- mock.sentinel.instance_path)
-
- self.assertTrue(getattr(mock_svc, self._DEFINE_SYSTEM).called)
- mock_set_mem.assert_called_with(mock_vm, mock_s, self._FAKE_MEMORY_MB,
- self._FAKE_DYNAMIC_MEMORY_RATIO)
-
- mock_set_vcpus.assert_called_with(mock_vm, mock_s,
- self._FAKE_VCPUS_NUM,
- False)
-
- def test_get_vm_scsi_controller(self):
- self._prepare_get_vm_controller(self._vmutils._SCSI_CTRL_RES_SUB_TYPE)
- path = self._vmutils.get_vm_scsi_controller(self._FAKE_VM_NAME)
- self.assertEqual(self._FAKE_RES_PATH, path)
-
- @mock.patch("nova.virt.hyperv.vmutils.VMUtils.get_attached_disks")
- def test_get_free_controller_slot(self, mock_get_attached_disks):
- with mock.patch.object(self._vmutils,
- '_get_disk_resource_address') as mock_get_addr:
- mock_get_addr.return_value = 3
- mock_get_attached_disks.return_value = [mock.sentinel.disk]
-
- response = self._vmutils.get_free_controller_slot(
- self._FAKE_CTRL_PATH)
-
- mock_get_attached_disks.assert_called_once_with(
- self._FAKE_CTRL_PATH)
-
- self.assertEqual(response, 0)
-
- def test_get_free_controller_slot_exception(self):
- mock_get_address = mock.Mock()
- mock_get_address.side_effect = range(
- constants.SCSI_CONTROLLER_SLOTS_NUMBER)
-
- mock_get_attached_disks = mock.Mock()
- mock_get_attached_disks.return_value = (
- [mock.sentinel.drive] * constants.SCSI_CONTROLLER_SLOTS_NUMBER)
-
- with mock.patch.multiple(self._vmutils,
- get_attached_disks=mock_get_attached_disks,
- _get_disk_resource_address=mock_get_address):
- self.assertRaises(vmutils.HyperVException,
- self._vmutils.get_free_controller_slot,
- mock.sentinel.scsi_controller_path)
-
- def test_get_vm_ide_controller(self):
- self._prepare_get_vm_controller(self._vmutils._IDE_CTRL_RES_SUB_TYPE)
- path = self._vmutils.get_vm_ide_controller(self._FAKE_VM_NAME,
- self._FAKE_ADDRESS)
- self.assertEqual(self._FAKE_RES_PATH, path)
-
- def test_get_vm_ide_controller_none(self):
- self._prepare_get_vm_controller(self._vmutils._IDE_CTRL_RES_SUB_TYPE)
- path = self._vmutils.get_vm_ide_controller(
- mock.sentinel.FAKE_VM_NAME, mock.sentinel.FAKE_NOT_FOUND_ADDR)
- self.assertNotEqual(self._FAKE_RES_PATH, path)
-
- def _prepare_get_vm_controller(self, resource_sub_type):
- mock_vm = self._lookup_vm()
- mock_vm_settings = mock.MagicMock()
- mock_rasds = mock.MagicMock()
- mock_rasds.path_.return_value = self._FAKE_RES_PATH
- mock_rasds.ResourceSubType = resource_sub_type
- mock_rasds.Address = self._FAKE_ADDRESS
- mock_vm_settings.associators.return_value = [mock_rasds]
- mock_vm.associators.return_value = [mock_vm_settings]
-
- def _prepare_resources(self, mock_path, mock_subtype, mock_vm_settings):
- mock_rasds = mock_vm_settings.associators.return_value[0]
- mock_rasds.path_.return_value = mock_path
- mock_rasds.ResourceSubType = mock_subtype
- return mock_rasds
-
- @mock.patch("nova.virt.hyperv.vmutils.VMUtils.get_free_controller_slot")
- @mock.patch("nova.virt.hyperv.vmutils.VMUtils._get_vm_scsi_controller")
- def test_attach_scsi_drive(self, mock_get_vm_scsi_controller,
- mock_get_free_controller_slot):
- mock_vm = self._lookup_vm()
- mock_get_vm_scsi_controller.return_value = self._FAKE_CTRL_PATH
- mock_get_free_controller_slot.return_value = self._FAKE_DRIVE_ADDR
-
- with mock.patch.object(self._vmutils,
- 'attach_drive') as mock_attach_drive:
- self._vmutils.attach_scsi_drive(mock_vm, self._FAKE_PATH,
- constants.DISK)
-
- mock_get_vm_scsi_controller.assert_called_once_with(mock_vm)
- mock_get_free_controller_slot.assert_called_once_with(
- self._FAKE_CTRL_PATH)
- mock_attach_drive.assert_called_once_with(
- mock_vm, self._FAKE_PATH, self._FAKE_CTRL_PATH,
- self._FAKE_DRIVE_ADDR, constants.DISK)
-
- @mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
- @mock.patch.object(vmutils.VMUtils, '_get_vm_ide_controller')
- def test_attach_ide_drive(self, mock_get_ide_ctrl, mock_get_new_rsd):
- mock_vm = self._lookup_vm()
- mock_rsd = mock_get_new_rsd.return_value
-
- with mock.patch.object(self._vmutils,
- '_add_virt_resource') as mock_add_virt_res:
- self._vmutils.attach_ide_drive(self._FAKE_VM_NAME,
- self._FAKE_CTRL_PATH,
- self._FAKE_CTRL_ADDR,
- self._FAKE_DRIVE_ADDR)
-
- mock_add_virt_res.assert_called_with(mock_rsd,
- mock_vm.path_.return_value)
-
- mock_get_ide_ctrl.assert_called_with(mock_vm, self._FAKE_CTRL_ADDR)
- self.assertTrue(mock_get_new_rsd.called)
-
- @mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
- def test_create_scsi_controller(self, mock_get_new_rsd):
- mock_vm = self._lookup_vm()
- with mock.patch.object(self._vmutils,
- '_add_virt_resource') as mock_add_virt_res:
- self._vmutils.create_scsi_controller(self._FAKE_VM_NAME)
-
- mock_add_virt_res.assert_called_with(mock_get_new_rsd.return_value,
- mock_vm.path_.return_value)
-
- @mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
- def test_attach_volume_to_controller(self, mock_get_new_rsd):
- mock_vm = self._lookup_vm()
- with mock.patch.object(self._vmutils,
- '_add_virt_resource') as mock_add_virt_res:
- self._vmutils.attach_volume_to_controller(
- self._FAKE_VM_NAME, self._FAKE_CTRL_PATH, self._FAKE_CTRL_ADDR,
- self._FAKE_MOUNTED_DISK_PATH)
-
- mock_add_virt_res.assert_called_with(mock_get_new_rsd.return_value,
- mock_vm.path_.return_value)
-
- @mock.patch.object(vmutils.VMUtils, '_modify_virt_resource')
- @mock.patch.object(vmutils.VMUtils, '_get_nic_data_by_name')
- def test_set_nic_connection(self, mock_get_nic_conn, mock_modify_virt_res):
- self._lookup_vm()
- mock_nic = mock_get_nic_conn.return_value
- self._vmutils.set_nic_connection(self._FAKE_VM_NAME, None, None)
-
- mock_modify_virt_res.assert_called_with(mock_nic, self._FAKE_VM_PATH)
-
- @mock.patch.object(vmutils.VMUtils, '_get_new_setting_data')
- def test_create_nic(self, mock_get_new_virt_res):
- self._lookup_vm()
- mock_nic = mock_get_new_virt_res.return_value
-
- with mock.patch.object(self._vmutils,
- '_add_virt_resource') as mock_add_virt_res:
- self._vmutils.create_nic(
- self._FAKE_VM_NAME, self._FAKE_RES_NAME, self._FAKE_ADDRESS)
-
- mock_add_virt_res.assert_called_with(mock_nic, self._FAKE_VM_PATH)
-
- @mock.patch.object(vmutils.VMUtils, '_get_nic_data_by_name')
- def test_destroy_nic(self, mock_get_nic_data_by_name):
- self._lookup_vm()
- fake_nic_data = mock_get_nic_data_by_name.return_value
- with mock.patch.object(self._vmutils,
- '_remove_virt_resource') as mock_rem_virt_res:
- self._vmutils.destroy_nic(self._FAKE_VM_NAME,
- mock.sentinel.FAKE_NIC_NAME)
- mock_rem_virt_res.assert_called_once_with(fake_nic_data,
- self._FAKE_VM_PATH)
-
- def test_set_vm_state(self):
- mock_vm = self._lookup_vm()
- mock_vm.RequestStateChange.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vmutils.set_vm_state(self._FAKE_VM_NAME,
- constants.HYPERV_VM_STATE_ENABLED)
- mock_vm.RequestStateChange.assert_called_with(
- constants.HYPERV_VM_STATE_ENABLED)
-
- def test_destroy_vm(self):
- self._lookup_vm()
-
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- getattr(mock_svc, self._DESTROY_SYSTEM).return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vmutils.destroy_vm(self._FAKE_VM_NAME)
-
- getattr(mock_svc, self._DESTROY_SYSTEM).assert_called_with(
- self._FAKE_VM_PATH)
-
- @mock.patch.object(vmutils.VMUtils, '_wait_for_job')
- def test_check_ret_val_ok(self, mock_wait_for_job):
- self._vmutils.check_ret_val(constants.WMI_JOB_STATUS_STARTED,
- self._FAKE_JOB_PATH)
- mock_wait_for_job.assert_called_once_with(self._FAKE_JOB_PATH)
-
- def test_check_ret_val_exception(self):
- self.assertRaises(vmutils.HyperVException,
- self._vmutils.check_ret_val,
- self._FAKE_RET_VAL_BAD,
- self._FAKE_JOB_PATH)
-
- def test_wait_for_job_done(self):
- mockjob = self._prepare_wait_for_job(constants.WMI_JOB_STATE_COMPLETED)
- job = self._vmutils._wait_for_job(self._FAKE_JOB_PATH)
- self.assertEqual(mockjob, job)
-
- def test_wait_for_job_killed(self):
- mockjob = self._prepare_wait_for_job(constants.JOB_STATE_KILLED)
- job = self._vmutils._wait_for_job(self._FAKE_JOB_PATH)
- self.assertEqual(mockjob, job)
-
- def test_wait_for_job_exception_concrete_job(self):
- mock_job = self._prepare_wait_for_job()
- mock_job.path.return_value.Class = self._CONCRETE_JOB
- self.assertRaises(vmutils.HyperVException,
- self._vmutils._wait_for_job,
- self._FAKE_JOB_PATH)
-
- def test_wait_for_job_exception_with_error(self):
- mock_job = self._prepare_wait_for_job()
- mock_job.GetError.return_value = (self._FAKE_ERROR, self._FAKE_RET_VAL)
- self.assertRaises(vmutils.HyperVException,
- self._vmutils._wait_for_job,
- self._FAKE_JOB_PATH)
-
- def test_wait_for_job_exception_no_error(self):
- mock_job = self._prepare_wait_for_job()
- mock_job.GetError.return_value = (None, None)
- self.assertRaises(vmutils.HyperVException,
- self._vmutils._wait_for_job,
- self._FAKE_JOB_PATH)
-
- def _prepare_wait_for_job(self, state=_FAKE_JOB_STATUS_BAD):
- mock_job = mock.MagicMock()
- mock_job.JobState = state
- mock_job.Description = self._FAKE_JOB_DESCRIPTION
- mock_job.ElapsedTime = self._FAKE_ELAPSED_TIME
-
- self._vmutils._get_wmi_obj = mock.MagicMock(return_value=mock_job)
- return mock_job
-
- def test_add_virt_resource(self):
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- getattr(mock_svc, self._ADD_RESOURCE).return_value = (
- self._FAKE_JOB_PATH, mock.MagicMock(), self._FAKE_RET_VAL)
- mock_res_setting_data = mock.MagicMock()
- mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA
-
- self._vmutils._add_virt_resource(mock_res_setting_data,
- self._FAKE_VM_PATH)
- self._assert_add_resources(mock_svc)
-
- def test_modify_virt_resource(self):
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- mock_svc.ModifyVirtualSystemResources.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
- mock_res_setting_data = mock.MagicMock()
- mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA
-
- self._vmutils._modify_virt_resource(mock_res_setting_data,
- self._FAKE_VM_PATH)
-
- mock_svc.ModifyVirtualSystemResources.assert_called_with(
- ResourceSettingData=[self._FAKE_RES_DATA],
- ComputerSystem=self._FAKE_VM_PATH)
-
- def test_remove_virt_resource(self):
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- getattr(mock_svc, self._REMOVE_RESOURCE).return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
- mock_res_setting_data = mock.MagicMock()
- mock_res_setting_data.path_.return_value = self._FAKE_RES_PATH
-
- self._vmutils._remove_virt_resource(mock_res_setting_data,
- self._FAKE_VM_PATH)
- self._assert_remove_resources(mock_svc)
-
- def test_set_disk_host_resource(self):
- self._lookup_vm()
- mock_rasds = self._create_mock_disks()
-
- self._vmutils._get_vm_disks = mock.MagicMock(
- return_value=([mock_rasds[0]], [mock_rasds[1]]))
- self._vmutils._modify_virt_resource = mock.MagicMock()
- self._vmutils._get_disk_resource_address = mock.MagicMock(
- return_value=self._FAKE_ADDRESS)
-
- self._vmutils.set_disk_host_resource(
- self._FAKE_VM_NAME,
- self._FAKE_CTRL_PATH,
- self._FAKE_ADDRESS,
- mock.sentinel.fake_new_mounted_disk_path)
- self._vmutils._get_disk_resource_address.assert_called_with(
- mock_rasds[0])
- self._vmutils._modify_virt_resource.assert_called_with(
- mock_rasds[0], self._FAKE_VM_PATH)
- self.assertEqual(
- mock.sentinel.fake_new_mounted_disk_path,
- mock_rasds[0].HostResource[0])
-
- @mock.patch.object(vmutils, 'wmi', create=True)
- @mock.patch.object(vmutils.VMUtils, 'check_ret_val')
- def test_take_vm_snapshot(self, mock_check_ret_val, mock_wmi):
- self._lookup_vm()
-
- mock_svc = self._get_snapshot_service()
- mock_svc.CreateVirtualSystemSnapshot.return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL, mock.MagicMock())
-
- self._vmutils.take_vm_snapshot(self._FAKE_VM_NAME)
-
- mock_svc.CreateVirtualSystemSnapshot.assert_called_with(
- self._FAKE_VM_PATH)
-
- mock_check_ret_val.assert_called_once_with(self._FAKE_RET_VAL,
- self._FAKE_JOB_PATH)
-
- def test_remove_vm_snapshot(self):
- mock_svc = self._get_snapshot_service()
- getattr(mock_svc, self._DESTROY_SNAPSHOT).return_value = (
- self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
-
- self._vmutils.remove_vm_snapshot(self._FAKE_SNAPSHOT_PATH)
- getattr(mock_svc, self._DESTROY_SNAPSHOT).assert_called_with(
- self._FAKE_SNAPSHOT_PATH)
-
- def test_detach_vm_disk(self):
- self._lookup_vm()
- mock_disk = self._prepare_mock_disk()
-
- with mock.patch.object(self._vmutils,
- '_remove_virt_resource') as mock_rm_virt_res:
- self._vmutils.detach_vm_disk(self._FAKE_VM_NAME,
- self._FAKE_HOST_RESOURCE)
-
- mock_rm_virt_res.assert_called_with(mock_disk, self._FAKE_VM_PATH)
-
- def _test_get_mounted_disk_resource_from_path(self, is_physical):
- mock_disk_1 = mock.MagicMock()
- mock_disk_2 = mock.MagicMock()
- conn_attr = (self._vmutils._PHYS_DISK_CONNECTION_ATTR if is_physical
- else self._vmutils._VIRT_DISK_CONNECTION_ATTR)
- setattr(mock_disk_2, conn_attr, [self._FAKE_MOUNTED_DISK_PATH])
- self._vmutils._conn.query.return_value = [mock_disk_1, mock_disk_2]
-
- mounted_disk = self._vmutils._get_mounted_disk_resource_from_path(
- self._FAKE_MOUNTED_DISK_PATH, is_physical)
-
- self.assertEqual(mock_disk_2, mounted_disk)
-
- def test_get_physical_mounted_disk_resource_from_path(self):
- self._test_get_mounted_disk_resource_from_path(is_physical=True)
-
- def test_get_virtual_mounted_disk_resource_from_path(self):
- self._test_get_mounted_disk_resource_from_path(is_physical=False)
-
- def test_get_controller_volume_paths(self):
- self._prepare_mock_disk()
- mock_disks = {self._FAKE_RES_PATH: self._FAKE_HOST_RESOURCE}
- disks = self._vmutils.get_controller_volume_paths(self._FAKE_RES_PATH)
- self.assertEqual(mock_disks, disks)
-
- def _prepare_mock_disk(self):
- mock_disk = mock.MagicMock()
- mock_disk.HostResource = [self._FAKE_HOST_RESOURCE]
- mock_disk.path.return_value.RelPath = self._FAKE_RES_PATH
- mock_disk.ResourceSubType = self._vmutils._HARD_DISK_RES_SUB_TYPE
- self._vmutils._conn.query.return_value = [mock_disk]
-
- return mock_disk
-
- def _get_snapshot_service(self):
- return self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
-
- def _assert_add_resources(self, mock_svc):
- getattr(mock_svc, self._ADD_RESOURCE).assert_called_with(
- [self._FAKE_RES_DATA], self._FAKE_VM_PATH)
-
- def _assert_remove_resources(self, mock_svc):
- getattr(mock_svc, self._REMOVE_RESOURCE).assert_called_with(
- [self._FAKE_RES_PATH], self._FAKE_VM_PATH)
-
- def test_get_active_instances(self):
- fake_vm = mock.MagicMock()
-
- type(fake_vm).ElementName = mock.PropertyMock(
- side_effect=['active_vm', 'inactive_vm'])
- type(fake_vm).EnabledState = mock.PropertyMock(
- side_effect=[constants.HYPERV_VM_STATE_ENABLED,
- constants.HYPERV_VM_STATE_DISABLED])
- self._vmutils.list_instances = mock.MagicMock(
- return_value=[mock.sentinel.fake_vm_name] * 2)
- self._vmutils._lookup_vm = mock.MagicMock(side_effect=[fake_vm] * 2)
- active_instances = self._vmutils.get_active_instances()
-
- self.assertEqual(['active_vm'], active_instances)
-
- def _test_get_vm_serial_port_connection(self, new_connection=None):
- old_serial_connection = 'old_serial_connection'
-
- mock_vm = self._lookup_vm()
- mock_vmsettings = [mock.MagicMock()]
- mock_vm.associators.return_value = mock_vmsettings
-
- fake_serial_port = mock.MagicMock()
-
- fake_serial_port.ResourceSubType = (
- self._vmutils._SERIAL_PORT_RES_SUB_TYPE)
- fake_serial_port.Connection = [old_serial_connection]
- mock_rasds = [fake_serial_port]
- mock_vmsettings[0].associators.return_value = mock_rasds
- self._vmutils._modify_virt_resource = mock.MagicMock()
- fake_modify = self._vmutils._modify_virt_resource
-
- ret_val = self._vmutils.get_vm_serial_port_connection(
- self._FAKE_VM_NAME, update_connection=new_connection)
-
- mock_vmsettings[0].associators.assert_called_once_with(
- wmi_result_class=self._vmutils._SERIAL_PORT_SETTING_DATA_CLASS)
-
- if new_connection:
- self.assertEqual(new_connection, ret_val)
- fake_modify.assert_called_once_with(fake_serial_port,
- mock_vm.path_())
- else:
- self.assertEqual(old_serial_connection, ret_val)
-
- def test_set_vm_serial_port_connection(self):
- self._test_get_vm_serial_port_connection('new_serial_connection')
-
- def test_get_vm_serial_port_connection(self):
- self._test_get_vm_serial_port_connection()
-
- def test_list_instance_notes(self):
- vs = mock.MagicMock()
- attrs = {'ElementName': 'fake_name',
- 'Notes': '4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3'}
- vs.configure_mock(**attrs)
- vs2 = mock.MagicMock(ElementName='fake_name2', Notes=None)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs,
- vs2]
- response = self._vmutils.list_instance_notes()
-
- self.assertEqual([(attrs['ElementName'], [attrs['Notes']])], response)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
- ['ElementName', 'Notes'],
- SettingType=self._vmutils._VIRTUAL_SYSTEM_CURRENT_SETTINGS)
-
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils.check_ret_val')
- def test_modify_virtual_system(self, mock_check_ret_val):
- mock_vs_man_svc = mock.MagicMock()
- mock_vmsetting = mock.MagicMock()
- fake_path = 'fake path'
- fake_job_path = 'fake job path'
- fake_ret_val = 'fake return value'
-
- mock_vs_man_svc.ModifyVirtualSystem.return_value = (0, fake_job_path,
- fake_ret_val)
-
- self._vmutils._modify_virtual_system(vs_man_svc=mock_vs_man_svc,
- vm_path=fake_path,
- vmsetting=mock_vmsetting)
-
- mock_vs_man_svc.ModifyVirtualSystem.assert_called_once_with(
- ComputerSystem=fake_path,
- SystemSettingData=mock_vmsetting.GetText_(1))
- mock_check_ret_val.assert_called_once_with(fake_ret_val, fake_job_path)
-
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils.check_ret_val')
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils._get_wmi_obj')
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils._modify_virtual_system')
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils._get_vm_setting_data')
- def test_create_vm_obj(self, mock_get_vm_setting_data,
- mock_modify_virtual_system,
- mock_get_wmi_obj, mock_check_ret_val):
- mock_vs_man_svc = mock.MagicMock()
- mock_vs_gs_data = mock.MagicMock()
- fake_vm_path = 'fake vm path'
- fake_job_path = 'fake job path'
- fake_ret_val = 'fake return value'
- _conn = self._vmutils._conn.Msvm_VirtualSystemGlobalSettingData
-
- _conn.new.return_value = mock_vs_gs_data
- mock_vs_man_svc.DefineVirtualSystem.return_value = (fake_vm_path,
- fake_job_path,
- fake_ret_val)
-
- response = self._vmutils._create_vm_obj(
- vs_man_svc=mock_vs_man_svc,
- vm_name='fake vm', vm_gen='fake vm gen',
- notes='fake notes', dynamic_memory_ratio=1.0,
- instance_path=mock.sentinel.instance_path)
-
- _conn.new.assert_called_once_with()
- self.assertEqual(mock_vs_gs_data.ElementName, 'fake vm')
- mock_vs_man_svc.DefineVirtualSystem.assert_called_once_with(
- [], None, mock_vs_gs_data.GetText_(1))
- mock_check_ret_val.assert_called_once_with(fake_ret_val, fake_job_path)
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_gs_data.ExternalDataRoot)
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_gs_data.SnapshotDataRoot)
-
- mock_get_wmi_obj.assert_called_with(fake_vm_path)
- mock_get_vm_setting_data.assert_called_once_with(mock_get_wmi_obj())
- mock_modify_virtual_system.assert_called_once_with(
- mock_vs_man_svc, fake_vm_path, mock_get_vm_setting_data())
-
- self.assertEqual(mock_get_vm_setting_data().Notes,
- '\n'.join('fake notes'))
- self.assertEqual(response, mock_get_wmi_obj())
-
- def test_list_instances(self):
- vs = mock.MagicMock()
- attrs = {'ElementName': 'fake_name'}
- vs.configure_mock(**attrs)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs]
- response = self._vmutils.list_instances()
-
- self.assertEqual([(attrs['ElementName'])], response)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
- ['ElementName'],
- SettingType=self._vmutils._VIRTUAL_SYSTEM_CURRENT_SETTINGS)
-
- @mock.patch.object(vmutils.VMUtils, "_clone_wmi_obj")
- def _test_check_clone_wmi_obj(self, mock_clone_wmi_obj, clone_objects):
- mock_obj = mock.MagicMock()
- self._vmutils._clone_wmi_objs = clone_objects
-
- response = self._vmutils._check_clone_wmi_obj(class_name="fakeClass",
- obj=mock_obj)
- if not clone_objects:
- self.assertEqual(mock_obj, response)
- else:
- mock_clone_wmi_obj.assert_called_once_with("fakeClass", mock_obj)
- self.assertEqual(mock_clone_wmi_obj.return_value, response)
-
- def test_check_clone_wmi_obj_true(self):
- self._test_check_clone_wmi_obj(clone_objects=True)
-
- def test_check_clone_wmi_obj_false(self):
- self._test_check_clone_wmi_obj(clone_objects=False)
-
- def test_clone_wmi_obj(self):
- mock_obj = mock.MagicMock()
- mock_value = mock.MagicMock()
- mock_value.Value = mock.sentinel.fake_value
- mock_obj._properties = [mock.sentinel.property]
- mock_obj.Properties_.Item.return_value = mock_value
-
- response = self._vmutils._clone_wmi_obj(
- class_name="FakeClass", obj=mock_obj)
-
- compare = self._vmutils._conn.FakeClass.new()
- self.assertEqual(mock.sentinel.fake_value,
- compare.Properties_.Item().Value)
- self.assertEqual(compare, response)
-
- def test_get_attached_disks(self):
- mock_scsi_ctrl_path = mock.MagicMock()
- expected_query = ("SELECT * FROM %(class_name)s "
- "WHERE (ResourceSubType='%(res_sub_type)s' OR "
- "ResourceSubType='%(res_sub_type_virt)s')"
- " AND Parent='%(parent)s'" %
- {"class_name":
- self._vmutils._RESOURCE_ALLOC_SETTING_DATA_CLASS,
- "res_sub_type":
- self._vmutils._PHYS_DISK_RES_SUB_TYPE,
- "res_sub_type_virt":
- self._vmutils._DISK_DRIVE_RES_SUB_TYPE,
- "parent":
- mock_scsi_ctrl_path.replace("'", "''")})
- expected_disks = self._vmutils._conn.query.return_value
-
- ret_disks = self._vmutils.get_attached_disks(mock_scsi_ctrl_path)
-
- self._vmutils._conn.query.assert_called_once_with(expected_query)
- self.assertEqual(expected_disks, ret_disks)
-
- def _get_fake_instance_notes(self):
- return self._FAKE_VM_UUID
-
- def test_instance_notes(self):
- self._lookup_vm()
- mock_vm_settings = mock.Mock()
- mock_vm_settings.Notes = self._get_fake_instance_notes()
- self._vmutils._get_vm_setting_data = mock.Mock(
- return_value=mock_vm_settings)
-
- notes = self._vmutils._get_instance_notes(mock.sentinel.vm_name)
-
- self.assertEqual(notes[0], self._FAKE_VM_UUID)
-
- def test_get_event_wql_query(self):
- cls = self._vmutils._COMPUTER_SYSTEM_CLASS
- field = self._vmutils._VM_ENABLED_STATE_PROP
- timeframe = 10
- filtered_states = [constants.HYPERV_VM_STATE_ENABLED,
- constants.HYPERV_VM_STATE_DISABLED]
-
- expected_checks = ' OR '.join(
- ["TargetInstance.%s = '%s'" % (field, state)
- for state in filtered_states])
- expected_query = (
- "SELECT %(field)s, TargetInstance "
- "FROM __InstanceModificationEvent "
- "WITHIN %(timeframe)s "
- "WHERE TargetInstance ISA '%(class)s' "
- "AND TargetInstance.%(field)s != "
- "PreviousInstance.%(field)s "
- "AND (%(checks)s)" %
- {'class': cls,
- 'field': field,
- 'timeframe': timeframe,
- 'checks': expected_checks})
-
- query = self._vmutils._get_event_wql_query(
- cls=cls, field=field, timeframe=timeframe,
- filtered_states=filtered_states)
- self.assertEqual(expected_query, query)
-
- def test_get_vm_power_state_change_listener(self):
- with mock.patch.object(self._vmutils,
- '_get_event_wql_query') as mock_get_query:
- listener = self._vmutils.get_vm_power_state_change_listener(
- mock.sentinel.timeframe,
- mock.sentinel.filtered_states)
-
- mock_get_query.assert_called_once_with(
- cls=self._vmutils._COMPUTER_SYSTEM_CLASS,
- field=self._vmutils._VM_ENABLED_STATE_PROP,
- timeframe=mock.sentinel.timeframe,
- filtered_states=mock.sentinel.filtered_states)
- watcher = self._vmutils._conn.Msvm_ComputerSystem.watch_for
- watcher.assert_called_once_with(
- raw_wql=mock_get_query.return_value,
- fields=[self._vmutils._VM_ENABLED_STATE_PROP])
-
- self.assertEqual(watcher.return_value, listener)
-
- def test_get_vm_generation_gen1(self):
- ret = self._vmutils.get_vm_generation(mock.sentinel.FAKE_VM_NAME)
- self.assertEqual(constants.VM_GEN_1, ret)
-
- def test_stop_vm_jobs(self):
- mock_vm = self._lookup_vm()
-
- mock_job1 = mock.MagicMock(Cancellable=True)
- mock_job2 = mock.MagicMock(Cancellable=True)
- mock_job3 = mock.MagicMock(Cancellable=True)
-
- mock_job1.JobState = 2
- mock_job2.JobState = 3
- mock_job3.JobState = constants.JOB_STATE_KILLED
-
- mock_vm_jobs = [mock_job1, mock_job2, mock_job3]
-
- mock_vm.associators.return_value = mock_vm_jobs
-
- self._vmutils.stop_vm_jobs(mock.sentinel.FAKE_VM_NAME)
-
- mock_job1.RequestStateChange.assert_called_once_with(
- self._vmutils._KILL_JOB_STATE_CHANGE_REQUEST)
- mock_job2.RequestStateChange.assert_called_once_with(
- self._vmutils._KILL_JOB_STATE_CHANGE_REQUEST)
- self.assertFalse(mock_job3.RequestStateChange.called)
-
- def test_is_job_completed_true(self):
- job = mock.MagicMock(JobState=constants.JOB_STATE_COMPLETED)
-
- self.assertTrue(self._vmutils._is_job_completed(job))
-
- def test_is_job_completed_false(self):
- job = mock.MagicMock(JobState=constants.WMI_JOB_STATE_RUNNING)
-
- self.assertFalse(self._vmutils._is_job_completed(job))
diff --git a/nova/tests/unit/virt/hyperv/test_vmutilsv2.py b/nova/tests/unit/virt/hyperv/test_vmutilsv2.py
deleted file mode 100644
index 4d8b5ff65b..0000000000
--- a/nova/tests/unit/virt/hyperv/test_vmutilsv2.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova.tests.unit.virt.hyperv import test_vmutils
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vmutilsv2
-
-
-class VMUtilsV2TestCase(test_vmutils.VMUtilsTestCase):
- """Unit tests for the Hyper-V VMUtilsV2 class."""
-
- _DEFINE_SYSTEM = 'DefineSystem'
- _DESTROY_SYSTEM = 'DestroySystem'
- _DESTROY_SNAPSHOT = 'DestroySnapshot'
-
- _ADD_RESOURCE = 'AddResourceSettings'
- _REMOVE_RESOURCE = 'RemoveResourceSettings'
- _SETTING_TYPE = 'VirtualSystemType'
- _VM_GEN = constants.VM_GEN_2
-
- _VIRTUAL_SYSTEM_TYPE_REALIZED = 'Microsoft:Hyper-V:System:Realized'
-
- def setUp(self):
- super(VMUtilsV2TestCase, self).setUp()
- self._vmutils = vmutilsv2.VMUtilsV2()
- self._vmutils._conn = mock.MagicMock()
-
- @mock.patch('nova.virt.hyperv.hostutils.HostUtils'
- '.check_min_windows_version')
- @mock.patch.object(vmutilsv2, 'sys')
- def test_serial_port_setting_data_win_version_10(self, mock_sys,
- mock_check_version):
- mock_sys.platform = 'win32'
- mock_check_version.return_value = True
- _vmutils = vmutilsv2.VMUtilsV2()
-
- self.assertEqual("Msvm_SerialPortSettingData",
- _vmutils._SERIAL_PORT_SETTING_DATA_CLASS)
-
- def test_create_vm(self):
- super(VMUtilsV2TestCase, self).test_create_vm()
- mock_vssd = self._vmutils._conn.Msvm_VirtualSystemSettingData.new()
- self.assertEqual(self._vmutils._VIRTUAL_SYSTEM_SUBTYPE_GEN2,
- mock_vssd.VirtualSystemSubType)
- self.assertFalse(mock_vssd.SecureBootEnabled)
-
- def test_modify_virt_resource(self):
- mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
- mock_svc.ModifyResourceSettings.return_value = (self._FAKE_JOB_PATH,
- mock.MagicMock(),
- self._FAKE_RET_VAL)
- mock_res_setting_data = mock.MagicMock()
- mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA
-
- self._vmutils._modify_virt_resource(mock_res_setting_data,
- self._FAKE_VM_PATH)
-
- mock_svc.ModifyResourceSettings.assert_called_with(
- ResourceSettings=[self._FAKE_RES_DATA])
-
- @mock.patch.object(vmutilsv2, 'wmi', create=True)
- @mock.patch.object(vmutilsv2.VMUtilsV2, 'check_ret_val')
- def test_take_vm_snapshot(self, mock_check_ret_val, mock_wmi):
- self._lookup_vm()
-
- mock_svc = self._get_snapshot_service()
- mock_svc.CreateSnapshot.return_value = (self._FAKE_JOB_PATH,
- mock.MagicMock(),
- self._FAKE_RET_VAL)
-
- self._vmutils.take_vm_snapshot(self._FAKE_VM_NAME)
-
- mock_svc.CreateSnapshot.assert_called_with(
- AffectedSystem=self._FAKE_VM_PATH,
- SnapshotType=self._vmutils._SNAPSHOT_FULL)
-
- mock_check_ret_val.assert_called_once_with(self._FAKE_RET_VAL,
- self._FAKE_JOB_PATH)
-
- @mock.patch.object(vmutilsv2.VMUtilsV2, '_add_virt_resource')
- @mock.patch.object(vmutilsv2.VMUtilsV2, '_get_new_setting_data')
- @mock.patch.object(vmutilsv2.VMUtilsV2, '_get_nic_data_by_name')
- def test_set_nic_connection(self, mock_get_nic_data, mock_get_new_sd,
- mock_add_virt_res):
- self._lookup_vm()
- fake_eth_port = mock_get_new_sd.return_value
-
- self._vmutils.set_nic_connection(self._FAKE_VM_NAME, None, None)
- mock_add_virt_res.assert_called_with(fake_eth_port, self._FAKE_VM_PATH)
-
- @mock.patch('nova.virt.hyperv.vmutils.VMUtils._get_vm_disks')
- def test_enable_vm_metrics_collection(self, mock_get_vm_disks):
- self._lookup_vm()
- mock_svc = self._vmutils._conn.Msvm_MetricService()[0]
-
- metric_def = mock.MagicMock()
- mock_disk = mock.MagicMock()
- mock_disk.path_.return_value = self._FAKE_RES_PATH
- mock_get_vm_disks.return_value = ([mock_disk], [mock_disk])
-
- fake_metric_def_paths = ['fake_0', 'fake_0', None]
- fake_metric_resource_paths = [self._FAKE_VM_PATH,
- self._FAKE_VM_PATH,
- self._FAKE_RES_PATH]
-
- metric_def.path_.side_effect = fake_metric_def_paths
- self._vmutils._conn.CIM_BaseMetricDefinition.return_value = [
- metric_def]
-
- self._vmutils.enable_vm_metrics_collection(self._FAKE_VM_NAME)
-
- calls = [mock.call(Name=def_name)
- for def_name in [self._vmutils._METRIC_AGGR_CPU_AVG,
- self._vmutils._METRIC_AGGR_MEMORY_AVG]]
- self._vmutils._conn.CIM_BaseMetricDefinition.assert_has_calls(calls)
-
- calls = []
- for i in range(len(fake_metric_def_paths)):
- calls.append(mock.call(
- Subject=fake_metric_resource_paths[i],
- Definition=fake_metric_def_paths[i],
- MetricCollectionEnabled=self._vmutils._METRIC_ENABLED))
-
- mock_svc.ControlMetrics.assert_has_calls(calls, any_order=True)
-
- def _get_snapshot_service(self):
- return self._vmutils._conn.Msvm_VirtualSystemSnapshotService()[0]
-
- def _assert_add_resources(self, mock_svc):
- getattr(mock_svc, self._ADD_RESOURCE).assert_called_with(
- self._FAKE_VM_PATH, [self._FAKE_RES_DATA])
-
- def _assert_remove_resources(self, mock_svc):
- getattr(mock_svc, self._REMOVE_RESOURCE).assert_called_with(
- [self._FAKE_RES_PATH])
-
- def test_list_instance_notes(self):
- vs = mock.MagicMock()
- attrs = {'ElementName': 'fake_name',
- 'Notes': ['4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3']}
- vs.configure_mock(**attrs)
- vs2 = mock.MagicMock(ElementName='fake_name2', Notes=None)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs,
- vs2]
- response = self._vmutils.list_instance_notes()
-
- self.assertEqual([(attrs['ElementName'], attrs['Notes'])], response)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
- ['ElementName', 'Notes'],
- VirtualSystemType=self._vmutils._VIRTUAL_SYSTEM_TYPE_REALIZED)
-
- def _get_fake_instance_notes(self):
- return [self._FAKE_VM_UUID]
-
- @mock.patch('nova.virt.hyperv.vmutilsv2.VMUtilsV2.check_ret_val')
- @mock.patch('nova.virt.hyperv.vmutilsv2.VMUtilsV2._get_wmi_obj')
- def _test_create_vm_obj(self, mock_get_wmi_obj, mock_check_ret_val,
- vm_path, dynamic_memory_ratio=1.0):
- mock_vs_man_svc = mock.MagicMock()
- mock_vs_data = mock.MagicMock()
- mock_job = mock.MagicMock()
- fake_job_path = 'fake job path'
- fake_ret_val = 'fake return value'
- fake_vm_name = 'fake_vm_name'
- _conn = self._vmutils._conn.Msvm_VirtualSystemSettingData
-
- mock_check_ret_val.return_value = mock_job
- _conn.new.return_value = mock_vs_data
- mock_vs_man_svc.DefineSystem.return_value = (fake_job_path,
- vm_path,
- fake_ret_val)
- mock_job.associators.return_value = ['fake vm path']
-
- response = self._vmutils._create_vm_obj(
- vs_man_svc=mock_vs_man_svc,
- vm_name=fake_vm_name,
- vm_gen='fake vm gen',
- notes='fake notes',
- dynamic_memory_ratio=dynamic_memory_ratio,
- instance_path=mock.sentinel.instance_path)
-
- if not vm_path:
- mock_job.associators.assert_called_once_with(
- self._vmutils._AFFECTED_JOB_ELEMENT_CLASS)
-
- _conn.new.assert_called_once_with()
- self.assertEqual(mock_vs_data.ElementName, fake_vm_name)
- mock_vs_man_svc.DefineSystem.assert_called_once_with(
- ResourceSettings=[], ReferenceConfiguration=None,
- SystemSettings=mock_vs_data.GetText_(1))
- mock_check_ret_val.assert_called_once_with(fake_ret_val, fake_job_path)
-
- if dynamic_memory_ratio > 1:
- self.assertFalse(mock_vs_data.VirtualNumaEnabled)
-
- mock_get_wmi_obj.assert_called_with('fake vm path')
-
- self.assertEqual(mock_vs_data.Notes, 'fake notes')
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_data.ConfigurationDataRoot)
- self.assertEqual(mock.sentinel.instance_path, mock_vs_data.LogDataRoot)
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_data.SnapshotDataRoot)
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_data.SuspendDataRoot)
- self.assertEqual(mock.sentinel.instance_path,
- mock_vs_data.SwapFileDataRoot)
- self.assertEqual(response, mock_get_wmi_obj())
-
- def test_create_vm_obj(self):
- self._test_create_vm_obj(vm_path='fake vm path')
-
- def test_create_vm_obj_no_vm_path(self):
- self._test_create_vm_obj(vm_path=None)
-
- def test_create_vm_obj_dynamic_memory(self):
- self._test_create_vm_obj(vm_path=None, dynamic_memory_ratio=1.1)
-
- def test_list_instances(self):
- vs = mock.MagicMock()
- attrs = {'ElementName': 'fake_name'}
- vs.configure_mock(**attrs)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs]
- response = self._vmutils.list_instances()
-
- self.assertEqual([(attrs['ElementName'])], response)
- self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
- ['ElementName'],
- VirtualSystemType=self._vmutils._VIRTUAL_SYSTEM_TYPE_REALIZED)
-
- def test_get_attached_disks(self):
- mock_scsi_ctrl_path = mock.MagicMock()
- expected_query = ("SELECT * FROM %(class_name)s "
- "WHERE (ResourceSubType='%(res_sub_type)s' OR "
- "ResourceSubType='%(res_sub_type_virt)s' OR "
- "ResourceSubType='%(res_sub_type_dvd)s') AND "
- "Parent = '%(parent)s'" %
- {"class_name":
- self._vmutils._RESOURCE_ALLOC_SETTING_DATA_CLASS,
- "res_sub_type":
- self._vmutils._PHYS_DISK_RES_SUB_TYPE,
- "res_sub_type_virt":
- self._vmutils._DISK_DRIVE_RES_SUB_TYPE,
- "res_sub_type_dvd":
- self._vmutils._DVD_DRIVE_RES_SUB_TYPE,
- "parent": mock_scsi_ctrl_path.replace("'", "''")})
- expected_disks = self._vmutils._conn.query.return_value
-
- ret_disks = self._vmutils.get_attached_disks(mock_scsi_ctrl_path)
-
- self._vmutils._conn.query.assert_called_once_with(expected_query)
- self.assertEqual(expected_disks, ret_disks)
-
- def test_get_vm_dvd_disk_paths(self):
- mock_vm = self._lookup_vm()
- mock_sasd1 = mock.MagicMock(
- ResourceSubType=self._vmutils._DVD_DISK_RES_SUB_TYPE,
- HostResource=[mock.sentinel.FAKE_DVD_PATH1])
- mock_settings = mock.MagicMock()
- mock_settings.associators.return_value = [mock_sasd1]
- mock_vm.associators.return_value = [mock_settings]
-
- ret_val = self._vmutils.get_vm_dvd_disk_paths(self._FAKE_VM_NAME)
- self.assertEqual(mock.sentinel.FAKE_DVD_PATH1, ret_val[0])
-
- @mock.patch.object(vmutilsv2.VMUtilsV2, '_get_vm_setting_data')
- def _test_get_vm_generation(self, vm_gen, mock_get_vm_setting_data):
- self._lookup_vm()
- vm_gen_string = "Microsoft:Hyper-V:SubType:" + str(vm_gen)
- mock_vssd = mock.MagicMock(VirtualSystemSubType=vm_gen_string)
- mock_get_vm_setting_data.return_value = mock_vssd
-
- ret = self._vmutils.get_vm_generation(mock.sentinel.FAKE_VM_NAME)
-
- self.assertEqual(vm_gen, ret)
-
- def test_get_vm_generation_gen1(self):
- self._test_get_vm_generation(constants.VM_GEN_1)
-
- def test_get_vm_generation_gen2(self):
- self._test_get_vm_generation(constants.VM_GEN_2)
diff --git a/nova/tests/unit/virt/hyperv/test_volumeutils.py b/nova/tests/unit/virt/hyperv/test_volumeutils.py
deleted file mode 100644
index 0a3f661cc2..0000000000
--- a/nova/tests/unit/virt/hyperv/test_volumeutils.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-#
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-from oslo_config import cfg
-
-from nova.tests.unit.virt.hyperv import test_basevolumeutils
-from nova.virt.hyperv import vmutils
-from nova.virt.hyperv import volumeutils
-
-CONF = cfg.CONF
-CONF.import_opt('volume_attach_retry_count', 'nova.virt.hyperv.volumeops',
- 'hyperv')
-
-
-class VolumeUtilsTestCase(test_basevolumeutils.BaseVolumeUtilsTestCase):
- """Unit tests for the Hyper-V VolumeUtils class."""
-
- _FAKE_PORTAL_ADDR = '10.1.1.1'
- _FAKE_PORTAL_PORT = '3260'
- _FAKE_LUN = 0
- _FAKE_TARGET = 'iqn.2010-10.org.openstack:fake_target'
-
- _FAKE_STDOUT_VALUE = 'The operation completed successfully'
-
- def setUp(self):
- super(VolumeUtilsTestCase, self).setUp()
- self._volutils = volumeutils.VolumeUtils()
- self._volutils._conn_wmi = mock.MagicMock()
- self._volutils._conn_cimv2 = mock.MagicMock()
- self.flags(volume_attach_retry_count=4, group='hyperv')
- self.flags(volume_attach_retry_interval=0, group='hyperv')
-
- def _test_login_target_portal(self, portal_connected):
- fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
- self._FAKE_PORTAL_PORT)
-
- self._volutils.execute = mock.MagicMock()
- if portal_connected:
- exec_output = 'Address and Socket: %s %s' % (
- self._FAKE_PORTAL_ADDR, self._FAKE_PORTAL_PORT)
- else:
- exec_output = ''
-
- self._volutils.execute.return_value = exec_output
-
- self._volutils._login_target_portal(fake_portal)
-
- call_list = self._volutils.execute.call_args_list
- all_call_args = [arg for call in call_list for arg in call[0]]
-
- if portal_connected:
- self.assertIn('RefreshTargetPortal', all_call_args)
- else:
- self.assertIn('AddTargetPortal', all_call_args)
-
- def test_login_connected_portal(self):
- self._test_login_target_portal(True)
-
- def test_login_new_portal(self):
- self._test_login_target_portal(False)
-
- def _test_login_target(self, target_connected=False, raise_exception=False,
- use_chap=False):
- fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
- self._FAKE_PORTAL_PORT)
- self._volutils.execute = mock.MagicMock()
- self._volutils._login_target_portal = mock.MagicMock()
-
- if use_chap:
- username, password = (mock.sentinel.username,
- mock.sentinel.password)
- else:
- username, password = None, None
-
- if target_connected:
- self._volutils.execute.return_value = self._FAKE_TARGET
- elif raise_exception:
- self._volutils.execute.return_value = ''
- else:
- self._volutils.execute.side_effect = (
- ['', '', '', self._FAKE_TARGET, ''])
-
- if raise_exception:
- self.assertRaises(vmutils.HyperVException,
- self._volutils.login_storage_target,
- self._FAKE_LUN, self._FAKE_TARGET,
- fake_portal, username, password)
- else:
- self._volutils.login_storage_target(self._FAKE_LUN,
- self._FAKE_TARGET,
- fake_portal,
- username, password)
-
- if target_connected:
- call_list = self._volutils.execute.call_args_list
- all_call_args = [arg for call in call_list for arg in call[0]]
- self.assertNotIn('qlogintarget', all_call_args)
- else:
- self._volutils.execute.assert_any_call(
- 'iscsicli.exe', 'qlogintarget',
- self._FAKE_TARGET, username, password)
-
- def test_login_connected_target(self):
- self._test_login_target(target_connected=True)
-
- def test_login_disconncted_target(self):
- self._test_login_target()
-
- def test_login_target_exception(self):
- self._test_login_target(raise_exception=True)
-
- def test_login_target_using_chap(self):
- self._test_login_target(use_chap=True)
-
- def _test_execute_wrapper(self, raise_exception):
- fake_cmd = ('iscsicli.exe', 'ListTargetPortals')
-
- if raise_exception:
- output = 'fake error'
- else:
- output = 'The operation completed successfully'
-
- with mock.patch('nova.utils.execute') as fake_execute:
- fake_execute.return_value = (output, None)
-
- if raise_exception:
- self.assertRaises(vmutils.HyperVException,
- self._volutils.execute,
- *fake_cmd)
- else:
- ret_val = self._volutils.execute(*fake_cmd)
- self.assertEqual(output, ret_val)
-
- def test_execute_raise_exception(self):
- self._test_execute_wrapper(True)
-
- def test_execute_exception(self):
- self._test_execute_wrapper(False)
-
- @mock.patch.object(volumeutils, 'utils')
- def test_logout_storage_target(self, mock_utils):
- mock_utils.execute.return_value = (self._FAKE_STDOUT_VALUE,
- mock.sentinel.FAKE_STDERR_VALUE)
- session = mock.MagicMock()
- session.SessionId = mock.sentinel.FAKE_SESSION_ID
- self._volutils._conn_wmi.query.return_value = [session]
-
- self._volutils.logout_storage_target(mock.sentinel.FAKE_IQN)
- mock_utils.execute.assert_called_once_with(
- 'iscsicli.exe', 'logouttarget', mock.sentinel.FAKE_SESSION_ID)
diff --git a/nova/tests/unit/virt/hyperv/test_volumeutilsv2.py b/nova/tests/unit/virt/hyperv/test_volumeutilsv2.py
deleted file mode 100644
index 5c73f0ce6a..0000000000
--- a/nova/tests/unit/virt/hyperv/test_volumeutilsv2.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-from oslo_config import cfg
-
-from nova import test
-from nova.virt.hyperv import vmutils
-from nova.virt.hyperv import volumeutilsv2
-
-CONF = cfg.CONF
-CONF.import_opt('volume_attach_retry_count', 'nova.virt.hyperv.volumeops',
- 'hyperv')
-
-
-class VolumeUtilsV2TestCase(test.NoDBTestCase):
- """Unit tests for the Hyper-V VolumeUtilsV2 class."""
-
- _FAKE_PORTAL_ADDR = '10.1.1.1'
- _FAKE_PORTAL_PORT = '3260'
- _FAKE_LUN = 0
- _FAKE_TARGET = 'iqn.2010-10.org.openstack:fake_target'
-
- def setUp(self):
- super(VolumeUtilsV2TestCase, self).setUp()
- self._volutilsv2 = volumeutilsv2.VolumeUtilsV2()
- self._volutilsv2._conn_storage = mock.MagicMock()
- self._volutilsv2._conn_wmi = mock.MagicMock()
- self.flags(volume_attach_retry_count=4, group='hyperv')
- self.flags(volume_attach_retry_interval=0, group='hyperv')
-
- def _test_login_target_portal(self, portal_connected):
- fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
- self._FAKE_PORTAL_PORT)
- fake_portal_object = mock.MagicMock()
- _query = self._volutilsv2._conn_storage.query
- self._volutilsv2._conn_storage.MSFT_iSCSITargetPortal = (
- fake_portal_object)
-
- if portal_connected:
- _query.return_value = [fake_portal_object]
- else:
- _query.return_value = None
-
- self._volutilsv2._login_target_portal(fake_portal)
-
- if portal_connected:
- fake_portal_object.Update.assert_called_once_with()
- else:
- fake_portal_object.New.assert_called_once_with(
- TargetPortalAddress=self._FAKE_PORTAL_ADDR,
- TargetPortalPortNumber=self._FAKE_PORTAL_PORT)
-
- def test_login_connected_portal(self):
- self._test_login_target_portal(True)
-
- def test_login_new_portal(self):
- self._test_login_target_portal(False)
-
- def _test_login_target(self, target_connected=False, raise_exception=False,
- use_chap=False):
- fake_portal = '%s:%s' % (self._FAKE_PORTAL_ADDR,
- self._FAKE_PORTAL_PORT)
-
- fake_target_object = mock.MagicMock()
-
- if target_connected:
- fake_target_object.IsConnected = True
- elif not raise_exception:
- type(fake_target_object).IsConnected = mock.PropertyMock(
- side_effect=[False, True])
- else:
- fake_target_object.IsConnected = False
-
- _query = self._volutilsv2._conn_storage.query
- _query.return_value = [fake_target_object]
-
- self._volutilsv2._conn_storage.MSFT_iSCSITarget = (
- fake_target_object)
-
- if use_chap:
- username, password = (mock.sentinel.username,
- mock.sentinel.password)
- auth = {
- 'AuthenticationType': self._volutilsv2._CHAP_AUTH_TYPE,
- 'ChapUsername': username,
- 'ChapSecret': password,
- }
- else:
- username, password = None, None
- auth = {}
-
- if raise_exception:
- self.assertRaises(vmutils.HyperVException,
- self._volutilsv2.login_storage_target,
- self._FAKE_LUN, self._FAKE_TARGET, fake_portal)
- else:
- self._volutilsv2.login_storage_target(self._FAKE_LUN,
- self._FAKE_TARGET,
- fake_portal,
- username, password)
-
- if target_connected:
- fake_target_object.Update.assert_called_with()
- else:
- fake_target_object.Connect.assert_called_once_with(
- IsPersistent=True, NodeAddress=self._FAKE_TARGET, **auth)
-
- def test_login_connected_target(self):
- self._test_login_target(target_connected=True)
-
- def test_login_disconncted_target(self):
- self._test_login_target()
-
- def test_login_target_exception(self):
- self._test_login_target(raise_exception=True)
-
- def test_login_target_using_chap(self):
- self._test_login_target(use_chap=True)
-
- def test_logout_storage_target(self):
- mock_msft_target = self._volutilsv2._conn_storage.MSFT_iSCSITarget
- mock_msft_session = self._volutilsv2._conn_storage.MSFT_iSCSISession
-
- mock_target = mock.MagicMock()
- mock_target.IsConnected = True
- mock_msft_target.return_value = [mock_target]
-
- mock_session = mock.MagicMock()
- mock_session.IsPersistent = True
- mock_msft_session.return_value = [mock_session]
-
- self._volutilsv2.logout_storage_target(self._FAKE_TARGET)
-
- mock_msft_target.assert_called_once_with(NodeAddress=self._FAKE_TARGET)
- mock_msft_session.assert_called_once_with(
- TargetNodeAddress=self._FAKE_TARGET)
-
- mock_session.Unregister.assert_called_once_with()
- mock_target.Disconnect.assert_called_once_with()
-
- @mock.patch.object(volumeutilsv2.VolumeUtilsV2, 'logout_storage_target')
- def test_execute_log_out(self, mock_logout_target):
- sess_class = self._volutilsv2._conn_wmi.MSiSCSIInitiator_SessionClass
-
- mock_session = mock.MagicMock()
- sess_class.return_value = [mock_session]
-
- self._volutilsv2.execute_log_out(mock.sentinel.FAKE_SESSION_ID)
-
- sess_class.assert_called_once_with(
- SessionId=mock.sentinel.FAKE_SESSION_ID)
- mock_logout_target.assert_called_once_with(mock_session.TargetName)
diff --git a/nova/virt/hyperv/basevolumeutils.py b/nova/virt/hyperv/basevolumeutils.py
deleted file mode 100644
index 5fcb4faceb..0000000000
--- a/nova/virt/hyperv/basevolumeutils.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#
-# Copyright 2012 Pedro Navarro Perez
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Helper methods for operations related to the management of volumes,
-and storage repositories
-"""
-
-import abc
-import re
-import sys
-
-if sys.platform == 'win32':
- import _winreg
- import wmi
-
-from oslo_log import log as logging
-
-from nova import block_device
-from nova.i18n import _LI
-from nova.virt import driver
-
-LOG = logging.getLogger(__name__)
-
-
-class BaseVolumeUtils(object):
- _FILE_DEVICE_DISK = 7
-
- def __init__(self, host='.'):
- if sys.platform == 'win32':
- self._conn_wmi = wmi.WMI(moniker='//%s/root/wmi' % host)
- self._conn_cimv2 = wmi.WMI(moniker='//%s/root/cimv2' % host)
- self._drive_number_regex = re.compile(r'DeviceID=\"[^,]*\\(\d+)\"')
-
- @abc.abstractmethod
- def login_storage_target(self, target_lun, target_iqn, target_portal):
- pass
-
- @abc.abstractmethod
- def logout_storage_target(self, target_iqn):
- pass
-
- @abc.abstractmethod
- def execute_log_out(self, session_id):
- pass
-
- def get_iscsi_initiator(self):
- """Get iscsi initiator name for this machine."""
-
- computer_system = self._conn_cimv2.Win32_ComputerSystem()[0]
- hostname = computer_system.name
- keypath = ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"
- "iSCSI\\Discovery")
- try:
- key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keypath, 0,
- _winreg.KEY_ALL_ACCESS)
- temp = _winreg.QueryValueEx(key, 'DefaultInitiatorName')
- initiator_name = str(temp[0])
- _winreg.CloseKey(key)
- except Exception:
- LOG.info(_LI("The ISCSI initiator name can't be found. "
- "Choosing the default one"))
- initiator_name = "iqn.1991-05.com.microsoft:" + hostname.lower()
- if computer_system.PartofDomain:
- initiator_name += '.' + computer_system.Domain.lower()
- return initiator_name
-
- def volume_in_mapping(self, mount_device, block_device_info):
- block_device_list = [block_device.strip_dev(vol['mount_device'])
- for vol in
- driver.block_device_info_get_mapping(
- block_device_info)]
- swap = driver.block_device_info_get_swap(block_device_info)
- if driver.swap_is_usable(swap):
- block_device_list.append(
- block_device.strip_dev(swap['device_name']))
- block_device_list += [block_device.strip_dev(
- ephemeral['device_name'])
- for ephemeral in
- driver.block_device_info_get_ephemerals(block_device_info)]
-
- LOG.debug("block_device_list %s", block_device_list)
- return block_device.strip_dev(mount_device) in block_device_list
-
- def _get_drive_number_from_disk_path(self, disk_path):
- drive_number = self._drive_number_regex.findall(disk_path)
- if drive_number:
- return int(drive_number[0])
-
- def get_session_id_from_mounted_disk(self, physical_drive_path):
- drive_number = self._get_drive_number_from_disk_path(
- physical_drive_path)
- if not drive_number:
- return None
-
- initiator_sessions = self._conn_wmi.MSiSCSIInitiator_SessionClass()
- for initiator_session in initiator_sessions:
- devices = initiator_session.Devices
- for device in devices:
- device_number = device.DeviceNumber
- if device_number == drive_number:
- return initiator_session.SessionId
-
- def _get_devices_for_target(self, target_iqn):
- initiator_sessions = self._conn_wmi.MSiSCSIInitiator_SessionClass(
- TargetName=target_iqn)
- if not initiator_sessions:
- return []
-
- return initiator_sessions[0].Devices
-
- def get_device_number_for_target(self, target_iqn, target_lun):
- devices = self._get_devices_for_target(target_iqn)
-
- for device in devices:
- if device.ScsiLun == target_lun:
- return device.DeviceNumber
-
- def get_target_lun_count(self, target_iqn):
- devices = self._get_devices_for_target(target_iqn)
- disk_devices = [device for device in devices
- if device.DeviceType == self._FILE_DEVICE_DISK]
- return len(disk_devices)
-
- def get_target_from_disk_path(self, disk_path):
- initiator_sessions = self._conn_wmi.MSiSCSIInitiator_SessionClass()
- drive_number = self._get_drive_number_from_disk_path(disk_path)
- if not drive_number:
- return None
-
- for initiator_session in initiator_sessions:
- devices = initiator_session.Devices
- for device in devices:
- if device.DeviceNumber == drive_number:
- return (device.TargetName, device.ScsiLun)
diff --git a/nova/virt/hyperv/constants.py b/nova/virt/hyperv/constants.py
index 3e07977572..00e8838676 100644
--- a/nova/virt/hyperv/constants.py
+++ b/nova/virt/hyperv/constants.py
@@ -60,15 +60,6 @@ PROCESSOR_FEATURE = {
17: 'xsave',
}
-WMI_JOB_STATUS_STARTED = 4096
-WMI_JOB_STATE_RUNNING = 4
-WMI_JOB_STATE_COMPLETED = 7
-
-VM_SUMMARY_NUM_PROCS = 4
-VM_SUMMARY_ENABLED_STATE = 100
-VM_SUMMARY_MEMORY_USAGE = 103
-VM_SUMMARY_UPTIME = 105
-
CTRL_TYPE_IDE = "IDE"
CTRL_TYPE_SCSI = "SCSI"
@@ -85,11 +76,6 @@ DISK_FORMAT_MAP = {
DISK_FORMAT_VHD = "VHD"
DISK_FORMAT_VHDX = "VHDX"
-VHD_TYPE_FIXED = 2
-VHD_TYPE_DYNAMIC = 3
-
-SCSI_CONTROLLER_SLOTS_NUMBER = 64
-
HOST_POWER_ACTION_SHUTDOWN = "shutdown"
HOST_POWER_ACTION_REBOOT = "reboot"
HOST_POWER_ACTION_STARTUP = "startup"
@@ -99,8 +85,3 @@ IMAGE_PROP_VM_GEN_2 = "hyperv-gen2"
VM_GEN_1 = 1
VM_GEN_2 = 2
-
-JOB_STATE_COMPLETED = 7
-JOB_STATE_TERMINATED = 8
-JOB_STATE_KILLED = 9
-JOB_STATE_COMPLETED_WITH_WARNINGS = 32768
diff --git a/nova/virt/hyperv/hostutils.py b/nova/virt/hyperv/hostutils.py
deleted file mode 100644
index 7f073e6a9c..0000000000
--- a/nova/virt/hyperv/hostutils.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import ctypes
-import socket
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from nova.i18n import _
-from nova.virt.hyperv import constants
-
-
-class HostUtils(object):
-
- _HOST_FORCED_REBOOT = 6
- _HOST_FORCED_SHUTDOWN = 12
- _DEFAULT_VM_GENERATION = constants.IMAGE_PROP_VM_GEN_1
-
- def __init__(self):
- if sys.platform == 'win32':
- self._conn_cimv2 = wmi.WMI(privileges=["Shutdown"])
- self._init_wmi_virt_conn()
-
- def _init_wmi_virt_conn(self):
- self._conn_virt = None
-
- def get_cpus_info(self):
- cpus = self._conn_cimv2.query("SELECT * FROM Win32_Processor "
- "WHERE ProcessorType = 3")
- cpus_list = []
- for cpu in cpus:
- cpu_info = {'Architecture': cpu.Architecture,
- 'Name': cpu.Name,
- 'Manufacturer': cpu.Manufacturer,
- 'NumberOfCores': cpu.NumberOfCores,
- 'NumberOfLogicalProcessors':
- cpu.NumberOfLogicalProcessors}
- cpus_list.append(cpu_info)
- return cpus_list
-
- def is_cpu_feature_present(self, feature_key):
- return ctypes.windll.kernel32.IsProcessorFeaturePresent(feature_key)
-
- def get_memory_info(self):
- """Returns a tuple with total visible memory and free physical memory
- expressed in kB.
- """
- mem_info = self._conn_cimv2.query("SELECT TotalVisibleMemorySize, "
- "FreePhysicalMemory "
- "FROM win32_operatingsystem")[0]
- return (long(mem_info.TotalVisibleMemorySize),
- long(mem_info.FreePhysicalMemory))
-
- def get_volume_info(self, drive):
- """Returns a tuple with total size and free space
- expressed in bytes.
- """
- logical_disk = self._conn_cimv2.query("SELECT Size, FreeSpace "
- "FROM win32_logicaldisk "
- "WHERE DeviceID='%s'"
- % drive)[0]
- return (long(logical_disk.Size), long(logical_disk.FreeSpace))
-
- def check_min_windows_version(self, major, minor, build=0):
- version_str = self.get_windows_version()
- return map(int, version_str.split('.')) >= [major, minor, build]
-
- def get_windows_version(self):
- return self._conn_cimv2.Win32_OperatingSystem()[0].Version
-
- def get_local_ips(self):
- addr_info = socket.getaddrinfo(socket.gethostname(), None, 0, 0, 0)
- # Returns IPv4 and IPv6 addresses, ordered by protocol family
- addr_info.sort()
- return [a[4][0] for a in addr_info]
-
- def get_host_tick_count64(self):
- return ctypes.windll.kernel32.GetTickCount64()
-
- def host_power_action(self, action):
- win32_os = self._conn_cimv2.Win32_OperatingSystem()[0]
-
- if action == constants.HOST_POWER_ACTION_SHUTDOWN:
- win32_os.Win32Shutdown(self._HOST_FORCED_SHUTDOWN)
- elif action == constants.HOST_POWER_ACTION_REBOOT:
- win32_os.Win32Shutdown(self._HOST_FORCED_REBOOT)
- else:
- raise NotImplementedError(
- _("Host %(action)s is not supported by the Hyper-V driver") %
- {"action": action})
-
- def get_supported_vm_types(self):
- """Get the supported Hyper-V VM generations.
- Hyper-V Generation 2 VMs are supported in Windows 8.1,
- Windows Server / Hyper-V Server 2012 R2 or newer.
-
- :returns: array of supported VM generations (ex. ['hyperv-gen1'])
- """
- if self.check_min_windows_version(6, 3):
- return [constants.IMAGE_PROP_VM_GEN_1,
- constants.IMAGE_PROP_VM_GEN_2]
- else:
- return [constants.IMAGE_PROP_VM_GEN_1]
-
- def get_default_vm_generation(self):
- return self._DEFAULT_VM_GENERATION
diff --git a/nova/virt/hyperv/hostutilsv2.py b/nova/virt/hyperv/hostutilsv2.py
deleted file mode 100644
index 7bed7a5797..0000000000
--- a/nova/virt/hyperv/hostutilsv2.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2015 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from nova.virt.hyperv import hostutils
-
-
-class HostUtilsV2(hostutils.HostUtils):
-
- FEATURE_RDS_VIRTUALIZATION = 322
-
- def __init__(self):
- super(HostUtilsV2, self).__init__()
- self._init_wmi_virt_conn()
-
- def _init_wmi_virt_conn(self):
- if sys.platform == 'win32':
- self._conn_virt = wmi.WMI(moniker='//./root/virtualization/v2')
diff --git a/nova/virt/hyperv/ioutils.py b/nova/virt/hyperv/ioutils.py
deleted file mode 100644
index e28deb84ff..0000000000
--- a/nova/virt/hyperv/ioutils.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright 2014 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import errno
-import os
-
-from eventlet import patcher
-from oslo_log import log as logging
-
-from nova.i18n import _LE
-
-LOG = logging.getLogger(__name__)
-
-native_threading = patcher.original('threading')
-
-
-class IOThread(native_threading.Thread):
- def __init__(self, src, dest, max_bytes):
- super(IOThread, self).__init__()
- self.setDaemon(True)
- self._src = src
- self._dest = dest
- self._dest_archive = dest + '.1'
- self._max_bytes = max_bytes
- self._stopped = native_threading.Event()
-
- def run(self):
- try:
- self._copy()
- except IOError as err:
- self._stopped.set()
- # Invalid argument error means that the vm console pipe was closed,
- # probably the vm was stopped. The worker can stop it's execution.
- if err.errno != errno.EINVAL:
- LOG.error(_LE("Error writing vm console log file from "
- "serial console pipe. Error: %s") % err)
-
- def _copy(self):
- with open(self._src, 'rb') as src:
- with open(self._dest, 'ab', 0) as dest:
- dest.seek(0, os.SEEK_END)
- log_size = dest.tell()
- while (not self._stopped.isSet()):
- # Read one byte at a time to avoid blocking.
- data = src.read(1)
- dest.write(data)
- log_size += len(data)
- if (log_size >= self._max_bytes):
- dest.close()
- if os.path.exists(self._dest_archive):
- os.remove(self._dest_archive)
- os.rename(self._dest, self._dest_archive)
- dest = open(self._dest, 'ab', 0)
- log_size = 0
-
- def join(self):
- self._stopped.set()
- super(IOThread, self).join()
-
- def is_active(self):
- return not self._stopped.isSet()
diff --git a/nova/virt/hyperv/livemigrationutils.py b/nova/virt/hyperv/livemigrationutils.py
deleted file mode 100644
index 8dbcef3002..0000000000
--- a/nova/virt/hyperv/livemigrationutils.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from oslo_log import log as logging
-
-from nova import exception
-from nova.i18n import _, _LE
-from nova.virt.hyperv import vmutils
-from nova.virt.hyperv import vmutilsv2
-from nova.virt.hyperv import volumeutilsv2
-
-LOG = logging.getLogger(__name__)
-
-
-class LiveMigrationUtils(object):
-
- def __init__(self):
- self._vmutils = vmutilsv2.VMUtilsV2()
- self._volutils = volumeutilsv2.VolumeUtilsV2()
-
- def _get_conn_v2(self, host='localhost'):
- try:
- return wmi.WMI(moniker='//%s/root/virtualization/v2' % host)
- except wmi.x_wmi as ex:
- LOG.exception(_LE('Get version 2 connection error'))
- if ex.com_error.hresult == -2147217394:
- msg = (_('Live migration is not supported on target host "%s"')
- % host)
- elif ex.com_error.hresult == -2147023174:
- msg = (_('Target live migration host "%s" is unreachable')
- % host)
- else:
- msg = _('Live migration failed: %s') % ex.message
- raise vmutils.HyperVException(msg)
-
- def check_live_migration_config(self):
- conn_v2 = self._get_conn_v2()
- migration_svc = conn_v2.Msvm_VirtualSystemMigrationService()[0]
- vsmssds = migration_svc.associators(
- wmi_association_class='Msvm_ElementSettingData',
- wmi_result_class='Msvm_VirtualSystemMigrationServiceSettingData')
- vsmssd = vsmssds[0]
- if not vsmssd.EnableVirtualSystemMigration:
- raise vmutils.HyperVException(
- _('Live migration is not enabled on this host'))
- if not migration_svc.MigrationServiceListenerIPAddressList:
- raise vmutils.HyperVException(
- _('Live migration networks are not configured on this host'))
-
- def _get_vm(self, conn_v2, vm_name):
- vms = conn_v2.Msvm_ComputerSystem(ElementName=vm_name)
- n = len(vms)
- if not n:
- raise exception.InstanceNotFound(_('VM not found: %s') % vm_name)
- elif n > 1:
- raise vmutils.HyperVException(_('Duplicate VM name found: %s')
- % vm_name)
- return vms[0]
-
- def _destroy_planned_vm(self, conn_v2_remote, planned_vm):
- LOG.debug("Destroying existing remote planned VM: %s",
- planned_vm.ElementName)
- vs_man_svc = conn_v2_remote.Msvm_VirtualSystemManagementService()[0]
- (job_path, ret_val) = vs_man_svc.DestroySystem(planned_vm.path_())
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def _check_existing_planned_vm(self, conn_v2_remote, vm):
- # Make sure that there's not yet a remote planned VM on the target
- # host for this VM
- planned_vms = conn_v2_remote.Msvm_PlannedComputerSystem(Name=vm.Name)
- if planned_vms:
- self._destroy_planned_vm(conn_v2_remote, planned_vms[0])
-
- def _create_remote_planned_vm(self, conn_v2_local, conn_v2_remote,
- vm, rmt_ip_addr_list, dest_host):
- # Staged
- vsmsd = conn_v2_local.query("select * from "
- "Msvm_VirtualSystemMigrationSettingData "
- "where MigrationType = 32770")[0]
- vsmsd.DestinationIPAddressList = rmt_ip_addr_list
- migration_setting_data = vsmsd.GetText_(1)
-
- LOG.debug("Creating remote planned VM for VM: %s",
- vm.ElementName)
- migr_svc = conn_v2_local.Msvm_VirtualSystemMigrationService()[0]
- (job_path, ret_val) = migr_svc.MigrateVirtualSystemToHost(
- ComputerSystem=vm.path_(),
- DestinationHost=dest_host,
- MigrationSettingData=migration_setting_data)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- return conn_v2_remote.Msvm_PlannedComputerSystem(Name=vm.Name)[0]
-
- def _get_physical_disk_paths(self, vm_name):
- ide_ctrl_path = self._vmutils.get_vm_ide_controller(vm_name, 0)
- if ide_ctrl_path:
- ide_paths = self._vmutils.get_controller_volume_paths(
- ide_ctrl_path)
- else:
- ide_paths = {}
-
- scsi_ctrl_path = self._vmutils.get_vm_scsi_controller(vm_name)
- scsi_paths = self._vmutils.get_controller_volume_paths(scsi_ctrl_path)
-
- return dict(ide_paths.items() + scsi_paths.items())
-
- def _get_remote_disk_data(self, vmutils_remote, disk_paths, dest_host):
- volutils_remote = volumeutilsv2.VolumeUtilsV2(dest_host)
-
- disk_paths_remote = {}
- for (rasd_rel_path, disk_path) in disk_paths.items():
- target = self._volutils.get_target_from_disk_path(disk_path)
- if target:
- (target_iqn, target_lun) = target
-
- dev_num = volutils_remote.get_device_number_for_target(
- target_iqn, target_lun)
- disk_path_remote = (
- vmutils_remote.get_mounted_disk_by_drive_number(dev_num))
-
- disk_paths_remote[rasd_rel_path] = disk_path_remote
- else:
- LOG.debug("Could not retrieve iSCSI target "
- "from disk path: %s", disk_path)
-
- return disk_paths_remote
-
- def _update_planned_vm_disk_resources(self, vmutils_remote, conn_v2_remote,
- planned_vm, vm_name,
- disk_paths_remote):
- vm_settings = planned_vm.associators(
- wmi_association_class='Msvm_SettingsDefineState',
- wmi_result_class='Msvm_VirtualSystemSettingData')[0]
-
- updated_resource_setting_data = []
- sasds = vm_settings.associators(
- wmi_association_class='Msvm_VirtualSystemSettingDataComponent')
- for sasd in sasds:
- if (sasd.ResourceType == 17 and sasd.ResourceSubType ==
- "Microsoft:Hyper-V:Physical Disk Drive" and
- sasd.HostResource):
- # Replace the local disk target with the correct remote one
- old_disk_path = sasd.HostResource[0]
- new_disk_path = disk_paths_remote.pop(sasd.path().RelPath)
-
- LOG.debug("Replacing host resource "
- "%(old_disk_path)s with "
- "%(new_disk_path)s on planned VM %(vm_name)s",
- {'old_disk_path': old_disk_path,
- 'new_disk_path': new_disk_path,
- 'vm_name': vm_name})
- sasd.HostResource = [new_disk_path]
- updated_resource_setting_data.append(sasd.GetText_(1))
-
- LOG.debug("Updating remote planned VM disk paths for VM: %s",
- vm_name)
- vsmsvc = conn_v2_remote.Msvm_VirtualSystemManagementService()[0]
- (res_settings, job_path, ret_val) = vsmsvc.ModifyResourceSettings(
- ResourceSettings=updated_resource_setting_data)
- vmutils_remote.check_ret_val(ret_val, job_path)
-
- def _get_vhd_setting_data(self, vm):
- vm_settings = vm.associators(
- wmi_association_class='Msvm_SettingsDefineState',
- wmi_result_class='Msvm_VirtualSystemSettingData')[0]
-
- new_resource_setting_data = []
- sasds = vm_settings.associators(
- wmi_association_class='Msvm_VirtualSystemSettingDataComponent',
- wmi_result_class='Msvm_StorageAllocationSettingData')
- for sasd in sasds:
- if (sasd.ResourceType == 31 and sasd.ResourceSubType ==
- "Microsoft:Hyper-V:Virtual Hard Disk"):
- new_resource_setting_data.append(sasd.GetText_(1))
- return new_resource_setting_data
-
- def _live_migrate_vm(self, conn_v2_local, vm, planned_vm, rmt_ip_addr_list,
- new_resource_setting_data, dest_host):
- # VirtualSystemAndStorage
- vsmsd = conn_v2_local.query("select * from "
- "Msvm_VirtualSystemMigrationSettingData "
- "where MigrationType = 32771")[0]
- vsmsd.DestinationIPAddressList = rmt_ip_addr_list
- if planned_vm:
- vsmsd.DestinationPlannedVirtualSystemId = planned_vm.Name
- migration_setting_data = vsmsd.GetText_(1)
-
- migr_svc = conn_v2_local.Msvm_VirtualSystemMigrationService()[0]
-
- LOG.debug("Starting live migration for VM: %s", vm.ElementName)
- (job_path, ret_val) = migr_svc.MigrateVirtualSystemToHost(
- ComputerSystem=vm.path_(),
- DestinationHost=dest_host,
- MigrationSettingData=migration_setting_data,
- NewResourceSettingData=new_resource_setting_data)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def _get_remote_ip_address_list(self, conn_v2_remote, dest_host):
- LOG.debug("Getting live migration networks for remote host: %s",
- dest_host)
- migr_svc_rmt = conn_v2_remote.Msvm_VirtualSystemMigrationService()[0]
- return migr_svc_rmt.MigrationServiceListenerIPAddressList
-
- def live_migrate_vm(self, vm_name, dest_host):
- self.check_live_migration_config()
-
- conn_v2_local = self._get_conn_v2()
- conn_v2_remote = self._get_conn_v2(dest_host)
-
- vm = self._get_vm(conn_v2_local, vm_name)
- self._check_existing_planned_vm(conn_v2_remote, vm)
-
- rmt_ip_addr_list = self._get_remote_ip_address_list(conn_v2_remote,
- dest_host)
-
- planned_vm = None
- disk_paths = self._get_physical_disk_paths(vm_name)
- if disk_paths:
- vmutils_remote = vmutilsv2.VMUtilsV2(dest_host)
- disk_paths_remote = self._get_remote_disk_data(vmutils_remote,
- disk_paths,
- dest_host)
-
- planned_vm = self._create_remote_planned_vm(conn_v2_local,
- conn_v2_remote,
- vm, rmt_ip_addr_list,
- dest_host)
-
- self._update_planned_vm_disk_resources(vmutils_remote,
- conn_v2_remote, planned_vm,
- vm_name, disk_paths_remote)
-
- new_resource_setting_data = self._get_vhd_setting_data(vm)
- self._live_migrate_vm(conn_v2_local, vm, planned_vm, rmt_ip_addr_list,
- new_resource_setting_data, dest_host)
diff --git a/nova/virt/hyperv/networkutils.py b/nova/virt/hyperv/networkutils.py
deleted file mode 100644
index 07ad489187..0000000000
--- a/nova/virt/hyperv/networkutils.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Utility class for network related operations.
-"""
-
-import sys
-import uuid
-
-if sys.platform == 'win32':
- import wmi
-
-from nova.i18n import _
-from nova.virt.hyperv import vmutils
-
-
-class NetworkUtils(object):
- def __init__(self):
- if sys.platform == 'win32':
- self._conn = wmi.WMI(moniker='//./root/virtualization')
-
- def get_external_vswitch(self, vswitch_name):
- if vswitch_name:
- vswitches = self._conn.Msvm_VirtualSwitch(ElementName=vswitch_name)
- else:
- # Find the vswitch that is connected to the first physical nic.
- ext_port = self._conn.Msvm_ExternalEthernetPort(IsBound='TRUE')[0]
- port = ext_port.associators(wmi_result_class='Msvm_SwitchPort')[0]
- vswitches = port.associators(wmi_result_class='Msvm_VirtualSwitch')
-
- if not len(vswitches):
- raise vmutils.HyperVException(_('vswitch "%s" not found')
- % vswitch_name)
- return vswitches[0].path_()
-
- def create_vswitch_port(self, vswitch_path, port_name):
- switch_svc = self._conn.Msvm_VirtualSwitchManagementService()[0]
- # Create a port on the vswitch.
- (new_port, ret_val) = switch_svc.CreateSwitchPort(
- Name=str(uuid.uuid4()),
- FriendlyName=port_name,
- ScopeOfResidence="",
- VirtualSwitch=vswitch_path)
- if ret_val != 0:
- raise vmutils.HyperVException(_("Failed to create vswitch port "
- "%(port_name)s on switch "
- "%(vswitch_path)s") %
- {'port_name': port_name,
- 'vswitch_path': vswitch_path})
- return new_port
-
- def vswitch_port_needed(self):
- # NOTE(alexpilotti): In WMI V2 the vswitch_path is set in the VM
- # setting data without the need for a vswitch port.
- return True
diff --git a/nova/virt/hyperv/networkutilsv2.py b/nova/virt/hyperv/networkutilsv2.py
deleted file mode 100644
index 558f7c44cd..0000000000
--- a/nova/virt/hyperv/networkutilsv2.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Utility class for network related operations.
-Based on the "root/virtualization/v2" namespace available starting with
-Hyper-V Server / Windows Server 2012.
-"""
-
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from nova.i18n import _
-from nova.virt.hyperv import networkutils
-from nova.virt.hyperv import vmutils
-
-
-class NetworkUtilsV2(networkutils.NetworkUtils):
- def __init__(self):
- if sys.platform == 'win32':
- self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
-
- def get_external_vswitch(self, vswitch_name):
- if vswitch_name:
- vswitches = self._conn.Msvm_VirtualEthernetSwitch(
- ElementName=vswitch_name)
- if not len(vswitches):
- raise vmutils.HyperVException(_('vswitch "%s" not found')
- % vswitch_name)
- else:
- # Find the vswitch that is connected to the first physical nic.
- ext_port = self._conn.Msvm_ExternalEthernetPort(IsBound='TRUE')[0]
- lep = ext_port.associators(wmi_result_class='Msvm_LANEndpoint')[0]
- lep1 = lep.associators(wmi_result_class='Msvm_LANEndpoint')[0]
- esw = lep1.associators(
- wmi_result_class='Msvm_EthernetSwitchPort')[0]
- vswitches = esw.associators(
- wmi_result_class='Msvm_VirtualEthernetSwitch')
-
- if not len(vswitches):
- raise vmutils.HyperVException(_('No external vswitch found'))
-
- return vswitches[0].path_()
-
- def create_vswitch_port(self, vswitch_path, port_name):
- raise NotImplementedError()
-
- def vswitch_port_needed(self):
- return False
diff --git a/nova/virt/hyperv/rdpconsoleutils.py b/nova/virt/hyperv/rdpconsoleutils.py
deleted file mode 100644
index c897ea8c73..0000000000
--- a/nova/virt/hyperv/rdpconsoleutils.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-class RDPConsoleUtils(object):
- _DEFAULT_HYPERV_RDP_PORT = 2179
-
- def get_rdp_console_port(self):
- return self._DEFAULT_HYPERV_RDP_PORT
diff --git a/nova/virt/hyperv/rdpconsoleutilsv2.py b/nova/virt/hyperv/rdpconsoleutilsv2.py
deleted file mode 100644
index 4c173e2278..0000000000
--- a/nova/virt/hyperv/rdpconsoleutilsv2.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-from nova.virt.hyperv import rdpconsoleutils
-
-if sys.platform == 'win32':
- import wmi
-
-
-class RDPConsoleUtilsV2(rdpconsoleutils.RDPConsoleUtils):
- def __init__(self):
- if sys.platform == 'win32':
- self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
-
- def get_rdp_console_port(self):
- rdp_setting_data = self._conn.Msvm_TerminalServiceSettingData()[0]
- return rdp_setting_data.ListenerPort
diff --git a/nova/virt/hyperv/utilsfactory.py b/nova/virt/hyperv/utilsfactory.py
deleted file mode 100644
index 96c612777e..0000000000
--- a/nova/virt/hyperv/utilsfactory.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_config import cfg
-from oslo_log import log as logging
-
-from nova.virt.hyperv import hostutils
-from nova.virt.hyperv import hostutilsv2
-from nova.virt.hyperv import livemigrationutils
-from nova.virt.hyperv import networkutilsv2
-from nova.virt.hyperv import pathutils
-from nova.virt.hyperv import rdpconsoleutilsv2
-from nova.virt.hyperv import vhdutilsv2
-from nova.virt.hyperv import vmutilsv2
-from nova.virt.hyperv import volumeutils
-from nova.virt.hyperv import volumeutilsv2
-
-CONF = cfg.CONF
-
-LOG = logging.getLogger(__name__)
-CONF.import_group('hyperv', 'os_win.utilsfactory')
-
-utils = hostutils.HostUtils()
-
-
-def _get_class(v1_class, v2_class, force_v1_flag=False):
- # V2 classes are supported starting from Hyper-V Server 2012 and
- # Windows Server 2012 (kernel version 6.2)
- if not force_v1_flag and utils.check_min_windows_version(6, 2):
- cls = v2_class
- else:
- cls = v1_class
- LOG.debug("Loading class: %(module_name)s.%(class_name)s",
- {'module_name': cls.__module__, 'class_name': cls.__name__})
- return cls
-
-
-def get_vmutils(host='.'):
- return vmutilsv2.VMUtilsV2(host)
-
-
-def get_vhdutils():
- return vhdutilsv2.VHDUtilsV2()
-
-
-def get_networkutils():
- return networkutilsv2.NetworkUtilsV2()
-
-
-def get_hostutils():
- return hostutilsv2.HostUtilsV2()
-
-
-def get_pathutils():
- return pathutils.PathUtils()
-
-
-def get_volumeutils():
- return _get_class(volumeutils.VolumeUtils, volumeutilsv2.VolumeUtilsV2,
- CONF.hyperv.force_volumeutils_v1)()
-
-
-def get_livemigrationutils():
- return livemigrationutils.LiveMigrationUtils()
-
-
-def get_rdpconsoleutils():
- return rdpconsoleutilsv2.RDPConsoleUtilsV2()
diff --git a/nova/virt/hyperv/vhdutils.py b/nova/virt/hyperv/vhdutils.py
deleted file mode 100644
index e5ac1311b7..0000000000
--- a/nova/virt/hyperv/vhdutils.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Utility class for VHD related operations.
-
-Official VHD format specs can be retrieved at:
-http://technet.microsoft.com/en-us/library/bb676673.aspx
-See "Download the Specifications Without Registering"
-
-Official VHDX format specs can be retrieved at:
-http://www.microsoft.com/en-us/download/details.aspx?id=34750
-"""
-import struct
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from xml.etree import ElementTree
-
-from nova.i18n import _
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vmutils
-
-
-VHD_HEADER_SIZE_FIX = 512
-VHD_BAT_ENTRY_SIZE = 4
-VHD_DYNAMIC_DISK_HEADER_SIZE = 1024
-VHD_HEADER_SIZE_DYNAMIC = 512
-VHD_FOOTER_SIZE_DYNAMIC = 512
-VHD_BLK_SIZE_OFFSET = 544
-
-VHD_SIGNATURE = 'conectix'
-VHDX_SIGNATURE = 'vhdxfile'
-
-
-class VHDUtils(object):
-
- def __init__(self):
- self._vmutils = vmutils.VMUtils()
- if sys.platform == 'win32':
- self._conn = wmi.WMI(moniker='//./root/virtualization')
-
- def validate_vhd(self, vhd_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (job_path, ret_val) = image_man_svc.ValidateVirtualHardDisk(
- Path=vhd_path)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def create_dynamic_vhd(self, path, max_internal_size, format):
- if format != constants.DISK_FORMAT_VHD:
- raise vmutils.HyperVException(_("Unsupported disk format: %s") %
- format)
-
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (job_path, ret_val) = image_man_svc.CreateDynamicVirtualHardDisk(
- Path=path, MaxInternalSize=max_internal_size)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def create_differencing_vhd(self, path, parent_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (job_path, ret_val) = image_man_svc.CreateDifferencingVirtualHardDisk(
- Path=path, ParentPath=parent_path)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def reconnect_parent_vhd(self, child_vhd_path, parent_vhd_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (job_path, ret_val) = image_man_svc.ReconnectParentVirtualHardDisk(
- ChildPath=child_vhd_path,
- ParentPath=parent_vhd_path,
- Force=True)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def merge_vhd(self, src_vhd_path, dest_vhd_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (job_path, ret_val) = image_man_svc.MergeVirtualHardDisk(
- SourcePath=src_vhd_path,
- DestinationPath=dest_vhd_path)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def _get_resize_method(self):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
- return image_man_svc.ExpandVirtualHardDisk
-
- def resize_vhd(self, vhd_path, new_max_size, is_file_max_size=True):
- if is_file_max_size:
- new_internal_max_size = self.get_internal_vhd_size_by_file_size(
- vhd_path, new_max_size)
- else:
- new_internal_max_size = new_max_size
-
- resize = self._get_resize_method()
-
- (job_path, ret_val) = resize(
- Path=vhd_path, MaxInternalSize=new_internal_max_size)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def get_internal_vhd_size_by_file_size(self, vhd_path, new_vhd_file_size):
- """Fixed VHD size = Data Block size + 512 bytes
- | Dynamic_VHD_size = Dynamic Disk Header
- | + Copy of hard disk footer
- | + Hard Disk Footer
- | + Data Block
- | + BAT
- | Dynamic Disk header fields
- | Copy of hard disk footer (512 bytes)
- | Dynamic Disk Header (1024 bytes)
- | BAT (Block Allocation table)
- | Data Block 1
- | Data Block 2
- | Data Block n
- | Hard Disk Footer (512 bytes)
- | Default block size is 2M
- | BAT entry size is 4byte
- """
- base_vhd_info = self.get_vhd_info(vhd_path)
- vhd_type = base_vhd_info['Type']
-
- if vhd_type == constants.VHD_TYPE_FIXED:
- vhd_header_size = VHD_HEADER_SIZE_FIX
- return new_vhd_file_size - vhd_header_size
- elif vhd_type == constants.VHD_TYPE_DYNAMIC:
- bs = self._get_vhd_dynamic_blk_size(vhd_path)
- bes = VHD_BAT_ENTRY_SIZE
- ddhs = VHD_DYNAMIC_DISK_HEADER_SIZE
- hs = VHD_HEADER_SIZE_DYNAMIC
- fs = VHD_FOOTER_SIZE_DYNAMIC
-
- max_internal_size = (new_vhd_file_size -
- (hs + ddhs + fs)) * bs / (bes + bs)
- return max_internal_size
- else:
- vhd_parent = self.get_vhd_parent_path(vhd_path)
- return self.get_internal_vhd_size_by_file_size(vhd_parent,
- new_vhd_file_size)
-
- def _get_vhd_dynamic_blk_size(self, vhd_path):
- blk_size_offset = VHD_BLK_SIZE_OFFSET
- try:
- with open(vhd_path, "rb") as f:
- f.seek(blk_size_offset)
- version = f.read(4)
- except IOError:
- raise vmutils.HyperVException(_("Unable to obtain block size from"
- " VHD %(vhd_path)s") %
- {"vhd_path": vhd_path})
- return struct.unpack('>i', version)[0]
-
- def get_vhd_parent_path(self, vhd_path):
- return self.get_vhd_info(vhd_path).get("ParentPath")
-
- def get_vhd_info(self, vhd_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (vhd_info,
- job_path,
- ret_val) = image_man_svc.GetVirtualHardDiskInfo(vhd_path)
- self._vmutils.check_ret_val(ret_val, job_path)
-
- vhd_info_dict = {}
-
- et = ElementTree.fromstring(vhd_info)
- for item in et.findall("PROPERTY"):
- name = item.attrib["NAME"]
- value_text = item.find("VALUE").text
- if name == "ParentPath":
- vhd_info_dict[name] = value_text
- elif name in ["FileSize", "MaxInternalSize"]:
- vhd_info_dict[name] = long(value_text)
- elif name in ["InSavedState", "InUse"]:
- vhd_info_dict[name] = bool(value_text)
- elif name == "Type":
- vhd_info_dict[name] = int(value_text)
-
- return vhd_info_dict
-
- def get_vhd_format(self, path):
- with open(path, 'rb') as f:
- # Read header
- if f.read(8) == VHDX_SIGNATURE:
- return constants.DISK_FORMAT_VHDX
-
- # Read footer
- f.seek(0, 2)
- file_size = f.tell()
- if file_size >= 512:
- f.seek(-512, 2)
- if f.read(8) == VHD_SIGNATURE:
- return constants.DISK_FORMAT_VHD
-
- raise vmutils.HyperVException(_('Unsupported virtual disk format'))
-
- def get_best_supported_vhd_format(self):
- return constants.DISK_FORMAT_VHD
diff --git a/nova/virt/hyperv/vhdutilsv2.py b/nova/virt/hyperv/vhdutilsv2.py
deleted file mode 100644
index 07f267d42a..0000000000
--- a/nova/virt/hyperv/vhdutilsv2.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Utility class for VHD related operations.
-Based on the "root/virtualization/v2" namespace available starting with
-Hyper-V Server / Windows Server 2012.
-"""
-import struct
-import sys
-
-if sys.platform == 'win32':
- import wmi
-
-from xml.etree import ElementTree
-
-from oslo_utils import units
-
-from nova.i18n import _
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import vhdutils
-from nova.virt.hyperv import vmutils
-from nova.virt.hyperv import vmutilsv2
-
-
-VHDX_BAT_ENTRY_SIZE = 8
-VHDX_HEADER_OFFSETS = [64 * units.Ki, 128 * units.Ki]
-VHDX_HEADER_SECTION_SIZE = units.Mi
-VHDX_LOG_LENGTH_OFFSET = 68
-VHDX_METADATA_SIZE_OFFSET = 64
-VHDX_REGION_TABLE_OFFSET = 192 * units.Ki
-VHDX_BS_METADATA_ENTRY_OFFSET = 48
-
-
-class VHDUtilsV2(vhdutils.VHDUtils):
-
- _VHD_TYPE_DYNAMIC = 3
- _VHD_TYPE_DIFFERENCING = 4
-
- _vhd_format_map = {
- constants.DISK_FORMAT_VHD: 2,
- constants.DISK_FORMAT_VHDX: 3,
- }
-
- def __init__(self):
- self._vmutils = vmutilsv2.VMUtilsV2()
- if sys.platform == 'win32':
- self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
-
- def create_dynamic_vhd(self, path, max_internal_size, format):
- vhd_format = self._vhd_format_map.get(format)
- if not vhd_format:
- raise vmutils.HyperVException(_("Unsupported disk format: %s") %
- format)
-
- self._create_vhd(self._VHD_TYPE_DYNAMIC, vhd_format, path,
- max_internal_size=max_internal_size)
-
- def create_differencing_vhd(self, path, parent_path):
- # Although this method can take a size argument in case of VHDX
- # images, avoid it as the underlying Win32 is currently not
- # resizing the disk properly. This can be reconsidered once the
- # Win32 issue is fixed.
- parent_vhd_info = self.get_vhd_info(parent_path)
- self._create_vhd(self._VHD_TYPE_DIFFERENCING,
- parent_vhd_info["Format"],
- path, parent_path=parent_path)
-
- def _create_vhd(self, vhd_type, format, path, max_internal_size=None,
- parent_path=None):
- vhd_info = self._conn.Msvm_VirtualHardDiskSettingData.new()
-
- vhd_info.Type = vhd_type
- vhd_info.Format = format
- vhd_info.Path = path
- vhd_info.ParentPath = parent_path
-
- if max_internal_size:
- vhd_info.MaxInternalSize = max_internal_size
-
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
- (job_path, ret_val) = image_man_svc.CreateVirtualHardDisk(
- VirtualDiskSettingData=vhd_info.GetText_(1))
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def reconnect_parent_vhd(self, child_vhd_path, parent_vhd_path):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
- vhd_info_xml = self._get_vhd_info_xml(image_man_svc, child_vhd_path)
-
- et = ElementTree.fromstring(vhd_info_xml)
- item = et.find(".//PROPERTY[@NAME='ParentPath']/VALUE")
- if item is not None:
- item.text = parent_vhd_path
- else:
- msg = (_("Failed to reconnect image %(child_vhd_path)s to "
- "parent %(parent_vhd_path)s. The child image has no "
- "parent path property.") %
- {'child_vhd_path': child_vhd_path,
- 'parent_vhd_path': parent_vhd_path})
- raise vmutils.HyperVException(msg)
-
- vhd_info_xml = ElementTree.tostring(et)
-
- (job_path, ret_val) = image_man_svc.SetVirtualHardDiskSettingData(
- VirtualDiskSettingData=vhd_info_xml)
-
- self._vmutils.check_ret_val(ret_val, job_path)
-
- def _get_resize_method(self):
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
- return image_man_svc.ResizeVirtualHardDisk
-
- def get_internal_vhd_size_by_file_size(self, vhd_path,
- new_vhd_file_size):
- """Get internal size of a VHD according to new VHD file size.
-
- VHDX Size = Header (1MB) + Log + Metadata Region + BAT + Payload Blocks
-
- The chunk size is the maximum number of bytes described by a SB
- block.
-
- Chunk size = 2^{23} * LogicalSectorSize
-
- :param str vhd_path: VHD file path
- :param new_vhd_file_size: Size of the new VHD file.
- :return: Internal VHD size according to new VHD file size.
- """
- vhd_format = self.get_vhd_format(vhd_path)
- if vhd_format == constants.DISK_FORMAT_VHD:
- return super(VHDUtilsV2,
- self).get_internal_vhd_size_by_file_size(
- vhd_path, new_vhd_file_size)
- else:
- vhd_info = self.get_vhd_info(vhd_path)
- vhd_type = vhd_info['Type']
- if vhd_type == self._VHD_TYPE_DIFFERENCING:
- vhd_parent = self.get_vhd_parent_path(vhd_path)
- return self.get_internal_vhd_size_by_file_size(vhd_parent,
- new_vhd_file_size)
- else:
- try:
- with open(vhd_path, 'rb') as f:
- hs = VHDX_HEADER_SECTION_SIZE
- bes = VHDX_BAT_ENTRY_SIZE
-
- lss = vhd_info['LogicalSectorSize']
- bs = self._get_vhdx_block_size(f)
- ls = self._get_vhdx_log_size(f)
- ms = self._get_vhdx_metadata_size_and_offset(f)[0]
-
- chunk_ratio = (1 << 23) * lss / bs
- size = new_vhd_file_size
-
- max_internal_size = (bs * chunk_ratio * (size - hs -
- ls - ms - bes - bes / chunk_ratio) / (bs *
- chunk_ratio + bes * chunk_ratio + bes))
-
- return max_internal_size - (max_internal_size % bs)
-
- except IOError as ex:
- raise vmutils.HyperVException(_("Unable to obtain "
- "internal size from VHDX: "
- "%(vhd_path)s. Exception: "
- "%(ex)s") %
- {"vhd_path": vhd_path,
- "ex": ex})
-
- def _get_vhdx_current_header_offset(self, vhdx_file):
- sequence_numbers = []
- for offset in VHDX_HEADER_OFFSETS:
- vhdx_file.seek(offset + 8)
- sequence_numbers.append(struct.unpack(' 1:
- raise HyperVException(_('Duplicate VM name found: %s') % vm_name)
- else:
- return vms[0]
-
- def vm_exists(self, vm_name):
- return self._lookup_vm(vm_name) is not None
-
- def get_vm_id(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- return vm.Name
-
- def _get_vm_setting_data(self, vm):
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- # Avoid snapshots
- return [s for s in vmsettings if s.SettingType == 3][0]
-
- def _set_vm_memory(self, vm, vmsetting, memory_mb, dynamic_memory_ratio):
- mem_settings = vmsetting.associators(
- wmi_result_class=self._MEMORY_SETTING_DATA_CLASS)[0]
-
- max_mem = long(memory_mb)
- mem_settings.Limit = max_mem
-
- if dynamic_memory_ratio > 1:
- mem_settings.DynamicMemoryEnabled = True
- # Must be a multiple of 2
- reserved_mem = min(
- long(max_mem / dynamic_memory_ratio) >> 1 << 1,
- max_mem)
- else:
- mem_settings.DynamicMemoryEnabled = False
- reserved_mem = max_mem
-
- mem_settings.Reservation = reserved_mem
- # Start with the minimum memory
- mem_settings.VirtualQuantity = reserved_mem
-
- self._modify_virt_resource(mem_settings, vm.path_())
-
- def _set_vm_vcpus(self, vm, vmsetting, vcpus_num, limit_cpu_features):
- procsetting = vmsetting.associators(
- wmi_result_class=self._PROCESSOR_SETTING_DATA_CLASS)[0]
- vcpus = long(vcpus_num)
- procsetting.VirtualQuantity = vcpus
- procsetting.Reservation = vcpus
- procsetting.Limit = 100000 # static assignment to 100%
- procsetting.LimitProcessorFeatures = limit_cpu_features
-
- self._modify_virt_resource(procsetting, vm.path_())
-
- def update_vm(self, vm_name, memory_mb, vcpus_num, limit_cpu_features,
- dynamic_memory_ratio):
- vm = self._lookup_vm_check(vm_name)
- vmsetting = self._get_vm_setting_data(vm)
- self._set_vm_memory(vm, vmsetting, memory_mb, dynamic_memory_ratio)
- self._set_vm_vcpus(vm, vmsetting, vcpus_num, limit_cpu_features)
-
- def check_admin_permissions(self):
- if not self._conn.Msvm_VirtualSystemManagementService():
- msg = _("The Windows account running nova-compute on this Hyper-V"
- " host doesn't have the required permissions to create or"
- " operate the virtual machine.")
- raise HyperVAuthorizationException(msg)
-
- def create_vm(self, vm_name, memory_mb, vcpus_num, limit_cpu_features,
- dynamic_memory_ratio, vm_gen, instance_path, notes=None):
- """Creates a VM."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
-
- LOG.debug('Creating VM %s', vm_name)
- vm = self._create_vm_obj(vs_man_svc, vm_name, vm_gen, notes,
- dynamic_memory_ratio, instance_path)
-
- vmsetting = self._get_vm_setting_data(vm)
-
- LOG.debug('Setting memory for vm %s', vm_name)
- self._set_vm_memory(vm, vmsetting, memory_mb, dynamic_memory_ratio)
-
- LOG.debug('Set vCPUs for vm %s', vm_name)
- self._set_vm_vcpus(vm, vmsetting, vcpus_num, limit_cpu_features)
-
- def _create_vm_obj(self, vs_man_svc, vm_name, vm_gen, notes,
- dynamic_memory_ratio, instance_path):
- vs_gs_data = self._conn.Msvm_VirtualSystemGlobalSettingData.new()
- vs_gs_data.ElementName = vm_name
- # Don't start automatically on host boot
- vs_gs_data.AutomaticStartupAction = self._AUTOMATIC_STARTUP_ACTION_NONE
- vs_gs_data.ExternalDataRoot = instance_path
- vs_gs_data.SnapshotDataRoot = instance_path
-
- (vm_path,
- job_path,
- ret_val) = vs_man_svc.DefineVirtualSystem([], None,
- vs_gs_data.GetText_(1))
- self.check_ret_val(ret_val, job_path)
-
- vm = self._get_wmi_obj(vm_path)
-
- if notes:
- vmsetting = self._get_vm_setting_data(vm)
- vmsetting.Notes = '\n'.join(notes)
- self._modify_virtual_system(vs_man_svc, vm_path, vmsetting)
-
- return self._get_wmi_obj(vm_path)
-
- def _modify_virtual_system(self, vs_man_svc, vm_path, vmsetting):
- (job_path, ret_val) = vs_man_svc.ModifyVirtualSystem(
- ComputerSystem=vm_path,
- SystemSettingData=vmsetting.GetText_(1))[1:]
- self.check_ret_val(ret_val, job_path)
-
- def get_vm_scsi_controller(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- return self._get_vm_scsi_controller(vm)
-
- def _get_vm_scsi_controller(self, vm):
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- rasds = vmsettings[0].associators(
- wmi_result_class=self._RESOURCE_ALLOC_SETTING_DATA_CLASS)
- res = [r for r in rasds
- if r.ResourceSubType == self._SCSI_CTRL_RES_SUB_TYPE][0]
- return res.path_()
-
- def _get_vm_ide_controller(self, vm, ctrller_addr):
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- rasds = vmsettings[0].associators(
- wmi_result_class=self._RESOURCE_ALLOC_SETTING_DATA_CLASS)
- ide_ctrls = [r for r in rasds
- if r.ResourceSubType == self._IDE_CTRL_RES_SUB_TYPE
- and r.Address == str(ctrller_addr)]
-
- return ide_ctrls[0].path_() if ide_ctrls else None
-
- def get_vm_ide_controller(self, vm_name, ctrller_addr):
- vm = self._lookup_vm_check(vm_name)
- return self._get_vm_ide_controller(vm, ctrller_addr)
-
- def get_attached_disks(self, scsi_controller_path):
- volumes = self._conn.query(
- self._get_attached_disks_query_string(scsi_controller_path))
- return volumes
-
- def _get_attached_disks_query_string(self, scsi_controller_path):
- return ("SELECT * FROM %(class_name)s WHERE ("
- "ResourceSubType='%(res_sub_type)s' OR "
- "ResourceSubType='%(res_sub_type_virt)s') AND "
- "Parent='%(parent)s'" % {
- 'class_name': self._RESOURCE_ALLOC_SETTING_DATA_CLASS,
- 'res_sub_type': self._PHYS_DISK_RES_SUB_TYPE,
- 'res_sub_type_virt': self._DISK_DRIVE_RES_SUB_TYPE,
- 'parent': scsi_controller_path.replace("'", "''")})
-
- def _get_new_setting_data(self, class_name):
- obj = self._conn.query("SELECT * FROM %s WHERE InstanceID "
- "LIKE '%%\\Default'" % class_name)[0]
- return self._check_clone_wmi_obj(class_name, obj)
-
- def _get_new_resource_setting_data(self, resource_sub_type,
- class_name=None):
- if class_name is None:
- class_name = self._RESOURCE_ALLOC_SETTING_DATA_CLASS
- obj = self._conn.query("SELECT * FROM %(class_name)s "
- "WHERE ResourceSubType = "
- "'%(res_sub_type)s' AND "
- "InstanceID LIKE '%%\\Default'" %
- {"class_name": class_name,
- "res_sub_type": resource_sub_type})[0]
- return self._check_clone_wmi_obj(class_name, obj)
-
- def _check_clone_wmi_obj(self, class_name, obj):
- if self._clone_wmi_objs:
- return self._clone_wmi_obj(class_name, obj)
- else:
- return obj
-
- def _clone_wmi_obj(self, class_name, obj):
- wmi_class = getattr(self._conn, class_name)
- new_obj = wmi_class.new()
- # Copy the properties from the original.
- for prop in obj._properties:
- value = obj.Properties_.Item(prop).Value
- new_obj.Properties_.Item(prop).Value = value
- return new_obj
-
- def attach_scsi_drive(self, vm_name, path, drive_type=constants.DISK):
- vm = self._lookup_vm_check(vm_name)
- ctrller_path = self._get_vm_scsi_controller(vm)
- drive_addr = self.get_free_controller_slot(ctrller_path)
- self.attach_drive(vm_name, path, ctrller_path, drive_addr, drive_type)
-
- def attach_ide_drive(self, vm_name, path, ctrller_addr, drive_addr,
- drive_type=constants.DISK):
- vm = self._lookup_vm_check(vm_name)
- ctrller_path = self._get_vm_ide_controller(vm, ctrller_addr)
- self.attach_drive(vm_name, path, ctrller_path, drive_addr, drive_type)
-
- def attach_drive(self, vm_name, path, ctrller_path, drive_addr,
- drive_type=constants.DISK):
- """Create a drive and attach it to the vm."""
-
- vm = self._lookup_vm_check(vm_name)
-
- if drive_type == constants.DISK:
- res_sub_type = self._DISK_DRIVE_RES_SUB_TYPE
- elif drive_type == constants.DVD:
- res_sub_type = self._DVD_DRIVE_RES_SUB_TYPE
-
- drive = self._get_new_resource_setting_data(res_sub_type)
-
- # Set the ctrller as parent.
- drive.Parent = ctrller_path
- drive.Address = drive_addr
- # Add the cloned disk drive object to the vm.
- new_resources = self._add_virt_resource(drive, vm.path_())
- drive_path = new_resources[0]
-
- if drive_type == constants.DISK:
- res_sub_type = self._HARD_DISK_RES_SUB_TYPE
- elif drive_type == constants.DVD:
- res_sub_type = self._DVD_DISK_RES_SUB_TYPE
-
- res = self._get_new_resource_setting_data(res_sub_type)
- # Set the new drive as the parent.
- res.Parent = drive_path
- res.Connection = [path]
-
- # Add the new vhd object as a virtual hard disk to the vm.
- self._add_virt_resource(res, vm.path_())
-
- def create_scsi_controller(self, vm_name):
- """Create an iscsi controller ready to mount volumes."""
-
- vm = self._lookup_vm_check(vm_name)
- scsicontrl = self._get_new_resource_setting_data(
- self._SCSI_CTRL_RES_SUB_TYPE)
-
- scsicontrl.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
- self._add_virt_resource(scsicontrl, vm.path_())
-
- def attach_volume_to_controller(self, vm_name, controller_path, address,
- mounted_disk_path):
- """Attach a volume to a controller."""
-
- vm = self._lookup_vm_check(vm_name)
-
- diskdrive = self._get_new_resource_setting_data(
- self._PHYS_DISK_RES_SUB_TYPE)
-
- diskdrive.Address = address
- diskdrive.Parent = controller_path
- diskdrive.HostResource = [mounted_disk_path]
- self._add_virt_resource(diskdrive, vm.path_())
-
- def _get_disk_resource_address(self, disk_resource):
- return disk_resource.Address
-
- def set_disk_host_resource(self, vm_name, controller_path, address,
- mounted_disk_path):
- disk_found = False
- vm = self._lookup_vm_check(vm_name)
- (disk_resources, volume_resources) = self._get_vm_disks(vm)
- for disk_resource in disk_resources + volume_resources:
- if (disk_resource.Parent == controller_path and
- self._get_disk_resource_address(disk_resource) ==
- str(address)):
- if (disk_resource.HostResource and
- disk_resource.HostResource[0] != mounted_disk_path):
- LOG.debug('Updating disk host resource "%(old)s" to '
- '"%(new)s"' %
- {'old': disk_resource.HostResource[0],
- 'new': mounted_disk_path})
- disk_resource.HostResource = [mounted_disk_path]
- self._modify_virt_resource(disk_resource, vm.path_())
- disk_found = True
- break
- if not disk_found:
- LOG.warning(_LW('Disk not found on controller '
- '"%(controller_path)s" with '
- 'address "%(address)s"'),
- {'controller_path': controller_path,
- 'address': address})
-
- def set_nic_connection(self, vm_name, nic_name, vswitch_conn_data):
- nic_data = self._get_nic_data_by_name(nic_name)
- nic_data.Connection = [vswitch_conn_data]
-
- vm = self._lookup_vm_check(vm_name)
- self._modify_virt_resource(nic_data, vm.path_())
-
- def destroy_nic(self, vm_name, nic_name):
- """Destroys the NIC with the given nic_name from the given VM.
-
- :param vm_name: The name of the VM which has the NIC to be destroyed.
- :param nic_name: The NIC's ElementName.
- """
- nic_data = self._get_nic_data_by_name(nic_name)
-
- vm = self._lookup_vm_check(vm_name)
- self._remove_virt_resource(nic_data, vm.path_())
-
- def _get_nic_data_by_name(self, name):
- return self._conn.Msvm_SyntheticEthernetPortSettingData(
- ElementName=name)[0]
-
- def create_nic(self, vm_name, nic_name, mac_address):
- """Create a (synthetic) nic and attach it to the vm."""
- # Create a new nic
- new_nic_data = self._get_new_setting_data(
- self._SYNTHETIC_ETHERNET_PORT_SETTING_DATA_CLASS)
-
- # Configure the nic
- new_nic_data.ElementName = nic_name
- new_nic_data.Address = mac_address.replace(':', '')
- new_nic_data.StaticMacAddress = 'True'
- new_nic_data.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
-
- # Add the new nic to the vm
- vm = self._lookup_vm_check(vm_name)
-
- self._add_virt_resource(new_nic_data, vm.path_())
-
- def soft_shutdown_vm(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- shutdown_component = vm.associators(
- wmi_result_class=self._SHUTDOWN_COMPONENT)
-
- if not shutdown_component:
- # If no shutdown_component is found, it means the VM is already
- # in a shutdown state.
- return
-
- reason = 'Soft shutdown requested by OpenStack Nova.'
- (ret_val, ) = shutdown_component[0].InitiateShutdown(Force=False,
- Reason=reason)
- self.check_ret_val(ret_val, None)
-
- def set_vm_state(self, vm_name, req_state):
- """Set the desired state of the VM."""
- vm = self._lookup_vm_check(vm_name)
- (job_path,
- ret_val) = vm.RequestStateChange(self._vm_power_states_map[req_state])
- # Invalid state for current operation (32775) typically means that
- # the VM is already in the state requested
- self.check_ret_val(ret_val, job_path, [0, 32775])
- LOG.debug("Successfully changed vm state of %(vm_name)s "
- "to %(req_state)s",
- {'vm_name': vm_name, 'req_state': req_state})
-
- def _get_disk_resource_disk_path(self, disk_resource):
- return disk_resource.Connection
-
- def get_vm_storage_paths(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- (disk_resources, volume_resources) = self._get_vm_disks(vm)
-
- volume_drives = []
- for volume_resource in volume_resources:
- drive_path = volume_resource.HostResource[0]
- volume_drives.append(drive_path)
-
- disk_files = []
- for disk_resource in disk_resources:
- disk_files.extend(
- [c for c in self._get_disk_resource_disk_path(disk_resource)])
-
- return (disk_files, volume_drives)
-
- def _get_vm_disks(self, vm):
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- rasds = vmsettings[0].associators(
- wmi_result_class=self._STORAGE_ALLOC_SETTING_DATA_CLASS)
- disk_resources = [r for r in rasds if
- r.ResourceSubType in
- [self._HARD_DISK_RES_SUB_TYPE,
- self._DVD_DISK_RES_SUB_TYPE]]
-
- if (self._RESOURCE_ALLOC_SETTING_DATA_CLASS !=
- self._STORAGE_ALLOC_SETTING_DATA_CLASS):
- rasds = vmsettings[0].associators(
- wmi_result_class=self._RESOURCE_ALLOC_SETTING_DATA_CLASS)
-
- volume_resources = [r for r in rasds if
- r.ResourceSubType == self._PHYS_DISK_RES_SUB_TYPE]
-
- return (disk_resources, volume_resources)
-
- def destroy_vm(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
-
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- # Remove the VM. Does not destroy disks.
- (job_path, ret_val) = vs_man_svc.DestroyVirtualSystem(vm.path_())
- self.check_ret_val(ret_val, job_path)
-
- def check_ret_val(self, ret_val, job_path, success_values=[0]):
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- return self._wait_for_job(job_path)
- elif ret_val not in success_values:
- raise HyperVException(_('Operation failed with return value: %s')
- % ret_val)
-
- def _wait_for_job(self, job_path):
- """Poll WMI job state and wait for completion."""
- job = self._get_wmi_obj(job_path)
-
- while job.JobState == constants.WMI_JOB_STATE_RUNNING:
- time.sleep(0.1)
- job = self._get_wmi_obj(job_path)
- if job.JobState == constants.JOB_STATE_KILLED:
- LOG.debug("WMI job killed with status %s.", job.JobState)
- return job
-
- if job.JobState != constants.WMI_JOB_STATE_COMPLETED:
- job_state = job.JobState
- if job.path().Class == "Msvm_ConcreteJob":
- err_sum_desc = job.ErrorSummaryDescription
- err_desc = job.ErrorDescription
- err_code = job.ErrorCode
- raise HyperVException(_("WMI job failed with status "
- "%(job_state)d. Error details: "
- "%(err_sum_desc)s - %(err_desc)s - "
- "Error code: %(err_code)d") %
- {'job_state': job_state,
- 'err_sum_desc': err_sum_desc,
- 'err_desc': err_desc,
- 'err_code': err_code})
- else:
- (error, ret_val) = job.GetError()
- if not ret_val and error:
- raise HyperVException(_("WMI job failed with status "
- "%(job_state)d. Error details: "
- "%(error)s") %
- {'job_state': job_state,
- 'error': error})
- else:
- raise HyperVException(_("WMI job failed with status "
- "%d. No error "
- "description available") %
- job_state)
- desc = job.Description
- elap = job.ElapsedTime
- LOG.debug("WMI job succeeded: %(desc)s, Elapsed=%(elap)s",
- {'desc': desc, 'elap': elap})
- return job
-
- def _get_wmi_obj(self, path):
- return wmi.WMI(moniker=path.replace('\\', '/'))
-
- def _add_virt_resource(self, res_setting_data, vm_path):
- """Adds a new resource to the VM."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- res_xml = [res_setting_data.GetText_(1)]
- (job_path,
- new_resources,
- ret_val) = vs_man_svc.AddVirtualSystemResources(res_xml, vm_path)
- self.check_ret_val(ret_val, job_path)
- return new_resources
-
- def _modify_virt_resource(self, res_setting_data, vm_path):
- """Updates a VM resource."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- (job_path, ret_val) = vs_man_svc.ModifyVirtualSystemResources(
- ResourceSettingData=[res_setting_data.GetText_(1)],
- ComputerSystem=vm_path)
- self.check_ret_val(ret_val, job_path)
-
- def _remove_virt_resource(self, res_setting_data, vm_path):
- """Removes a VM resource."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- res_path = [res_setting_data.path_()]
- (job_path, ret_val) = vs_man_svc.RemoveVirtualSystemResources(res_path,
- vm_path)
- self.check_ret_val(ret_val, job_path)
-
- def take_vm_snapshot(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
-
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
-
- (job_path, ret_val,
- snp_setting_data) = vs_man_svc.CreateVirtualSystemSnapshot(vm.path_())
- self.check_ret_val(ret_val, job_path)
-
- job_wmi_path = job_path.replace('\\', '/')
- job = wmi.WMI(moniker=job_wmi_path)
- snp_setting_data = job.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)[0]
- return snp_setting_data.path_()
-
- def remove_vm_snapshot(self, snapshot_path):
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
-
- (job_path, ret_val) = vs_man_svc.RemoveVirtualSystemSnapshot(
- snapshot_path)
- self.check_ret_val(ret_val, job_path)
-
- def detach_vm_disk(self, vm_name, disk_path, is_physical=True):
- vm = self._lookup_vm_check(vm_name)
- disk_resource = self._get_mounted_disk_resource_from_path(disk_path,
- is_physical)
-
- if disk_resource:
- parent = self._conn.query("SELECT * FROM "
- "Msvm_ResourceAllocationSettingData "
- "WHERE __PATH = '%s'" %
- disk_resource.Parent)[0]
-
- self._remove_virt_resource(disk_resource, vm.path_())
- if not is_physical:
- self._remove_virt_resource(parent, vm.path_())
-
- def _get_mounted_disk_resource_from_path(self, disk_path, is_physical):
- if is_physical:
- class_name = self._RESOURCE_ALLOC_SETTING_DATA_CLASS
- res_sub_type = self._PHYS_DISK_RES_SUB_TYPE
- conn_attr = self._PHYS_DISK_CONNECTION_ATTR
- else:
- class_name = self._STORAGE_ALLOC_SETTING_DATA_CLASS
- res_sub_type = self._HARD_DISK_RES_SUB_TYPE
- conn_attr = self._VIRT_DISK_CONNECTION_ATTR
-
- disk_resources = self._conn.query("SELECT * FROM %(class_name)s "
- "WHERE ResourceSubType = "
- "'%(res_sub_type)s'" %
- {"class_name": class_name,
- "res_sub_type": res_sub_type})
-
- for disk_resource in disk_resources:
- conn = getattr(disk_resource, conn_attr, None)
- if conn and conn[0].lower() == disk_path.lower():
- return disk_resource
-
- def get_mounted_disk_by_drive_number(self, device_number):
- mounted_disks = self._conn.query("SELECT * FROM Msvm_DiskDrive "
- "WHERE DriveNumber=" +
- str(device_number))
- if len(mounted_disks):
- return mounted_disks[0].path_()
-
- def get_controller_volume_paths(self, controller_path):
- disks = self._conn.query("SELECT * FROM %(class_name)s "
- "WHERE ResourceSubType = '%(res_sub_type)s' "
- "AND Parent='%(parent)s'" %
- {"class_name":
- self._RESOURCE_ALLOC_SETTING_DATA_CLASS,
- "res_sub_type":
- self._PHYS_DISK_RES_SUB_TYPE,
- "parent":
- controller_path})
- disk_data = {}
- for disk in disks:
- if disk.HostResource:
- disk_data[disk.path().RelPath] = disk.HostResource[0]
- return disk_data
-
- def get_free_controller_slot(self, scsi_controller_path):
- attached_disks = self.get_attached_disks(scsi_controller_path)
- used_slots = [int(self._get_disk_resource_address(disk))
- for disk in attached_disks]
-
- for slot in range(constants.SCSI_CONTROLLER_SLOTS_NUMBER):
- if slot not in used_slots:
- return slot
- raise HyperVException(_("Exceeded the maximum number of slots"))
-
- def enable_vm_metrics_collection(self, vm_name):
- raise NotImplementedError(_("Metrics collection is not supported on "
- "this version of Hyper-V"))
-
- def get_vm_serial_port_connection(self, vm_name, update_connection=None):
- vm = self._lookup_vm_check(vm_name)
-
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- rasds = vmsettings[0].associators(
- wmi_result_class=self._SERIAL_PORT_SETTING_DATA_CLASS)
- serial_port = (
- [r for r in rasds if
- r.ResourceSubType == self._SERIAL_PORT_RES_SUB_TYPE][0])
-
- if update_connection:
- serial_port.Connection = [update_connection]
- self._modify_virt_resource(serial_port, vm.path_())
-
- if len(serial_port.Connection) > 0:
- return serial_port.Connection[0]
-
- def get_active_instances(self):
- """Return the names of all the active instances known to Hyper-V."""
- vm_names = self.list_instances()
- vms = [self._lookup_vm(vm_name) for vm_name in vm_names]
- active_vm_names = [v.ElementName for v in vms
- if v.EnabledState == constants.HYPERV_VM_STATE_ENABLED]
-
- return active_vm_names
-
- def get_vm_power_state_change_listener(self, timeframe, filtered_states):
- field = self._VM_ENABLED_STATE_PROP
- query = self._get_event_wql_query(cls=self._COMPUTER_SYSTEM_CLASS,
- field=field,
- timeframe=timeframe,
- filtered_states=filtered_states)
- return self._conn.Msvm_ComputerSystem.watch_for(raw_wql=query,
- fields=[field])
-
- def _get_event_wql_query(self, cls, field,
- timeframe, filtered_states=None):
- """Return a WQL query used for polling WMI events.
-
- :param cls: the WMI class polled for events
- :param field: the field checked
- :param timeframe: check for events that occurred in
- the specified timeframe
- :param filtered_states: only catch events triggered when a WMI
- object transitioned into one of those
- states.
- """
- query = ("SELECT %(field)s, TargetInstance "
- "FROM __InstanceModificationEvent "
- "WITHIN %(timeframe)s "
- "WHERE TargetInstance ISA '%(class)s' "
- "AND TargetInstance.%(field)s != "
- "PreviousInstance.%(field)s" %
- {'class': cls,
- 'field': field,
- 'timeframe': timeframe})
- if filtered_states:
- checks = ["TargetInstance.%s = '%s'" % (field, state)
- for state in filtered_states]
- query += " AND (%s)" % " OR ".join(checks)
- return query
-
- def _get_instance_notes(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- vmsettings = self._get_vm_setting_data(vm)
- return [note for note in vmsettings.Notes.split('\n') if note]
-
- def get_instance_uuid(self, vm_name):
- instance_notes = self._get_instance_notes(vm_name)
- if instance_notes and uuidutils.is_uuid_like(instance_notes[0]):
- return instance_notes[0]
-
- def get_vm_power_state(self, vm_enabled_state):
- return self._enabled_states_map.get(vm_enabled_state,
- constants.HYPERV_VM_STATE_OTHER)
-
- def get_vm_generation(self, vm_name):
- return constants.VM_GEN_1
-
- def stop_vm_jobs(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- vm_jobs = vm.associators(wmi_result_class=self._CONCRETE_JOB_CLASS)
-
- for job in vm_jobs:
- if job and job.Cancellable and not self._is_job_completed(job):
-
- job.RequestStateChange(self._KILL_JOB_STATE_CHANGE_REQUEST)
-
- return vm_jobs
-
- def _is_job_completed(self, job):
- return job.JobState in self._completed_job_states
diff --git a/nova/virt/hyperv/vmutilsv2.py b/nova/virt/hyperv/vmutilsv2.py
deleted file mode 100644
index b647b8fb4a..0000000000
--- a/nova/virt/hyperv/vmutilsv2.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""
-Utility class for VM related operations.
-Based on the "root/virtualization/v2" namespace available starting with
-Hyper-V Server / Windows Server 2012.
-"""
-
-import sys
-import uuid
-
-if sys.platform == 'win32':
- import wmi
-
-from oslo_config import cfg
-from oslo_log import log as logging
-
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import hostutils
-from nova.virt.hyperv import vmutils
-
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-class VMUtilsV2(vmutils.VMUtils):
-
- _PHYS_DISK_RES_SUB_TYPE = 'Microsoft:Hyper-V:Physical Disk Drive'
- _DISK_DRIVE_RES_SUB_TYPE = 'Microsoft:Hyper-V:Synthetic Disk Drive'
- _DVD_DRIVE_RES_SUB_TYPE = 'Microsoft:Hyper-V:Synthetic DVD Drive'
- _SCSI_RES_SUBTYPE = 'Microsoft:Hyper-V:Synthetic SCSI Controller'
- _HARD_DISK_RES_SUB_TYPE = 'Microsoft:Hyper-V:Virtual Hard Disk'
- _DVD_DISK_RES_SUB_TYPE = 'Microsoft:Hyper-V:Virtual CD/DVD Disk'
- _IDE_CTRL_RES_SUB_TYPE = 'Microsoft:Hyper-V:Emulated IDE Controller'
- _SCSI_CTRL_RES_SUB_TYPE = 'Microsoft:Hyper-V:Synthetic SCSI Controller'
- _SERIAL_PORT_RES_SUB_TYPE = 'Microsoft:Hyper-V:Serial Port'
-
- _VIRTUAL_SYSTEM_SUBTYPE = 'VirtualSystemSubType'
- _VIRTUAL_SYSTEM_TYPE_REALIZED = 'Microsoft:Hyper-V:System:Realized'
- _VIRTUAL_SYSTEM_SUBTYPE_GEN2 = 'Microsoft:Hyper-V:SubType:2'
-
- _SNAPSHOT_FULL = 2
-
- _METRIC_AGGR_CPU_AVG = 'Aggregated Average CPU Utilization'
- _METRIC_AGGR_MEMORY_AVG = 'Aggregated Average Memory Utilization'
- _METRIC_ENABLED = 2
-
- _STORAGE_ALLOC_SETTING_DATA_CLASS = 'Msvm_StorageAllocationSettingData'
- _ETHERNET_PORT_ALLOCATION_SETTING_DATA_CLASS = \
- 'Msvm_EthernetPortAllocationSettingData'
-
- _VIRT_DISK_CONNECTION_ATTR = "HostResource"
-
- _AUTOMATIC_STARTUP_ACTION_NONE = 2
-
- _vm_power_states_map = {constants.HYPERV_VM_STATE_ENABLED: 2,
- constants.HYPERV_VM_STATE_DISABLED: 3,
- constants.HYPERV_VM_STATE_SHUTTING_DOWN: 4,
- constants.HYPERV_VM_STATE_REBOOT: 11,
- constants.HYPERV_VM_STATE_PAUSED: 9,
- constants.HYPERV_VM_STATE_SUSPENDED: 6}
-
- def __init__(self, host='.'):
- if sys.platform == 'win32':
- # A separate WMI class for VM serial ports has been introduced
- # in Windows 10 / Windows Server 2016
- if hostutils.HostUtils().check_min_windows_version(10, 0):
- self._SERIAL_PORT_SETTING_DATA_CLASS = (
- "Msvm_SerialPortSettingData")
- super(VMUtilsV2, self).__init__(host)
-
- def _init_hyperv_wmi_conn(self, host):
- self._conn = wmi.WMI(moniker='//%s/root/virtualization/v2' % host)
-
- def list_instance_notes(self):
- instance_notes = []
-
- for vs in self._conn.Msvm_VirtualSystemSettingData(
- ['ElementName', 'Notes'],
- VirtualSystemType=self._VIRTUAL_SYSTEM_TYPE_REALIZED):
- if vs.Notes is not None:
- instance_notes.append(
- (vs.ElementName, [v for v in vs.Notes if v]))
-
- return instance_notes
-
- def list_instances(self):
- """Return the names of all the instances known to Hyper-V."""
- return [v.ElementName for v in
- self._conn.Msvm_VirtualSystemSettingData(
- ['ElementName'],
- VirtualSystemType=self._VIRTUAL_SYSTEM_TYPE_REALIZED)]
-
- def _create_vm_obj(self, vs_man_svc, vm_name, vm_gen, notes,
- dynamic_memory_ratio, instance_path):
- vs_data = self._conn.Msvm_VirtualSystemSettingData.new()
- vs_data.ElementName = vm_name
- vs_data.Notes = notes
- # Don't start automatically on host boot
- vs_data.AutomaticStartupAction = self._AUTOMATIC_STARTUP_ACTION_NONE
-
- # vNUMA and dynamic memory are mutually exclusive
- if dynamic_memory_ratio > 1:
- vs_data.VirtualNumaEnabled = False
-
- if vm_gen == constants.VM_GEN_2:
- vs_data.VirtualSystemSubType = self._VIRTUAL_SYSTEM_SUBTYPE_GEN2
- vs_data.SecureBootEnabled = False
-
- # Created VMs must have their *DataRoot paths in the same location as
- # the instances' path.
- vs_data.ConfigurationDataRoot = instance_path
- vs_data.LogDataRoot = instance_path
- vs_data.SnapshotDataRoot = instance_path
- vs_data.SuspendDataRoot = instance_path
- vs_data.SwapFileDataRoot = instance_path
-
- (job_path,
- vm_path,
- ret_val) = vs_man_svc.DefineSystem(ResourceSettings=[],
- ReferenceConfiguration=None,
- SystemSettings=vs_data.GetText_(1))
- job = self.check_ret_val(ret_val, job_path)
- if not vm_path and job:
- vm_path = job.associators(self._AFFECTED_JOB_ELEMENT_CLASS)[0]
- return self._get_wmi_obj(vm_path)
-
- def _get_vm_setting_data(self, vm):
- vmsettings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
- # Avoid snapshots
- return [s for s in vmsettings if
- s.VirtualSystemType == self._VIRTUAL_SYSTEM_TYPE_REALIZED][0]
-
- def _get_attached_disks_query_string(self, scsi_controller_path):
- # DVD Drives can be attached to SCSI as well, if the VM Generation is 2
- return ("SELECT * FROM Msvm_ResourceAllocationSettingData WHERE ("
- "ResourceSubType='%(res_sub_type)s' OR "
- "ResourceSubType='%(res_sub_type_virt)s' OR "
- "ResourceSubType='%(res_sub_type_dvd)s') AND "
- "Parent = '%(parent)s'" % {
- 'res_sub_type': self._PHYS_DISK_RES_SUB_TYPE,
- 'res_sub_type_virt': self._DISK_DRIVE_RES_SUB_TYPE,
- 'res_sub_type_dvd': self._DVD_DRIVE_RES_SUB_TYPE,
- 'parent': scsi_controller_path.replace("'", "''")})
-
- def attach_drive(self, vm_name, path, ctrller_path, drive_addr,
- drive_type=constants.DISK):
- """Create a drive and attach it to the vm."""
-
- vm = self._lookup_vm_check(vm_name)
-
- if drive_type == constants.DISK:
- res_sub_type = self._DISK_DRIVE_RES_SUB_TYPE
- elif drive_type == constants.DVD:
- res_sub_type = self._DVD_DRIVE_RES_SUB_TYPE
-
- drive = self._get_new_resource_setting_data(res_sub_type)
-
- # Set the ctrller as parent.
- drive.Parent = ctrller_path
- drive.Address = drive_addr
- drive.AddressOnParent = drive_addr
- # Add the cloned disk drive object to the vm.
- new_resources = self._add_virt_resource(drive, vm.path_())
- drive_path = new_resources[0]
-
- if drive_type == constants.DISK:
- res_sub_type = self._HARD_DISK_RES_SUB_TYPE
- elif drive_type == constants.DVD:
- res_sub_type = self._DVD_DISK_RES_SUB_TYPE
-
- res = self._get_new_resource_setting_data(
- res_sub_type, self._STORAGE_ALLOC_SETTING_DATA_CLASS)
-
- res.Parent = drive_path
- res.HostResource = [path]
-
- self._add_virt_resource(res, vm.path_())
-
- def attach_volume_to_controller(self, vm_name, controller_path, address,
- mounted_disk_path):
- """Attach a volume to a controller."""
-
- vm = self._lookup_vm_check(vm_name)
-
- diskdrive = self._get_new_resource_setting_data(
- self._PHYS_DISK_RES_SUB_TYPE)
-
- diskdrive.AddressOnParent = address
- diskdrive.Parent = controller_path
- diskdrive.HostResource = [mounted_disk_path]
-
- self._add_virt_resource(diskdrive, vm.path_())
-
- def _get_disk_resource_address(self, disk_resource):
- return disk_resource.AddressOnParent
-
- def create_scsi_controller(self, vm_name):
- """Create an iscsi controller ready to mount volumes."""
- scsicontrl = self._get_new_resource_setting_data(
- self._SCSI_RES_SUBTYPE)
-
- scsicontrl.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
-
- vm = self._lookup_vm_check(vm_name)
- self._add_virt_resource(scsicontrl, vm.path_())
-
- def _get_disk_resource_disk_path(self, disk_resource):
- return disk_resource.HostResource
-
- def destroy_vm(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
-
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- # Remove the VM. It does not destroy any associated virtual disk.
- (job_path, ret_val) = vs_man_svc.DestroySystem(vm.path_())
- self.check_ret_val(ret_val, job_path)
-
- def _add_virt_resource(self, res_setting_data, vm_path):
- """Adds a new resource to the VM."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- res_xml = [res_setting_data.GetText_(1)]
- (job_path,
- new_resources,
- ret_val) = vs_man_svc.AddResourceSettings(vm_path, res_xml)
- self.check_ret_val(ret_val, job_path)
- return new_resources
-
- def _modify_virt_resource(self, res_setting_data, vm_path):
- """Updates a VM resource."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- (job_path,
- out_res_setting_data,
- ret_val) = vs_man_svc.ModifyResourceSettings(
- ResourceSettings=[res_setting_data.GetText_(1)])
- self.check_ret_val(ret_val, job_path)
-
- def _remove_virt_resource(self, res_setting_data, vm_path):
- """Removes a VM resource."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- res_path = [res_setting_data.path_()]
- (job_path, ret_val) = vs_man_svc.RemoveResourceSettings(res_path)
- self.check_ret_val(ret_val, job_path)
-
- def get_vm_state(self, vm_name):
- settings = self.get_vm_summary_info(vm_name)
- return settings['EnabledState']
-
- def take_vm_snapshot(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- vs_snap_svc = self._conn.Msvm_VirtualSystemSnapshotService()[0]
-
- (job_path, snp_setting_data, ret_val) = vs_snap_svc.CreateSnapshot(
- AffectedSystem=vm.path_(),
- SnapshotType=self._SNAPSHOT_FULL)
- self.check_ret_val(ret_val, job_path)
-
- job_wmi_path = job_path.replace('\\', '/')
- job = wmi.WMI(moniker=job_wmi_path)
- snp_setting_data = job.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)[0]
-
- return snp_setting_data.path_()
-
- def remove_vm_snapshot(self, snapshot_path):
- vs_snap_svc = self._conn.Msvm_VirtualSystemSnapshotService()[0]
- (job_path, ret_val) = vs_snap_svc.DestroySnapshot(snapshot_path)
- self.check_ret_val(ret_val, job_path)
-
- def set_nic_connection(self, vm_name, nic_name, vswitch_conn_data):
- nic_data = self._get_nic_data_by_name(nic_name)
-
- eth_port_data = self._get_new_setting_data(
- self._ETHERNET_PORT_ALLOCATION_SETTING_DATA_CLASS)
-
- eth_port_data.HostResource = [vswitch_conn_data]
- eth_port_data.Parent = nic_data.path_()
-
- vm = self._lookup_vm_check(vm_name)
- self._add_virt_resource(eth_port_data, vm.path_())
-
- def enable_vm_metrics_collection(self, vm_name):
- metric_names = [self._METRIC_AGGR_CPU_AVG,
- self._METRIC_AGGR_MEMORY_AVG]
-
- vm = self._lookup_vm_check(vm_name)
- metric_svc = self._conn.Msvm_MetricService()[0]
- (disks, volumes) = self._get_vm_disks(vm)
- filtered_disks = [d for d in disks if
- d.ResourceSubType is not self._DVD_DISK_RES_SUB_TYPE]
-
- # enable metrics for disk.
- for disk in filtered_disks:
- self._enable_metrics(metric_svc, disk)
-
- for metric_name in metric_names:
- metric_def = self._conn.CIM_BaseMetricDefinition(Name=metric_name)
- if not metric_def:
- LOG.debug("Metric not found: %s", metric_name)
- else:
- self._enable_metrics(metric_svc, vm, metric_def[0].path_())
-
- def _enable_metrics(self, metric_svc, element, definition_path=None):
- metric_svc.ControlMetrics(
- Subject=element.path_(),
- Definition=definition_path,
- MetricCollectionEnabled=self._METRIC_ENABLED)
-
- def get_vm_dvd_disk_paths(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
-
- settings = vm.associators(
- wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)[0]
- sasds = settings.associators(
- wmi_result_class=self._STORAGE_ALLOC_SETTING_DATA_CLASS)
-
- dvd_paths = [sasd.HostResource[0] for sasd in sasds
- if sasd.ResourceSubType == self._DVD_DISK_RES_SUB_TYPE]
-
- return dvd_paths
-
- def _get_instance_notes(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- vmsettings = self._get_vm_setting_data(vm)
- return [note for note in vmsettings.Notes if note]
-
- def get_vm_generation(self, vm_name):
- vm = self._lookup_vm_check(vm_name)
- vssd = self._get_vm_setting_data(vm)
- if hasattr(vssd, self._VIRTUAL_SYSTEM_SUBTYPE):
- # expected format: 'Microsoft:Hyper-V:SubType:2'
- return int(vssd.VirtualSystemSubType.split(':')[-1])
- return constants.VM_GEN_1
diff --git a/nova/virt/hyperv/volumeutils.py b/nova/virt/hyperv/volumeutils.py
deleted file mode 100644
index fa5f2ff93e..0000000000
--- a/nova/virt/hyperv/volumeutils.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright 2012 Pedro Navarro Perez
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Helper methods for operations related to the management of volumes,
-and storage repositories
-
-Official Microsoft iSCSI Initiator and iSCSI command line interface
-documentation can be retrieved at:
-http://www.microsoft.com/en-us/download/details.aspx?id=34750
-"""
-
-import re
-import time
-
-from oslo_config import cfg
-from oslo_log import log as logging
-from six.moves import range
-
-from nova.i18n import _
-from nova import utils
-from nova.virt.hyperv import basevolumeutils
-from nova.virt.hyperv import vmutils
-
-LOG = logging.getLogger(__name__)
-
-CONF = cfg.CONF
-
-
-class VolumeUtils(basevolumeutils.BaseVolumeUtils):
-
- def __init__(self):
- super(VolumeUtils, self).__init__()
-
- def execute(self, *args, **kwargs):
- stdout_value, stderr_value = utils.execute(*args, **kwargs)
- if stdout_value.find('The operation completed successfully') == -1:
- raise vmutils.HyperVException(_('An error has occurred when '
- 'calling the iscsi initiator: %s')
- % stdout_value)
- return stdout_value
-
- def _login_target_portal(self, target_portal):
- (target_address,
- target_port) = utils.parse_server_string(target_portal)
-
- output = self.execute('iscsicli.exe', 'ListTargetPortals')
- pattern = r'Address and Socket *: (.*)'
- portals = [addr.split() for addr in re.findall(pattern, output)]
- LOG.debug("Ensuring connection to portal: %s" % target_portal)
- if [target_address, str(target_port)] in portals:
- self.execute('iscsicli.exe', 'RefreshTargetPortal',
- target_address, target_port)
- else:
- # Adding target portal to iscsi initiator. Sending targets
- self.execute('iscsicli.exe', 'AddTargetPortal',
- target_address, target_port,
- '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
- '*', '*')
-
- def login_storage_target(self, target_lun, target_iqn, target_portal,
- auth_username=None, auth_password=None):
- """Ensure that the target is logged in."""
-
- self._login_target_portal(target_portal)
- # Listing targets
- self.execute('iscsicli.exe', 'ListTargets')
-
- retry_count = CONF.hyperv.volume_attach_retry_count
-
- # If the target is not connected, at least two iterations are needed:
- # one for performing the login and another one for checking if the
- # target was logged in successfully.
- if retry_count < 2:
- retry_count = 2
-
- for attempt in range(retry_count):
- try:
- session_info = self.execute('iscsicli.exe', 'SessionList')
- if session_info.find(target_iqn) == -1:
- # Sending login
- self.execute('iscsicli.exe', 'qlogintarget', target_iqn,
- auth_username, auth_password)
- else:
- return
- except vmutils.HyperVException as exc:
- LOG.debug("Attempt %(attempt)d to connect to target "
- "%(target_iqn)s failed. Retrying. "
- "Exceptipn: %(exc)s ",
- {'target_iqn': target_iqn,
- 'exc': exc,
- 'attempt': attempt})
- time.sleep(CONF.hyperv.volume_attach_retry_interval)
-
- raise vmutils.HyperVException(_('Failed to login target %s') %
- target_iqn)
-
- def logout_storage_target(self, target_iqn):
- """Logs out storage target through its session id."""
-
- sessions = self._conn_wmi.query("SELECT * FROM "
- "MSiSCSIInitiator_SessionClass "
- "WHERE TargetName='%s'" % target_iqn)
- for session in sessions:
- self.execute_log_out(session.SessionId)
-
- def execute_log_out(self, session_id):
- """Executes log out of the session described by its session ID."""
- self.execute('iscsicli.exe', 'logouttarget', session_id)
diff --git a/nova/virt/hyperv/volumeutilsv2.py b/nova/virt/hyperv/volumeutilsv2.py
deleted file mode 100644
index 0a29e01d48..0000000000
--- a/nova/virt/hyperv/volumeutilsv2.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright 2012 Pedro Navarro Perez
-# Copyright 2013 Cloudbase Solutions Srl
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Helper methods for operations related to the management of volumes
-and storage repositories on Windows Server 2012 and above
-"""
-import sys
-import time
-
-if sys.platform == 'win32':
- import wmi
-
-from oslo_config import cfg
-from oslo_log import log as logging
-from six.moves import range
-
-from nova.i18n import _
-from nova import utils
-from nova.virt.hyperv import basevolumeutils
-from nova.virt.hyperv import vmutils
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-
-class VolumeUtilsV2(basevolumeutils.BaseVolumeUtils):
- _CHAP_AUTH_TYPE = 'ONEWAYCHAP'
-
- def __init__(self, host='.'):
- super(VolumeUtilsV2, self).__init__(host)
-
- storage_namespace = '//%s/root/microsoft/windows/storage' % host
- if sys.platform == 'win32':
- self._conn_storage = wmi.WMI(moniker=storage_namespace)
-
- def _login_target_portal(self, target_portal):
- (target_address,
- target_port) = utils.parse_server_string(target_portal)
-
- # Checking if the portal is already connected.
- portal = self._conn_storage.query("SELECT * FROM "
- "MSFT_iSCSITargetPortal "
- "WHERE TargetPortalAddress='%s' "
- "AND TargetPortalPortNumber='%s'"
- % (target_address, target_port))
- if portal:
- portal[0].Update()
- else:
- # Adding target portal to iscsi initiator. Sending targets
- portal = self._conn_storage.MSFT_iSCSITargetPortal
- portal.New(TargetPortalAddress=target_address,
- TargetPortalPortNumber=target_port)
-
- def login_storage_target(self, target_lun, target_iqn, target_portal,
- auth_username=None, auth_password=None):
- """Ensure that the target is logged in."""
-
- self._login_target_portal(target_portal)
-
- retry_count = CONF.hyperv.volume_attach_retry_count
-
- # If the target is not connected, at least two iterations are needed:
- # one for performing the login and another one for checking if the
- # target was logged in successfully.
- if retry_count < 2:
- retry_count = 2
-
- for attempt in range(retry_count):
- target = self._conn_storage.query("SELECT * FROM MSFT_iSCSITarget "
- "WHERE NodeAddress='%s' " %
- target_iqn)
-
- if target and target[0].IsConnected:
- if attempt == 0:
- # The target was already connected but an update may be
- # required
- target[0].Update()
- return
- try:
- target = self._conn_storage.MSFT_iSCSITarget
- auth = {}
- if auth_username and auth_password:
- auth['AuthenticationType'] = self._CHAP_AUTH_TYPE
- auth['ChapUsername'] = auth_username
- auth['ChapSecret'] = auth_password
- target.Connect(NodeAddress=target_iqn,
- IsPersistent=True, **auth)
- time.sleep(CONF.hyperv.volume_attach_retry_interval)
- except wmi.x_wmi as exc:
- LOG.debug("Attempt %(attempt)d to connect to target "
- "%(target_iqn)s failed. Retrying. "
- "WMI exception: %(exc)s " %
- {'target_iqn': target_iqn,
- 'exc': exc,
- 'attempt': attempt})
- raise vmutils.HyperVException(_('Failed to login target %s') %
- target_iqn)
-
- def logout_storage_target(self, target_iqn):
- """Logs out storage target through its session id."""
- targets = self._conn_storage.MSFT_iSCSITarget(NodeAddress=target_iqn)
- if targets:
- target = targets[0]
- if target.IsConnected:
- sessions = self._conn_storage.MSFT_iSCSISession(
- TargetNodeAddress=target_iqn)
-
- for session in sessions:
- if session.IsPersistent:
- session.Unregister()
-
- target.Disconnect()
-
- def execute_log_out(self, session_id):
- sessions = self._conn_wmi.MSiSCSIInitiator_SessionClass(
- SessionId=session_id)
- if sessions:
- self.logout_storage_target(sessions[0].TargetName)
diff --git a/tests-py3.txt b/tests-py3.txt
index 4ede0b456b..b70da7e0a4 100644
--- a/tests-py3.txt
+++ b/tests-py3.txt
@@ -241,29 +241,16 @@ nova.tests.unit.virt.disk.mount.test_nbd.NbdTestCase
nova.tests.unit.virt.hyperv.test_driver.HyperVDriverTestCase
nova.tests.unit.virt.hyperv.test_eventhandler.EventHandlerTestCase
nova.tests.unit.virt.hyperv.test_hostops.HostOpsTestCase
-nova.tests.unit.virt.hyperv.test_hostutils.HostUtilsTestCase
-nova.tests.unit.virt.hyperv.test_ioutils.IOThreadTestCase
nova.tests.unit.virt.hyperv.test_livemigrationops.LiveMigrationOpsTestCase
-nova.tests.unit.virt.hyperv.test_livemigrationutils.LiveMigrationUtilsTestCase
nova.tests.unit.virt.hyperv.test_migrationops.MigrationOpsTestCase
-nova.tests.unit.virt.hyperv.test_networkutils.NetworkUtilsTestCase
-nova.tests.unit.virt.hyperv.test_networkutilsv2.NetworkUtilsV2TestCase
nova.tests.unit.virt.hyperv.test_pathutils.PathUtilsTestCase
nova.tests.unit.virt.hyperv.test_rdpconsoleops.RDPConsoleOpsTestCase
-nova.tests.unit.virt.hyperv.test_rdpconsoleutilsv2.RDPConsoleUtilsV2TestCase
nova.tests.unit.virt.hyperv.test_snapshotops.SnapshotOpsTestCase
-nova.tests.unit.virt.hyperv.test_utilsfactory.TestHyperVUtilsFactory
-nova.tests.unit.virt.hyperv.test_vhdutils.VHDUtilsTestCase
-nova.tests.unit.virt.hyperv.test_vhdutilsv2.VHDUtilsV2TestCase
nova.tests.unit.virt.hyperv.test_vif.HyperVNovaNetworkVIFDriverTestCase
nova.tests.unit.virt.hyperv.test_vmops.VMOpsTestCase
-nova.tests.unit.virt.hyperv.test_vmutils.VMUtilsTestCase
-nova.tests.unit.virt.hyperv.test_vmutilsv2.VMUtilsV2TestCase
nova.tests.unit.virt.hyperv.test_volumeops.ISCSIVolumeDriverTestCase
nova.tests.unit.virt.hyperv.test_volumeops.SMBFSVolumeDriverTestCase
nova.tests.unit.virt.hyperv.test_volumeops.VolumeOpsTestCase
-nova.tests.unit.virt.hyperv.test_volumeutils.VolumeUtilsTestCase
-nova.tests.unit.virt.hyperv.test_volumeutilsv2.VolumeUtilsV2TestCase
nova.tests.unit.virt.ironic.test_driver.IronicDriverTestCase
nova.tests.unit.virt.ironic.test_patcher.IronicDriverFieldsTestCase
nova.tests.unit.virt.libvirt.storage.test_lvm.LvmTestCase