summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessandro Pilotti <ap@pilotti.it>2013-01-29 00:53:24 +0200
committerAlessandro Pilotti <ap@pilotti.it>2013-01-29 23:22:27 +0200
commitcdfa0d0b3395ce3db6aab21a8f4d39059565e641 (patch)
tree6ff1c19ead07eca53afadac6f5f9df49338b3266
parentce09c50c9253131396f713edbf11ca427341be0e (diff)
Nova Hyper-V driver refactoring
Blueprint: hyper-v-testing-serialization-improvements This patchset contains a major refactoring of the Hyper-V driver. The main reason for this refactoring is to provide proper component abstraction and decoupling, thus replacing almost entirely the remaining pre-Essex code previously available. This leads to a considerable semplification of the testing framework, which is now entirely based on stubs and mocks (mox), without any serialized stub / mock. From an architectural perspective, the main driver class delegates operations to "ops" classes (e.g. VMOps, VolumeOps, etc) which contain the main logic and delegate OS specific actions to "utils" classes (e.g. VMUtils, LiveMigrationUtils, etc) where the WMI and Win32 API OS specific code resides. Additional attention has been put also into a better PEP8 code formatting, including compliance with not mandatory checks like E121 through E128. Change-Id: I900719c02b7c6b48d44ca68903813a1dcd023f9f
-rw-r--r--nova/tests/hyperv/README.rst83
-rw-r--r--nova/tests/hyperv/__init__.py16
-rw-r--r--nova/tests/hyperv/basetestcase.py105
-rw-r--r--nova/tests/hyperv/db_fakes.py86
-rw-r--r--nova/tests/hyperv/fake.py46
-rw-r--r--nova/tests/hyperv/hypervutils.py262
-rw-r--r--nova/tests/hyperv/mockproxy.py272
-rw-r--r--nova/tests/hyperv/stubs/README.rst2
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gzbin670 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gzbin2768 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gzbin257 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gzbin660 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gzbin702 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gzbin571 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gzbin277 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gzbin652 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gzbin23220 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gzbin28631 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gzbin385 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gzbin260 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gzbin578 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gzbin20274 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gzbin725 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gzbin426 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gzbin257 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gzbin660 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gzbin31833 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gzbin726 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gzbin250 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gzbin621 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gzbin744 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gzbin267 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gzbin640 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gzbin25238 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gzbin29404 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.utils.p.gzbin278 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.virt.configdrive.p.gzbin603 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gzbin724 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_shutil.p.gzbin300 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gzbin2806 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gzbin441 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gzbin756 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.utils.p.gzbin308 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.virt.configdrive.p.gzbin634 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gzbin753 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_shutil.p.gzbin331 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gzbin605 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gzbin458 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gzbin743 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gzbin21875 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gzbin29013 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.utils.p.gzbin280 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.virt.configdrive.p.gzbin607 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_shutil.p.gzbin303 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gzbin2810 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gzbin443 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gzbin673 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gzbin19822 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.utils.p.gzbin272 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.virt.configdrive.p.gzbin598 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_os.p.gzbin750 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_shutil.p.gzbin294 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_time.p.gzbin416 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_uuid.p.gzbin710 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_wmi.p.gzbin23205 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.utils.p.gzbin277 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.virt.configdrive.p.gzbin606 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gzbin720 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_shutil.p.gzbin300 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gzbin2806 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gzbin441 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gzbin756 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gzbin29674 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gzbin929 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gzbin266 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gzbin423 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gzbin309 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gzbin1465 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_os.p.gzbin415 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_shutil.p.gzbin301 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_wmi.p.gzbin1075 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.utils.p.gzbin273 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.virt.configdrive.p.gzbin600 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_os.p.gzbin718 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_shutil.p.gzbin295 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_time.p.gzbin417 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_uuid.p.gzbin705 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_wmi.p.gzbin22566 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_shutil.p.gzbin277 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_wmi.p.gzbin7893 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_shutil.p.gzbin301 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_wmi.p.gzbin1071 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.utils.p.gzbin279 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.virt.configdrive.p.gzbin605 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gzbin601 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_shutil.p.gzbin301 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gzbin424 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gzbin716 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.utils.p.gzbin299 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.virt.configdrive.p.gzbin625 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gzbin621 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_shutil.p.gzbin321 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gzbin441 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gzbin732 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gzbin23107 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gzbin25350 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.utils.p.gzbin285 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.virt.configdrive.p.gzbin612 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_os.p.gzbin731 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_shutil.p.gzbin307 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_time.p.gzbin429 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_uuid.p.gzbin720 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_wmi.p.gzbin22768 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.utils.p.gzbin269 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.virt.configdrive.p.gzbin597 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_os.p.gzbin715 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_shutil.p.gzbin292 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_time.p.gzbin414 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_uuid.p.gzbin708 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_wmi.p.gzbin22557 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.utils.p.gzbin294 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.virt.configdrive.p.gzbin620 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_os.p.gzbin738 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_shutil.p.gzbin316 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_time.p.gzbin437 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_uuid.p.gzbin730 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_wmi.p.gzbin22712 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.utils.p.gzbin273 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.virt.configdrive.p.gzbin599 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_os.p.gzbin718 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_shutil.p.gzbin296 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_time.p.gzbin418 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_uuid.p.gzbin710 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_wmi.p.gzbin22466 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.utils.p.gzbin287 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.virt.configdrive.p.gzbin617 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_os.p.gzbin735 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_shutil.p.gzbin311 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_time.p.gzbin434 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_uuid.p.gzbin726 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_wmi.p.gzbin22540 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.utils.p.gzbin273 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.virt.configdrive.p.gzbin600 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_os.p.gzbin717 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_shutil.p.gzbin295 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_time.p.gzbin418 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_uuid.p.gzbin707 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_wmi.p.gzbin22780 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_nova.utils.p.gzbin343 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_os.p.gzbin536 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_shutil.p.gzbin315 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_time.p.gzbin273 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_uuid.p.gzbin386 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_wmi.p.gzbin1642 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_nova.utils.p.gzbin345 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_shutil.p.gzbin318 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_uuid.p.gzbin388 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_wmi.p.gzbin1073 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.utils.p.gzbin270 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.virt.configdrive.p.gzbin597 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_os.p.gzbin716 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_shutil.p.gzbin293 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_time.p.gzbin416 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_uuid.p.gzbin709 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_wmi.p.gzbin22819 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.utils.p.gzbin287 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.virt.configdrive.p.gzbin613 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_os.p.gzbin732 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_shutil.p.gzbin309 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_time.p.gzbin432 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_uuid.p.gzbin723 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_wmi.p.gzbin22530 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.utils.p.gzbin270 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.virt.configdrive.p.gzbin594 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_os.p.gzbin715 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_shutil.p.gzbin293 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_time.p.gzbin418 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_uuid.p.gzbin707 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_wmi.p.gzbin23017 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.utils.p.gzbin272 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.virt.configdrive.p.gzbin600 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_os.p.gzbin1012 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_shutil.p.gzbin433 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_time.p.gzbin419 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_uuid.p.gzbin750 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.utils.p.gzbin292 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.virt.configdrive.p.gzbin619 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_os.p.gzbin1034 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_shutil.p.gzbin458 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_time.p.gzbin439 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_uuid.p.gzbin773 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_wmi.p.gzbin23801 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_wmi.p.gzbin23695 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.utils.p.gzbin289 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.virt.configdrive.p.gzbin828 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_os.p.gzbin890 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_shutil.p.gzbin311 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_time.p.gzbin432 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_uuid.p.gzbin811 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_wmi.p.gzbin30294 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.utils.p.gzbin493 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.virt.configdrive.p.gzbin822 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_os.p.gzbin913 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_shutil.p.gzbin305 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_time.p.gzbin427 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_uuid.p.gzbin804 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_wmi.p.gzbin29760 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.utils.p.gzbin280 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.virt.configdrive.p.gzbin607 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_os.p.gzbin725 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_shutil.p.gzbin302 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_time.p.gzbin424 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_uuid.p.gzbin716 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_wmi.p.gzbin23822 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.utils.p.gzbin285 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.virt.configdrive.p.gzbin616 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_os.p.gzbin731 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_shutil.p.gzbin308 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_time.p.gzbin430 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_uuid.p.gzbin721 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_wmi.p.gzbin23138 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.utils.p.gzbin283 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.virt.configdrive.p.gzbin608 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_os.p.gzbin605 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_shutil.p.gzbin305 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_time.p.gzbin426 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_uuid.p.gzbin717 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_wmi.p.gzbin23617 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.utils.p.gzbin291 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.virt.configdrive.p.gzbin618 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_os.p.gzbin734 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_shutil.p.gzbin313 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_time.p.gzbin430 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_uuid.p.gzbin725 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_wmi.p.gzbin21340 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.utils.p.gzbin291 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.virt.configdrive.p.gzbin616 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_os.p.gzbin734 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_shutil.p.gzbin312 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_time.p.gzbin433 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_uuid.p.gzbin729 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_wmi.p.gzbin22722 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.utils.p.gzbin271 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.virt.configdrive.p.gzbin598 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_os.p.gzbin717 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_shutil.p.gzbin294 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_time.p.gzbin418 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_uuid.p.gzbin710 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_wmi.p.gzbin22741 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.utils.p.gzbin288 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.virt.configdrive.p.gzbin614 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_os.p.gzbin732 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_shutil.p.gzbin310 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_time.p.gzbin432 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_uuid.p.gzbin724 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_wmi.p.gzbin22524 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.utils.p.gzbin272 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.virt.configdrive.p.gzbin599 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_os.p.gzbin716 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_shutil.p.gzbin294 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_time.p.gzbin416 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_uuid.p.gzbin707 -> 0 bytes
-rw-r--r--nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_wmi.p.gzbin22903 -> 0 bytes
-rw-r--r--nova/tests/test_hypervapi.py904
-rw-r--r--nova/virt/hyperv/__init__.py16
-rw-r--r--nova/virt/hyperv/baseops.py69
-rw-r--r--nova/virt/hyperv/basevolumeutils.py67
-rw-r--r--nova/virt/hyperv/constants.py9
-rw-r--r--nova/virt/hyperv/driver.py96
-rw-r--r--nova/virt/hyperv/hostops.py164
-rw-r--r--nova/virt/hyperv/hostutils.py74
-rw-r--r--nova/virt/hyperv/ioutils.py26
-rw-r--r--nova/virt/hyperv/livemigrationops.py114
-rw-r--r--nova/virt/hyperv/livemigrationutils.py115
-rw-r--r--nova/virt/hyperv/networkutils.py62
-rw-r--r--nova/virt/hyperv/pathutils.py67
-rw-r--r--nova/virt/hyperv/snapshotops.py160
-rw-r--r--nova/virt/hyperv/vhdutils.py72
-rw-r--r--nova/virt/hyperv/vif.py71
-rw-r--r--nova/virt/hyperv/vmops.py511
-rw-r--r--nova/virt/hyperv/vmutils.py510
-rw-r--r--nova/virt/hyperv/volumeops.py277
-rw-r--r--nova/virt/hyperv/volumeutils.py80
-rw-r--r--nova/virt/hyperv/volumeutilsV2.py70
-rw-r--r--nova/virt/hyperv/volumeutilsv2.py75
285 files changed, 2102 insertions, 2379 deletions
diff --git a/nova/tests/hyperv/README.rst b/nova/tests/hyperv/README.rst
deleted file mode 100644
index c7ba16046..000000000
--- a/nova/tests/hyperv/README.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-=====================================
-OpenStack Hyper-V Nova Testing Architecture
-=====================================
-
-The Hyper-V Nova Compute plugin uses Windows Management Instrumentation (WMI)
-as the main API for hypervisor related operations.
-WMI has a database / procedural oriented nature that can become difficult to
-test with a traditional static mock / stub based unit testing approach.
-
-The included Hyper-V testing framework has been developed with the
-following goals:
-
-1) Dynamic mock generation.
-2) Decoupling. No dependencies on WMI or any other module.
- The tests are designed to work with mocked objects in all cases, including
- OS-dependent (e.g. wmi, os, subprocess) and non-deterministic
- (e.g. time, uuid) modules
-3) Transparency. Mocks and real objects can be swapped via DI
- or monkey patching.
-4) Platform independence.
-5) Tests need to be executed against the real object or against the mocks
- with a simple configuration switch. Development efforts can highly
- benefit from this feature.
-6) It must be possible to change a mock's behavior without running the tests
- against the hypervisor (e.g. by manually adding a value / return value).
-
-The tests included in this package include dynamically generated mock objects,
-based on the recording of the attribute values and invocations on the
-real WMI objects and other OS dependent features.
-The generated mock objects are serialized in the nova/tests/hyperv/stubs
-directory as gzipped pickled objects.
-
-An environment variable controls the execution mode of the tests.
-
-Recording mode:
-
-NOVA_GENERATE_TEST_MOCKS=True
-Tests are executed on the hypervisor (without mocks), and mock objects are
-generated.
-
-Replay mode:
-
-NOVA_GENERATE_TEST_MOCKS=
-Tests are executed with the existing mock objects (default).
-
-Mock generation is performed by nova.tests.hyperv.mockproxy.MockProxy.
-Instances of this class wrap objects that need to be mocked and act as a
-delegate on the wrapped object by leveraging Python's __getattr__ feature.
-Attribute values and method call return values are recorded at each access.
-Objects returned by attributes and method invocations are wrapped in a
-MockProxy consistently.
-From a caller perspective, the MockProxy is completely transparent,
-with the exception of calls to the type(...) builtin function.
-
-At the end of the test, a mock is generated by each MockProxy by calling
-the get_mock() method. A mock is represented by an instance of the
-nova.tests.hyperv.mockproxy.Mock class.
-
-The Mock class task consists of replicating the behaviour of the mocked
-objects / modules by returning the same values in the same order, for example:
-
-def check_path(path):
- if not os.path.exists(path):
- os.makedirs(path)
-
-check_path(path)
-# The second time os.path.exists returns True
-check_path(path)
-
-The injection of MockProxy / Mock instances is performed by the
-nova.tests.hyperv.basetestcase.BaseTestCase class in the setUp()
-method via selective monkey patching.
-Mocks are serialized in tearDown() during recording.
-
-The actual Hyper-V test case inherits from BaseTestCase:
-nova.tests.hyperv.test_hypervapi.HyperVAPITestCase
-
-
-Future directions:
-
-1) Replace the pickled files with a more generic serialization option (e.g. json)
-2) Add methods to statically extend the mocks (e.g. method call return values)
-3) Extend an existing framework, e.g. mox
diff --git a/nova/tests/hyperv/__init__.py b/nova/tests/hyperv/__init__.py
index e69de29bb..090fc0639 100644
--- a/nova/tests/hyperv/__init__.py
+++ b/nova/tests/hyperv/__init__.py
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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.
diff --git a/nova/tests/hyperv/basetestcase.py b/nova/tests/hyperv/basetestcase.py
deleted file mode 100644
index c4f6cf95f..000000000
--- a/nova/tests/hyperv/basetestcase.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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.
-
-"""
-TestCase for MockProxy based tests and related classes.
-"""
-
-import gzip
-import os
-import pickle
-import sys
-
-from nova import test
-from nova.tests.hyperv import mockproxy
-
-gen_test_mocks_key = 'NOVA_GENERATE_TEST_MOCKS'
-
-
-class BaseTestCase(test.TestCase):
- """TestCase for MockProxy based tests."""
-
- def run(self, result=None):
- self._currentResult = result
- super(BaseTestCase, self).run(result)
-
- def setUp(self):
- super(BaseTestCase, self).setUp()
- self._mps = {}
-
- def tearDown(self):
- super(BaseTestCase, self).tearDown()
-
- # python-subunit will wrap test results with a decorator.
- # Need to access the decorated member of results to get the
- # actual test result when using python-subunit.
- if hasattr(self._currentResult, 'decorated'):
- result = self._currentResult.decorated
- else:
- result = self._currentResult
- has_errors = len([test for (test, msgs) in result.errors
- if test.id() == self.id()]) > 0
- failed = len([test for (test, msgs) in result.failures
- if test.id() == self.id()]) > 0
-
- if not has_errors and not failed:
- self._save_mock_proxies()
-
- def _save_mock(self, name, mock):
- path = self._get_stub_file_path(self.id(), name)
- pickle.dump(mock, gzip.open(path, 'wb'))
-
- def _get_stub_file_path(self, test_name, mock_name):
- # test naming differs between platforms
- prefix = 'nova.tests.'
- if test_name.startswith(prefix):
- test_name = test_name[len(prefix):]
- file_name = '{0}_{1}.p.gz'.format(test_name, mock_name)
- return os.path.join(os.path.dirname(mockproxy.__file__),
- "stubs", file_name)
-
- def _load_mock(self, name):
- path = self._get_stub_file_path(self.id(), name)
- if os.path.exists(path):
- return pickle.load(gzip.open(path, 'rb'))
- else:
- return None
-
- def _load_mock_or_create_proxy(self, module_name):
- m = None
- if not gen_test_mocks_key in os.environ or \
- os.environ[gen_test_mocks_key].lower() \
- not in ['true', 'yes', '1']:
- m = self._load_mock(module_name)
- else:
- __import__(module_name)
- module = sys.modules[module_name]
- m = mockproxy.MockProxy(module)
- self._mps[module_name] = m
- return m
-
- def _inject_mocks_in_modules(self, objects_to_mock, modules_to_test):
- for module_name in objects_to_mock:
- mp = self._load_mock_or_create_proxy(module_name)
- for mt in modules_to_test:
- module_local_name = module_name.split('.')[-1]
- setattr(mt, module_local_name, mp)
-
- def _save_mock_proxies(self):
- for name, mp in self._mps.items():
- m = mp.get_mock()
- if m.has_values():
- self._save_mock(name, m)
diff --git a/nova/tests/hyperv/db_fakes.py b/nova/tests/hyperv/db_fakes.py
index 16d894df8..e384e909a 100644
--- a/nova/tests/hyperv/db_fakes.py
+++ b/nova/tests/hyperv/db_fakes.py
@@ -29,35 +29,35 @@ from nova import utils
def get_fake_instance_data(name, project_id, user_id):
return {'name': name,
- 'id': 1,
- 'uuid': str(uuid.uuid4()),
- 'project_id': project_id,
- 'user_id': user_id,
- 'image_ref': "1",
- 'kernel_id': "1",
- 'ramdisk_id': "1",
- 'mac_address': "de:ad:be:ef:be:ef",
- 'instance_type':
- {'name': 'm1.tiny',
- 'memory_mb': 512,
- 'vcpus': 1,
- 'root_gb': 0,
- 'flavorid': 1,
- 'rxtx_factor': 1}
- }
+ 'id': 1,
+ 'uuid': str(uuid.uuid4()),
+ 'project_id': project_id,
+ 'user_id': user_id,
+ 'image_ref': "1",
+ 'kernel_id': "1",
+ 'ramdisk_id': "1",
+ 'mac_address': "de:ad:be:ef:be:ef",
+ 'instance_type':
+ {'name': 'm1.tiny',
+ 'memory_mb': 512,
+ 'vcpus': 1,
+ 'root_gb': 0,
+ 'flavorid': 1,
+ 'rxtx_factor': 1}
+ }
def get_fake_image_data(project_id, user_id):
return {'name': 'image1',
- 'id': 1,
- 'project_id': project_id,
- 'user_id': user_id,
- 'image_ref': "1",
- 'kernel_id': "1",
- 'ramdisk_id': "1",
- 'mac_address': "de:ad:be:ef:be:ef",
- 'instance_type': 'm1.tiny',
- }
+ 'id': 1,
+ 'project_id': project_id,
+ 'user_id': user_id,
+ 'image_ref': "1",
+ 'kernel_id': "1",
+ 'ramdisk_id': "1",
+ 'mac_address': "de:ad:be:ef:be:ef",
+ 'instance_type': 'm1.tiny',
+ }
def get_fake_volume_info_data(target_portal, volume_id):
@@ -72,25 +72,25 @@ def get_fake_volume_info_data(target_portal, volume_id):
'auth_method': 'fake',
'auth_method': 'fake',
}
-}
+ }
def get_fake_block_device_info(target_portal, volume_id):
- return {
- 'block_device_mapping': [{'connection_info': {
- 'driver_volume_type': 'iscsi',
- 'data': {'target_lun': 1,
- 'volume_id': volume_id,
- 'target_iqn': 'iqn.2010-10.org.openstack:volume-' +
- volume_id,
- 'target_portal': target_portal,
- 'target_discovered': False}},
- 'mount_device': 'vda',
- 'delete_on_termination': False}],
+ return {'block_device_mapping': [{'connection_info': {
+ 'driver_volume_type': 'iscsi',
+ 'data': {'target_lun': 1,
+ 'volume_id': volume_id,
+ 'target_iqn':
+ 'iqn.2010-10.org.openstack:volume-' +
+ volume_id,
+ 'target_portal': target_portal,
+ 'target_discovered': False}},
+ 'mount_device': 'vda',
+ 'delete_on_termination': False}],
'root_device_name': None,
'ephemerals': [],
'swap': None
- }
+ }
def stub_out_db_instance_api(stubs):
@@ -99,11 +99,9 @@ def stub_out_db_instance_api(stubs):
INSTANCE_TYPES = {
'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1),
'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2),
- 'm1.medium':
- dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3),
+ 'm1.medium': dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3),
'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4),
- 'm1.xlarge':
- dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)}
+ 'm1.xlarge': dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)}
class FakeModel(object):
"""Stubs out for model."""
@@ -152,7 +150,7 @@ def stub_out_db_instance_api(stubs):
'vcpus': instance_type['vcpus'],
'mac_addresses': [{'address': values['mac_address']}],
'root_gb': instance_type['root_gb'],
- }
+ }
return FakeModel(base_options)
def fake_network_get_by_instance(context, instance_id):
@@ -181,4 +179,4 @@ def stub_out_db_instance_api(stubs):
stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all)
stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name)
stubs.Set(db, 'block_device_mapping_get_all_by_instance',
- fake_block_device_mapping_get_all_by_instance)
+ fake_block_device_mapping_get_all_by_instance)
diff --git a/nova/tests/hyperv/fake.py b/nova/tests/hyperv/fake.py
new file mode 100644
index 000000000..9890a5462
--- /dev/null
+++ b/nova/tests/hyperv/fake.py
@@ -0,0 +1,46 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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 io
+import os
+
+
+class PathUtils(object):
+ def open(self, path, mode):
+ return io.BytesIO(b'fake content')
+
+ def get_instances_path(self):
+ return 'C:\\FakePath\\'
+
+ def get_instance_path(self, instance_name):
+ return os.path.join(self.get_instances_path(), instance_name)
+
+ def get_vhd_path(self, instance_name):
+ instance_path = self.get_instance_path(instance_name)
+ return os.path.join(instance_path, instance_name + ".vhd")
+
+ def get_base_vhd_path(self, image_name):
+ base_dir = os.path.join(self.get_instances_path(), '_base')
+ return os.path.join(base_dir, image_name + ".vhd")
+
+ def make_export_path(self, instance_name):
+ export_folder = os.path.join(self.get_instances_path(), "export",
+ instance_name)
+ return export_folder
+
+ def vhd_exists(self, path):
+ return False
diff --git a/nova/tests/hyperv/hypervutils.py b/nova/tests/hyperv/hypervutils.py
deleted file mode 100644
index b71e60229..000000000
--- a/nova/tests/hyperv/hypervutils.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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.
-
-"""
-Hyper-V classes to be used in testing.
-"""
-
-import sys
-import time
-
-from nova import exception
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import volumeutilsV2
-from xml.etree import ElementTree
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
-
-
-class HyperVUtils(object):
- def __init__(self):
- self.__conn = None
- self.__conn_v2 = None
- self.__conn_cimv2 = None
- self.__conn_wmi = None
- self.__conn_storage = None
- self._volumeutils = volumeutilsV2.VolumeUtilsV2(
- self._conn_storage, self._conn_wmi)
-
- @property
- def _conn(self):
- if self.__conn is None:
- self.__conn = wmi.WMI(moniker='//./root/virtualization')
- return self.__conn
-
- @property
- def _conn_v2(self):
- if self.__conn_v2 is None:
- self.__conn_v2 = wmi.WMI(moniker='//./root/virtualization/v2')
- return self.__conn_v2
-
- @property
- def _conn_cimv2(self):
- if self.__conn_cimv2 is None:
- self.__conn_cimv2 = wmi.WMI(moniker='//./root/cimv2')
- return self.__conn_cimv2
-
- @property
- def _conn_wmi(self):
- if self.__conn_wmi is None:
- self.__conn_wmi = wmi.WMI(moniker='//./root/wmi')
- return self.__conn_wmi
-
- @property
- def _conn_storage(self):
- if self.__conn_storage is None:
- storage_namespace = '//./Root/Microsoft/Windows/Storage'
- self.__conn_storage = wmi.WMI(moniker=storage_namespace)
- return self.__conn_storage
-
- def create_vhd(self, path):
- image_service = self._conn.query(
- "Select * from Msvm_ImageManagementService")[0]
- (job, ret_val) = image_service.CreateDynamicVirtualHardDisk(
- Path=path, MaxInternalSize=3 * 1024 * 1024)
-
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._check_job_status(job)
- else:
- success = (ret_val == 0)
- if not success:
- raise Exception('Failed to create Dynamic disk %s with error %d'
- % (path, ret_val))
-
- def _check_job_status(self, jobpath):
- """Poll WMI job state for completion."""
- job_wmi_path = jobpath.replace('\\', '/')
- job = wmi.WMI(moniker=job_wmi_path)
-
- while job.JobState == constants.WMI_JOB_STATE_RUNNING:
- time.sleep(0.1)
- job = wmi.WMI(moniker=job_wmi_path)
- return job.JobState == constants.WMI_JOB_STATE_COMPLETED
-
- def _get_vm(self, vm_name, conn=None):
- if conn is None:
- conn = self._conn
- vml = conn.Msvm_ComputerSystem(ElementName=vm_name)
- if not len(vml):
- raise exception.InstanceNotFound(instance=vm_name)
- return vml[0]
-
- def remote_vm_exists(self, server, vm_name):
- conn = wmi.WMI(moniker='//' + server + '/root/virtualization')
- return self._vm_exists(conn, vm_name)
-
- def vm_exists(self, vm_name):
- return self._vm_exists(self._conn, vm_name)
-
- def _vm_exists(self, conn, vm_name):
- return len(conn.Msvm_ComputerSystem(ElementName=vm_name)) > 0
-
- def _get_vm_summary(self, vm_name):
- vm = self._get_vm(vm_name)
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- vmsettings = vm.associators(
- wmi_association_class='Msvm_SettingsDefineState',
- wmi_result_class='Msvm_VirtualSystemSettingData')
- settings_paths = [v.path_() for v in vmsettings]
- return vs_man_svc.GetSummaryInformation([100, 105],
- settings_paths)[1][0]
-
- def get_vm_uptime(self, vm_name):
- return self._get_vm_summary(vm_name).UpTime
-
- def get_vm_state(self, vm_name):
- return self._get_vm_summary(vm_name).EnabledState
-
- def set_vm_state(self, vm_name, req_state):
- self._set_vm_state(self._conn, vm_name, req_state)
-
- def _set_vm_state(self, conn, vm_name, req_state):
- vm = self._get_vm(vm_name, conn)
- (job, ret_val) = vm.RequestStateChange(req_state)
-
- success = False
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._check_job_status(job)
- elif ret_val == 0:
- success = True
- elif ret_val == 32775:
- #Invalid state for current operation. Typically means it is
- #already in the state requested
- success = True
- if not success:
- raise Exception(_("Failed to change vm state of %(vm_name)s"
- " to %(req_state)s") % locals())
-
- def get_vm_disks(self, vm_name):
- return self._get_vm_disks(self._conn, vm_name)
-
- def _get_vm_disks(self, conn, vm_name):
- vm = self._get_vm(vm_name, conn)
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- rasds = vmsettings[0].associators(
- wmi_result_class='MSVM_ResourceAllocationSettingData')
-
- disks = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Virtual Hard Disk']
- disk_files = []
- for disk in disks:
- disk_files.extend([c for c in disk.Connection])
-
- volumes = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Physical Disk Drive']
- volume_drives = []
- for volume in volumes:
- hostResources = volume.HostResource
- drive_path = hostResources[0]
- volume_drives.append(drive_path)
-
- dvds = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Virtual CD/DVD Disk']
- dvd_files = []
- for dvd in dvds:
- dvd_files.extend([c for c in dvd.Connection])
-
- return (disk_files, volume_drives, dvd_files)
-
- def remove_remote_vm(self, server, vm_name):
- conn = wmi.WMI(moniker='//' + server + '/root/virtualization')
- conn_cimv2 = wmi.WMI(moniker='//' + server + '/root/cimv2')
- self._remove_vm(vm_name, conn, conn_cimv2)
-
- def remove_vm(self, vm_name):
- self._remove_vm(vm_name, self._conn, self._conn_cimv2)
-
- def _remove_vm(self, vm_name, conn, conn_cimv2):
- vm = self._get_vm(vm_name, conn)
- vs_man_svc = conn.Msvm_VirtualSystemManagementService()[0]
- #Stop the VM first.
- self._set_vm_state(conn, vm_name, 3)
-
- (disk_files, volume_drives, dvd_files) = self._get_vm_disks(conn,
- vm_name)
-
- (job, ret_val) = vs_man_svc.DestroyVirtualSystem(vm.path_())
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._check_job_status(job)
- elif ret_val == 0:
- success = True
- if not success:
- raise Exception(_('Failed to destroy vm %s') % vm_name)
-
- #Delete associated vhd disk files.
- for disk in disk_files + dvd_files:
- vhd_file = conn_cimv2.query(
- "Select * from CIM_DataFile where Name = '" +
- disk.replace("'", "''") + "'")[0]
- vhd_file.Delete()
-
- def _get_target_iqn(self, volume_id):
- return 'iqn.2010-10.org.openstack:volume-' + volume_id
-
- def logout_iscsi_volume_sessions(self, volume_id):
- target_iqn = self._get_target_iqn(volume_id)
- if (self.iscsi_volume_sessions_exist(volume_id)):
- self._volumeutils.logout_storage_target(target_iqn)
-
- def iscsi_volume_sessions_exist(self, volume_id):
- target_iqn = self._get_target_iqn(volume_id)
- return len(self._conn_wmi.query(
- "SELECT * FROM MSiSCSIInitiator_SessionClass \
- WHERE TargetName='" + target_iqn + "'")) > 0
-
- def get_vm_count(self):
- return len(self._conn.query(
- "Select * from Msvm_ComputerSystem where Description "
- "<> 'Microsoft Hosting Computer System'"))
-
- def get_vm_snapshots_count(self, vm_name):
- return len(self._conn.query(
- "Select * from Msvm_VirtualSystemSettingData where \
- SettingType = 5 and SystemName = '" + vm_name + "'"))
-
- def get_vhd_parent_path(self, vhd_path):
-
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
-
- (vhd_info, job_path, ret_val) = \
- image_man_svc.GetVirtualHardDiskInfo(vhd_path)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise Exception(_("Failed to get info for disk %s") %
- (vhd_path))
-
- base_disk_path = None
- et = ElementTree.fromstring(vhd_info)
- for item in et.findall("PROPERTY"):
- if item.attrib["NAME"] == "ParentPath":
- base_disk_path = item.find("VALUE").text
- break
-
- return base_disk_path
diff --git a/nova/tests/hyperv/mockproxy.py b/nova/tests/hyperv/mockproxy.py
deleted file mode 100644
index 513422c13..000000000
--- a/nova/tests/hyperv/mockproxy.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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
-
-"""
-Classes for dynamic generation of mock objects.
-"""
-
-import inspect
-
-
-def serialize_obj(obj):
- if isinstance(obj, float):
- val = str(round(obj, 10))
- elif isinstance(obj, dict):
- d = {}
- for k1, v1 in obj.items():
- d[k1] = serialize_obj(v1)
- val = str(d)
- elif isinstance(obj, list):
- l1 = []
- for i1 in obj:
- l1.append(serialize_obj(i1))
- val = str(l1)
- elif isinstance(obj, tuple):
- l1 = ()
- for i1 in obj:
- l1 = l1 + (serialize_obj(i1),)
- val = str(l1)
- else:
- if isinstance(obj, str) or isinstance(obj, unicode):
- val = obj
- elif hasattr(obj, '__str__') and inspect.ismethod(obj.__str__):
- val = str(obj)
- else:
- val = str(type(obj))
- return val
-
-
-def serialize_args(*args, **kwargs):
- """Workaround for float string conversion issues in Python 2.6."""
- return serialize_obj((args, kwargs))
-
-
-class MockException(Exception):
- def __init__(self, message):
- super(MockException, self).__init__(message)
-
-
-class Mock(object):
- def _get_next_value(self, name):
- c = self._access_count.get(name)
- if c is None:
- c = 0
- else:
- c = c + 1
- self._access_count[name] = c
-
- try:
- value = self._values[name][c]
- except IndexError as ex:
- raise MockException(_('Couldn\'t find invocation num. %(c)d '
- 'of attribute "%(name)s"') % locals())
- return value
-
- def _get_next_ret_value(self, name, params):
- d = self._access_count.get(name)
- if d is None:
- d = {}
- self._access_count[name] = d
- c = d.get(params)
- if c is None:
- c = 0
- else:
- c = c + 1
- d[params] = c
-
- try:
- m = self._values[name]
- except KeyError as ex:
- raise MockException(_('Couldn\'t find attribute "%s"') % (name))
-
- try:
- value = m[params][c]
- except KeyError as ex:
- raise MockException(_('Couldn\'t find attribute "%(name)s" '
- 'with arguments "%(params)s"') % locals())
- except IndexError as ex:
- raise MockException(_('Couldn\'t find invocation num. %(c)d '
- 'of attribute "%(name)s" with arguments "%(params)s"')
- % locals())
-
- return value
-
- def __init__(self, values):
- self._values = values
- self._access_count = {}
-
- def has_values(self):
- return len(self._values) > 0
-
- def __getattr__(self, name):
- if name.startswith('__') and name.endswith('__'):
- return object.__getattribute__(self, name)
- else:
- try:
- isdict = isinstance(self._values[name], dict)
- except KeyError as ex:
- raise MockException(_('Couldn\'t find attribute "%s"')
- % (name))
-
- if isdict:
- def newfunc(*args, **kwargs):
- params = serialize_args(args, kwargs)
- return self._get_next_ret_value(name, params)
- return newfunc
- else:
- return self._get_next_value(name)
-
- def __str__(self):
- return self._get_next_value('__str__')
-
- def __iter__(self):
- return getattr(self._get_next_value('__iter__'), '__iter__')()
-
- def __len__(self):
- return self._get_next_value('__len__')
-
- def __getitem__(self, key):
- return self._get_next_ret_value('__getitem__', str(key))
-
- def __call__(self, *args, **kwargs):
- params = serialize_args(args, kwargs)
- return self._get_next_ret_value('__call__', params)
-
-
-class MockProxy(object):
- def __init__(self, wrapped):
- self._wrapped = wrapped
- self._recorded_values = {}
-
- def _get_proxy_object(self, obj):
- if hasattr(obj, '__dict__') or isinstance(obj, tuple) or \
- isinstance(obj, list) or isinstance(obj, dict):
- p = MockProxy(obj)
- else:
- p = obj
- return p
-
- def __getattr__(self, name):
- if name in ['_wrapped']:
- return object.__getattribute__(self, name)
- else:
- attr = getattr(self._wrapped, name)
- if inspect.isfunction(attr) or inspect.ismethod(attr) or \
- inspect.isbuiltin(attr):
- def newfunc(*args, **kwargs):
- result = attr(*args, **kwargs)
- p = self._get_proxy_object(result)
- params = serialize_args(args, kwargs)
- self._add_recorded_ret_value(name, params, p)
- return p
- return newfunc
- elif hasattr(attr, '__dict__') or (hasattr(attr, '__getitem__')
- and not (isinstance(attr, str) or isinstance(attr, unicode))):
- p = MockProxy(attr)
- else:
- p = attr
- self._add_recorded_value(name, p)
- return p
-
- def __setattr__(self, name, value):
- if name in ['_wrapped', '_recorded_values']:
- object.__setattr__(self, name, value)
- else:
- setattr(self._wrapped, name, value)
-
- def _add_recorded_ret_value(self, name, params, val):
- d = self._recorded_values.get(name)
- if d is None:
- d = {}
- self._recorded_values[name] = d
- l = d.get(params)
- if l is None:
- l = []
- d[params] = l
- l.append(val)
-
- def _add_recorded_value(self, name, val):
- if not name in self._recorded_values:
- self._recorded_values[name] = []
- self._recorded_values[name].append(val)
-
- def get_mock(self):
- values = {}
- for k, v in self._recorded_values.items():
- if isinstance(v, dict):
- d = {}
- values[k] = d
- for k1, v1 in v.items():
- l = []
- d[k1] = l
- for i1 in v1:
- if isinstance(i1, MockProxy):
- l.append(i1.get_mock())
- else:
- l.append(i1)
- else:
- l = []
- values[k] = l
- for i in v:
- if isinstance(i, MockProxy):
- l.append(i.get_mock())
- elif isinstance(i, dict):
- d = {}
- for k1, v1 in v.items():
- if isinstance(v1, MockProxy):
- d[k1] = v1.get_mock()
- else:
- d[k1] = v1
- l.append(d)
- elif isinstance(i, list):
- l1 = []
- for i1 in i:
- if isinstance(i1, MockProxy):
- l1.append(i1.get_mock())
- else:
- l1.append(i1)
- l.append(l1)
- else:
- l.append(i)
- return Mock(values)
-
- def __str__(self):
- s = str(self._wrapped)
- self._add_recorded_value('__str__', s)
- return s
-
- def __len__(self):
- l = len(self._wrapped)
- self._add_recorded_value('__len__', l)
- return l
-
- def __iter__(self):
- it = []
- for i in self._wrapped:
- it.append(self._get_proxy_object(i))
- self._add_recorded_value('__iter__', it)
- return iter(it)
-
- def __getitem__(self, key):
- p = self._get_proxy_object(self._wrapped[key])
- self._add_recorded_ret_value('__getitem__', str(key), p)
- return p
-
- def __call__(self, *args, **kwargs):
- c = self._wrapped(*args, **kwargs)
- p = self._get_proxy_object(c)
- params = serialize_args(args, kwargs)
- self._add_recorded_ret_value('__call__', params, p)
- return p
diff --git a/nova/tests/hyperv/stubs/README.rst b/nova/tests/hyperv/stubs/README.rst
deleted file mode 100644
index 150fd3ad1..000000000
--- a/nova/tests/hyperv/stubs/README.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Files with extension p.gz are compressed pickle files containing serialized
-mocks used during unit testing
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz
deleted file mode 100644
index c65832c57..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz
deleted file mode 100644
index 7076c4868..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz
deleted file mode 100644
index c251f9d6c..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz
deleted file mode 100644
index cac08e3d0..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz
deleted file mode 100644
index d6e624bb0..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz
deleted file mode 100644
index bb18f7453..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz
deleted file mode 100644
index a5f592a74..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz
deleted file mode 100644
index 4bebe0e72..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz
deleted file mode 100644
index 29a610f36..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz
deleted file mode 100644
index ca92ece00..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz
deleted file mode 100644
index 58269455d..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz
deleted file mode 100644
index 97cd7e62b..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz
deleted file mode 100644
index 708197430..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz
deleted file mode 100644
index d5eb4d746..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz
deleted file mode 100644
index d8c63d8ad..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz
deleted file mode 100644
index d0b27d201..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz
deleted file mode 100644
index 657379cec..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz
deleted file mode 100644
index 8bf58ef5c..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz
deleted file mode 100644
index c20281811..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz
deleted file mode 100644
index a198af844..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz
deleted file mode 100644
index 749eabe40..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz
deleted file mode 100644
index c40e6f995..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz
deleted file mode 100644
index c67dc9271..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz
deleted file mode 100644
index 0d671fc18..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz
deleted file mode 100644
index 66583beb1..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz
deleted file mode 100644
index efdef819f..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz b/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz
deleted file mode 100644
index 5edd6f147..000000000
--- a/nova/tests/hyperv/stubs/nova.tests.test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.utils.p.gz
deleted file mode 100644
index f968e2af5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.virt.configdrive.p.gz
deleted file mode 100644
index bd5ced9f8..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz
deleted file mode 100644
index a48a21ca9..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_shutil.p.gz
deleted file mode 100644
index c662b602a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz
deleted file mode 100644
index 6a692b3d8..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz
deleted file mode 100644
index f2ae56be1..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz
deleted file mode 100644
index 2d24523aa..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.utils.p.gz
deleted file mode 100644
index aca0d6f0c..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.virt.configdrive.p.gz
deleted file mode 100644
index bbeec53df..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz
deleted file mode 100644
index 3bf9bd13a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_shutil.p.gz
deleted file mode 100644
index 62e3fa329..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz
deleted file mode 100644
index 36970348a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz
deleted file mode 100644
index 8db997abf..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz
deleted file mode 100644
index 73f90ac2b..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz
deleted file mode 100644
index 3ae9a6f46..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_with_target_connection_failure_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz
deleted file mode 100644
index 5b851f9b7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_attach_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.utils.p.gz
deleted file mode 100644
index 7a1c47449..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.virt.configdrive.p.gz
deleted file mode 100644
index 48583265e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_shutil.p.gz
deleted file mode 100644
index 90d6a2ca6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz
deleted file mode 100644
index 3b17cc74f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz
deleted file mode 100644
index 162f52457..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz
deleted file mode 100644
index f88f8bc86..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz
deleted file mode 100644
index f671dc247..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_boot_from_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.utils.p.gz
deleted file mode 100644
index 37892d051..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.virt.configdrive.p.gz
deleted file mode 100644
index 9aec45796..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_os.p.gz
deleted file mode 100644
index ffc21536e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_shutil.p.gz
deleted file mode 100644
index b47c49202..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_time.p.gz
deleted file mode 100644
index 78e4292b6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_uuid.p.gz
deleted file mode 100644
index 5bc7602a8..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_wmi.p.gz
deleted file mode 100644
index 9ba025e55..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_destroy_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.utils.p.gz
deleted file mode 100644
index 3341bca28..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.virt.configdrive.p.gz
deleted file mode 100644
index 56cb9d103..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz
deleted file mode 100644
index 81205e04d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_shutil.p.gz
deleted file mode 100644
index 9d1311341..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz
deleted file mode 100644
index a151a99b4..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_subprocess.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz
deleted file mode 100644
index b1d0b0f3a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz
deleted file mode 100644
index c2985c424..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz
deleted file mode 100644
index 2c4901c9f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_detach_volume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz
deleted file mode 100644
index 2481a7b3e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz
deleted file mode 100644
index 61cbc1854..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz
deleted file mode 100644
index 09b86b24e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz
deleted file mode 100644
index ba89bfd7e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz
deleted file mode 100644
index cfce8c10a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_os.p.gz
deleted file mode 100644
index 6092f36ab..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_shutil.p.gz
deleted file mode 100644
index 010c07e56..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_wmi.p.gz
deleted file mode 100644
index 9d3adec48..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_host_stats_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.utils.p.gz
deleted file mode 100644
index 995dde1b5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.virt.configdrive.p.gz
deleted file mode 100644
index 12d18d12e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_os.p.gz
deleted file mode 100644
index 64c756ffa..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_shutil.p.gz
deleted file mode 100644
index d2cefdc37..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_time.p.gz
deleted file mode 100644
index 9fdef3b90..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_uuid.p.gz
deleted file mode 100644
index c34d2308b..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_wmi.p.gz
deleted file mode 100644
index 36a342e7c..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_info_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_shutil.p.gz
deleted file mode 100644
index 3ab35a29f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_wmi.p.gz
deleted file mode 100644
index 411c0ed07..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_detail_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_shutil.p.gz
deleted file mode 100644
index 1af20acde..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_wmi.p.gz
deleted file mode 100644
index d84122d77..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_list_instances_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.utils.p.gz
deleted file mode 100644
index d650f40a5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.virt.configdrive.p.gz
deleted file mode 100644
index a03d442a4..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz
deleted file mode 100644
index 993d9bb2d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_shutil.p.gz
deleted file mode 100644
index 6693c2ce9..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz
deleted file mode 100644
index 07898dd55..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz
deleted file mode 100644
index 56e583449..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.utils.p.gz
deleted file mode 100644
index 5d4c0e111..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.virt.configdrive.p.gz
deleted file mode 100644
index cb52cb974..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz
deleted file mode 100644
index 8b2ff15f3..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_shutil.p.gz
deleted file mode 100644
index aee1fb14d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz
deleted file mode 100644
index f926d206f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz
deleted file mode 100644
index 483b23d53..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz
deleted file mode 100644
index 14d61039f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_with_target_failure_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz
deleted file mode 100644
index daecf0156..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_live_migration_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.utils.p.gz
deleted file mode 100644
index 548b88148..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.virt.configdrive.p.gz
deleted file mode 100644
index 8545a1833..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_os.p.gz
deleted file mode 100644
index c1daf3db9..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_shutil.p.gz
deleted file mode 100644
index 750d68d29..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_time.p.gz
deleted file mode 100644
index 6e91b72a2..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_uuid.p.gz
deleted file mode 100644
index 2d0349d96..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_wmi.p.gz
deleted file mode 100644
index 6b9ef360a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_already_paused_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.utils.p.gz
deleted file mode 100644
index 3e582226f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.virt.configdrive.p.gz
deleted file mode 100644
index 723966011..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_os.p.gz
deleted file mode 100644
index 29b73888b..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_shutil.p.gz
deleted file mode 100644
index 595124af2..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_time.p.gz
deleted file mode 100644
index 03d53be74..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_uuid.p.gz
deleted file mode 100644
index 2a0663e6f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_wmi.p.gz
deleted file mode 100644
index e651c02fc..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pause_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.utils.p.gz
deleted file mode 100644
index a50935649..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.virt.configdrive.p.gz
deleted file mode 100644
index 4b07271c1..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_os.p.gz
deleted file mode 100644
index f62298ed7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_shutil.p.gz
deleted file mode 100644
index 12a164f23..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_time.p.gz
deleted file mode 100644
index 33f1862e6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_uuid.p.gz
deleted file mode 100644
index 80853eea4..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_wmi.p.gz
deleted file mode 100644
index 5cebe527d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_already_powered_off_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.utils.p.gz
deleted file mode 100644
index d0c431b9d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.virt.configdrive.p.gz
deleted file mode 100644
index d231f803d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_os.p.gz
deleted file mode 100644
index 25fe5f3ff..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_shutil.p.gz
deleted file mode 100644
index 8be80ba56..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_time.p.gz
deleted file mode 100644
index 51b6f2df8..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_uuid.p.gz
deleted file mode 100644
index 97812405e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_wmi.p.gz
deleted file mode 100644
index 20b2e021e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_off_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.utils.p.gz
deleted file mode 100644
index c32f9ecd2..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.virt.configdrive.p.gz
deleted file mode 100644
index 672376a0e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_os.p.gz
deleted file mode 100644
index aa6f4ca8a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_shutil.p.gz
deleted file mode 100644
index 00f5770a7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_time.p.gz
deleted file mode 100644
index 1631f35df..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_uuid.p.gz
deleted file mode 100644
index ec28756ad..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_wmi.p.gz
deleted file mode 100644
index 699ccde76..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_already_running_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.utils.p.gz
deleted file mode 100644
index 2b99fb9cd..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.virt.configdrive.p.gz
deleted file mode 100644
index a43bfeb7e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_os.p.gz
deleted file mode 100644
index 57e74e618..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_shutil.p.gz
deleted file mode 100644
index 273364d95..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_time.p.gz
deleted file mode 100644
index 732a0f2e6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_uuid.p.gz
deleted file mode 100644
index d6cb32559..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_wmi.p.gz
deleted file mode 100644
index e44197039..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_power_on_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_nova.utils.p.gz
deleted file mode 100644
index 456af2816..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_os.p.gz
deleted file mode 100644
index 93568dcef..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_shutil.p.gz
deleted file mode 100644
index 6a4b90850..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_time.p.gz
deleted file mode 100644
index fc816320f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_uuid.p.gz
deleted file mode 100644
index 83cf9c071..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_wmi.p.gz
deleted file mode 100644
index 93977743f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_cow_image_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_nova.utils.p.gz
deleted file mode 100644
index f58f80a79..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_shutil.p.gz
deleted file mode 100644
index 18a8aed13..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_uuid.p.gz
deleted file mode 100644
index 4225a72b0..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_wmi.p.gz
deleted file mode 100644
index 363c431d4..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_pre_live_migration_no_cow_image_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.utils.p.gz
deleted file mode 100644
index 8761703dc..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.virt.configdrive.p.gz
deleted file mode 100644
index fc907ed31..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_os.p.gz
deleted file mode 100644
index 0eca8e6ce..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_shutil.p.gz
deleted file mode 100644
index 0886c942d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_time.p.gz
deleted file mode 100644
index d0fb77bd1..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_uuid.p.gz
deleted file mode 100644
index df3961276..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_wmi.p.gz
deleted file mode 100644
index 4df451154..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_reboot_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.utils.p.gz
deleted file mode 100644
index 59724b43d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.virt.configdrive.p.gz
deleted file mode 100644
index 4b3711ec0..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_os.p.gz
deleted file mode 100644
index 2f9a5de9c..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_shutil.p.gz
deleted file mode 100644
index 8ffa516c0..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_time.p.gz
deleted file mode 100644
index 6aade88c6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_uuid.p.gz
deleted file mode 100644
index 276c06397..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_wmi.p.gz
deleted file mode 100644
index 77a1650d4..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_already_running_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.utils.p.gz
deleted file mode 100644
index ce19ed290..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.virt.configdrive.p.gz
deleted file mode 100644
index b2dadcd4d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_os.p.gz
deleted file mode 100644
index aa378fedd..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_shutil.p.gz
deleted file mode 100644
index 333a27b89..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_time.p.gz
deleted file mode 100644
index 16ca553f6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_uuid.p.gz
deleted file mode 100644
index 8cf3b564e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_wmi.p.gz
deleted file mode 100644
index 0a2c8513b..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_resume_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.utils.p.gz
deleted file mode 100644
index ae42d7734..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.virt.configdrive.p.gz
deleted file mode 100644
index 4fec34d08..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_os.p.gz
deleted file mode 100644
index 74e8e95a6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_shutil.p.gz
deleted file mode 100644
index da0528797..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_time.p.gz
deleted file mode 100644
index 63f02bc75..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_uuid.p.gz
deleted file mode 100644
index c014d5003..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.utils.p.gz
deleted file mode 100644
index 592658541..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.virt.configdrive.p.gz
deleted file mode 100644
index 892f3c346..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_os.p.gz
deleted file mode 100644
index 9996339f5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_shutil.p.gz
deleted file mode 100644
index 409ee5ef7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_time.p.gz
deleted file mode 100644
index 9e799c196..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_uuid.p.gz
deleted file mode 100644
index 848024366..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_wmi.p.gz
deleted file mode 100644
index 687952c4c..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_with_update_failure_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_wmi.p.gz
deleted file mode 100644
index 57988a6b6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_snapshot_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.utils.p.gz
deleted file mode 100644
index 303a47019..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.virt.configdrive.p.gz
deleted file mode 100644
index c211622e1..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_os.p.gz
deleted file mode 100644
index 5e5303cbc..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_shutil.p.gz
deleted file mode 100644
index 1bcbd48f3..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_time.p.gz
deleted file mode 100644
index ae557d73d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_uuid.p.gz
deleted file mode 100644
index 90ebff4e7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_wmi.p.gz
deleted file mode 100644
index beccc2737..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_cdrom_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.utils.p.gz
deleted file mode 100644
index af5082ab6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.virt.configdrive.p.gz
deleted file mode 100644
index 837d81b70..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_os.p.gz
deleted file mode 100644
index ecea62a01..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_shutil.p.gz
deleted file mode 100644
index 283cd7fdd..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_time.p.gz
deleted file mode 100644
index 44dcc89ae..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_uuid.p.gz
deleted file mode 100644
index 5c520c768..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_wmi.p.gz
deleted file mode 100644
index aec53305d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_config_drive_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.utils.p.gz
deleted file mode 100644
index a16c88e54..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.virt.configdrive.p.gz
deleted file mode 100644
index d9c4e9c82..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_os.p.gz
deleted file mode 100644
index 94aafb39a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_shutil.p.gz
deleted file mode 100644
index e0ad00bf6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_time.p.gz
deleted file mode 100644
index 00f7839ba..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_uuid.p.gz
deleted file mode 100644
index 77422d3f5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_wmi.p.gz
deleted file mode 100644
index 414194a9d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_cow_image_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.utils.p.gz
deleted file mode 100644
index b1e825822..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.virt.configdrive.p.gz
deleted file mode 100644
index 1e3d89fea..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_os.p.gz
deleted file mode 100644
index 627c78d7e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_shutil.p.gz
deleted file mode 100644
index e577cdb5e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_time.p.gz
deleted file mode 100644
index 72962fc52..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_uuid.p.gz
deleted file mode 100644
index 5d1351a14..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_wmi.p.gz
deleted file mode 100644
index eb0ed7241..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_config_drive_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.utils.p.gz
deleted file mode 100644
index c65264688..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.virt.configdrive.p.gz
deleted file mode 100644
index ca40d6413..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_os.p.gz
deleted file mode 100644
index 1d8081a3e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_shutil.p.gz
deleted file mode 100644
index e03633b90..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_time.p.gz
deleted file mode 100644
index 00c56dacc..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_uuid.p.gz
deleted file mode 100644
index 7381c3cc6..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_wmi.p.gz
deleted file mode 100644
index 115ed1dd5..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_cow_image_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.utils.p.gz
deleted file mode 100644
index df40b08c0..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.virt.configdrive.p.gz
deleted file mode 100644
index b51766f75..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_os.p.gz
deleted file mode 100644
index 092a1f933..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_shutil.p.gz
deleted file mode 100644
index 77f333c00..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_time.p.gz
deleted file mode 100644
index 8ab166a60..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_uuid.p.gz
deleted file mode 100644
index 97e96be17..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_wmi.p.gz
deleted file mode 100644
index 728464ca9..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_spawn_no_vswitch_exception_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.utils.p.gz
deleted file mode 100644
index 4aa6d171a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.virt.configdrive.p.gz
deleted file mode 100644
index df063a22e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_os.p.gz
deleted file mode 100644
index b30363fcc..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_shutil.p.gz
deleted file mode 100644
index 1681d9947..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_time.p.gz
deleted file mode 100644
index 4469fd90e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_uuid.p.gz
deleted file mode 100644
index f94f2ebb9..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_wmi.p.gz
deleted file mode 100644
index 03afe2235..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_already_suspended_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.utils.p.gz
deleted file mode 100644
index 2f95f62bf..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.virt.configdrive.p.gz
deleted file mode 100644
index 2e7ab44ad..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_os.p.gz
deleted file mode 100644
index eb514d086..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_shutil.p.gz
deleted file mode 100644
index 810c9e14d..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_time.p.gz
deleted file mode 100644
index 2eb2a8372..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_uuid.p.gz
deleted file mode 100644
index 67311757a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_wmi.p.gz
deleted file mode 100644
index 0779125b3..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_suspend_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.utils.p.gz
deleted file mode 100644
index 7e6cc708e..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.virt.configdrive.p.gz
deleted file mode 100644
index 0ce4bbf63..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_os.p.gz
deleted file mode 100644
index 9068792c7..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_shutil.p.gz
deleted file mode 100644
index 9b06cb884..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_time.p.gz
deleted file mode 100644
index e91e6c965..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_uuid.p.gz
deleted file mode 100644
index 271ded270..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_wmi.p.gz
deleted file mode 100644
index 253bdfc82..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_already_running_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.utils.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.utils.p.gz
deleted file mode 100644
index 20486b189..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.utils.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.virt.configdrive.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.virt.configdrive.p.gz
deleted file mode 100644
index be92217ed..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_nova.virt.configdrive.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_os.p.gz
deleted file mode 100644
index 36059e753..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_os.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_shutil.p.gz
deleted file mode 100644
index aea394e9f..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_shutil.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_time.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_time.p.gz
deleted file mode 100644
index 4850d3cda..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_time.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_uuid.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_uuid.p.gz
deleted file mode 100644
index 99bf1806c..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_uuid.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_wmi.p.gz
deleted file mode 100644
index 87b571e4a..000000000
--- a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_unpause_wmi.p.gz
+++ /dev/null
Binary files differ
diff --git a/nova/tests/test_hypervapi.py b/nova/tests/test_hypervapi.py
index 9fec9d151..3b624e6d1 100644
--- a/nova/tests/test_hypervapi.py
+++ b/nova/tests/test_hypervapi.py
@@ -18,37 +18,53 @@
Test suite for the Hyper-V driver and related APIs.
"""
-import json
+import io
+import mox
import os
import platform
import shutil
-import sys
+import time
import uuid
+from nova.api.metadata import base as instance_metadata
from nova.compute import power_state
from nova.compute import task_states
from nova import context
from nova import db
from nova.image import glance
from nova.openstack.common import cfg
+from nova import test
from nova.tests import fake_network
-from nova.tests.hyperv import basetestcase
from nova.tests.hyperv import db_fakes
-from nova.tests.hyperv import hypervutils
-from nova.tests.hyperv import mockproxy
-import nova.tests.image.fake as fake_image
+from nova.tests.hyperv import fake
+from nova.tests.image import fake as fake_image
from nova.tests import matchers
+from nova import utils
+from nova.virt import configdrive
+from nova.virt.hyperv import basevolumeutils
from nova.virt.hyperv import constants
from nova.virt.hyperv import driver as driver_hyperv
+from nova.virt.hyperv import hostutils
+from nova.virt.hyperv import livemigrationutils
+from nova.virt.hyperv import networkutils
+from nova.virt.hyperv import pathutils
+from nova.virt.hyperv import vhdutils
from nova.virt.hyperv import vmutils
+from nova.virt.hyperv import volumeutils
+from nova.virt.hyperv import volumeutilsv2
from nova.virt import images
CONF = cfg.CONF
+CONF.import_opt('vswitch_name', 'nova.virt.hyperv.vif')
-class HyperVAPITestCase(basetestcase.BaseTestCase):
+class HyperVAPITestCase(test.TestCase):
"""Unit tests for Hyper-V driver calls."""
+ def __init__(self, test_case_name):
+ self._mox = mox.Mox()
+ super(HyperVAPITestCase, self).__init__(test_case_name)
+
def setUp(self):
super(HyperVAPITestCase, self).setUp()
@@ -56,22 +72,22 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
self._project_id = 'fake'
self._instance_data = None
self._image_metadata = None
- self._dest_server = None
self._fetched_image = None
self._update_image_raise_exception = False
- self._post_method_called = False
- self._recover_method_called = False
self._volume_target_portal = 'testtargetportal:3260'
- self._volume_id = '8957e088-dbee-4216-8056-978353a3e737'
+ self._volume_id = '0ef5d708-45ab-4129-8c59-d774d2837eb7'
self._context = context.RequestContext(self._user_id, self._project_id)
+ self._instance_ide_disks = []
+ self._instance_ide_dvds = []
+ self._instance_volume_disks = []
self._setup_stubs()
self.flags(instances_path=r'C:\Hyper-V\test\instances',
vswitch_name='external',
- network_api_class='nova.network.quantumv2.api.API')
+ network_api_class='nova.network.quantumv2.api.API',
+ force_volumeutils_v1=True)
- self._hypervutils = hypervutils.HyperVUtils()
self._conn = driver_hyperv.HyperVDriver(None)
def _setup_stubs(self):
@@ -79,14 +95,8 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
fake_image.stub_out_image_service(self.stubs)
fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs)
- def fake_dumps(msg, default=None, **kwargs):
- return '""'
- self.stubs.Set(json, 'dumps', fake_dumps)
-
def fake_fetch(context, image_id, target, user, project):
self._fetched_image = target
- if not os.path.exists(target):
- self._hypervutils.create_vhd(target)
self.stubs.Set(images, 'fetch', fake_fetch)
def fake_get_remote_image_service(context, name):
@@ -98,104 +108,198 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
self._image_metadata = image_metadata
return (FakeGlanceImageService(), 1)
self.stubs.Set(glance, 'get_remote_image_service',
- fake_get_remote_image_service)
-
- # Modules to mock
- modules_to_mock = [
- 'wmi',
- 'os',
- 'shutil',
- 'uuid',
- 'time',
- 'multiprocessing',
- '_winreg',
- 'nova.virt.configdrive',
- 'nova.utils',
- 'ctypes'
- ]
+ fake_get_remote_image_service)
+
+ def fake_sleep(ms):
+ pass
+ self.stubs.Set(time, 'sleep', fake_sleep)
+
+ self.stubs.Set(pathutils, 'PathUtils', fake.PathUtils)
+ self._mox.StubOutWithMock(fake.PathUtils, 'open')
+
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'vm_exists')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'create_vm')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'destroy_vm')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'attach_ide_drive')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'create_scsi_controller')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'create_nic')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'set_vm_state')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'list_instances')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_summary_info')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'take_vm_snapshot')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'remove_vm_snapshot')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'set_nic_connection')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_iscsi_controller')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_ide_controller')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'get_attached_disks_count')
+ self._mox.StubOutWithMock(vmutils.VMUtils,
+ 'attach_volume_to_controller')
+ self._mox.StubOutWithMock(vmutils.VMUtils,
+ 'get_mounted_disk_by_drive_number')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'detach_vm_disk')
+
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'create_differencing_vhd')
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'reconnect_parent_vhd')
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'merge_vhd')
+ self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_parent_path')
+
+ self._mox.StubOutWithMock(hostutils.HostUtils, 'get_cpus_info')
+ self._mox.StubOutWithMock(hostutils.HostUtils,
+ 'is_cpu_feature_present')
+ self._mox.StubOutWithMock(hostutils.HostUtils, 'get_memory_info')
+ self._mox.StubOutWithMock(hostutils.HostUtils, 'get_volume_info')
+ self._mox.StubOutWithMock(hostutils.HostUtils, 'get_windows_version')
+
+ self._mox.StubOutWithMock(networkutils.NetworkUtils,
+ 'get_external_vswitch')
+ self._mox.StubOutWithMock(networkutils.NetworkUtils,
+ 'create_vswitch_port')
+
+ self._mox.StubOutWithMock(livemigrationutils.LiveMigrationUtils,
+ 'live_migrate_vm')
+ self._mox.StubOutWithMock(livemigrationutils.LiveMigrationUtils,
+ 'check_live_migration_config')
+
+ self._mox.StubOutWithMock(basevolumeutils.BaseVolumeUtils,
+ 'volume_in_mapping')
+ self._mox.StubOutWithMock(basevolumeutils.BaseVolumeUtils,
+ 'get_session_id_from_mounted_disk')
+ self._mox.StubOutWithMock(basevolumeutils.BaseVolumeUtils,
+ 'get_device_number_for_target')
+
+ self._mox.StubOutWithMock(volumeutils.VolumeUtils,
+ 'login_storage_target')
+ self._mox.StubOutWithMock(volumeutils.VolumeUtils,
+ 'logout_storage_target')
+ self._mox.StubOutWithMock(volumeutils.VolumeUtils,
+ 'execute_log_out')
+
+ self._mox.StubOutWithMock(volumeutilsv2.VolumeUtilsV2,
+ 'login_storage_target')
+ self._mox.StubOutWithMock(volumeutilsv2.VolumeUtilsV2,
+ 'logout_storage_target')
+ self._mox.StubOutWithMock(volumeutilsv2.VolumeUtilsV2,
+ 'execute_log_out')
+
+ self._mox.StubOutWithMock(shutil, 'copyfile')
+ self._mox.StubOutWithMock(shutil, 'rmtree')
+
+ self._mox.StubOutWithMock(os, 'remove')
+
+ self._mox.StubOutClassWithMocks(instance_metadata, 'InstanceMetadata')
+ self._mox.StubOutWithMock(instance_metadata.InstanceMetadata,
+ 'metadata_for_config_drive')
+
+ # Can't use StubOutClassWithMocks due to __exit__ and __enter__
+ self._mox.StubOutWithMock(configdrive, 'ConfigDriveBuilder')
+ self._mox.StubOutWithMock(configdrive.ConfigDriveBuilder, 'make_drive')
+
+ self._mox.StubOutWithMock(utils, 'execute')
- # Modules in which the mocks are going to be injected
- from nova.virt.hyperv import baseops
- from nova.virt.hyperv import basevolumeutils
- from nova.virt.hyperv import hostops
- from nova.virt.hyperv import livemigrationops
- from nova.virt.hyperv import snapshotops
- from nova.virt.hyperv import vif
- from nova.virt.hyperv import vmops
- from nova.virt.hyperv import volumeops
- from nova.virt.hyperv import volumeutils
- from nova.virt.hyperv import volumeutilsV2
-
- modules_to_test = [
- driver_hyperv,
- basevolumeutils,
- baseops,
- hostops,
- vif,
- vmops,
- vmutils,
- volumeops,
- volumeutils,
- volumeutilsV2,
- snapshotops,
- livemigrationops,
- hypervutils,
- db_fakes,
- sys.modules[__name__]
- ]
+ def tearDown(self):
+ self._mox.UnsetStubs()
+ super(HyperVAPITestCase, self).tearDown()
- self._inject_mocks_in_modules(modules_to_mock, modules_to_test)
+ def test_get_available_resource(self):
+ cpu_info = {'Architecture': 'fake',
+ 'Name': 'fake',
+ 'Manufacturer': 'ACME, Inc.',
+ 'NumberOfCores': 2,
+ 'NumberOfLogicalProcessors': 4}
- if isinstance(snapshotops.wmi, mockproxy.Mock):
- from nova.virt.hyperv import ioutils
- import StringIO
+ tot_mem_kb = 2000000L
+ free_mem_kb = 1000000L
- def fake_open(name, mode):
- return StringIO.StringIO("fake file content")
- self.stubs.Set(ioutils, 'open', fake_open)
+ tot_hdd_b = 4L * 1024 ** 3
+ free_hdd_b = 3L * 1024 ** 3
- def tearDown(self):
- try:
- if self._instance_data and self._hypervutils.vm_exists(
- self._instance_data["name"]):
- self._hypervutils.remove_vm(self._instance_data["name"])
+ windows_version = '6.2.9200'
- if self._dest_server and \
- self._hypervutils.remote_vm_exists(self._dest_server,
- self._instance_data["name"]):
- self._hypervutils.remove_remote_vm(self._dest_server,
- self._instance_data["name"])
+ hostutils.HostUtils.get_memory_info().AndReturn((tot_mem_kb,
+ free_mem_kb))
- self._hypervutils.logout_iscsi_volume_sessions(self._volume_id)
+ m = hostutils.HostUtils.get_volume_info(mox.IsA(str))
+ m.AndReturn((tot_hdd_b, free_hdd_b))
- shutil.rmtree(CONF.instances_path, True)
+ hostutils.HostUtils.get_cpus_info().AndReturn([cpu_info])
+ m = hostutils.HostUtils.is_cpu_feature_present(mox.IsA(int))
+ m.MultipleTimes()
- fake_image.FakeImageService_reset()
- finally:
- super(HyperVAPITestCase, self).tearDown()
+ m = hostutils.HostUtils.get_windows_version()
+ m.AndReturn(windows_version)
- def test_get_available_resource(self):
+ self._mox.ReplayAll()
dic = self._conn.get_available_resource(None)
+ self._mox.VerifyAll()
+ self.assertEquals(dic['vcpus'], cpu_info['NumberOfLogicalProcessors'])
self.assertEquals(dic['hypervisor_hostname'], platform.node())
+ self.assertEquals(dic['memory_mb'], tot_mem_kb / 1024)
+ self.assertEquals(dic['memory_mb_used'],
+ tot_mem_kb / 1024 - free_mem_kb / 1024)
+ self.assertEquals(dic['local_gb'], tot_hdd_b / 1024 ** 3)
+ self.assertEquals(dic['local_gb_used'],
+ tot_hdd_b / 1024 ** 3 - free_hdd_b / 1024 ** 3)
+ self.assertEquals(dic['hypervisor_version'],
+ windows_version.replace('.', ''))
def test_get_host_stats(self):
+ tot_mem_kb = 2000000L
+ free_mem_kb = 1000000L
+
+ tot_hdd_b = 4L * 1024 ** 3
+ free_hdd_b = 3L * 1024 ** 3
+
+ hostutils.HostUtils.get_memory_info().AndReturn((tot_mem_kb,
+ free_mem_kb))
+
+ m = hostutils.HostUtils.get_volume_info(mox.IsA(str))
+ m.AndReturn((tot_hdd_b, free_hdd_b))
+
+ self._mox.ReplayAll()
dic = self._conn.get_host_stats(True)
+ self._mox.VerifyAll()
+
+ self.assertEquals(dic['disk_total'], tot_hdd_b / 1024 ** 3)
+ self.assertEquals(dic['disk_available'], free_hdd_b / 1024 ** 3)
+
+ self.assertEquals(dic['host_memory_total'], tot_mem_kb / 1024)
+ self.assertEquals(dic['host_memory_free'], free_mem_kb / 1024)
self.assertEquals(dic['disk_total'],
- dic['disk_used'] + dic['disk_available'])
+ dic['disk_used'] + dic['disk_available'])
self.assertEquals(dic['host_memory_total'],
- dic['host_memory_overhead'] + dic['host_memory_free'])
+ dic['host_memory_overhead'] +
+ dic['host_memory_free'])
def test_list_instances(self):
- num_vms = self._hypervutils.get_vm_count()
+ fake_instances = ['fake1', 'fake2']
+ vmutils.VMUtils.list_instances().AndReturn(fake_instances)
+
+ self._mox.ReplayAll()
instances = self._conn.list_instances()
+ self._mox.VerifyAll()
- self.assertEquals(len(instances), num_vms)
+ self.assertEquals(instances, fake_instances)
def test_get_info(self):
- self._spawn_instance(True)
+ self._instance_data = self._get_instance_data()
+
+ summary_info = {'NumberOfProcessors': 2,
+ 'EnabledState': constants.HYPERV_VM_STATE_ENABLED,
+ 'MemoryUsage': 1000,
+ 'UpTime': 1}
+
+ m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name))
+ m.AndReturn(True)
+
+ func = mox.Func(self._check_instance_name)
+ m = vmutils.VMUtils.get_vm_summary_info(func)
+ m.AndReturn(summary_info)
+
+ self._mox.ReplayAll()
info = self._conn.get_info(self._instance_data)
+ self._mox.VerifyAll()
self.assertEquals(info["state"], power_state.RUNNING)
@@ -205,189 +309,237 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
def test_spawn_no_cow_image(self):
self._test_spawn_instance(False)
- def test_spawn_config_drive(self):
- self.skip('broken by move to contextlib for configdrive')
-
+ def _setup_spawn_config_drive_mocks(self, use_cdrom):
+ im = instance_metadata.InstanceMetadata(mox.IgnoreArg(),
+ content=mox.IsA(list),
+ extra_md=mox.IsA(dict))
+
+ cdb = self._mox.CreateMockAnything()
+ m = configdrive.ConfigDriveBuilder(instance_md=mox.IgnoreArg())
+ m.AndReturn(cdb)
+ # __enter__ and __exit__ are required by "with"
+ cdb.__enter__().AndReturn(cdb)
+ cdb.make_drive(mox.IsA(str))
+ cdb.__exit__(None, None, None).AndReturn(None)
+
+ if not use_cdrom:
+ utils.execute(CONF.qemu_img_cmd,
+ 'convert',
+ '-f',
+ 'raw',
+ '-O',
+ 'vpc',
+ mox.IsA(str),
+ mox.IsA(str),
+ attempts=1)
+ os.remove(mox.IsA(str))
+
+ m = vmutils.VMUtils.attach_ide_drive(mox.IsA(str),
+ mox.IsA(str),
+ mox.IsA(int),
+ mox.IsA(int),
+ mox.IsA(str))
+ m.WithSideEffects(self._add_ide_disk)
+
+ def _test_spawn_config_drive(self, use_cdrom):
self.flags(force_config_drive=True)
+ self.flags(config_drive_cdrom=use_cdrom)
self.flags(mkisofs_cmd='mkisofs.exe')
- self._spawn_instance(True)
+ self._setup_spawn_config_drive_mocks(use_cdrom)
- (vhd_paths, _, dvd_paths) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(dvd_paths), 0)
- self.assertEquals(len(vhd_paths), 2)
+ if use_cdrom:
+ expected_ide_disks = 1
+ expected_ide_dvds = 1
+ else:
+ expected_ide_disks = 2
+ expected_ide_dvds = 0
- def test_spawn_config_drive_cdrom(self):
- self.skip('broken by move to contextlib for configdrive')
+ self._test_spawn_instance(expected_ide_disks=expected_ide_disks,
+ expected_ide_dvds=expected_ide_dvds)
- self.flags(force_config_drive=True)
- self.flags(config_drive_cdrom=True)
- self.flags(mkisofs_cmd='mkisofs.exe')
-
- self._spawn_instance(True)
+ def test_spawn_config_drive(self):
+ self._test_spawn_config_drive(False)
- (vhd_paths, _, dvd_paths) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(dvd_paths), 1)
- self.assertEquals(len(vhd_paths), 1)
- self.assertTrue(os.path.exists(dvd_paths[0]))
+ def test_spawn_config_drive_cdrom(self):
+ self._test_spawn_config_drive(True)
def test_spawn_no_config_drive(self):
self.flags(force_config_drive=False)
- self._spawn_instance(True)
+ expected_ide_disks = 1
+ expected_ide_dvds = 0
+
+ self._test_spawn_instance(expected_ide_disks=expected_ide_disks,
+ expected_ide_dvds=expected_ide_dvds)
+
+ def test_spawn_nova_net_vif(self):
+ self.flags(network_api_class='nova.network.api.API')
+ # Reinstantiate driver, as the VIF plugin is loaded during __init__
+ self._conn = driver_hyperv.HyperVDriver(None)
+
+ def setup_vif_mocks():
+ fake_vswitch_path = 'fake vswitch path'
+ fake_vswitch_port = 'fake port'
+
+ m = networkutils.NetworkUtils.get_external_vswitch(
+ CONF.vswitch_name)
+ m.AndReturn(fake_vswitch_path)
+
+ m = networkutils.NetworkUtils.create_vswitch_port(
+ fake_vswitch_path, mox.IsA(str))
+ m.AndReturn(fake_vswitch_port)
- (_, _, dvd_paths) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(dvd_paths), 0)
+ vmutils.VMUtils.set_nic_connection(mox.IsA(str), mox.IsA(str),
+ fake_vswitch_port)
- def test_spawn_no_vswitch_exception(self):
+ self._test_spawn_instance(setup_vif_mocks_func=setup_vif_mocks)
+
+ def test_spawn_nova_net_vif_no_vswitch_exception(self):
self.flags(network_api_class='nova.network.api.API')
# Reinstantiate driver, as the VIF plugin is loaded during __init__
self._conn = driver_hyperv.HyperVDriver(None)
- # Set flag to a non existing vswitch
- self.flags(vswitch_name=str(uuid.uuid4()))
- self.assertRaises(vmutils.HyperVException, self._spawn_instance, True)
- self.assertFalse(self._hypervutils.vm_exists(
- self._instance_data["name"]))
+ def setup_vif_mocks():
+ m = networkutils.NetworkUtils.get_external_vswitch(
+ CONF.vswitch_name)
+ m.AndRaise(vmutils.HyperVException(_('fake vswitch not found')))
+
+ self.assertRaises(vmutils.HyperVException, self._test_spawn_instance,
+ setup_vif_mocks_func=setup_vif_mocks,
+ with_exception=True)
+
+ def _check_instance_name(self, vm_name):
+ return vm_name == self._instance_data['name']
def _test_vm_state_change(self, action, from_state, to_state):
- self._spawn_instance(True)
- if from_state:
- self._hypervutils.set_vm_state(self._instance_data["name"],
- from_state)
- action(self._instance_data)
+ self._instance_data = self._get_instance_data()
- vmstate = self._hypervutils.get_vm_state(self._instance_data["name"])
- self.assertEquals(vmstate, to_state)
+ vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
+ to_state)
+
+ self._mox.ReplayAll()
+ action(self._instance_data)
+ self._mox.VerifyAll()
def test_pause(self):
self._test_vm_state_change(self._conn.pause, None,
- constants.HYPERV_VM_STATE_PAUSED)
+ constants.HYPERV_VM_STATE_PAUSED)
def test_pause_already_paused(self):
self._test_vm_state_change(self._conn.pause,
- constants.HYPERV_VM_STATE_PAUSED,
- constants.HYPERV_VM_STATE_PAUSED)
+ constants.HYPERV_VM_STATE_PAUSED,
+ constants.HYPERV_VM_STATE_PAUSED)
def test_unpause(self):
self._test_vm_state_change(self._conn.unpause,
- constants.HYPERV_VM_STATE_PAUSED,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_PAUSED,
+ constants.HYPERV_VM_STATE_ENABLED)
def test_unpause_already_running(self):
self._test_vm_state_change(self._conn.unpause, None,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_ENABLED)
def test_suspend(self):
self._test_vm_state_change(self._conn.suspend, None,
- constants.HYPERV_VM_STATE_SUSPENDED)
+ constants.HYPERV_VM_STATE_SUSPENDED)
def test_suspend_already_suspended(self):
self._test_vm_state_change(self._conn.suspend,
- constants.HYPERV_VM_STATE_SUSPENDED,
- constants.HYPERV_VM_STATE_SUSPENDED)
+ constants.HYPERV_VM_STATE_SUSPENDED,
+ constants.HYPERV_VM_STATE_SUSPENDED)
def test_resume(self):
self._test_vm_state_change(lambda i: self._conn.resume(i, None),
- constants.HYPERV_VM_STATE_SUSPENDED,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_SUSPENDED,
+ constants.HYPERV_VM_STATE_ENABLED)
def test_resume_already_running(self):
self._test_vm_state_change(lambda i: self._conn.resume(i, None), None,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_ENABLED)
def test_power_off(self):
self._test_vm_state_change(self._conn.power_off, None,
- constants.HYPERV_VM_STATE_DISABLED)
+ constants.HYPERV_VM_STATE_DISABLED)
def test_power_off_already_powered_off(self):
- self._test_vm_state_change(self._conn.suspend,
- constants.HYPERV_VM_STATE_DISABLED,
- constants.HYPERV_VM_STATE_DISABLED)
+ self._test_vm_state_change(self._conn.power_off,
+ constants.HYPERV_VM_STATE_DISABLED,
+ constants.HYPERV_VM_STATE_DISABLED)
def test_power_on(self):
self._test_vm_state_change(self._conn.power_on,
- constants.HYPERV_VM_STATE_DISABLED,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_DISABLED,
+ constants.HYPERV_VM_STATE_ENABLED)
def test_power_on_already_running(self):
self._test_vm_state_change(self._conn.power_on, None,
- constants.HYPERV_VM_STATE_ENABLED)
+ constants.HYPERV_VM_STATE_ENABLED)
def test_reboot(self):
- self._spawn_instance(True)
network_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
- self._conn.reboot(self._instance_data, network_info, None)
+ self._instance_data = self._get_instance_data()
- vmstate = self._hypervutils.get_vm_state(self._instance_data["name"])
- self.assertEquals(vmstate, constants.HYPERV_VM_STATE_ENABLED)
+ vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
+ constants.HYPERV_VM_STATE_REBOOT)
+
+ self._mox.ReplayAll()
+ self._conn.reboot(self._instance_data, network_info, None)
+ self._mox.VerifyAll()
def test_destroy(self):
- self._spawn_instance(True)
- (vhd_paths, _, _) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
+ self._instance_data = self._get_instance_data()
- self._conn.destroy(self._instance_data)
+ m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name))
+ m.AndReturn(True)
- self.assertFalse(self._hypervutils.vm_exists(
- self._instance_data["name"]))
- self._instance_data = None
+ m = vmutils.VMUtils.destroy_vm(mox.Func(self._check_instance_name),
+ True)
+ m.AndReturn([])
- for vhd_path in vhd_paths:
- self.assertFalse(os.path.exists(vhd_path))
+ self._mox.ReplayAll()
+ self._conn.destroy(self._instance_data)
+ self._mox.VerifyAll()
def test_live_migration(self):
- self.flags(limit_cpu_features=True)
- self._spawn_instance(False)
+ self._test_live_migration(False)
- # Existing server
- self._dest_server = "HV12OSDEMO2"
+ def test_live_migration_with_target_failure(self):
+ self._test_live_migration(True)
- self._live_migration(self._dest_server)
+ def _test_live_migration(self, test_failure):
+ dest_server = 'fake_server'
- instance_name = self._instance_data["name"]
- self.assertFalse(self._hypervutils.vm_exists(instance_name))
- self.assertTrue(self._hypervutils.remote_vm_exists(self._dest_server,
- instance_name))
+ instance_data = self._get_instance_data()
- self.assertTrue(self._post_method_called)
- self.assertFalse(self._recover_method_called)
+ fake_post_method = self._mox.CreateMockAnything()
+ if not test_failure:
+ fake_post_method(self._context, instance_data, dest_server,
+ False)
- def test_live_migration_with_target_failure(self):
- self.flags(limit_cpu_features=True)
- self._spawn_instance(False)
+ fake_recover_method = self._mox.CreateMockAnything()
+ if test_failure:
+ fake_recover_method(self._context, instance_data, dest_server,
+ False)
- dest_server = "nonexistingserver"
+ m = livemigrationutils.LiveMigrationUtils.live_migrate_vm(
+ instance_data['name'], dest_server)
+ if test_failure:
+ m.AndRaise(Exception('Simulated failure'))
- exception_raised = False
+ self._mox.ReplayAll()
try:
- self._live_migration(dest_server)
+ self._conn.live_migration(self._context, instance_data,
+ dest_server, fake_post_method,
+ fake_recover_method)
+ exception_raised = False
except Exception:
exception_raised = True
- # Cannot use assertRaises with pythoncom.com_error on Linux
- self.assertTrue(exception_raised)
-
- instance_name = self._instance_data["name"]
- self.assertTrue(self._hypervutils.vm_exists(instance_name))
-
- self.assertFalse(self._post_method_called)
- self.assertTrue(self._recover_method_called)
-
- def _live_migration(self, dest_server):
- def fake_post_method(context, instance_ref, dest, block_migration):
- self._post_method_called = True
-
- def fake_recover_method(context, instance_ref, dest, block_migration):
- self._recover_method_called = True
-
- self._conn.live_migration(self._context, self._instance_data,
- dest_server, fake_post_method, fake_recover_method)
+ self.assertTrue(not test_failure ^ exception_raised)
+ self._mox.VerifyAll()
def test_pre_live_migration_cow_image(self):
self._test_pre_live_migration(True)
@@ -398,83 +550,134 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
def _test_pre_live_migration(self, cow):
self.flags(use_cow_images=cow)
- instance_name = 'openstack_unit_test_vm_' + str(uuid.uuid4())
+ instance_data = self._get_instance_data()
network_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
- instance_data = db_fakes.get_fake_instance_data(instance_name,
- self._project_id, self._user_id)
- block_device_info = None
+ m = livemigrationutils.LiveMigrationUtils.check_live_migration_config()
+ m.AndReturn(True)
+
+ if cow:
+ m = basevolumeutils.BaseVolumeUtils.volume_in_mapping(mox.IsA(str),
+ None)
+ m.AndReturn([])
+
+ self._mox.ReplayAll()
self._conn.pre_live_migration(self._context, instance_data,
- block_device_info, network_info)
+ None, network_info)
+ self._mox.VerifyAll()
if cow:
- self.assertTrue(not self._fetched_image is None)
+ self.assertTrue(self._fetched_image is not None)
else:
self.assertTrue(self._fetched_image is None)
def test_snapshot_with_update_failure(self):
- expected_calls = [
- {'args': (),
- 'kwargs':
- {'task_state': task_states.IMAGE_PENDING_UPLOAD}},
- {'args': (),
- 'kwargs':
- {'task_state': task_states.IMAGE_UPLOADING,
- 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
- func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
-
- self._spawn_instance(True)
+ (snapshot_name, func_call_matcher) = self._setup_snapshot_mocks()
self._update_image_raise_exception = True
- snapshot_name = 'test_snapshot_' + str(uuid.uuid4())
+
+ self._mox.ReplayAll()
self.assertRaises(vmutils.HyperVException, self._conn.snapshot,
self._context, self._instance_data, snapshot_name,
func_call_matcher.call)
+ self._mox.VerifyAll()
- # assert states changed in correct order
+ # Assert states changed in correct order
self.assertIsNone(func_call_matcher.match())
- # assert VM snapshots have been removed
- self.assertEquals(self._hypervutils.get_vm_snapshots_count(
- self._instance_data["name"]), 0)
-
- def test_snapshot(self):
+ def _setup_snapshot_mocks(self):
expected_calls = [
{'args': (),
- 'kwargs':
- {'task_state': task_states.IMAGE_PENDING_UPLOAD}},
- {'args': (),
- 'kwargs':
- {'task_state': task_states.IMAGE_UPLOADING,
- 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
+ 'kwargs': {'task_state': task_states.IMAGE_PENDING_UPLOAD}},
+ {'args': (),
+ 'kwargs': {'task_state': task_states.IMAGE_UPLOADING,
+ 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}
+ ]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
- self._spawn_instance(True)
-
snapshot_name = 'test_snapshot_' + str(uuid.uuid4())
+
+ fake_hv_snapshot_path = 'fake_snapshot_path'
+ fake_parent_vhd_path = 'C:\\fake_vhd_path\\parent.vhd'
+
+ self._instance_data = self._get_instance_data()
+
+ func = mox.Func(self._check_instance_name)
+ m = vmutils.VMUtils.take_vm_snapshot(func)
+ m.AndReturn(fake_hv_snapshot_path)
+
+ m = vhdutils.VHDUtils.get_vhd_parent_path(mox.IsA(str))
+ m.AndReturn(fake_parent_vhd_path)
+
+ self._fake_dest_disk_path = None
+
+ def copy_dest_disk_path(src, dest):
+ self._fake_dest_disk_path = dest
+
+ m = shutil.copyfile(mox.IsA(str), mox.IsA(str))
+ m.WithSideEffects(copy_dest_disk_path)
+
+ self._fake_dest_base_disk_path = None
+
+ def copy_dest_base_disk_path(src, dest):
+ self._fake_dest_base_disk_path = dest
+
+ m = shutil.copyfile(fake_parent_vhd_path, mox.IsA(str))
+ m.WithSideEffects(copy_dest_base_disk_path)
+
+ def check_dest_disk_path(path):
+ return path == self._fake_dest_disk_path
+
+ def check_dest_base_disk_path(path):
+ return path == self._fake_dest_base_disk_path
+
+ func1 = mox.Func(check_dest_disk_path)
+ func2 = mox.Func(check_dest_base_disk_path)
+ # Make sure that the hyper-v base and differential VHDs are merged
+ vhdutils.VHDUtils.reconnect_parent_vhd(func1, func2)
+ vhdutils.VHDUtils.merge_vhd(func1, func2)
+
+ def check_snapshot_path(snapshot_path):
+ return snapshot_path == fake_hv_snapshot_path
+
+ # Make sure that the Hyper-V snapshot is removed
+ func = mox.Func(check_snapshot_path)
+ vmutils.VMUtils.remove_vm_snapshot(func)
+
+ shutil.rmtree(mox.IsA(str))
+
+ m = fake.PathUtils.open(func2, 'rb')
+ m.AndReturn(io.BytesIO(b'fake content'))
+
+ return (snapshot_name, func_call_matcher)
+
+ def test_snapshot(self):
+ (snapshot_name, func_call_matcher) = self._setup_snapshot_mocks()
+
+ self._mox.ReplayAll()
self._conn.snapshot(self._context, self._instance_data, snapshot_name,
func_call_matcher.call)
+ self._mox.VerifyAll()
self.assertTrue(self._image_metadata and
- "disk_format" in self._image_metadata and
- self._image_metadata["disk_format"] == "vhd")
+ "disk_format" in self._image_metadata and
+ self._image_metadata["disk_format"] == "vhd")
- # assert states changed in correct order
+ # Assert states changed in correct order
self.assertIsNone(func_call_matcher.match())
- # assert VM snapshots have been removed
- self.assertEquals(self._hypervutils.get_vm_snapshots_count(
- self._instance_data["name"]), 0)
+ def _get_instance_data(self):
+ instance_name = 'openstack_unit_test_vm_' + str(uuid.uuid4())
+ return db_fakes.get_fake_instance_data(instance_name,
+ self._project_id,
+ self._user_id)
def _spawn_instance(self, cow, block_device_info=None):
self.flags(use_cow_images=cow)
- instance_name = 'openstack_unit_test_vm_' + str(uuid.uuid4())
-
- self._instance_data = db_fakes.get_fake_instance_data(instance_name,
- self._project_id, self._user_id)
+ self._instance_data = self._get_instance_data()
instance = db.instance_create(self._context, self._instance_data)
image = db_fakes.get_fake_image_data(self._project_id, self._user_id)
@@ -487,73 +690,216 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
network_info=network_info,
block_device_info=block_device_info)
- def _test_spawn_instance(self, cow):
- self._spawn_instance(cow)
+ def _add_ide_disk(self, vm_name, path, ctrller_addr,
+ drive_addr, drive_type):
+ if drive_type == constants.IDE_DISK:
+ self._instance_ide_disks.append(path)
+ elif drive_type == constants.IDE_DVD:
+ self._instance_ide_dvds.append(path)
+
+ def _add_volume_disk(self, vm_name, controller_path, address,
+ mounted_disk_path):
+ self._instance_volume_disks.append(mounted_disk_path)
- self.assertTrue(self._hypervutils.vm_exists(
- self._instance_data["name"]))
+ def _setup_spawn_instance_mocks(self, cow, setup_vif_mocks_func=None,
+ with_exception=False,
+ block_device_info=None):
+ self._test_vm_name = None
- vmstate = self._hypervutils.get_vm_state(self._instance_data["name"])
- self.assertEquals(vmstate, constants.HYPERV_VM_STATE_ENABLED)
+ def set_vm_name(vm_name):
+ self._test_vm_name = vm_name
- (vhd_paths, _, _) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(vhd_paths), 1)
+ def check_vm_name(vm_name):
+ return vm_name == self._test_vm_name
+
+ m = vmutils.VMUtils.vm_exists(mox.IsA(str))
+ m.WithSideEffects(set_vm_name).AndReturn(False)
+
+ if not block_device_info:
+ m = basevolumeutils.BaseVolumeUtils.volume_in_mapping(mox.IsA(str),
+ None)
+ m.AndReturn([])
+ else:
+ m = basevolumeutils.BaseVolumeUtils.volume_in_mapping(
+ mox.IsA(str), block_device_info)
+ m.AndReturn(True)
- parent_path = self._hypervutils.get_vhd_parent_path(vhd_paths[0])
if cow:
- self.assertTrue(not parent_path is None)
- self.assertEquals(self._fetched_image, parent_path)
+ def check_path(parent_path):
+ return parent_path == self._fetched_image
+
+ vhdutils.VHDUtils.create_differencing_vhd(mox.IsA(str),
+ mox.Func(check_path))
+
+ vmutils.VMUtils.create_vm(mox.Func(check_vm_name), mox.IsA(int),
+ mox.IsA(int), mox.IsA(bool))
+
+ if not block_device_info:
+ m = vmutils.VMUtils.attach_ide_drive(mox.Func(check_vm_name),
+ mox.IsA(str),
+ mox.IsA(int),
+ mox.IsA(int),
+ mox.IsA(str))
+ m.WithSideEffects(self._add_ide_disk).InAnyOrder()
+
+ m = vmutils.VMUtils.create_scsi_controller(mox.Func(check_vm_name))
+ m.InAnyOrder()
+
+ vmutils.VMUtils.create_nic(mox.Func(check_vm_name), mox.IsA(str),
+ mox.IsA(str)).InAnyOrder()
+
+ if setup_vif_mocks_func:
+ setup_vif_mocks_func()
+
+ # TODO(alexpilotti) Based on where the exception is thrown
+ # some of the above mock calls need to be skipped
+ if with_exception:
+ m = vmutils.VMUtils.vm_exists(mox.Func(check_vm_name))
+ m.AndReturn(True)
+
+ vmutils.VMUtils.destroy_vm(mox.Func(check_vm_name), True)
else:
- self.assertTrue(parent_path is None)
- self.assertEquals(self._fetched_image, vhd_paths[0])
+ vmutils.VMUtils.set_vm_state(mox.Func(check_vm_name),
+ constants.HYPERV_VM_STATE_ENABLED)
+
+ def _test_spawn_instance(self, cow=True,
+ expected_ide_disks=1,
+ expected_ide_dvds=0,
+ setup_vif_mocks_func=None,
+ with_exception=False):
+ self._setup_spawn_instance_mocks(cow, setup_vif_mocks_func,
+ with_exception)
+
+ self._mox.ReplayAll()
+ self._spawn_instance(cow, )
+ self._mox.VerifyAll()
+
+ self.assertEquals(len(self._instance_ide_disks), expected_ide_disks)
+ self.assertEquals(len(self._instance_ide_dvds), expected_ide_dvds)
+
+ if not cow:
+ self.assertEquals(self._fetched_image, self._instance_ide_disks[0])
+
+ def test_attach_volume(self):
+ instance_data = self._get_instance_data()
+ instance_name = instance_data['name']
- def _attach_volume(self):
- self._spawn_instance(True)
connection_info = db_fakes.get_fake_volume_info_data(
self._volume_target_portal, self._volume_id)
+ data = connection_info['data']
+ target_lun = data['target_lun']
+ target_iqn = data['target_iqn']
+ target_portal = data['target_portal']
- self._conn.attach_volume(connection_info,
- self._instance_data, '/dev/sdc')
+ mount_point = '/dev/sdc'
- def test_attach_volume(self):
- self._attach_volume()
+ volumeutils.VolumeUtils.login_storage_target(target_lun,
+ target_iqn,
+ target_portal)
+
+ fake_mounted_disk = "fake_mounted_disk"
+ fake_device_number = 0
+ fake_controller_path = 'fake_scsi_controller_path'
+ fake_free_slot = 1
+
+ m = volumeutils.VolumeUtils.get_device_number_for_target(target_iqn,
+ target_lun)
+ m.AndReturn(fake_device_number)
+
+ m = vmutils.VMUtils.get_mounted_disk_by_drive_number(
+ fake_device_number)
+ m.AndReturn(fake_mounted_disk)
- (_, volumes_paths, _) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(volumes_paths), 1)
+ m = vmutils.VMUtils.get_vm_iscsi_controller(instance_name)
+ m.AndReturn(fake_controller_path)
- sessions_exist = self._hypervutils.iscsi_volume_sessions_exist(
- self._volume_id)
- self.assertTrue(sessions_exist)
+ m = vmutils.VMUtils.get_attached_disks_count(fake_controller_path)
+ m.AndReturn(fake_free_slot)
+
+ m = vmutils.VMUtils.attach_volume_to_controller(instance_name,
+ fake_controller_path,
+ fake_free_slot,
+ fake_mounted_disk)
+ m.WithSideEffects(self._add_volume_disk)
+
+ self._mox.ReplayAll()
+ self._conn.attach_volume(connection_info, instance_data, mount_point)
+ self._mox.VerifyAll()
+
+ self.assertEquals(len(self._instance_volume_disks), 1)
def test_detach_volume(self):
- self._attach_volume()
+ instance_data = self._get_instance_data()
+ instance_name = instance_data['name']
+
connection_info = db_fakes.get_fake_volume_info_data(
self._volume_target_portal, self._volume_id)
+ data = connection_info['data']
+ target_lun = data['target_lun']
+ target_iqn = data['target_iqn']
+ target_portal = data['target_portal']
+ mount_point = '/dev/sdc'
- self._conn.detach_volume(connection_info,
- self._instance_data, '/dev/sdc')
+ fake_mounted_disk = "fake_mounted_disk"
+ fake_device_number = 0
+ fake_free_slot = 1
+ m = volumeutils.VolumeUtils.get_device_number_for_target(target_iqn,
+ target_lun)
+ m.AndReturn(fake_device_number)
- (_, volumes_paths, _) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
- self.assertEquals(len(volumes_paths), 0)
+ m = vmutils.VMUtils.get_mounted_disk_by_drive_number(
+ fake_device_number)
+ m.AndReturn(fake_mounted_disk)
- sessions_exist = self._hypervutils.iscsi_volume_sessions_exist(
- self._volume_id)
- self.assertFalse(sessions_exist)
+ vmutils.VMUtils.detach_vm_disk(mox.IsA(str), fake_mounted_disk)
+
+ volumeutils.VolumeUtils.logout_storage_target(mox.IsA(str))
+
+ self._mox.ReplayAll()
+ self._conn.detach_volume(connection_info, instance_data, mount_point)
+ self._mox.VerifyAll()
def test_boot_from_volume(self):
+ connection_info = db_fakes.get_fake_volume_info_data(
+ self._volume_target_portal, self._volume_id)
+ data = connection_info['data']
+ target_lun = data['target_lun']
+ target_iqn = data['target_iqn']
+ target_portal = data['target_portal']
+
block_device_info = db_fakes.get_fake_block_device_info(
self._volume_target_portal, self._volume_id)
- self._spawn_instance(False, block_device_info)
+ fake_mounted_disk = "fake_mounted_disk"
+ fake_device_number = 0
+ fake_controller_path = 'fake_scsi_controller_path'
+
+ volumeutils.VolumeUtils.login_storage_target(target_lun,
+ target_iqn,
+ target_portal)
+
+ m = volumeutils.VolumeUtils.get_device_number_for_target(target_iqn,
+ target_lun)
+ m.AndReturn(fake_device_number)
- (_, volumes_paths, _) = self._hypervutils.get_vm_disks(
- self._instance_data["name"])
+ m = vmutils.VMUtils.get_mounted_disk_by_drive_number(
+ fake_device_number)
+ m.AndReturn(fake_mounted_disk)
- self.assertEquals(len(volumes_paths), 1)
+ m = vmutils.VMUtils.get_vm_ide_controller(mox.IsA(str), mox.IsA(int))
+ m.AndReturn(fake_controller_path)
+
+ m = vmutils.VMUtils.attach_volume_to_controller(mox.IsA(str),
+ fake_controller_path,
+ 0,
+ fake_mounted_disk)
+ m.WithSideEffects(self._add_volume_disk)
+
+ self._setup_spawn_instance_mocks(cow=False,
+ block_device_info=block_device_info)
+
+ self._mox.ReplayAll()
+ self._spawn_instance(False, block_device_info)
+ self._mox.VerifyAll()
- sessions_exist = self._hypervutils.iscsi_volume_sessions_exist(
- self._volume_id)
- self.assertTrue(sessions_exist)
+ self.assertEquals(len(self._instance_volume_disks), 1)
diff --git a/nova/virt/hyperv/__init__.py b/nova/virt/hyperv/__init__.py
index e69de29bb..090fc0639 100644
--- a/nova/virt/hyperv/__init__.py
+++ b/nova/virt/hyperv/__init__.py
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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.
diff --git a/nova/virt/hyperv/baseops.py b/nova/virt/hyperv/baseops.py
deleted file mode 100644
index 5b617f898..000000000
--- a/nova/virt/hyperv/baseops.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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.
-
-"""
-Management base class for Hyper-V operations.
-"""
-import sys
-
-from nova.openstack.common import log as logging
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
-
-LOG = logging.getLogger(__name__)
-
-
-class BaseOps(object):
- def __init__(self):
- self.__conn = None
- self.__conn_v2 = None
- self.__conn_cimv2 = None
- self.__conn_wmi = None
- self.__conn_storage = None
-
- @property
- def _conn(self):
- if self.__conn is None:
- self.__conn = wmi.WMI(moniker='//./root/virtualization')
- return self.__conn
-
- @property
- def _conn_v2(self):
- if self.__conn_v2 is None:
- self.__conn_v2 = wmi.WMI(moniker='//./root/virtualization/v2')
- return self.__conn_v2
-
- @property
- def _conn_cimv2(self):
- if self.__conn_cimv2 is None:
- self.__conn_cimv2 = wmi.WMI(moniker='//./root/cimv2')
- return self.__conn_cimv2
-
- @property
- def _conn_wmi(self):
- if self.__conn_wmi is None:
- self.__conn_wmi = wmi.WMI(moniker='//./root/wmi')
- return self.__conn_wmi
-
- @property
- def _conn_storage(self):
- if self.__conn_storage is None:
- storage_namespace = '//./Root/Microsoft/Windows/Storage'
- self.__conn_storage = wmi.WMI(moniker=storage_namespace)
- return self.__conn_storage
diff --git a/nova/virt/hyperv/basevolumeutils.py b/nova/virt/hyperv/basevolumeutils.py
index 2352c3bef..34b15ea53 100644
--- a/nova/virt/hyperv/basevolumeutils.py
+++ b/nova/virt/hyperv/basevolumeutils.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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
@@ -20,17 +21,18 @@ Helper methods for operations related to the management of volumes,
and storage repositories
"""
+import abc
import sys
+if sys.platform == 'win32':
+ import _winreg
+ import wmi
+
from nova import block_device
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova.virt import driver
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import _winreg
-
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_opt('my_ip', 'nova.netconf')
@@ -38,25 +40,40 @@ CONF.import_opt('my_ip', 'nova.netconf')
class BaseVolumeUtils(object):
+ def __init__(self):
+ if sys.platform == 'win32':
+ self._conn_wmi = wmi.WMI(moniker='//./root/wmi')
+
+ @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, cim_conn):
"""Get iscsi initiator name for this machine."""
computer_system = cim_conn.Win32_ComputerSystem()[0]
hostname = computer_system.name
- keypath = \
- r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery"
+ keypath = ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"
+ "iSCSI\\Discovery")
try:
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keypath, 0,
- _winreg.KEY_ALL_ACCESS)
+ _winreg.KEY_ALL_ACCESS)
temp = _winreg.QueryValueEx(key, 'DefaultInitiatorName')
initiator_name = str(temp[0])
_winreg.CloseKey(key)
except Exception:
LOG.info(_("The ISCSI initiator name can't be found. "
- "Choosing the default one"))
+ "Choosing the default one"))
computer_system = cim_conn.Win32_ComputerSystem()[0]
- initiator_name = "iqn.1991-05.com.microsoft:" + \
- hostname.lower()
+ initiator_name = "iqn.1991-05.com.microsoft:" + hostname.lower()
return {
'ip': CONF.my_ip,
'initiator': initiator_name,
@@ -78,3 +95,33 @@ class BaseVolumeUtils(object):
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):
+ # TODO(pnavarro) replace with regex
+ start_device_id = disk_path.find('"', disk_path.find('DeviceID'))
+ end_device_id = disk_path.find('"', start_device_id + 1)
+ device_id = disk_path[start_device_id + 1:end_device_id]
+ return device_id[device_id.find("\\") + 2:]
+
+ def get_session_id_from_mounted_disk(self, physical_drive_path):
+ drive_number = self._get_drive_number_from_disk_path(
+ physical_drive_path)
+ initiator_sessions = self._conn_wmi.query("SELECT * FROM "
+ "MSiSCSIInitiator_Session"
+ "Class")
+ for initiator_session in initiator_sessions:
+ devices = initiator_session.Devices
+ for device in devices:
+ device_number = str(device.DeviceNumber)
+ if device_number == drive_number:
+ return initiator_session.SessionId
+
+ def get_device_number_for_target(self, target_iqn, target_lun):
+ initiator_session = self._conn_wmi.query("SELECT * FROM "
+ "MSiSCSIInitiator_Session"
+ "Class WHERE TargetName='%s'"
+ % target_iqn)[0]
+ devices = initiator_session.Devices
+ for device in devices:
+ if device.ScsiLun == target_lun:
+ return device.DeviceNumber
diff --git a/nova/virt/hyperv/constants.py b/nova/virt/hyperv/constants.py
index 4be569e88..31323f0f4 100644
--- a/nova/virt/hyperv/constants.py
+++ b/nova/virt/hyperv/constants.py
@@ -35,15 +35,6 @@ HYPERV_POWER_STATE = {
HYPERV_VM_STATE_SUSPENDED: power_state.SUSPENDED
}
-REQ_POWER_STATE = {
- 'Enabled': HYPERV_VM_STATE_ENABLED,
- 'Disabled': HYPERV_VM_STATE_DISABLED,
- 'Reboot': HYPERV_VM_STATE_REBOOT,
- 'Reset': HYPERV_VM_STATE_RESET,
- 'Paused': HYPERV_VM_STATE_PAUSED,
- 'Suspended': HYPERV_VM_STATE_SUSPENDED,
-}
-
WMI_WIN32_PROCESSOR_ARCHITECTURE = {
0: 'x86',
1: 'MIPS',
diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py
index 9316b2598..e8bf8c416 100644
--- a/nova/virt/hyperv/driver.py
+++ b/nova/virt/hyperv/driver.py
@@ -16,49 +16,7 @@
# under the License.
"""
-A connection to Hyper-V .
-Uses Windows Management Instrumentation (WMI) calls to interact with Hyper-V
-Hyper-V WMI usage:
- http://msdn.microsoft.com/en-us/library/cc723875%28v=VS.85%29.aspx
-The Hyper-V object model briefly:
- The physical computer and its hosted virtual machines are each represented
- by the Msvm_ComputerSystem class.
-
- Each virtual machine is associated with a
- Msvm_VirtualSystemGlobalSettingData (vs_gs_data) instance and one or more
- Msvm_VirtualSystemSettingData (vmsetting) instances. For each vmsetting
- there is a series of Msvm_ResourceAllocationSettingData (rasd) objects.
- The rasd objects describe the settings for each device in a VM.
- Together, the vs_gs_data, vmsettings and rasds describe the configuration
- of the virtual machine.
-
- Creating new resources such as disks and nics involves cloning a default
- rasd object and appropriately modifying the clone and calling the
- AddVirtualSystemResources WMI method
- Changing resources such as memory uses the ModifyVirtualSystemResources
- WMI method
-
-Using the Python WMI library:
- Tutorial:
- http://timgolden.me.uk/python/wmi/tutorial.html
- Hyper-V WMI objects can be retrieved simply by using the class name
- of the WMI object and optionally specifying a column to filter the
- result set. More complex filters can be formed using WQL (sql-like)
- queries.
- The parameters and return tuples of WMI method calls can gleaned by
- examining the doc string. For example:
- >>> vs_man_svc.ModifyVirtualSystemResources.__doc__
- ModifyVirtualSystemResources (ComputerSystem, ResourceSettingData[])
- => (Job, ReturnValue)'
- When passing setting data (ResourceSettingData) to the WMI method,
- an XML representation of the data is passed in using GetText_(1).
- Available methods on a service can be determined using method.keys():
- >>> vs_man_svc.methods.keys()
- vmsettings and rasds for a vm can be retrieved using the 'associators'
- method with the appropriate return class.
- Long running WMI commands generally return a Job (an instance of
- Msvm_ConcreteJob) whose state can be polled to determine when it finishes
-
+A Hyper-V Nova Compute driver.
"""
from nova.openstack.common import log as logging
@@ -84,7 +42,7 @@ class HyperVDriver(driver.ComputeDriver):
self._volumeops)
def init_host(self, host):
- self._host = host
+ pass
def list_instances(self):
return self._vmops.list_instances()
@@ -92,7 +50,7 @@ class HyperVDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None):
self._vmops.spawn(context, instance, image_meta, injected_files,
- admin_password, network_info, block_device_info)
+ admin_password, network_info, block_device_info)
def reboot(self, instance, network_info, reboot_type,
block_device_info=None):
@@ -106,16 +64,12 @@ class HyperVDriver(driver.ComputeDriver):
return self._vmops.get_info(instance)
def attach_volume(self, connection_info, instance, mountpoint):
- """Attach volume storage to VM instance."""
return self._volumeops.attach_volume(connection_info,
- instance['name'],
- mountpoint)
+ instance['name'])
def detach_volume(self, connection_info, instance, mountpoint):
- """Detach volume storage to VM instance."""
return self._volumeops.detach_volume(connection_info,
- instance['name'],
- mountpoint)
+ instance['name'])
def get_volume_connector(self, instance):
return self._volumeops.get_volume_connector(instance)
@@ -151,30 +105,38 @@ class HyperVDriver(driver.ComputeDriver):
self._vmops.power_on(instance)
def live_migration(self, context, instance_ref, dest, post_method,
- recover_method, block_migration=False, migrate_data=None):
+ recover_method, block_migration=False,
+ migrate_data=None):
self._livemigrationops.live_migration(context, instance_ref, dest,
- post_method, recover_method, block_migration, migrate_data)
+ post_method, recover_method,
+ block_migration, migrate_data)
def compare_cpu(self, cpu_info):
return self._livemigrationops.compare_cpu(cpu_info)
def pre_live_migration(self, context, instance, block_device_info,
- network_info, migrate_data=None):
+ network_info, migrate_data=None):
self._livemigrationops.pre_live_migration(context, instance,
- block_device_info, network_info)
+ block_device_info,
+ network_info)
def post_live_migration_at_destination(self, ctxt, instance_ref,
- network_info, block_migration, block_device_info=None):
+ network_info,
+ block_migr=False,
+ block_device_info=None):
self._livemigrationops.post_live_migration_at_destination(ctxt,
- instance_ref, network_info, block_migration)
-
- def check_can_live_migrate_destination(self, ctxt, instance,
- src_compute_info, dst_compute_info,
- block_migration, disk_over_commit):
+ instance_ref,
+ network_info,
+ block_migr)
+
+ def check_can_live_migrate_destination(self, ctxt, instance_ref,
+ src_compute_info, dst_compute_info,
+ block_migration=False,
+ disk_over_commit=False):
pass
def check_can_live_migrate_destination_cleanup(self, ctxt,
- dest_check_data):
+ dest_check_data):
pass
def check_can_live_migrate_source(self, ctxt, instance, dest_check_data):
@@ -188,25 +150,21 @@ class HyperVDriver(driver.ComputeDriver):
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
LOG.debug(_("ensure_filtering_rules_for_instance called"),
- instance=instance_ref)
+ instance=instance_ref)
def unfilter_instance(self, instance, network_info):
- """Stop filtering instance."""
LOG.debug(_("unfilter_instance called"), instance=instance)
def confirm_migration(self, migration, instance, network_info):
- """Confirms a resize, destroying the source VM."""
LOG.debug(_("confirm_migration called"), instance=instance)
def finish_revert_migration(self, instance, network_info,
block_device_info=None):
- """Finish reverting a resize, powering back on the instance."""
LOG.debug(_("finish_revert_migration called"), instance=instance)
def finish_migration(self, context, migration, instance, disk_info,
- network_info, image_meta, resize_instance=False,
- block_device_info=None):
- """Completes a resize, turning on the migrated instance."""
+ network_info, image_meta, resize_instance=False,
+ block_device_info=None):
LOG.debug(_("finish_migration called"), instance=instance)
def get_console_output(self, instance):
diff --git a/nova/virt/hyperv/hostops.py b/nova/virt/hyperv/hostops.py
index 5cbe46c1c..5a22b60de 100644
--- a/nova/virt/hyperv/hostops.py
+++ b/nova/virt/hyperv/hostops.py
@@ -18,25 +18,23 @@
"""
Management class for host operations.
"""
-import ctypes
-import multiprocessing
import os
import platform
-from nova.openstack.common import cfg
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
-from nova.virt.hyperv import baseops
from nova.virt.hyperv import constants
+from nova.virt.hyperv import hostutils
+from nova.virt.hyperv import pathutils
-CONF = cfg.CONF
LOG = logging.getLogger(__name__)
-class HostOps(baseops.BaseOps):
+class HostOps(object):
def __init__(self):
- super(HostOps, self).__init__()
self._stats = None
+ self._hostutils = hostutils.HostUtils()
+ self._pathutils = pathutils.PathUtils()
def _get_cpu_info(self):
"""Get the CPU information.
@@ -44,94 +42,51 @@ class HostOps(baseops.BaseOps):
of the central processor in the hypervisor.
"""
cpu_info = dict()
- processor = self._conn_cimv2.query(
- "SELECT * FROM Win32_Processor WHERE ProcessorType = 3")
- cpu_info['arch'] = constants.WMI_WIN32_PROCESSOR_ARCHITECTURE\
- .get(processor[0].Architecture, 'Unknown')
- cpu_info['model'] = processor[0].Name
- cpu_info['vendor'] = processor[0].Manufacturer
+ processors = self._hostutils.get_cpus_info()
+
+ w32_arch_dict = constants.WMI_WIN32_PROCESSOR_ARCHITECTURE
+ cpu_info['arch'] = w32_arch_dict.get(processors[0]['Architecture'],
+ 'Unknown')
+ cpu_info['model'] = processors[0]['Name']
+ cpu_info['vendor'] = processors[0]['Manufacturer']
topology = dict()
- topology['sockets'] = len(processor)
- topology['cores'] = processor[0].NumberOfCores
- topology['threads'] = processor[0].NumberOfLogicalProcessors\
- / processor[0].NumberOfCores
+ topology['sockets'] = len(processors)
+ topology['cores'] = processors[0]['NumberOfCores']
+ topology['threads'] = (processors[0]['NumberOfLogicalProcessors'] /
+ processors[0]['NumberOfCores'])
cpu_info['topology'] = topology
features = list()
for fkey, fname in constants.PROCESSOR_FEATURE.items():
- if ctypes.windll.kernel32.IsProcessorFeaturePresent(fkey):
+ if self._hostutils.is_cpu_feature_present(fkey):
features.append(fname)
cpu_info['features'] = features
- return jsonutils.dumps(cpu_info)
+ return cpu_info
- def _get_vcpu_total(self):
- """Get vcpu number of physical computer.
- :returns: the number of cpu core.
- """
- # On certain platforms, this will raise a NotImplementedError.
- try:
- return multiprocessing.cpu_count()
- except NotImplementedError:
- LOG.warn(_("Cannot get the number of cpu, because this "
- "function is not implemented for this platform. "
- "This error can be safely ignored for now."))
- return 0
-
- def _get_memory_mb_total(self):
- """Get the total memory size(MB) of physical computer.
- :returns: the total amount of memory(MB).
- """
- total_kb = self._conn_cimv2.query(
- "SELECT TotalVisibleMemorySize FROM win32_operatingsystem")[0]\
- .TotalVisibleMemorySize
- total_mb = long(total_kb) / 1024
- return total_mb
+ def _get_memory_info(self):
+ (total_mem_kb, free_mem_kb) = self._hostutils.get_memory_info()
+ total_mem_mb = total_mem_kb / 1024
+ free_mem_mb = free_mem_kb / 1024
+ return (total_mem_mb, free_mem_mb, total_mem_mb - free_mem_mb)
def _get_local_hdd_info_gb(self):
- """Get the total and used size of the volume containing
- CONF.instances_path expressed in GB.
- :returns:
- A tuple with the total and used space in GB.
- """
- normalized_path = os.path.normpath(CONF.instances_path)
- drive, path = os.path.splitdrive(normalized_path)
- hdd_info = self._conn_cimv2.query(
- ("SELECT FreeSpace,Size FROM win32_logicaldisk WHERE DeviceID='%s'"
- ) % drive)[0]
- total_gb = long(hdd_info.Size) / (1024 ** 3)
- free_gb = long(hdd_info.FreeSpace) / (1024 ** 3)
- used_gb = total_gb - free_gb
- return total_gb, used_gb
+ (drive, _) = os.path.splitdrive(self._pathutils.get_instances_path())
+ (size, free_space) = self._hostutils.get_volume_info(drive)
- def _get_vcpu_used(self):
- """Get vcpu usage number of physical computer.
- :returns: The total number of vcpu that currently used.
- """
- #TODO(jordanrinke) figure out a way to count assigned VCPUs
- total_vcpu = 0
- return total_vcpu
-
- def _get_memory_mb_used(self):
- """Get the free memory size(MB) of physical computer.
- :returns: the total usage of memory(MB).
- """
- total_kb = self._conn_cimv2.query(
- "SELECT FreePhysicalMemory FROM win32_operatingsystem")[0]\
- .FreePhysicalMemory
- total_mb = long(total_kb) / 1024
-
- return total_mb
+ total_gb = size / (1024 ** 3)
+ free_gb = free_space / (1024 ** 3)
+ used_gb = total_gb - free_gb
+ return (total_gb, free_gb, used_gb)
def _get_hypervisor_version(self):
"""Get hypervisor version.
:returns: hypervisor version (ex. 12003)
"""
- version = self._conn_cimv2.Win32_OperatingSystem()[0]\
- .Version.replace('.', '')
- LOG.info(_('Windows version: %s ') % version)
+ version = self._hostutils.get_windows_version().replace('.', '')
+ LOG.debug(_('Windows version: %s ') % version)
return version
def get_available_resource(self):
@@ -143,36 +98,53 @@ class HostOps(baseops.BaseOps):
:returns: dictionary describing resources
"""
- LOG.info(_('get_available_resource called'))
-
- local_gb, used_gb = self._get_local_hdd_info_gb()
- dic = {'vcpus': self._get_vcpu_total(),
- 'memory_mb': self._get_memory_mb_total(),
- 'local_gb': local_gb,
- 'vcpus_used': self._get_vcpu_used(),
- 'memory_mb_used': self._get_memory_mb_used(),
- 'local_gb_used': used_gb,
+ LOG.debug(_('get_available_resource called'))
+
+ (total_mem_mb,
+ free_mem_mb,
+ used_mem_mb) = self._get_memory_info()
+
+ (total_hdd_gb,
+ free_hdd_gb,
+ used_hdd_gb) = self._get_local_hdd_info_gb()
+
+ cpu_info = self._get_cpu_info()
+ cpu_topology = cpu_info['topology']
+ vcpus = (cpu_topology['sockets'] *
+ cpu_topology['cores'] *
+ cpu_topology['threads'])
+
+ dic = {'vcpus': vcpus,
+ 'memory_mb': total_mem_mb,
+ 'memory_mb_used': used_mem_mb,
+ 'local_gb': total_hdd_gb,
+ 'local_gb_used': used_hdd_gb,
'hypervisor_type': "hyperv",
'hypervisor_version': self._get_hypervisor_version(),
'hypervisor_hostname': platform.node(),
- 'cpu_info': self._get_cpu_info()}
+ 'vcpus_used': 0,
+ 'cpu_info': jsonutils.dumps(cpu_info)}
return dic
def _update_stats(self):
LOG.debug(_("Updating host stats"))
+ (total_mem_mb, free_mem_mb, used_mem_mb) = self._get_memory_info()
+ (total_hdd_gb,
+ free_hdd_gb,
+ used_hdd_gb) = self._get_local_hdd_info_gb()
+
data = {}
- data["disk_total"], data["disk_used"] = self._get_local_hdd_info_gb()
- data["disk_available"] = data["disk_total"] - data["disk_used"]
- data["host_memory_total"] = self._get_memory_mb_total()
- data["host_memory_overhead"] = self._get_memory_mb_used()
- data["host_memory_free"] = \
- data["host_memory_total"] - data["host_memory_overhead"]
- data["host_memory_free_computed"] = data["host_memory_free"]
- data["supported_instances"] = \
- [('i686', 'hyperv', 'hvm'),
- ('x86_64', 'hyperv', 'hvm')]
+ data["disk_total"] = total_hdd_gb
+ data["disk_used"] = used_hdd_gb
+ data["disk_available"] = free_hdd_gb
+ data["host_memory_total"] = total_mem_mb
+ data["host_memory_overhead"] = used_mem_mb
+ data["host_memory_free"] = free_mem_mb
+ data["host_memory_free_computed"] = free_mem_mb
+ data["supported_instances"] = [('i686', 'hyperv', 'hvm'),
+ ('x86_64', 'hyperv', 'hvm')]
data["hypervisor_hostname"] = platform.node()
self._stats = data
diff --git a/nova/virt/hyperv/hostutils.py b/nova/virt/hyperv/hostutils.py
new file mode 100644
index 000000000..71f3bc5b2
--- /dev/null
+++ b/nova/virt/hyperv/hostutils.py
@@ -0,0 +1,74 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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 sys
+
+if sys.platform == 'win32':
+ import wmi
+
+from nova.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+
+class HostUtils(object):
+ def __init__(self):
+ if sys.platform == 'win32':
+ self._conn_cimv2 = wmi.WMI(moniker='//./root/cimv2')
+
+ 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 get_windows_version(self):
+ return self._conn_cimv2.Win32_OperatingSystem()[0].Version
diff --git a/nova/virt/hyperv/ioutils.py b/nova/virt/hyperv/ioutils.py
deleted file mode 100644
index d927e317f..000000000
--- a/nova/virt/hyperv/ioutils.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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 to ease the task of creating stubs of built in IO functions.
-"""
-
-import __builtin__
-
-
-def open(name, mode):
- return __builtin__.open(name, mode)
diff --git a/nova/virt/hyperv/livemigrationops.py b/nova/virt/hyperv/livemigrationops.py
index 232cbd660..8ee3005f1 100644
--- a/nova/virt/hyperv/livemigrationops.py
+++ b/nova/virt/hyperv/livemigrationops.py
@@ -19,144 +19,66 @@
Management class for live migration VM operations.
"""
import os
-import sys
-from nova import exception
from nova.openstack.common import cfg
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
-from nova.virt.hyperv import baseops
-from nova.virt.hyperv import constants
+from nova.virt.hyperv import livemigrationutils
+from nova.virt.hyperv import pathutils
from nova.virt.hyperv import vmutils
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
+from nova.virt import images
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_opt('use_cow_images', 'nova.virt.driver')
-class LiveMigrationOps(baseops.BaseOps):
+class LiveMigrationOps(object):
def __init__(self, volumeops):
- super(LiveMigrationOps, self).__init__()
+ self._pathutils = pathutils.PathUtils()
self._vmutils = vmutils.VMUtils()
+ self._livemigrutils = livemigrationutils.LiveMigrationUtils()
self._volumeops = volumeops
- def _check_live_migration_config(self):
- try:
- self._conn_v2
- except Exception:
- raise vmutils.HyperVException(
- _('Live migration is not supported " \
- "by this version of Hyper-V'))
-
- migration_svc = self._conn_v2.Msvm_VirtualSystemMigrationService()[0]
- vsmssd = migration_svc.associators(
- wmi_association_class='Msvm_ElementSettingData',
- wmi_result_class='Msvm_VirtualSystemMigrationServiceSettingData')[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 live_migration(self, context, instance_ref, dest, post_method,
- recover_method, block_migration=False, migrate_data=None):
+ recover_method, block_migration=False,
+ migrate_data=None):
LOG.debug(_("live_migration called"), instance=instance_ref)
instance_name = instance_ref["name"]
try:
- self._check_live_migration_config()
-
- vm_name = self._vmutils.lookup(self._conn, instance_name)
- if vm_name is None:
- raise exception.InstanceNotFound(instance=instance_name)
- vm = self._conn_v2.Msvm_ComputerSystem(
- ElementName=instance_name)[0]
- 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":
- #sasd.PoolId = ""
- new_resource_setting_data.append(sasd.GetText_(1))
-
- LOG.debug(_("Getting live migration networks for remote "
- "host: %s"), dest)
- _conn_v2_remote = wmi.WMI(
- moniker='//' + dest + '/root/virtualization/v2')
- migration_svc_remote = \
- _conn_v2_remote.Msvm_VirtualSystemMigrationService()[0]
- remote_ip_address_list = \
- migration_svc_remote.MigrationServiceListenerIPAddressList
-
- # VirtualSystemAndStorage
- vsmsd = self._conn_v2.query("select * from "
- "Msvm_VirtualSystemMigrationSettingData "
- "where MigrationType = 32771")[0]
- vsmsd.DestinationIPAddressList = remote_ip_address_list
- migration_setting_data = vsmsd.GetText_(1)
-
- migration_svc =\
- self._conn_v2.Msvm_VirtualSystemMigrationService()[0]
-
- LOG.debug(_("Starting live migration for instance: %s"),
- instance_name)
- (job_path, ret_val) = migration_svc.MigrateVirtualSystemToHost(
- ComputerSystem=vm.path_(),
- DestinationHost=dest,
- MigrationSettingData=migration_setting_data,
- NewResourceSettingData=new_resource_setting_data)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _('Failed to live migrate VM %s') % instance_name)
+ self._livemigrutils.live_migrate_vm(instance_name, dest)
except Exception:
with excutils.save_and_reraise_exception():
LOG.debug(_("Calling live migration recover_method "
- "for instance: %s"), instance_name)
+ "for instance: %s"), instance_name)
recover_method(context, instance_ref, dest, block_migration)
LOG.debug(_("Calling live migration post_method for instance: %s"),
- instance_name)
+ instance_name)
post_method(context, instance_ref, dest, block_migration)
def pre_live_migration(self, context, instance, block_device_info,
- network_info):
+ network_info):
LOG.debug(_("pre_live_migration called"), instance=instance)
- self._check_live_migration_config()
+ self._livemigrutils.check_live_migration_config()
if CONF.use_cow_images:
ebs_root = self._volumeops.volume_in_mapping(
self._volumeops.get_default_root_device(),
block_device_info)
if not ebs_root:
- base_vhd_path = self._vmutils.get_base_vhd_path(
+ base_vhd_path = self._pathutils.get_base_vhd_path(
instance["image_ref"])
if not os.path.exists(base_vhd_path):
- self._vmutils.fetch_image(base_vhd_path, context,
- instance["image_ref"],
- instance["user_id"],
- instance["project_id"])
+ images.fetch(context, instance["image_ref"], base_vhd_path,
+ instance["user_id"], instance["project_id"])
def post_live_migration_at_destination(self, ctxt, instance_ref,
- network_info, block_migration):
+ network_info, block_migration):
LOG.debug(_("post_live_migration_at_destination called"),
- instance=instance_ref)
+ instance=instance_ref)
def compare_cpu(self, cpu_info):
LOG.debug(_("compare_cpu called %s"), cpu_info)
diff --git a/nova/virt/hyperv/livemigrationutils.py b/nova/virt/hyperv/livemigrationutils.py
new file mode 100644
index 000000000..6af4f0fa5
--- /dev/null
+++ b/nova/virt/hyperv/livemigrationutils.py
@@ -0,0 +1,115 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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 nova.openstack.common import log as logging
+from nova.virt.hyperv import vmutils
+
+LOG = logging.getLogger(__name__)
+
+
+class LiveMigrationUtils(object):
+
+ def __init__(self):
+ self._vmutils = vmutils.VMUtils()
+
+ 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(ex)
+ 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 vmutils.HyperVException(_('VM not found: %s') % vm_name)
+ elif n > 1:
+ raise vmutils.HyperVException(_('Duplicate VM name found: %s')
+ % vm_name)
+ return vms[0]
+
+ def live_migrate_vm(self, vm_name, dest_host):
+ self.check_live_migration_config()
+
+ # We need a v2 namespace VM object
+ conn_v2_local = self._get_conn_v2()
+
+ vm = self._get_vm(conn_v2_local, vm_name)
+ 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"):
+ #sasd.PoolId = ""
+ new_resource_setting_data.append(sasd.GetText_(1))
+
+ LOG.debug(_("Getting live migration networks for remote host: %s"),
+ dest_host)
+ conn_v2_remote = self._get_conn_v2(dest_host)
+ migr_svc_rmt = conn_v2_remote.Msvm_VirtualSystemMigrationService()[0]
+ rmt_ip_addr_list = migr_svc_rmt.MigrationServiceListenerIPAddressList
+
+ # VirtualSystemAndStorage
+ vsmsd = conn_v2_local.query("select * from "
+ "Msvm_VirtualSystemMigrationSettingData "
+ "where MigrationType = 32771")[0]
+ vsmsd.DestinationIPAddressList = rmt_ip_addr_list
+ migration_setting_data = vsmsd.GetText_(1)
+
+ migr_svc = conn_v2_local.Msvm_VirtualSystemMigrationService()[0]
+
+ LOG.debug(_("Starting live migration for VM: %s"), vm_name)
+ (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)
diff --git a/nova/virt/hyperv/networkutils.py b/nova/virt/hyperv/networkutils.py
new file mode 100644
index 000000000..4e1f68685
--- /dev/null
+++ b/nova/virt/hyperv/networkutils.py
@@ -0,0 +1,62 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# 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.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") % locals())
+ return new_port
diff --git a/nova/virt/hyperv/pathutils.py b/nova/virt/hyperv/pathutils.py
new file mode 100644
index 000000000..7bc2e7ac2
--- /dev/null
+++ b/nova/virt/hyperv/pathutils.py
@@ -0,0 +1,67 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# 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 os
+import shutil
+
+from nova.openstack.common import cfg
+from nova.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+CONF = cfg.CONF
+CONF.import_opt('instances_path', 'nova.compute.manager')
+
+
+class PathUtils(object):
+ def open(self, path, mode):
+ """Wrapper on __builin__.open used to simplify unit testing."""
+ import __builtin__
+ return __builtin__.open(path, mode)
+
+ def get_instances_path(self):
+ return os.path.normpath(CONF.instances_path)
+
+ def get_instance_path(self, instance_name):
+ instance_path = os.path.join(self.get_instances_path(), instance_name)
+ if not os.path.exists(instance_path):
+ LOG.debug(_('Creating folder %s '), instance_path)
+ os.makedirs(instance_path)
+ return instance_path
+
+ def get_vhd_path(self, instance_name):
+ instance_path = self.get_instance_path(instance_name)
+ return os.path.join(instance_path, instance_name + ".vhd")
+
+ def get_base_vhd_path(self, image_name):
+ base_dir = os.path.join(self.get_instances_path(), '_base')
+ if not os.path.exists(base_dir):
+ os.makedirs(base_dir)
+ return os.path.join(base_dir, image_name + ".vhd")
+
+ def make_export_path(self, instance_name):
+ export_folder = os.path.join(self.get_instances_path(), "export",
+ instance_name)
+ if os.path.isdir(export_folder):
+ LOG.debug(_('Removing existing folder %s '), export_folder)
+ shutil.rmtree(export_folder)
+ LOG.debug(_('Creating folder %s '), export_folder)
+ os.makedirs(export_folder)
+ return export_folder
+
+ def vhd_exists(self, path):
+ return os.path.exists(path)
diff --git a/nova/virt/hyperv/snapshotops.py b/nova/virt/hyperv/snapshotops.py
index cdc6e45a4..c43f59b70 100644
--- a/nova/virt/hyperv/snapshotops.py
+++ b/nova/virt/hyperv/snapshotops.py
@@ -20,173 +20,97 @@ Management class for VM snapshot operations.
"""
import os
import shutil
-import sys
from nova.compute import task_states
-from nova import exception
from nova.image import glance
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
-from nova.virt.hyperv import baseops
-from nova.virt.hyperv import constants
-from nova.virt.hyperv import ioutils
+from nova.virt.hyperv import pathutils
+from nova.virt.hyperv import vhdutils
from nova.virt.hyperv import vmutils
-from xml.etree import ElementTree
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
-class SnapshotOps(baseops.BaseOps):
+class SnapshotOps(object):
def __init__(self):
- super(SnapshotOps, self).__init__()
+ self._pathutils = pathutils.PathUtils()
self._vmutils = vmutils.VMUtils()
+ self._vhdutils = vhdutils.VHDUtils()
+
+ def _save_glance_image(self, context, name, image_vhd_path):
+ (glance_image_service,
+ image_id) = glance.get_remote_image_service(context, name)
+ image_metadata = {"is_public": False,
+ "disk_format": "vhd",
+ "container_format": "bare",
+ "properties": {}}
+ with self._pathutils.open(image_vhd_path, 'rb') as f:
+ glance_image_service.update(context, image_id, image_metadata, f)
def snapshot(self, context, instance, name, update_task_state):
"""Create snapshot from a running VM instance."""
instance_name = instance["name"]
- vm = self._vmutils.lookup(self._conn, instance_name)
- if vm is None:
- raise exception.InstanceNotFound(instance=instance_name)
- vm = self._conn.Msvm_ComputerSystem(ElementName=instance_name)[0]
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
LOG.debug(_("Creating snapshot for instance %s"), instance_name)
- (job_path, ret_val, snap_setting_data) = \
- vs_man_svc.CreateVirtualSystemSnapshot(vm.path_())
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- if success:
- job_wmi_path = job_path.replace('\\', '/')
- job = wmi.WMI(moniker=job_wmi_path)
- snap_setting_data = job.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')[0]
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _('Failed to create snapshot for VM %s') %
- instance_name)
- else:
- update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)
+ snapshot_path = self._vmutils.take_vm_snapshot(instance_name)
+ update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)
export_folder = None
- f = None
try:
- src_vhd_path = os.path.join(CONF.instances_path, instance_name,
- instance_name + ".vhd")
-
- image_man_svc = self._conn.Msvm_ImageManagementService()[0]
+ src_vhd_path = self._pathutils.get_vhd_path(instance_name)
LOG.debug(_("Getting info for VHD %s"), src_vhd_path)
- (src_vhd_info, job_path, ret_val) = \
- image_man_svc.GetVirtualHardDiskInfo(src_vhd_path)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _("Failed to get info for disk %s") %
- (src_vhd_path))
+ src_base_disk_path = self._vhdutils.get_vhd_parent_path(
+ src_vhd_path)
- src_base_disk_path = None
- et = ElementTree.fromstring(src_vhd_info)
- for item in et.findall("PROPERTY"):
- if item.attrib["NAME"] == "ParentPath":
- src_base_disk_path = item.find("VALUE").text
- break
-
- export_folder = self._vmutils.make_export_path(instance_name)
+ export_folder = self._pathutils.make_export_path(instance_name)
dest_vhd_path = os.path.join(export_folder, os.path.basename(
src_vhd_path))
LOG.debug(_('Copying VHD %(src_vhd_path)s to %(dest_vhd_path)s'),
- locals())
+ locals())
shutil.copyfile(src_vhd_path, dest_vhd_path)
image_vhd_path = None
if not src_base_disk_path:
image_vhd_path = dest_vhd_path
else:
- dest_base_disk_path = os.path.join(export_folder,
- os.path.basename(src_base_disk_path))
+ basename = os.path.basename(src_base_disk_path)
+ dest_base_disk_path = os.path.join(export_folder, basename)
LOG.debug(_('Copying base disk %(src_vhd_path)s to '
- '%(dest_base_disk_path)s'), locals())
+ '%(dest_base_disk_path)s'), locals())
shutil.copyfile(src_base_disk_path, dest_base_disk_path)
LOG.debug(_("Reconnecting copied base VHD "
- "%(dest_base_disk_path)s and diff VHD %(dest_vhd_path)s"),
- locals())
- (job_path, ret_val) = \
- image_man_svc.ReconnectParentVirtualHardDisk(
- ChildPath=dest_vhd_path,
- ParentPath=dest_base_disk_path,
- Force=True)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _("Failed to reconnect base disk "
- "%(dest_base_disk_path)s and diff disk "
- "%(dest_vhd_path)s") %
- locals())
+ "%(dest_base_disk_path)s and diff "
+ "VHD %(dest_vhd_path)s"), locals())
+ self._vhdutils.reconnect_parent_vhd(dest_vhd_path,
+ dest_base_disk_path)
LOG.debug(_("Merging base disk %(dest_base_disk_path)s and "
- "diff disk %(dest_vhd_path)s"),
- locals())
- (job_path, ret_val) = image_man_svc.MergeVirtualHardDisk(
- SourcePath=dest_vhd_path,
- DestinationPath=dest_base_disk_path)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _("Failed to merge base disk %(dest_base_disk_path)s "
- "and diff disk %(dest_vhd_path)s") %
- locals())
+ "diff disk %(dest_vhd_path)s"), locals())
+ self._vhdutils.merge_vhd(dest_vhd_path, dest_base_disk_path)
image_vhd_path = dest_base_disk_path
- (glance_image_service, image_id) = \
- glance.get_remote_image_service(context, name)
- image_metadata = {"is_public": False,
- "disk_format": "vhd",
- "container_format": "bare",
- "properties": {}}
- f = ioutils.open(image_vhd_path, 'rb')
- LOG.debug(
- _("Updating Glance image %(image_id)s with content from "
- "merged disk %(image_vhd_path)s"),
- locals())
+ LOG.debug(_("Updating Glance image %(image_id)s with content from "
+ "merged disk %(image_vhd_path)s"), locals())
update_task_state(task_state=task_states.IMAGE_UPLOADING,
expected_state=task_states.IMAGE_PENDING_UPLOAD)
- glance_image_service.update(context, image_id, image_metadata, f)
+ self._save_glance_image(context, name, image_vhd_path)
LOG.debug(_("Snapshot image %(image_id)s updated for VM "
- "%(instance_name)s"), locals())
+ "%(instance_name)s"), locals())
finally:
- LOG.debug(_("Removing snapshot %s"), name)
- (job_path, ret_val) = vs_man_svc.RemoveVirtualSystemSnapshot(
- snap_setting_data.path_())
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job_path)
- else:
- success = (ret_val == 0)
- if not success:
- raise vmutils.HyperVException(
- _('Failed to remove snapshot for VM %s') %
- instance_name)
- if f:
- f.close()
+ try:
+ LOG.debug(_("Removing snapshot %s"), name)
+ self._vmutils.remove_vm_snapshot(snapshot_path)
+ except Exception as ex:
+ LOG.exception(ex)
+ LOG.warning(_('Failed to remove snapshot for VM %s')
+ % instance_name)
if export_folder:
LOG.debug(_('Removing folder %s '), export_folder)
shutil.rmtree(export_folder)
diff --git a/nova/virt/hyperv/vhdutils.py b/nova/virt/hyperv/vhdutils.py
new file mode 100644
index 000000000..21c4b4a6d
--- /dev/null
+++ b/nova/virt/hyperv/vhdutils.py
@@ -0,0 +1,72 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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 nova.virt.hyperv import vmutils
+from xml.etree import ElementTree
+
+
+class VHDUtils(object):
+
+ def __init__(self):
+ self._vmutils = vmutils.VMUtils()
+ if sys.platform == 'win32':
+ self._conn = wmi.WMI(moniker='//./root/virtualization')
+
+ 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_vhd_parent_path(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)
+
+ base_disk_path = None
+ et = ElementTree.fromstring(vhd_info)
+ for item in et.findall("PROPERTY"):
+ if item.attrib["NAME"] == "ParentPath":
+ base_disk_path = item.find("VALUE").text
+ break
+ return base_disk_path
diff --git a/nova/virt/hyperv/vif.py b/nova/virt/hyperv/vif.py
index e01006eaa..cfe7c6a4c 100644
--- a/nova/virt/hyperv/vif.py
+++ b/nova/virt/hyperv/vif.py
@@ -15,17 +15,12 @@
# 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 abc
-import sys
-import uuid
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
+import abc
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
+from nova.virt.hyperv import networkutils
from nova.virt.hyperv import vmutils
@@ -70,65 +65,17 @@ class HyperVNovaNetworkVIFDriver(HyperVBaseVIFDriver):
def __init__(self):
self._vmutils = vmutils.VMUtils()
- self._conn = wmi.WMI(moniker='//./root/virtualization')
-
- def _find_external_network(self):
- """Find the vswitch that is connected to the physical nic.
- Assumes only one physical nic on the host
- """
- #If there are no physical nics connected to networks, return.
- LOG.debug(_("Attempting to bind NIC to %s ")
- % CONF.vswitch_name)
- if CONF.vswitch_name:
- LOG.debug(_("Attempting to bind NIC to %s ")
- % CONF.vswitch_name)
- bound = self._conn.Msvm_VirtualSwitch(
- ElementName=CONF.vswitch_name)
- else:
- LOG.debug(_("No vSwitch specified, attaching to default"))
- self._conn.Msvm_ExternalEthernetPort(IsBound='TRUE')
- if len(bound) == 0:
- return None
- if CONF.vswitch_name:
- return self._conn.Msvm_VirtualSwitch(
- ElementName=CONF.vswitch_name)[0]\
- .associators(wmi_result_class='Msvm_SwitchPort')[0]\
- .associators(wmi_result_class='Msvm_VirtualSwitch')[0]
- else:
- return self._conn.Msvm_ExternalEthernetPort(IsBound='TRUE')\
- .associators(wmi_result_class='Msvm_SwitchPort')[0]\
- .associators(wmi_result_class='Msvm_VirtualSwitch')[0]
+ self._netutils = networkutils.NetworkUtils()
def plug(self, instance, vif):
- extswitch = self._find_external_network()
- if extswitch is None:
- raise vmutils.HyperVException(_('Cannot find vSwitch'))
+ vswitch_path = self._netutils.get_external_vswitch(
+ CONF.vswitch_name)
vm_name = instance['name']
-
- nic_data = self._conn.Msvm_SyntheticEthernetPortSettingData(
- ElementName=vif['id'])[0]
-
- 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=vm_name,
- ScopeOfResidence="",
- VirtualSwitch=extswitch.path_())
- if ret_val != 0:
- LOG.error(_('Failed creating a port on the external vswitch'))
- raise vmutils.HyperVException(_('Failed creating port for %s') %
- vm_name)
- ext_path = extswitch.path_()
- LOG.debug(_("Created switch port %(vm_name)s on switch %(ext_path)s")
- % locals())
-
- vms = self._conn.MSVM_ComputerSystem(ElementName=vm_name)
- vm = vms[0]
-
- nic_data.Connection = [new_port]
- self._vmutils.modify_virt_resource(self._conn, nic_data, vm)
+ LOG.debug(_('Creating vswitch port for instance: %s') % vm_name)
+ vswitch_port = self._netutils.create_vswitch_port(vswitch_path,
+ vm_name)
+ self._vmutils.set_nic_connection(vm_name, vif['id'], vswitch_port)
def unplug(self, instance, vif):
#TODO(alepilotti) Not implemented
diff --git a/nova/virt/hyperv/vmops.py b/nova/virt/hyperv/vmops.py
index 3d8958266..8ce1d508b 100644
--- a/nova/virt/hyperv/vmops.py
+++ b/nova/virt/hyperv/vmops.py
@@ -19,7 +19,6 @@
Management class for basic VM operations.
"""
import os
-import uuid
from nova.api.metadata import base as instance_metadata
from nova import exception
@@ -29,29 +28,31 @@ from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
from nova import utils
from nova.virt import configdrive
-from nova.virt.hyperv import baseops
from nova.virt.hyperv import constants
+from nova.virt.hyperv import pathutils
+from nova.virt.hyperv import vhdutils
from nova.virt.hyperv import vmutils
+from nova.virt import images
LOG = logging.getLogger(__name__)
hyperv_opts = [
cfg.BoolOpt('limit_cpu_features',
- default=False,
- help='Required for live migration among '
- 'hosts with different CPU features'),
+ default=False,
+ help='Required for live migration among '
+ 'hosts with different CPU features'),
cfg.BoolOpt('config_drive_inject_password',
- default=False,
- help='Sets the admin password in the config drive image'),
+ default=False,
+ help='Sets the admin password in the config drive image'),
cfg.StrOpt('qemu_img_cmd',
default="qemu-img.exe",
help='qemu-img is used to convert between '
'different image types'),
cfg.BoolOpt('config_drive_cdrom',
- default=False,
- help='Attaches the Config Drive image as a cdrom drive '
- 'instead of a disk drive')
- ]
+ default=False,
+ help='Attaches the Config Drive image as a cdrom drive '
+ 'instead of a disk drive')
+]
CONF = cfg.CONF
CONF.register_opts(hyperv_opts)
@@ -59,19 +60,20 @@ CONF.import_opt('use_cow_images', 'nova.virt.driver')
CONF.import_opt('network_api_class', 'nova.network')
-class VMOps(baseops.BaseOps):
+class VMOps(object):
_vif_driver_class_map = {
'nova.network.quantumv2.api.API':
- 'nova.virt.hyperv.vif.HyperVQuantumVIFDriver',
+ 'nova.virt.hyperv.vif.HyperVQuantumVIFDriver',
'nova.network.api.API':
- 'nova.virt.hyperv.vif.HyperVNovaNetworkVIFDriver',
+ 'nova.virt.hyperv.vif.HyperVNovaNetworkVIFDriver',
}
def __init__(self, volumeops):
- super(VMOps, self).__init__()
-
self._vmutils = vmutils.VMUtils()
+ self._vhdutils = vhdutils.VHDUtils()
+ self._pathutils = pathutils.PathUtils()
self._volumeops = volumeops
+ self._vif_driver = None
self._load_vif_driver_class()
def _load_vif_driver_class(self):
@@ -84,124 +86,106 @@ class VMOps(baseops.BaseOps):
CONF.network_api_class)
def list_instances(self):
- """Return the names of all the instances known to Hyper-V."""
- vms = [v.ElementName
- for v in self._conn.Msvm_ComputerSystem(['ElementName'],
- Caption="Virtual Machine")]
- return vms
+ return self._vmutils.list_instances()
def get_info(self, instance):
"""Get information about the VM."""
LOG.debug(_("get_info called for instance"), instance=instance)
- return self._get_info(instance['name'])
-
- def _get_info(self, instance_name):
- vm = self._vmutils.lookup(self._conn, instance_name)
- if vm is None:
- raise exception.InstanceNotFound(instance=instance_name)
- vm = self._conn.Msvm_ComputerSystem(
- ElementName=instance_name)[0]
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- vmsettings = vm.associators(
- wmi_association_class='Msvm_SettingsDefineState',
- wmi_result_class='Msvm_VirtualSystemSettingData')
- settings_paths = [v.path_() for v in vmsettings]
- #See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
- summary_info = vs_man_svc.GetSummaryInformation(
- [constants.VM_SUMMARY_NUM_PROCS,
- constants.VM_SUMMARY_ENABLED_STATE,
- constants.VM_SUMMARY_MEMORY_USAGE,
- constants.VM_SUMMARY_UPTIME],
- settings_paths)[1]
- info = summary_info[0]
-
- LOG.debug(_("hyperv vm state: %s"), info.EnabledState)
- state = constants.HYPERV_POWER_STATE[info.EnabledState]
- memusage = str(info.MemoryUsage)
- numprocs = str(info.NumberOfProcessors)
- uptime = str(info.UpTime)
-
- LOG.debug(_("Got Info for vm %(instance_name)s: state=%(state)d,"
- " mem=%(memusage)s, num_cpu=%(numprocs)s,"
- " uptime=%(uptime)s"), locals())
+ instance_name = instance['name']
+ if not self._vmutils.vm_exists(instance_name):
+ raise exception.InstanceNotFound(instance=instance)
+
+ info = self._vmutils.get_vm_summary_info(instance_name)
+
+ state = constants.HYPERV_POWER_STATE[info['EnabledState']]
return {'state': state,
- 'max_mem': info.MemoryUsage,
- 'mem': info.MemoryUsage,
- 'num_cpu': info.NumberOfProcessors,
- 'cpu_time': info.UpTime}
+ 'max_mem': info['MemoryUsage'],
+ 'mem': info['MemoryUsage'],
+ 'num_cpu': info['NumberOfProcessors'],
+ 'cpu_time': info['UpTime']}
def spawn(self, context, instance, image_meta, injected_files,
- admin_password, network_info, block_device_info=None):
+ admin_password, network_info, block_device_info=None):
"""Create a new VM and start it."""
- vm = self._vmutils.lookup(self._conn, instance['name'])
- if vm is not None:
- raise exception.InstanceExists(name=instance['name'])
+
+ instance_name = instance['name']
+ if self._vmutils.vm_exists(instance_name):
+ raise exception.InstanceExists(name=instance_name)
ebs_root = self._volumeops.volume_in_mapping(
self._volumeops.get_default_root_device(),
- block_device_info)
+ block_device_info)
#If is not a boot from volume spawn
if not (ebs_root):
#Fetch the file, assume it is a VHD file.
- vhdfile = self._vmutils.get_vhd_path(instance['name'])
+ vhdfile = self._pathutils.get_vhd_path(instance_name)
try:
- self._cache_image(fn=self._vmutils.fetch_image,
- context=context,
- target=vhdfile,
- fname=instance['image_ref'],
- image_id=instance['image_ref'],
- user=instance['user_id'],
- project=instance['project_id'],
- cow=CONF.use_cow_images)
+ self._cache_image(fn=self._fetch_image,
+ context=context,
+ target=vhdfile,
+ fname=instance['image_ref'],
+ image_id=instance['image_ref'],
+ user=instance['user_id'],
+ project=instance['project_id'],
+ cow=CONF.use_cow_images)
except Exception as exn:
LOG.exception(_('cache image failed: %s'), exn)
- self.destroy(instance)
+ raise
try:
- self._create_vm(instance)
+ self._vmutils.create_vm(instance_name,
+ instance['memory_mb'],
+ instance['vcpus'],
+ CONF.limit_cpu_features)
if not ebs_root:
- self._attach_ide_drive(instance['name'], vhdfile, 0, 0,
- constants.IDE_DISK)
+ self._vmutils.attach_ide_drive(instance_name,
+ vhdfile,
+ 0,
+ 0,
+ constants.IDE_DISK)
else:
self._volumeops.attach_boot_volume(block_device_info,
- instance['name'])
+ instance_name)
- #A SCSI controller for volumes connection is created
- self._create_scsi_controller(instance['name'])
+ self._vmutils.create_scsi_controller(instance_name)
for vif in network_info:
- self._create_nic(instance['name'], vif)
+ LOG.debug(_('Creating nic for instance: %s'), instance_name)
+ self._vmutils.create_nic(instance_name,
+ vif['id'],
+ vif['address'])
self._vif_driver.plug(instance, vif)
if configdrive.required_by(instance):
self._create_config_drive(instance, injected_files,
- admin_password)
+ admin_password)
- LOG.debug(_('Starting VM %s '), instance['name'])
- self._set_vm_state(instance['name'], 'Enabled')
- LOG.info(_('Started VM %s '), instance['name'])
- except Exception as exn:
- LOG.exception(_('spawn vm failed: %s'), exn)
+ self._set_vm_state(instance_name,
+ constants.HYPERV_VM_STATE_ENABLED)
+ except Exception as ex:
+ LOG.exception(ex)
self.destroy(instance)
- raise exn
+ raise vmutils.HyperVException(_('Spawn instance failed'))
def _create_config_drive(self, instance, injected_files, admin_password):
if CONF.config_drive_format != 'iso9660':
vmutils.HyperVException(_('Invalid config_drive_format "%s"') %
- CONF.config_drive_format)
+ CONF.config_drive_format)
+
+ LOG.info(_('Using config drive for instance: %s'), instance=instance)
- LOG.info(_('Using config drive'), instance=instance)
extra_md = {}
if admin_password and CONF.config_drive_inject_password:
extra_md['admin_pass'] = admin_password
inst_md = instance_metadata.InstanceMetadata(instance,
- content=injected_files, extra_md=extra_md)
+ content=injected_files,
+ extra_md=extra_md)
- instance_path = self._vmutils.get_instance_path(
+ instance_path = self._pathutils.get_instance_path(
instance['name'])
configdrive_path_iso = os.path.join(instance_path, 'configdrive.iso')
LOG.info(_('Creating config drive at %(path)s'),
@@ -218,7 +202,7 @@ class VMOps(baseops.BaseOps):
if not CONF.config_drive_cdrom:
drive_type = constants.IDE_DISK
configdrive_path = os.path.join(instance_path,
- 'configdrive.vhd')
+ 'configdrive.vhd')
utils.execute(CONF.qemu_img_cmd,
'convert',
'-f',
@@ -233,302 +217,88 @@ class VMOps(baseops.BaseOps):
drive_type = constants.IDE_DVD
configdrive_path = configdrive_path_iso
- self._attach_ide_drive(instance['name'], configdrive_path, 1, 0,
- drive_type)
-
- def _create_vm(self, instance):
- """Create a VM but don't start it."""
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
+ self._vmutils.attach_ide_drive(instance['name'], configdrive_path,
+ 1, 0, drive_type)
- vs_gs_data = self._conn.Msvm_VirtualSystemGlobalSettingData.new()
- vs_gs_data.ElementName = instance["name"]
- (job, ret_val) = vs_man_svc.DefineVirtualSystem(
- [], None, vs_gs_data.GetText_(1))[1:]
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job)
- else:
- success = (ret_val == 0)
-
- if not success:
- raise vmutils.HyperVException(_('Failed to create VM %s') %
- instance["name"])
-
- LOG.debug(_('Created VM %s...'), instance["name"])
- vm = self._conn.Msvm_ComputerSystem(ElementName=instance["name"])[0]
-
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- vmsetting = [s for s in vmsettings
- if s.SettingType == 3][0] # avoid snapshots
- memsetting = vmsetting.associators(
- wmi_result_class='Msvm_MemorySettingData')[0]
- #No Dynamic Memory, so reservation, limit and quantity are identical.
- mem = long(str(instance['memory_mb']))
- memsetting.VirtualQuantity = mem
- memsetting.Reservation = mem
- memsetting.Limit = mem
-
- (job, ret_val) = vs_man_svc.ModifyVirtualSystemResources(
- vm.path_(), [memsetting.GetText_(1)])
- LOG.debug(_('Set memory for vm %s...'), instance["name"])
- procsetting = vmsetting.associators(
- wmi_result_class='Msvm_ProcessorSettingData')[0]
- vcpus = long(instance['vcpus'])
- procsetting.VirtualQuantity = vcpus
- procsetting.Reservation = vcpus
- procsetting.Limit = 100000 # static assignment to 100%
-
- if CONF.limit_cpu_features:
- procsetting.LimitProcessorFeatures = True
-
- (job, ret_val) = vs_man_svc.ModifyVirtualSystemResources(
- vm.path_(), [procsetting.GetText_(1)])
- LOG.debug(_('Set vcpus for vm %s...'), instance["name"])
-
- def _create_scsi_controller(self, vm_name):
- """Create an iscsi controller ready to mount volumes."""
- LOG.debug(_('Creating a scsi controller for %(vm_name)s for volume '
- 'attaching') % locals())
- vms = self._conn.MSVM_ComputerSystem(ElementName=vm_name)
- vm = vms[0]
- scsicontrldefault = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType = 'Microsoft Synthetic SCSI Controller'\
- AND InstanceID LIKE '%Default%'")[0]
- if scsicontrldefault is None:
- raise vmutils.HyperVException(_('Controller not found'))
- scsicontrl = self._vmutils.clone_wmi_obj(self._conn,
- 'Msvm_ResourceAllocationSettingData', scsicontrldefault)
- scsicontrl.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
- scsiresource = self._vmutils.add_virt_resource(self._conn,
- scsicontrl, vm)
- if scsiresource is None:
- raise vmutils.HyperVException(
- _('Failed to add scsi controller to VM %s') %
- vm_name)
-
- def _get_ide_controller(self, vm, ctrller_addr):
- #Find the IDE controller for the vm.
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- rasds = vmsettings[0].associators(
- wmi_result_class='MSVM_ResourceAllocationSettingData')
- ctrller = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Emulated IDE Controller'
- and r.Address == str(ctrller_addr)]
- return ctrller
-
- def _attach_ide_drive(self, vm_name, path, ctrller_addr, drive_addr,
- drive_type=constants.IDE_DISK):
- """Create an IDE drive and attach it to the vm."""
- LOG.debug(_('Creating disk for %(vm_name)s by attaching'
- ' disk file %(path)s') % locals())
-
- vms = self._conn.MSVM_ComputerSystem(ElementName=vm_name)
- vm = vms[0]
-
- ctrller = self._get_ide_controller(vm, ctrller_addr)
-
- if drive_type == constants.IDE_DISK:
- resSubType = 'Microsoft Synthetic Disk Drive'
- elif drive_type == constants.IDE_DVD:
- resSubType = 'Microsoft Synthetic DVD Drive'
-
- #Find the default disk drive object for the vm and clone it.
- drivedflt = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType LIKE '%(resSubType)s'\
- AND InstanceID LIKE '%%Default%%'" % locals())[0]
- drive = self._vmutils.clone_wmi_obj(self._conn,
- 'Msvm_ResourceAllocationSettingData', drivedflt)
- #Set the IDE ctrller as parent.
- drive.Parent = ctrller[0].path_()
- drive.Address = drive_addr
- #Add the cloned disk drive object to the vm.
- new_resources = self._vmutils.add_virt_resource(self._conn,
- drive, vm)
- if new_resources is None:
- raise vmutils.HyperVException(
- _('Failed to add drive to VM %s') %
- vm_name)
- drive_path = new_resources[0]
- LOG.debug(_('New %(drive_type)s drive path is %(drive_path)s') %
- locals())
-
- if drive_type == constants.IDE_DISK:
- resSubType = 'Microsoft Virtual Hard Disk'
- elif drive_type == constants.IDE_DVD:
- resSubType = 'Microsoft Virtual CD/DVD Disk'
-
- #Find the default VHD disk object.
- drivedefault = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType LIKE '%(resSubType)s' AND \
- InstanceID LIKE '%%Default%%' " % locals())[0]
-
- #Clone the default and point it to the image file.
- res = self._vmutils.clone_wmi_obj(self._conn,
- 'Msvm_ResourceAllocationSettingData', drivedefault)
- #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.
- new_resources = self._vmutils.add_virt_resource(self._conn, res, vm)
- if new_resources is None:
- raise vmutils.HyperVException(
- _('Failed to add %(drive_type)s image to VM %(vm_name)s') %
- locals())
- LOG.info(_('Created drive type %(drive_type)s for %(vm_name)s') %
- locals())
-
- def _create_nic(self, vm_name, vif):
- """Create a (synthetic) nic and attach it to the vm."""
- LOG.debug(_('Creating nic for %s '), vm_name)
-
- #Create a new nic
- syntheticnics_data = self._conn.Msvm_SyntheticEthernetPortSettingData()
- default_nic_data = [n for n in syntheticnics_data
- if n.InstanceID.rfind('Default') > 0]
- new_nic_data = self._vmutils.clone_wmi_obj(self._conn,
- 'Msvm_SyntheticEthernetPortSettingData',
- default_nic_data[0])
-
- #Configure the nic
- new_nic_data.ElementName = vif['id']
- new_nic_data.Address = vif['address'].replace(':', '')
- new_nic_data.StaticMacAddress = 'True'
- new_nic_data.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
-
- #Add the new nic to the vm
- vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
- vm = vms[0]
-
- new_resources = self._vmutils.add_virt_resource(self._conn,
- new_nic_data, vm)
- if new_resources is None:
- raise vmutils.HyperVException(_('Failed to add nic to VM %s') %
- vm_name)
- LOG.info(_("Created nic for %s "), vm_name)
+ def destroy(self, instance, network_info=None, cleanup=True,
+ destroy_disks=True):
+ instance_name = instance['name']
+ LOG.debug(_("Got request to destroy instance: %s"), instance_name)
+ try:
+ if self._vmutils.vm_exists(instance_name):
+ volumes_drives_list = self._vmutils.destroy_vm(instance_name,
+ destroy_disks)
+ #Disconnect volumes
+ for volume_drive in volumes_drives_list:
+ self._volumeops.disconnect_volume(volume_drive)
+ else:
+ LOG.debug(_("Instance not found: %s"), instance_name)
+ except Exception as ex:
+ LOG.exception(ex)
+ raise vmutils.HyperVException(_('Failed to destroy instance: %s') %
+ instance_name)
def reboot(self, instance, network_info, reboot_type):
"""Reboot the specified instance."""
- vm = self._vmutils.lookup(self._conn, instance['name'])
- if vm is None:
- raise exception.InstanceNotFound(instance_id=instance["id"])
- self._set_vm_state(instance['name'], 'Reboot')
-
- def destroy(self, instance, network_info=None, cleanup=True,
- destroy_disks=True):
- """Destroy the VM. Also destroy the associated VHD disk files."""
- LOG.debug(_("Got request to destroy vm %s"), instance['name'])
- vm = self._vmutils.lookup(self._conn, instance['name'])
- if vm is None:
- return
- vm = self._conn.Msvm_ComputerSystem(ElementName=instance['name'])[0]
- vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
- #Stop the VM first.
- self._set_vm_state(instance['name'], 'Disabled')
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- rasds = vmsettings[0].associators(
- wmi_result_class='MSVM_ResourceAllocationSettingData')
- disks = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Virtual Hard Disk']
- disk_files = []
- volumes = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Physical Disk Drive']
- volumes_drives_list = []
- #collect the volumes information before destroying the VM.
- for volume in volumes:
- hostResources = volume.HostResource
- drive_path = hostResources[0]
- #Appending the Msvm_Disk path
- volumes_drives_list.append(drive_path)
- #Collect disk file information before destroying the VM.
- for disk in disks:
- disk_files.extend([c for c in disk.Connection])
- #Nuke the VM. Does not destroy disks.
- (job, ret_val) = vs_man_svc.DestroyVirtualSystem(vm.path_())
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job)
- elif ret_val == 0:
- success = True
- if not success:
- raise vmutils.HyperVException(_('Failed to destroy vm %s') %
- instance['name'])
- if destroy_disks:
- #Disconnect volumes
- for volume_drive in volumes_drives_list:
- self._volumeops.disconnect_volume(volume_drive)
- #Delete associated vhd disk files.
- for disk in disk_files:
- vhdfile = self._conn_cimv2.query(
- "Select * from CIM_DataFile where Name = '" +
- disk.replace("'", "''") + "'")[0]
- LOG.debug(_("Del: disk %(vhdfile)s vm %(name)s")
- % {'vhdfile': vhdfile, 'name': instance['name']})
- vhdfile.Delete()
+ LOG.debug(_("reboot instance"), instance=instance)
+ self._set_vm_state(instance['name'],
+ constants.HYPERV_VM_STATE_REBOOT)
def pause(self, instance):
"""Pause VM instance."""
LOG.debug(_("Pause instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Paused')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_PAUSED)
def unpause(self, instance):
"""Unpause paused VM instance."""
LOG.debug(_("Unpause instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Enabled')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_ENABLED)
def suspend(self, instance):
"""Suspend the specified instance."""
print instance
LOG.debug(_("Suspend instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Suspended')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_SUSPENDED)
def resume(self, instance):
"""Resume the suspended VM instance."""
LOG.debug(_("Resume instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Enabled')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_ENABLED)
def power_off(self, instance):
"""Power off the specified instance."""
LOG.debug(_("Power off instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Disabled')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_DISABLED)
def power_on(self, instance):
"""Power on the specified instance."""
LOG.debug(_("Power on instance"), instance=instance)
- self._set_vm_state(instance["name"], 'Enabled')
+ self._set_vm_state(instance["name"],
+ constants.HYPERV_VM_STATE_ENABLED)
def _set_vm_state(self, vm_name, req_state):
- """Set the desired state of the VM."""
- vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
- if len(vms) == 0:
- return False
- (job, ret_val) = vms[0].RequestStateChange(
- constants.REQ_POWER_STATE[req_state])
- success = False
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job)
- elif ret_val == 0:
- success = True
- elif ret_val == 32775:
- #Invalid state for current operation. Typically means it is
- #already in the state requested
- success = True
- if success:
- LOG.info(_("Successfully changed vm state of %(vm_name)s"
- " to %(req_state)s") % locals())
- else:
+ try:
+ self._vmutils.set_vm_state(vm_name, req_state)
+ LOG.debug(_("Successfully changed state of VM %(vm_name)s"
+ " to: %(req_state)s") % locals())
+ except Exception as ex:
+ LOG.exception(ex)
msg = _("Failed to change vm state of %(vm_name)s"
" to %(req_state)s") % locals()
- LOG.error(msg)
raise vmutils.HyperVException(msg)
- def _cache_image(self, fn, target, fname, cow=False, Size=None,
- *args, **kwargs):
- """Wrapper for a method that creates an image that caches the image.
+ def _fetch_image(self, target, context, image_id, user, project,
+ *args, **kwargs):
+ images.fetch(context, image_id, target, user, project)
+
+ def _cache_image(self, fn, target, fname, cow=False, size=None,
+ *args, **kwargs):
+ """Wrapper for a method that creates and caches an image.
This wrapper will save the image into a common store and create a
copy for use by the hypervisor.
@@ -543,32 +313,23 @@ class VMOps(baseops.BaseOps):
"""
@lockutils.synchronized(fname, 'nova-')
def call_if_not_exists(path, fn, *args, **kwargs):
- if not os.path.exists(path):
- fn(target=path, *args, **kwargs)
+ if not os.path.exists(path):
+ fn(target=path, *args, **kwargs)
- if not os.path.exists(target):
- LOG.debug(_("use_cow_image:%s"), cow)
+ if not self._pathutils.vhd_exists(target):
+ LOG.debug(_("Use CoW image: %s"), cow)
if cow:
- base = self._vmutils.get_base_vhd_path(fname)
- call_if_not_exists(base, fn, *args, **kwargs)
-
- image_service = self._conn.query(
- "Select * from Msvm_ImageManagementService")[0]
- (job, ret_val) = \
- image_service.CreateDifferencingVirtualHardDisk(
- Path=target, ParentPath=base)
- LOG.debug(
- "Creating difference disk: JobID=%s, Source=%s, Target=%s",
- job, base, target)
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self._vmutils.check_job_status(job)
- else:
- success = (ret_val == 0)
-
- if not success:
+ parent_path = self._pathutils.get_base_vhd_path(fname)
+ call_if_not_exists(parent_path, fn, *args, **kwargs)
+
+ LOG.debug(_("Creating differencing VHD. Parent: "
+ "%(parent_path)s, Target: %(target)s") % locals())
+ try:
+ self._vhdutils.create_differencing_vhd(target, parent_path)
+ except Exception as ex:
+ LOG.exception(ex)
raise vmutils.HyperVException(
- _('Failed to create Difference Disk from '
- '%(base)s to %(target)s') % locals())
-
+ _('Failed to create a differencing disk from '
+ '%(parent_path)s to %(target)s') % locals())
else:
call_if_not_exists(target, fn, *args, **kwargs)
diff --git a/nova/virt/hyperv/vmutils.py b/nova/virt/hyperv/vmutils.py
index d899f977d..0305d8306 100644
--- a/nova/virt/hyperv/vmutils.py
+++ b/nova/virt/hyperv/vmutils.py
@@ -16,24 +16,20 @@
# under the License.
"""
-Utility class for VM related operations.
+Utility class for VM related operations on Hyper-V.
"""
-import os
-import shutil
import sys
import time
import uuid
+if sys.platform == 'win32':
+ import wmi
+
from nova import exception
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova.virt.hyperv import constants
-from nova.virt import images
-
-# Check needed for unit testing on Unix
-if sys.platform == 'win32':
- import wmi
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
@@ -45,19 +41,342 @@ class HyperVException(exception.NovaException):
class VMUtils(object):
- def lookup(self, conn, i):
- vms = conn.Msvm_ComputerSystem(ElementName=i)
+
+ def __init__(self):
+ if sys.platform == 'win32':
+ self._conn = wmi.WMI(moniker='//./root/virtualization')
+ self._conn_cimv2 = wmi.WMI(moniker='//./root/cimv2')
+
+ def list_instances(self):
+ """Return the names of all the instances known to Hyper-V."""
+ vm_names = [v.ElementName
+ for v in self._conn.Msvm_ComputerSystem(['ElementName'],
+ Caption="Virtual Machine")]
+ return vm_names
+
+ def get_vm_summary_info(self, vm_name):
+ vm = self._lookup_vm_check(vm_name)
+
+ vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
+ vmsettings = vm.associators(
+ wmi_association_class='Msvm_SettingsDefineState',
+ wmi_result_class='Msvm_VirtualSystemSettingData')
+ settings_paths = [v.path_() for v in vmsettings]
+ #See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
+ (ret_val, summary_info) = vs_man_svc.GetSummaryInformation(
+ [constants.VM_SUMMARY_NUM_PROCS,
+ constants.VM_SUMMARY_ENABLED_STATE,
+ constants.VM_SUMMARY_MEMORY_USAGE,
+ constants.VM_SUMMARY_UPTIME],
+ settings_paths)
+ if ret_val:
+ raise HyperVException(_('Cannot get VM summary data for: %s')
+ % vm_name)
+
+ si = summary_info[0]
+ memory_usage = None
+ if si.MemoryUsage is not None:
+ memory_usage = long(si.MemoryUsage)
+ up_time = None
+ if si.UpTime is not None:
+ up_time = long(si.UpTime)
+
+ summary_info_dict = {'NumberOfProcessors': si.NumberOfProcessors,
+ 'EnabledState': si.EnabledState,
+ 'MemoryUsage': memory_usage,
+ 'UpTime': up_time}
+ return summary_info_dict
+
+ def _lookup_vm_check(self, vm_name):
+ vm = self._lookup_vm(vm_name)
+ if not vm:
+ raise HyperVException(_('VM not found: %s') % vm_name)
+ return vm
+
+ def _lookup_vm(self, vm_name):
+ vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
n = len(vms)
if n == 0:
return None
elif n > 1:
- raise HyperVException(_('duplicate name found: %s') % i)
+ raise HyperVException(_('Duplicate VM name found: %s') % vm_name)
else:
- return vms[0].ElementName
+ return vms[0]
+
+ def vm_exists(self, vm_name):
+ return self._lookup_vm(vm_name) is not None
+
+ def _get_vm_setting_data(self, vm):
+ vmsettings = vm.associators(
+ wmi_result_class='Msvm_VirtualSystemSettingData')
+ # Avoid snapshots
+ return [s for s in vmsettings if s.SettingType == 3][0]
+
+ def _set_vm_memory(self, vm, vmsetting, memory_mb):
+ memsetting = vmsetting.associators(
+ wmi_result_class='Msvm_MemorySettingData')[0]
+ #No Dynamic Memory, so reservation, limit and quantity are identical.
+ mem = long(memory_mb)
+ memsetting.VirtualQuantity = mem
+ memsetting.Reservation = mem
+ memsetting.Limit = mem
+
+ self._modify_virt_resource(memsetting, vm.path_())
+
+ def _set_vm_vcpus(self, vm, vmsetting, vcpus_num, limit_cpu_features):
+ procsetting = vmsetting.associators(
+ wmi_result_class='Msvm_ProcessorSettingData')[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 create_vm(self, vm_name, memory_mb, vcpus_num, limit_cpu_features):
+ """Creates a VM."""
+ vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
+
+ vs_gs_data = self._conn.Msvm_VirtualSystemGlobalSettingData.new()
+ vs_gs_data.ElementName = vm_name
+
+ LOG.debug(_('Creating VM %s'), vm_name)
+ (job_path,
+ ret_val) = vs_man_svc.DefineVirtualSystem([], None,
+ vs_gs_data.GetText_(1))[1:]
+ self.check_ret_val(ret_val, job_path)
+
+ vm = self._lookup_vm_check(vm_name)
+ vmsetting = self._get_vm_setting_data(vm)
+
+ LOG.debug(_('Setting memory for vm %s'), vm_name)
+ self._set_vm_memory(vm, vmsetting, memory_mb)
+
+ LOG.debug(_('Set vCPUs for vm %s'), vm_name)
+ self._set_vm_vcpus(vm, vmsetting, vcpus_num, limit_cpu_features)
+
+ def get_vm_iscsi_controller(self, vm_name):
+ vm = self._lookup_vm_check(vm_name)
+
+ vmsettings = vm.associators(
+ wmi_result_class='Msvm_VirtualSystemSettingData')
+ rasds = vmsettings[0].associators(
+ wmi_result_class='MSVM_ResourceAllocationSettingData')
+ res = [r for r in rasds
+ if r.ResourceSubType ==
+ 'Microsoft Synthetic SCSI Controller'][0]
+ return res.path_()
+
+ def _get_vm_ide_controller(self, vm, ctrller_addr):
+ vmsettings = vm.associators(
+ wmi_result_class='Msvm_VirtualSystemSettingData')
+ rasds = vmsettings[0].associators(
+ wmi_result_class='MSVM_ResourceAllocationSettingData')
+ return [r for r in rasds
+ if r.ResourceSubType == 'Microsoft Emulated IDE Controller'
+ and r.Address == str(ctrller_addr)][0].path_()
+
+ 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_count(self, scsi_controller_path):
+ volumes = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData "
+ "WHERE ResourceSubType LIKE "
+ "'Microsoft Physical Disk Drive' "
+ "AND Parent = '%s'" %
+ scsi_controller_path.replace("'", "''"))
+ return len(volumes)
+
+ def attach_ide_drive(self, vm_name, path, ctrller_addr, drive_addr,
+ drive_type=constants.IDE_DISK):
+ """Create an IDE drive and attach it to the vm."""
+
+ vm = self._lookup_vm_check(vm_name)
+
+ ctrller_path = self._get_vm_ide_controller(vm, ctrller_addr)
+
+ if drive_type == constants.IDE_DISK:
+ res_sub_type = 'Microsoft Synthetic Disk Drive'
+ elif drive_type == constants.IDE_DVD:
+ res_sub_type = 'Microsoft Synthetic DVD Drive'
+
+ #Find the default disk drive object for the vm and clone it.
+ drivedflt = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData "
+ "WHERE ResourceSubType LIKE "
+ "'%(res_sub_type)s' AND InstanceID LIKE "
+ "'%%Default%%'" % locals())[0]
+ drive = self._clone_wmi_obj('Msvm_ResourceAllocationSettingData',
+ drivedflt)
+ #Set the IDE 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.IDE_DISK:
+ res_sub_type = 'Microsoft Virtual Hard Disk'
+ elif drive_type == constants.IDE_DVD:
+ res_sub_type = 'Microsoft Virtual CD/DVD Disk'
+
+ #Find the default VHD disk object.
+ drivedefault = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData "
+ "WHERE ResourceSubType LIKE "
+ "'%(res_sub_type)s' AND "
+ "InstanceID LIKE '%%Default%%'"
+ % locals())[0]
+
+ #Clone the default and point it to the image file.
+ res = self._clone_wmi_obj('Msvm_ResourceAllocationSettingData',
+ drivedefault)
+ #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)
+ scsicontrldflt = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData "
+ "WHERE ResourceSubType = 'Microsoft "
+ "Synthetic SCSI Controller' AND "
+ "InstanceID LIKE '%Default%'")[0]
+ if scsicontrldflt is None:
+ raise HyperVException(_('Controller not found'))
+ scsicontrl = self._clone_wmi_obj('Msvm_ResourceAllocationSettingData',
+ scsicontrldflt)
+ scsicontrl.VirtualSystemIdentifiers = ['{' + str(uuid.uuid4()) + '}']
+ scsiresource = 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."""
- def check_job_status(self, jobpath):
- """Poll WMI job state for completion."""
- job_wmi_path = jobpath.replace('\\', '/')
+ vm = self._lookup_vm_check(vm_name)
+
+ diskdflt = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData "
+ "WHERE ResourceSubType LIKE "
+ "'Microsoft Physical Disk Drive' "
+ "AND InstanceID LIKE '%Default%'")[0]
+ diskdrive = self._clone_wmi_obj('Msvm_ResourceAllocationSettingData',
+ diskdflt)
+ diskdrive.Address = address
+ diskdrive.Parent = controller_path
+ diskdrive.HostResource = [mounted_disk_path]
+ self._add_virt_resource(diskdrive, vm.path_())
+
+ def set_nic_connection(self, vm_name, nic_name, vswitch_port):
+ nic_data = self._get_nic_data_by_name(nic_name)
+ nic_data.Connection = [vswitch_port]
+
+ vm = self._lookup_vm_check(vm_name)
+ self._modify_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
+ syntheticnics_data = self._conn.Msvm_SyntheticEthernetPortSettingData()
+ default_nic_data = [n for n in syntheticnics_data
+ if n.InstanceID.rfind('Default') > 0]
+ new_nic_data = self._clone_wmi_obj(
+ 'Msvm_SyntheticEthernetPortSettingData', default_nic_data[0])
+
+ #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 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(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") % locals())
+
+ def destroy_vm(self, vm_name, destroy_disks=True):
+ """Destroy the VM. Also destroy the associated VHD disk files."""
+
+ vm = self._lookup_vm_check(vm_name)
+
+ #Stop the VM first.
+ self.set_vm_state(vm_name, constants.HYPERV_VM_STATE_DISABLED)
+
+ vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
+ vmsettings = vm.associators(
+ wmi_result_class='Msvm_VirtualSystemSettingData')
+ rasds = vmsettings[0].associators(
+ wmi_result_class='MSVM_ResourceAllocationSettingData')
+ disk_resources = [r for r in rasds
+ if r.ResourceSubType ==
+ 'Microsoft Virtual Hard Disk']
+ volume_resources = [r for r in rasds
+ if r.ResourceSubType ==
+ 'Microsoft Physical Disk Drive']
+
+ #Collect volumes information before destroying the VM.
+ volumes_drives_list = []
+ for volume_resource in volume_resources:
+ drive_path = volume_resource.HostResource[0]
+ #Appending the Msvm_Disk path
+ volumes_drives_list.append(drive_path)
+
+ #Collect disk file information before destroying the VM.
+ disk_files = []
+ for disk_resource in disk_resources:
+ disk_files.extend([c for c in disk_resource.Connection])
+
+ #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)
+
+ if destroy_disks:
+ #Delete associated vhd disk files.
+ for disk in disk_files:
+ LOG.debug(_("Deleting disk file: %(disk)s") % locals())
+ self._delete_file(disk)
+
+ return volumes_drives_list
+
+ def _delete_file(self, path):
+ f = self._conn_cimv2.query("Select * from CIM_DataFile where "
+ "Name = '%s'" % path.replace("'", "''"))[0]
+ f.Delete()
+
+ def check_ret_val(self, ret_val, job_path, success_values=[0]):
+ if ret_val == constants.WMI_JOB_STATUS_STARTED:
+ 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_wmi_path = job_path.replace('\\', '/')
job = wmi.WMI(moniker=job_wmi_path)
while job.JobState == constants.WMI_JOB_STATE_RUNNING:
@@ -69,54 +388,30 @@ class VMUtils(object):
err_sum_desc = job.ErrorSummaryDescription
err_desc = job.ErrorDescription
err_code = job.ErrorCode
- LOG.debug(_("WMI job failed with status %(job_state)d. "
- "Error details: %(err_sum_desc)s - %(err_desc)s - "
- "Error code: %(err_code)d") % locals())
+ raise HyperVException(_("WMI job failed with status "
+ "%(job_state)d. Error details: "
+ "%(err_sum_desc)s - %(err_desc)s - "
+ "Error code: %(err_code)d")
+ % locals())
else:
(error, ret_val) = job.GetError()
if not ret_val and error:
- LOG.debug(_("WMI job failed with status %(job_state)d. "
- "Error details: %(error)s") % locals())
+ raise HyperVException(_("WMI job failed with status "
+ "%(job_state)d. Error details: "
+ "%(error)s") % locals())
else:
- LOG.debug(_("WMI job failed with status %(job_state)d. "
- "No error description available") % locals())
- return False
+ raise HyperVException(_("WMI job failed with status "
+ "%(job_state)d. No error "
+ "description available")
+ % locals())
desc = job.Description
elap = job.ElapsedTime
LOG.debug(_("WMI job succeeded: %(desc)s, Elapsed=%(elap)s")
- % locals())
- return True
-
- def get_instance_path(self, instance_name):
- instance_path = os.path.join(CONF.instances_path, instance_name)
- if not os.path.exists(instance_path):
- LOG.debug(_('Creating folder %s '), instance_path)
- os.makedirs(instance_path)
- return instance_path
-
- def get_vhd_path(self, instance_name):
- instance_path = self.get_instance_path(instance_name)
- return os.path.join(instance_path, instance_name + ".vhd")
-
- def get_base_vhd_path(self, image_name):
- base_dir = os.path.join(CONF.instances_path, '_base')
- if not os.path.exists(base_dir):
- os.makedirs(base_dir)
- return os.path.join(base_dir, image_name + ".vhd")
-
- def make_export_path(self, instance_name):
- export_folder = os.path.join(CONF.instances_path, "export",
- instance_name)
- if os.path.isdir(export_folder):
- LOG.debug(_('Removing existing folder %s '), export_folder)
- shutil.rmtree(export_folder)
- LOG.debug(_('Creating folder %s '), export_folder)
- os.makedirs(export_folder)
- return export_folder
-
- def clone_wmi_obj(self, conn, wmi_class, wmi_obj):
+ % locals())
+
+ def _clone_wmi_obj(self, wmi_class, wmi_obj):
"""Clone a WMI object."""
- cl = conn.__getattr__(wmi_class) # get the class
+ cl = getattr(self._conn, wmi_class) # get the class
newinst = cl.new()
#Copy the properties from the original.
for prop in wmi_obj._properties:
@@ -125,51 +420,78 @@ class VMUtils(object):
strguid.append(str(uuid.uuid4()))
newinst.Properties_.Item(prop).Value = strguid
else:
- newinst.Properties_.Item(prop).Value = \
- wmi_obj.Properties_.Item(prop).Value
+ prop_value = wmi_obj.Properties_.Item(prop).Value
+ newinst.Properties_.Item(prop).Value = prop_value
+
return newinst
- def add_virt_resource(self, conn, res_setting_data, target_vm):
+ def _add_virt_resource(self, res_setting_data, vm_path):
"""Adds a new resource to the VM."""
- vs_man_svc = conn.Msvm_VirtualSystemManagementService()[0]
- (job, new_resources, ret_val) = vs_man_svc.\
- AddVirtualSystemResources([res_setting_data.GetText_(1)],
- target_vm.path_())
- success = True
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self.check_job_status(job)
- else:
- success = (ret_val == 0)
- if success:
- return new_resources
- else:
- return None
+ 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, conn, res_setting_data, target_vm):
+ def _modify_virt_resource(self, res_setting_data, vm_path):
"""Updates a VM resource."""
- vs_man_svc = conn.Msvm_VirtualSystemManagementService()[0]
- (job, ret_val) = vs_man_svc.ModifyVirtualSystemResources(
+ vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
+ (job_path, ret_val) = vs_man_svc.ModifyVirtualSystemResources(
ResourceSettingData=[res_setting_data.GetText_(1)],
- ComputerSystem=target_vm.path_())
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self.check_job_status(job)
- else:
- success = (ret_val == 0)
- return success
+ ComputerSystem=vm_path)
+ self.check_ret_val(ret_val, job_path)
- def remove_virt_resource(self, conn, res_setting_data, target_vm):
+ def _remove_virt_resource(self, res_setting_data, vm_path):
"""Removes a VM resource."""
- vs_man_svc = conn.Msvm_VirtualSystemManagementService()[0]
- (job, ret_val) = vs_man_svc.\
- RemoveVirtualSystemResources([res_setting_data.path_()],
- target_vm.path_())
- success = True
- if ret_val == constants.WMI_JOB_STATUS_STARTED:
- success = self.check_job_status(job)
- else:
- success = (ret_val == 0)
- return success
+ 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='Msvm_VirtualSystemSettingData')[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):
+ vm = self._lookup_vm_check(vm_name)
+ physical_disk = self._get_mounted_disk_resource_from_path(
+ disk_path)
+ self._remove_virt_resource(physical_disk, vm.path_())
+
+ def _get_mounted_disk_resource_from_path(self, disk_path):
+ physical_disks = self._conn.query("SELECT * FROM "
+ "Msvm_ResourceAllocationSettingData"
+ " WHERE ResourceSubType = "
+ "'Microsoft Physical Disk Drive'")
+ for physical_disk in physical_disks:
+ if physical_disk.HostResource:
+ if physical_disk.HostResource[0].lower() == disk_path.lower():
+ return physical_disk
- def fetch_image(self, target, context, image_id, user, project,
- *args, **kwargs):
- images.fetch(context, image_id, target, user, project)
+ 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_()
diff --git a/nova/virt/hyperv/volumeops.py b/nova/virt/hyperv/volumeops.py
index b69cf7bf1..a7e56b739 100644
--- a/nova/virt/hyperv/volumeops.py
+++ b/nova/virt/hyperv/volumeops.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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
@@ -20,210 +21,140 @@ Management class for Storage-related functions (attach, detach, etc).
"""
import time
-from nova import block_device
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova.virt import driver
-from nova.virt.hyperv import baseops
+from nova.virt.hyperv import hostutils
from nova.virt.hyperv import vmutils
from nova.virt.hyperv import volumeutils
-from nova.virt.hyperv import volumeutilsV2
+from nova.virt.hyperv import volumeutilsv2
LOG = logging.getLogger(__name__)
hyper_volumeops_opts = [
cfg.IntOpt('hyperv_attaching_volume_retry_count',
- default=10,
- help='The number of times we retry on attaching volume '),
+ default=10,
+ help='The number of times we retry on attaching volume '),
cfg.IntOpt('hyperv_wait_between_attach_retry',
- default=5,
- help='The seconds to wait between a volume attachment attempt'),
+ default=5,
+ help='The seconds to wait between an volume '
+ 'attachment attempt'),
cfg.BoolOpt('force_volumeutils_v1',
- default=False,
- help='Force volumeutils v1'),
- ]
+ default=False,
+ help='Force volumeutils v1'),
+]
CONF = cfg.CONF
CONF.register_opts(hyper_volumeops_opts)
CONF.import_opt('my_ip', 'nova.netconf')
-class VolumeOps(baseops.BaseOps):
+class VolumeOps(object):
"""
Management class for Volume-related tasks
"""
def __init__(self):
- super(VolumeOps, self).__init__()
-
+ self._hostutils = hostutils.HostUtils()
self._vmutils = vmutils.VMUtils()
- self._driver = driver
- self._block_device = block_device
- self._time = time
+ self._volutils = self._get_volume_utils()
self._initiator = None
self._default_root_device = 'vda'
- self._attaching_volume_retry_count = \
- CONF.hyperv_attaching_volume_retry_count
- self._wait_between_attach_retry = \
- CONF.hyperv_wait_between_attach_retry
- self._volutils = self._get_volume_utils()
def _get_volume_utils(self):
- if(not CONF.force_volumeutils_v1) and \
- (self._get_hypervisor_version() >= 6.2):
- return volumeutilsV2.VolumeUtilsV2(
- self._conn_storage, self._conn_wmi)
+ if(not CONF.force_volumeutils_v1 and
+ self._hostutils.get_windows_version() >= 6.2):
+ return volumeutilsv2.VolumeUtilsV2()
else:
- return volumeutils.VolumeUtils(self._conn_wmi)
-
- def _get_hypervisor_version(self):
- """Get hypervisor version.
- :returns: hypervisor version (ex. 12003)
- """
- version = self._conn_cimv2.Win32_OperatingSystem()[0]\
- .Version
- LOG.info(_('Windows version: %s ') % version)
- return version
+ return volumeutils.VolumeUtils()
def attach_boot_volume(self, block_device_info, vm_name):
"""Attach the boot volume to the IDE controller."""
+
LOG.debug(_("block device info: %s"), block_device_info)
- ebs_root = self._driver.block_device_info_get_mapping(
+ ebs_root = driver.block_device_info_get_mapping(
block_device_info)[0]
+
connection_info = ebs_root['connection_info']
data = connection_info['data']
target_lun = data['target_lun']
target_iqn = data['target_iqn']
target_portal = data['target_portal']
self._volutils.login_storage_target(target_lun, target_iqn,
- target_portal)
+ target_portal)
try:
#Getting the mounted disk
- mounted_disk = self._get_mounted_disk_from_lun(target_iqn,
- target_lun)
- #Attach to IDE controller
+ mounted_disk_path = self._get_mounted_disk_from_lun(target_iqn,
+ target_lun)
#Find the IDE controller for the vm.
- vms = self._conn.MSVM_ComputerSystem(ElementName=vm_name)
- vm = vms[0]
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- rasds = vmsettings[0].associators(
- wmi_result_class='MSVM_ResourceAllocationSettingData')
- ctrller = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Emulated IDE Controller'
- and r.Address == "0"]
+ ctrller_path = self._vmutils.get_vm_ide_controller(vm_name, 0)
#Attaching to the same slot as the VHD disk file
- self._attach_volume_to_controller(ctrller, 0, mounted_disk, vm)
+ self._vmutils.attach_volume_to_controller(vm_name,
+ ctrller_path, 0,
+ mounted_disk_path)
except Exception as exn:
LOG.exception(_('Attach boot from volume failed: %s'), exn)
self._volutils.logout_storage_target(target_iqn)
raise vmutils.HyperVException(
- _('Unable to attach boot volume to instance %s')
- % vm_name)
+ _('Unable to attach boot volume to instance %s') % vm_name)
def volume_in_mapping(self, mount_device, block_device_info):
return self._volutils.volume_in_mapping(mount_device,
- block_device_info)
+ block_device_info)
- def attach_volume(self, connection_info, instance_name, mountpoint):
+ def attach_volume(self, connection_info, instance_name):
"""Attach a volume to the SCSI controller."""
- LOG.debug(_("Attach_volume: %(connection_info)s, %(instance_name)s,"
- " %(mountpoint)s") % locals())
+ LOG.debug(_("Attach_volume: %(connection_info)s to %(instance_name)s")
+ % locals())
data = connection_info['data']
target_lun = data['target_lun']
target_iqn = data['target_iqn']
target_portal = data['target_portal']
self._volutils.login_storage_target(target_lun, target_iqn,
- target_portal)
+ target_portal)
try:
#Getting the mounted disk
- mounted_disk = self._get_mounted_disk_from_lun(target_iqn,
- target_lun)
+ mounted_disk_path = self._get_mounted_disk_from_lun(target_iqn,
+ target_lun)
#Find the SCSI controller for the vm
- vms = self._conn.MSVM_ComputerSystem(ElementName=instance_name)
- vm = vms[0]
- vmsettings = vm.associators(
- wmi_result_class='Msvm_VirtualSystemSettingData')
- rasds = vmsettings[0].associators(
- wmi_result_class='MSVM_ResourceAllocationSettingData')
- ctrller = [r for r in rasds
- if r.ResourceSubType == 'Microsoft Synthetic SCSI Controller']
- self._attach_volume_to_controller(
- ctrller, self._get_free_controller_slot(ctrller[0]),
- mounted_disk, vm)
+ ctrller_path = self._vmutils.get_vm_iscsi_controller(instance_name)
+
+ slot = self._get_free_controller_slot(ctrller_path)
+ self._vmutils.attach_volume_to_controller(instance_name,
+ ctrller_path,
+ slot,
+ mounted_disk_path)
except Exception as exn:
LOG.exception(_('Attach volume failed: %s'), exn)
self._volutils.logout_storage_target(target_iqn)
- raise vmutils.HyperVException(
- _('Unable to attach volume to instance %s')
- % instance_name)
+ raise vmutils.HyperVException(_('Unable to attach volume '
+ 'to instance %s') % instance_name)
- def _attach_volume_to_controller(self, controller, address, mounted_disk,
- instance):
- """Attach a volume to a controller."""
- #Find the default disk drive object for the vm and clone it.
- diskdflt = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType LIKE 'Microsoft Physical Disk Drive'\
- AND InstanceID LIKE '%Default%'")[0]
- diskdrive = self._vmutils.clone_wmi_obj(self._conn,
- 'Msvm_ResourceAllocationSettingData', diskdflt)
- diskdrive.Address = address
- diskdrive.Parent = controller[0].path_()
- diskdrive.HostResource = [mounted_disk[0].path_()]
- new_resources = self._vmutils.add_virt_resource(self._conn, diskdrive,
- instance)
- if new_resources is None:
- raise vmutils.HyperVException(_('Failed to add volume to VM %s') %
- instance)
+ def _get_free_controller_slot(self, scsi_controller_path):
+ #Slots starts from 0, so the lenght of the disks gives us the free slot
+ return self._vmutils.get_attached_disks_count(scsi_controller_path)
- def _get_free_controller_slot(self, scsi_controller):
- #Getting volumes mounted in the SCSI controller
- volumes = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType LIKE 'Microsoft Physical Disk Drive'\
- AND Parent = '" + scsi_controller.path_() + "'")
- #Slots starts from 0, so the length of the disks gives us the free slot
- return len(volumes)
-
- def detach_volume(self, connection_info, instance_name, mountpoint):
+ def detach_volume(self, connection_info, instance_name):
"""Dettach a volume to the SCSI controller."""
- LOG.debug(_("Detach_volume: %(connection_info)s, %(instance_name)s,"
- " %(mountpoint)s") % locals())
+ LOG.debug(_("Detach_volume: %(connection_info)s "
+ "from %(instance_name)s") % locals())
data = connection_info['data']
target_lun = data['target_lun']
target_iqn = data['target_iqn']
#Getting the mounted disk
- mounted_disk = self._get_mounted_disk_from_lun(target_iqn, target_lun)
- physical_list = self._conn.query(
- "SELECT * FROM Msvm_ResourceAllocationSettingData \
- WHERE ResourceSubType LIKE 'Microsoft Physical Disk Drive'")
- physical_disk = 0
- for phydisk in physical_list:
- host_resource_list = phydisk.HostResource
- if host_resource_list is None:
- continue
- host_resource = str(host_resource_list[0].lower())
- mounted_disk_path = str(mounted_disk[0].path_().lower())
- LOG.debug(_("Mounted disk to detach is: %s"), mounted_disk_path)
- LOG.debug(_("host_resource disk detached is: %s"), host_resource)
- if host_resource == mounted_disk_path:
- physical_disk = phydisk
- LOG.debug(_("Physical disk detached is: %s"), physical_disk)
- vms = self._conn.MSVM_ComputerSystem(ElementName=instance_name)
- vm = vms[0]
- remove_result = self._vmutils.remove_virt_resource(self._conn,
- physical_disk, vm)
- if remove_result is False:
- raise vmutils.HyperVException(
- _('Failed to remove volume from VM %s') %
- instance_name)
+ mounted_disk_path = self._get_mounted_disk_from_lun(target_iqn,
+ target_lun)
+
+ LOG.debug(_("Detaching physical disk from instance: %s"),
+ mounted_disk_path)
+ self._vmutils.detach_vm_disk(instance_name, mounted_disk_path)
+
#Sending logout
self._volutils.logout_storage_target(target_iqn)
def get_volume_connector(self, instance):
if not self._initiator:
- self._initiator = self._get_iscsi_initiator()
+ self._initiator = self._volutils.get_iscsi_initiator()
if not self._initiator:
LOG.warn(_('Could not determine iscsi initiator name'),
instance=instance)
@@ -232,87 +163,35 @@ class VolumeOps(baseops.BaseOps):
'initiator': self._initiator,
}
- def _get_iscsi_initiator(self):
- return self._volutils.get_iscsi_initiator(self._conn_cimv2)
-
def _get_mounted_disk_from_lun(self, target_iqn, target_lun):
- initiator_session = self._conn_wmi.query(
- "SELECT * FROM MSiSCSIInitiator_SessionClass \
- WHERE TargetName='" + target_iqn + "'")[0]
- devices = initiator_session.Devices
- device_number = None
- for device in devices:
- LOG.debug(_("device.InitiatorName: %s"), device.InitiatorName)
- LOG.debug(_("device.TargetName: %s"), device.TargetName)
- LOG.debug(_("device.ScsiPortNumber: %s"), device.ScsiPortNumber)
- LOG.debug(_("device.ScsiPathId: %s"), device.ScsiPathId)
- LOG.debug(_("device.ScsiTargetId): %s"), device.ScsiTargetId)
- LOG.debug(_("device.ScsiLun: %s"), device.ScsiLun)
- LOG.debug(_("device.DeviceInterfaceGuid :%s"),
- device.DeviceInterfaceGuid)
- LOG.debug(_("device.DeviceInterfaceName: %s"),
- device.DeviceInterfaceName)
- LOG.debug(_("device.LegacyName: %s"), device.LegacyName)
- LOG.debug(_("device.DeviceType: %s"), device.DeviceType)
- LOG.debug(_("device.DeviceNumber %s"), device.DeviceNumber)
- LOG.debug(_("device.PartitionNumber :%s"), device.PartitionNumber)
- scsi_lun = device.ScsiLun
- if scsi_lun == target_lun:
- device_number = device.DeviceNumber
+ device_number = self._volutils.get_device_number_for_target(target_iqn,
+ target_lun)
if device_number is None:
- raise vmutils.HyperVException(
- _('Unable to find a mounted disk for'
- ' target_iqn: %s') % target_iqn)
- LOG.debug(_("Device number : %s"), device_number)
- LOG.debug(_("Target lun : %s"), target_lun)
+ raise vmutils.HyperVException(_('Unable to find a mounted '
+ 'disk for target_iqn: %s')
+ % target_iqn)
+ LOG.debug(_('Device number: %(device_number)s, '
+ 'target lun: %(target_lun)s') % locals())
#Finding Mounted disk drive
- for i in range(1, self._attaching_volume_retry_count):
- mounted_disk = self._conn.query(
- "SELECT * FROM Msvm_DiskDrive WHERE DriveNumber=" +
- str(device_number) + "")
- LOG.debug(_("Mounted disk is: %s"), mounted_disk)
- if len(mounted_disk) > 0:
+ for i in range(1, CONF.hyperv_attaching_volume_retry_count):
+ mounted_disk_path = self._vmutils.get_mounted_disk_by_drive_number(
+ device_number)
+ if mounted_disk_path:
break
- self._time.sleep(self._wait_between_attach_retry)
- mounted_disk = self._conn.query(
- "SELECT * FROM Msvm_DiskDrive WHERE DriveNumber=" +
- str(device_number) + "")
- LOG.debug(_("Mounted disk is: %s"), mounted_disk)
- if len(mounted_disk) == 0:
- raise vmutils.HyperVException(
- _('Unable to find a mounted disk for'
- ' target_iqn: %s') % target_iqn)
- return mounted_disk
+ time.sleep(CONF.hyperv_wait_between_attach_retry)
+
+ if not mounted_disk_path:
+ raise vmutils.HyperVException(_('Unable to find a mounted disk '
+ 'for target_iqn: %s')
+ % target_iqn)
+ return mounted_disk_path
def disconnect_volume(self, physical_drive_path):
#Get the session_id of the ISCSI connection
- session_id = self._get_session_id_from_mounted_disk(
+ session_id = self._volutils.get_session_id_from_mounted_disk(
physical_drive_path)
#Logging out the target
self._volutils.execute_log_out(session_id)
- def _get_session_id_from_mounted_disk(self, physical_drive_path):
- drive_number = self._get_drive_number_from_disk_path(
- physical_drive_path)
- LOG.debug(_("Drive number to disconnect is: %s"), drive_number)
- initiator_sessions = self._conn_wmi.query(
- "SELECT * FROM MSiSCSIInitiator_SessionClass")
- for initiator_session in initiator_sessions:
- devices = initiator_session.Devices
- for device in devices:
- deviceNumber = str(device.DeviceNumber)
- LOG.debug(_("DeviceNumber : %s"), deviceNumber)
- if deviceNumber == drive_number:
- return initiator_session.SessionId
-
- def _get_drive_number_from_disk_path(self, disk_path):
- LOG.debug(_("Disk path to parse: %s"), disk_path)
- start_device_id = disk_path.find('"', disk_path.find('DeviceID'))
- LOG.debug(_("start_device_id: %s"), start_device_id)
- end_device_id = disk_path.find('"', start_device_id + 1)
- LOG.debug(_("end_device_id: %s"), end_device_id)
- deviceID = disk_path[start_device_id + 1:end_device_id]
- return deviceID[deviceID.find("\\") + 2:]
-
def get_default_root_device(self):
return self._default_root_device
diff --git a/nova/virt/hyperv/volumeutils.py b/nova/virt/hyperv/volumeutils.py
index 051c37fd6..713ace258 100644
--- a/nova/virt/hyperv/volumeutils.py
+++ b/nova/virt/hyperv/volumeutils.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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
@@ -35,47 +36,48 @@ CONF = cfg.CONF
class VolumeUtils(basevolumeutils.BaseVolumeUtils):
- def __init__(self, conn_wmi):
- self._conn_wmi = conn_wmi
+ def __init__(self):
+ super(VolumeUtils, self).__init__()
- def execute(self, *args, **kwargs):
- _PIPE = subprocess.PIPE # pylint: disable=E1101
- proc = subprocess.Popen(
- [args],
- stdin=_PIPE,
- stdout=_PIPE,
- stderr=_PIPE,
- )
- stdout_value, stderr_value = proc.communicate()
- if stdout_value.find('The operation completed successfully') == -1:
- raise vmutils.HyperVException(_('An error has occurred when '
- 'calling the iscsi initiator: %s') % stdout_value)
+ def execute(self, *args, **kwargs):
+ _PIPE = subprocess.PIPE # pylint: disable=E1101
+ proc = subprocess.Popen(
+ [args],
+ stdin=_PIPE,
+ stdout=_PIPE,
+ stderr=_PIPE,
+ )
+ stdout_value, stderr_value = proc.communicate()
+ if stdout_value.find('The operation completed successfully') == -1:
+ raise vmutils.HyperVException(_('An error has occurred when '
+ 'calling the iscsi initiator: %s')
+ % stdout_value)
- def login_storage_target(self, target_lun, target_iqn, target_portal):
- """Add target portal, list targets and logins to the target."""
- separator = target_portal.find(':')
- target_address = target_portal[:separator]
- target_port = target_portal[separator + 1:]
- #Adding target portal to iscsi initiator. Sending targets
- self.execute('iscsicli.exe ' + 'AddTargetPortal ' +
- target_address + ' ' + target_port +
- ' * * * * * * * * * * * * *')
- #Listing targets
- self.execute('iscsicli.exe ' + 'LisTargets')
- #Sending login
- self.execute('iscsicli.exe ' + 'qlogintarget ' + target_iqn)
- #Waiting the disk to be mounted. Research this to avoid sleep
- time.sleep(CONF.hyperv_wait_between_attach_retry)
+ def login_storage_target(self, target_lun, target_iqn, target_portal):
+ """Add target portal, list targets and logins to the target."""
+ separator = target_portal.find(':')
+ target_address = target_portal[:separator]
+ target_port = target_portal[separator + 1:]
+ #Adding target portal to iscsi initiator. Sending targets
+ self.execute('iscsicli.exe ' + 'AddTargetPortal ' +
+ target_address + ' ' + target_port +
+ ' * * * * * * * * * * * * *')
+ #Listing targets
+ self.execute('iscsicli.exe ' + 'LisTargets')
+ #Sending login
+ self.execute('iscsicli.exe ' + 'qlogintarget ' + target_iqn)
+ #Waiting the disk to be mounted. Research this to avoid sleep
+ time.sleep(CONF.hyperv_wait_between_attach_retry)
- def logout_storage_target(self, target_iqn):
- """Logs out storage target through its session id."""
+ 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='" + target_iqn + "'")
- for session in sessions:
- self.execute_log_out(session.SessionId)
+ 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)
+ 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 6f5bcdac9..000000000
--- a/nova/virt/hyperv/volumeutilsV2.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 Pedro Navarro Perez
-# 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 for Windows 2012
-"""
-import time
-
-from nova.openstack.common import cfg
-from nova.openstack.common import log as logging
-from nova.virt.hyperv import basevolumeutils
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-
-class VolumeUtilsV2(basevolumeutils.BaseVolumeUtils):
-
- def __init__(self, conn_storage, conn_wmi):
- self._conn_storage = conn_storage
- self._conn_wmi = conn_wmi
-
- def login_storage_target(self, target_lun, target_iqn,
- target_portal):
- """Add target portal, list targets and logins to the target."""
- separator = target_portal.find(':')
- target_address = target_portal[:separator]
- target_port = target_portal[separator + 1:]
- #Adding target portal to iscsi initiator. Sending targets
- portal = self._conn_storage.__getattr__("MSFT_iSCSITargetPortal")
- portal.New(TargetPortalAddress=target_address,
- TargetPortalPortNumber=target_port)
- #Connecting to the target
- target = self._conn_storage.__getattr__("MSFT_iSCSITarget")
- target.Connect(NodeAddress=target_iqn,
- IsPersistent=True)
- #Waiting the disk to be mounted. Research this
- time.sleep(CONF.hyperv_wait_between_attach_retry)
-
- def logout_storage_target(self, target_iqn):
- """Logs out storage target through its session id."""
-
- target = self._conn_storage.MSFT_iSCSITarget(
- NodeAddress=target_iqn)[0]
- if target.IsConnected:
- session = self._conn_storage.MSFT_iSCSISession(
- TargetNodeAddress=target_iqn)[0]
- if session.IsPersistent:
- session.Unregister()
- target.Disconnect()
-
- def execute_log_out(self, session_id):
- session = self._conn_wmi.MSiSCSIInitiator_SessionClass(
- SessionId=session_id)[0]
- self.logout_storage_target(session.TargetName)
diff --git a/nova/virt/hyperv/volumeutilsv2.py b/nova/virt/hyperv/volumeutilsv2.py
new file mode 100644
index 000000000..8322d31d3
--- /dev/null
+++ b/nova/virt/hyperv/volumeutilsv2.py
@@ -0,0 +1,75 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# 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 nova.openstack.common import cfg
+from nova.openstack.common import log as logging
+from nova.virt.hyperv import basevolumeutils
+
+LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+
+
+class VolumeUtilsV2(basevolumeutils.BaseVolumeUtils):
+ def __init__(self):
+ super(VolumeUtilsV2, self).__init__()
+
+ storage_namespace = '//./root/microsoft/windows/storage'
+ if sys.platform == 'win32':
+ self._conn_storage = wmi.WMI(moniker=storage_namespace)
+
+ def login_storage_target(self, target_lun, target_iqn, target_portal):
+ """Add target portal, list targets and logins to the target."""
+ separator = target_portal.find(':')
+ target_address = target_portal[:separator]
+ target_port = target_portal[separator + 1:]
+ #Adding target portal to iscsi initiator. Sending targets
+ portal = self._conn_storage.MSFT_iSCSITargetPortal
+ portal.New(TargetPortalAddress=target_address,
+ TargetPortalPortNumber=target_port)
+ #Connecting to the target
+ target = self._conn_storage.MSFT_iSCSITarget
+ target.Connect(NodeAddress=target_iqn,
+ IsPersistent=True)
+ #Waiting the disk to be mounted. Research this
+ time.sleep(CONF.hyperv_wait_between_attach_retry)
+
+ def logout_storage_target(self, target_iqn):
+ """Logs out storage target through its session id."""
+
+ target = self._conn_storage.MSFT_iSCSITarget(NodeAddress=target_iqn)[0]
+ if target.IsConnected:
+ session = self._conn_storage.MSFT_iSCSISession(
+ TargetNodeAddress=target_iqn)[0]
+ if session.IsPersistent:
+ session.Unregister()
+ target.Disconnect()
+
+ def execute_log_out(self, session_id):
+ session = self._conn_wmi.MSiSCSIInitiator_SessionClass(
+ SessionId=session_id)[0]
+ self.logout_storage_target(session.TargetName)