diff --git a/hyperv/nova/block_device_manager.py b/hyperv/nova/block_device_manager.py index 814f2d25..f4397430 100644 --- a/hyperv/nova/block_device_manager.py +++ b/hyperv/nova/block_device_manager.py @@ -19,12 +19,12 @@ Module contains helper methods for dealing with block device information """ from nova import block_device +from nova import exception from nova.virt import configdrive from nova.virt import driver from hyperv.i18n import _ from hyperv.nova import constants -from hyperv.nova import vmutils from hyperv.nova import volumeops @@ -86,9 +86,8 @@ class BlockDeviceInfoManager(object): root_disk['type'] = self._TYPE_FOR_DISK_FORMAT.get( image_meta['disk_format']) if root_disk['type'] is None: - msg = _("Hyper-V driver does not support image type " - "%s.") % image_meta['disk_format'] - raise vmutils.HyperVException(msg) + raise exception.InvalidDiskFormat( + disk_format=image_meta['disk_format']) root_disk['path'] = None root_disk['connection_info'] = None @@ -115,7 +114,7 @@ class BlockDeviceInfoManager(object): msg = _("There are no more free slots on controller %s" ) % controller_type - raise vmutils.HyperVException(msg) + raise exception.Invalid(msg) def is_boot_from_volume(self, block_device_info): if block_device_info: @@ -156,7 +155,7 @@ class BlockDeviceInfoManager(object): "for generation %(vm_gen)s instances." ) % {'disk_bus': disk_bus, 'vm_gen': vm_gen} - raise vmutils.HyperVException(msg) + raise exception.InvalidDiskInfo(reason=msg) device_type = bdm.get('device_type') if not device_type: @@ -164,7 +163,7 @@ class BlockDeviceInfoManager(object): elif device_type != 'disk': msg = _("Hyper-V does not support disk type %s for ephemerals " "or volumes.") % device_type - raise vmutils.HyperVException(msg) + raise exception.InvalidDiskInfo(reason=msg) (bdm['drive_addr'], bdm['ctrl_disk_addr']) = self._get_available_controller_slot( diff --git a/hyperv/nova/driver.py b/hyperv/nova/driver.py index 51642ef5..220dbeb5 100644 --- a/hyperv/nova/driver.py +++ b/hyperv/nova/driver.py @@ -19,6 +19,7 @@ A Hyper-V Nova Compute driver. import platform +from nova import exception from nova.virt import driver from oslo_log import log as logging from oslo_utils import excutils @@ -34,7 +35,6 @@ from hyperv.nova import rdpconsoleops from hyperv.nova import serialconsoleops from hyperv.nova import snapshotops from hyperv.nova import vmops -from hyperv.nova import vmutils from hyperv.nova import volumeops LOG = logging.getLogger(__name__) @@ -69,12 +69,11 @@ class HyperVDriver(driver.ComputeDriver): # the version is of Windows is older than Windows Server 2012 R2. # Log an error, lettingusers know that this version is not # supported any longer. - err_msg = _LE('You are running nova-compute on an unsupported ' + LOG.error(_LE('You are running nova-compute on an unsupported ' 'version of Windows (older than Windows / Hyper-V ' 'Server 2012). The support for this version of ' - 'Windows has been removed in Mitaka.') - LOG.error(err_msg) - raise vmutils.HyperVException(err_msg) + 'Windows has been removed in Mitaka.')) + raise exception.HypervisorTooOld(version='6.2') @property def need_legacy_block_device_info(self): diff --git a/hyperv/nova/hostops.py b/hyperv/nova/hostops.py index 20a3af26..5aefa73b 100644 --- a/hyperv/nova/hostops.py +++ b/hyperv/nova/hostops.py @@ -40,7 +40,6 @@ from hyperv.i18n import _, _LE, _LI from hyperv.nova import constants from hyperv.nova import utilsfactory from hyperv.nova import vmops -from hyperv.nova import vmutils hyper_host_opts = [ cfg.IntOpt('evacuate_task_state_timeout', @@ -270,8 +269,8 @@ class HostOps(object): LOG.info(_LI('All vms have been migrated successfully.' 'Host is down for maintenance')) return 'on_maintenance' - raise vmutils.HyperVException( - _('Not all vms have been migrated: %s remaining instances.') + raise exception.MigrationError( + reason=_('Not all vms have been migrated: %s remaining instances.') % remaining_vms) def _set_service_state(self, host, binary, is_disabled): diff --git a/hyperv/nova/imagecache.py b/hyperv/nova/imagecache.py index eedfd0a5..6876e9f8 100644 --- a/hyperv/nova/imagecache.py +++ b/hyperv/nova/imagecache.py @@ -18,6 +18,7 @@ Image caching and management. import os import re +from nova import exception from nova import utils from nova.virt import imagecache from nova.virt import images @@ -29,7 +30,6 @@ from oslo_utils import uuidutils from hyperv.i18n import _ from hyperv.nova import utilsfactory -from hyperv.nova import vmutils LOG = logging.getLogger(__name__) @@ -78,12 +78,8 @@ class ImageCache(imagecache.ImageCacheManager): vhd_path, root_vhd_size)) if root_vhd_internal_size < vhd_size: - raise vmutils.HyperVException( - _("Cannot resize the image to a size smaller than the VHD " - "max. internal size: %(vhd_size)s. Requested disk size: " - "%(root_vhd_size)s") % - {'vhd_size': vhd_size, 'root_vhd_size': root_vhd_size} - ) + raise exception.FlavorDiskSmallerThanImage( + flavor_size=root_vhd_size, image_size=vhd_size) if root_vhd_internal_size > vhd_size: path_parts = os.path.splitext(vhd_path) resized_vhd_path = '%s_%s%s' % (path_parts[0], @@ -179,7 +175,7 @@ class ImageCache(imagecache.ImageCacheManager): 'Rescue image size: %(rescue_image_size)s. ' 'Flavor disk size:%(flavor_disk_size)s. ' 'Rescue image id %(rescue_image_id)s.') - raise vmutils.HyperVException(err_msg % + raise exception.FlavorDiskSmallerThanImage(err_msg % {'rescue_image_size': rescue_image_size, 'flavor_disk_size': flavor_disk_size, 'rescue_image_id': rescue_image_id}) diff --git a/hyperv/nova/migrationops.py b/hyperv/nova/migrationops.py index 7f0f053f..410fc640 100644 --- a/hyperv/nova/migrationops.py +++ b/hyperv/nova/migrationops.py @@ -31,7 +31,6 @@ from hyperv.nova import constants from hyperv.nova import imagecache from hyperv.nova import utilsfactory from hyperv.nova import vmops -from hyperv.nova import vmutils from hyperv.nova import volumeops LOG = logging.getLogger(__name__) @@ -114,22 +113,22 @@ class MigrationOps(object): if new_root_gb < curr_root_gb: raise exception.InstanceFaultRollback( - vmutils.VHDResizeException( - _("Cannot resize the root disk to a smaller size. " - "Current size: %(curr_root_gb)s GB. Requested size: " - "%(new_root_gb)s GB") % - {'curr_root_gb': curr_root_gb, - 'new_root_gb': new_root_gb})) + exception.CannotResizeDisk( + reason=_("Cannot resize the root disk to a smaller size. " + "Current size: %(curr_root_gb)s GB. Requested " + "size: %(new_root_gb)s GB.") % { + 'curr_root_gb': curr_root_gb, + 'new_root_gb': new_root_gb})) if new_eph_gb < curr_eph_gb: - raise exception.InstanceFaultRollback( - vmutils.VHDResizeException( - _("Cannot resize the ephemeral disk(s) to a smaller " - "size. Current total ephemeral size: " - "%(curr_eph_gb)s GB. Requested total size: " - "%(new_eph_gb)s GB") % - {'curr_eph_gb': curr_eph_gb, - 'new_eph_gb': new_eph_gb})) + raise exception.InstanceFaultRollback( + exception.CannotResizeDisk( + reason=_("Cannot resize the ephemeral disk(s) to a smaller" + " size. Current total ephemeral size: " + "%(curr_eph_gb)s GB. Requested total size: " + "%(new_eph_gb)s GB") % { + 'curr_eph_gb': curr_eph_gb, + 'new_eph_gb': new_eph_gb})) def migrate_disk_and_power_off(self, context, instance, dest, flavor, network_info, @@ -174,9 +173,8 @@ class MigrationOps(object): self._vmops.attach_config_drive(instance, configdrive_path, vm_gen) else: - raise vmutils.HyperVException( - _("Config drive is required by instance: %s, " - "but it does not exist.") % instance.name) + raise exception.ConfigDriveNotFound( + instance_uuid=instance.uuid) def finish_revert_migration(self, context, instance, network_info, block_device_info=None, power_on=True): @@ -186,7 +184,7 @@ class MigrationOps(object): self._revert_migration_files(instance_name) image_meta = self._imagecache.get_image_details(context, instance) - vm_gen = self._vmops.get_image_vm_generation(image_meta) + vm_gen = self._vmops.get_image_vm_generation(instance.uuid, image_meta) self._block_dev_manager.validate_and_update_bdi( instance, image_meta, vm_gen, block_device_info) @@ -196,7 +194,7 @@ class MigrationOps(object): root_device['path'] = self._pathutils.lookup_root_vhd_path( instance_name) if not root_device['path']: - raise vmutils.HyperVException( + raise exception.DiskNotFound( _("Cannot find boot VHD file for instance: %s") % instance_name) @@ -246,8 +244,12 @@ class MigrationOps(object): def _check_resize_vhd(self, vhd_path, vhd_info, new_size): curr_size = vhd_info['MaxInternalSize'] if new_size < curr_size: - raise vmutils.VHDResizeException(_("Cannot resize a VHD " - "to a smaller size")) + raise exception.CannotResizeDisk( + reason=_("Cannot resize the root disk to a smaller size. " + "Current size: %(curr_root_gb)s GB. Requested " + "size: %(new_root_gb)s GB.") % { + 'curr_root_gb': curr_size, + 'new_root_gb': new_size}) elif new_size > curr_size: self._resize_vhd(vhd_path, new_size) @@ -286,7 +288,7 @@ class MigrationOps(object): instance_name = instance.name - vm_gen = self._vmops.get_image_vm_generation(image_meta) + vm_gen = self._vmops.get_image_vm_generation(instance.uuid, image_meta) self._block_dev_manager.validate_and_update_bdi( instance, image_meta, vm_gen, block_device_info) @@ -296,9 +298,9 @@ class MigrationOps(object): root_device['path'] = self._pathutils.lookup_root_vhd_path( instance_name) if not root_device['path']: - raise vmutils.HyperVException(_("Cannot find boot VHD " - "file for instance: %s") % - instance_name) + raise exception.DiskNotFound(_("Cannot find boot VHD " + "file for instance: %s") % + instance_name) root_vhd_info = self._vhdutils.get_vhd_info(root_device['path']) src_base_disk_path = root_vhd_info.get("ParentPath") @@ -332,9 +334,9 @@ class MigrationOps(object): instance_name, eph_name) if not eph['path'] and not resize_instance: - raise vmutils.HyperVException(_("Cannot find ephemeral VHD " - "file for instance: %s") % - instance_name) + raise exception.DiskNotFound(_("Cannot find ephemeral VHD " + "file for instance: %s") % + instance_name) if resize_instance and not eph['path'] and new_eph_gb: eph['format'] = ( self._vhdutils.get_best_supported_vhd_format()) diff --git a/hyperv/nova/pathutils.py b/hyperv/nova/pathutils.py index e86a66fe..3c3ce543 100644 --- a/hyperv/nova/pathutils.py +++ b/hyperv/nova/pathutils.py @@ -21,6 +21,7 @@ import time if sys.platform == 'win32': import wmi +from nova import exception from nova import utils from oslo_config import cfg from oslo_log import log as logging @@ -166,7 +167,7 @@ class PathUtils(object): return path except WindowsError as ex: if ex.winerror == ERROR_INVALID_NAME: - raise vmutils.HyperVException(_( + raise exception.AdminRequired(_( "Cannot access \"%(instances_path)s\", make sure the " "path exists and that you have the proper permissions. " "In particular Nova-Compute must not be executed with the " diff --git a/hyperv/nova/serialconsolehandler.py b/hyperv/nova/serialconsolehandler.py index 58531f7b..61422b68 100644 --- a/hyperv/nova/serialconsolehandler.py +++ b/hyperv/nova/serialconsolehandler.py @@ -27,7 +27,6 @@ from hyperv.nova import ioutils from hyperv.nova import namedpipe from hyperv.nova import serialproxy from hyperv.nova import utilsfactory -from hyperv.nova import vmutils CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -139,7 +138,7 @@ class SerialConsoleHandler(object): if not serial_port_conns: err_msg = _("No suitable serial port pipe was found " "for instance %(instance_name)s") - raise vmutils.HyperVException( + raise exception.NovaException( err_msg % {'instance_name': self._instance_name}) serial_port_mapping = {} diff --git a/hyperv/nova/serialconsoleops.py b/hyperv/nova/serialconsoleops.py index 3966412d..c8796bff 100644 --- a/hyperv/nova/serialconsoleops.py +++ b/hyperv/nova/serialconsoleops.py @@ -17,14 +17,14 @@ import functools import os from nova import exception -from nova.i18n import _, _LI, _LE # noqa +from nova.i18n import _LI, _LE # noqa from nova import utils from oslo_config import cfg from oslo_log import log as logging +import six from hyperv.nova import serialconsolehandler from hyperv.nova import utilsfactory -from hyperv.nova import vmutils CONF = cfg.CONF @@ -101,11 +101,8 @@ class SerialConsoleOps(object): log += fp.read() return log except IOError as err: - msg = (_("Could not get instance %(instance_name)s " - "console output. Error: %(err)s") % - {'instance_name': instance_name, - 'err': err}) - raise vmutils.HyperVException(msg) + raise exception.ConsoleLogOutputException( + instance_id=instance_name, reason=six.text_type(err)) def start_console_handlers(self): active_instances = self._vmutils.get_active_instances() diff --git a/hyperv/nova/serialproxy.py b/hyperv/nova/serialproxy.py index 629b097b..5b4664f9 100644 --- a/hyperv/nova/serialproxy.py +++ b/hyperv/nova/serialproxy.py @@ -18,10 +18,10 @@ from eventlet import patcher import functools import socket +from nova import exception from nova.i18n import _ from hyperv.nova import constants -from hyperv.nova import vmutils threading = patcher.original('threading') @@ -69,7 +69,7 @@ class SerialProxy(threading.Thread): {'addr': self._addr, 'port': self._port, 'instance_name': self._instance_name, 'error': err}) - raise vmutils.HyperVException(msg) + raise exception.NovaException(msg) def stop(self): self._stopped.set() diff --git a/hyperv/nova/vmops.py b/hyperv/nova/vmops.py index e06c4d7c..21f03403 100644 --- a/hyperv/nova/vmops.py +++ b/hyperv/nova/vmops.py @@ -172,7 +172,7 @@ class VMOps(object): path = None if root_disk_info['type'] == constants.DISK: path = self._create_root_vhd(context, instance) - self.check_vm_image_type(vm_gen, path) + self.check_vm_image_type(instance.uuid, vm_gen, path) elif root_disk_info['type'] == constants.DVD: path = self._create_root_iso(context, instance) root_disk_info['path'] = path @@ -249,12 +249,8 @@ class VMOps(object): def _is_resize_needed(self, vhd_path, old_size, new_size, instance): if new_size < old_size: - error_msg = _("Cannot resize a VHD to a smaller size, the" - " original size is %(old_size)s, the" - " newer size is %(new_size)s" - ) % {'old_size': old_size, - 'new_size': new_size} - raise vmutils.VHDResizeException(error_msg) + raise exception.FlavorDiskSmallerThanImage( + flavor_size=new_size, image_size=old_size) elif new_size > old_size: LOG.debug("Resizing VHD %(vhd_path)s to new " "size %(new_size)s" % @@ -296,7 +292,7 @@ class VMOps(object): # Make sure we're starting with a clean slate. self._delete_disk_files(instance_name) - vm_gen = self.get_image_vm_generation(image_meta) + vm_gen = self.get_image_vm_generation(instance.uuid, image_meta) self._block_device_manager.validate_and_update_bdi( instance, image_meta, vm_gen, block_device_info) @@ -322,12 +318,13 @@ class VMOps(object): with excutils.save_and_reraise_exception(): self.destroy(instance) - def _requires_certificate(self, image_meta): + def _requires_certificate(self, instance_id, image_meta): os_type = image_meta.get('properties', {}).get('os_type', None) if not os_type: - raise vmutils.HyperVException( - _('For secure boot, os_type must be specified in image ' - 'properties.')) + reason = _('For secure boot, os_type must be specified in image ' + 'properties.') + raise exception.InstanceUnacceptable(instance_id=instance_id, + reason=reason) elif os_type == 'windows': return False return True @@ -349,7 +346,10 @@ class VMOps(object): else: requires_secure_boot = image_prop_secure_boot == constants.REQUIRED if vm_gen != constants.VM_GEN_2 and requires_secure_boot: - raise vmutils.HyperVException(_('Secure boot requires gen 2 VM.')) + + reason = _('Secure boot requires generation 2 VM.') + raise exception.InstanceUnacceptable(instance_id=instance.uuid, + reason=reason) return requires_secure_boot def create_instance(self, instance, network_info, root_device, @@ -391,9 +391,10 @@ class VMOps(object): constants.FLAVOR_REMOTE_FX_EXTRA_SPEC_KEY) if remote_fx_config: if vm_gen == constants.VM_GEN_2: - raise vmutils.HyperVException(_("RemoteFX is not supported " - "on generation 2 virtual " - "machines.")) + reason = _("RemoteFX is not supported on generation 2 virtual " + "machines.") + raise exception.InstanceUnacceptable(instance_id=instance.uuid, + reason=reason) else: self._configure_remotefx(instance, remote_fx_config) @@ -452,36 +453,33 @@ class VMOps(object): self._vmutils.attach_ide_drive(instance_name, path, drive_addr, ctrl_disk_addr, drive_type) - def get_image_vm_generation(self, image_meta): + def get_image_vm_generation(self, instance_id, image_meta): image_props = image_meta['properties'] default_vm_gen = self._hostutils.get_default_vm_generation() image_prop_vm = image_props.get(constants.IMAGE_PROP_VM_GEN, default_vm_gen) if image_prop_vm not in self._hostutils.get_supported_vm_types(): - LOG.error(_LE('Requested VM Generation %s is not supported on ' - ' this OS.'), image_prop_vm) - raise vmutils.HyperVException( - _('Requested VM Generation %s is not supported on this ' - 'OS.') % image_prop_vm) + reason = _LE('Requested VM Generation %s is not supported on ' + 'this OS.') % image_prop_vm + raise exception.InstanceUnacceptable(instance_id=instance_id, + reason=reason) return VM_GENERATIONS[image_prop_vm] - def check_vm_image_type(self, vm_gen, root_vhd_path): + def check_vm_image_type(self, instance_id, vm_gen, root_vhd_path): if (vm_gen != constants.VM_GEN_1 and root_vhd_path and self._vhdutils.get_vhd_format( root_vhd_path) == constants.DISK_FORMAT_VHD): - LOG.error(_LE('Requested VM Generation %s, but provided VHD ' - 'instead of VHDX.'), vm_gen) - raise vmutils.HyperVException( - _('Requested VM Generation %s, but provided VHD instead of ' - 'VHDX.') % vm_gen) + reason = _LE('Requested VM Generation %s is not supported on ' + 'this OS.') % vm_gen + raise exception.InstanceUnacceptable(instance_id=instance_id, + reason=reason) def _create_config_drive(self, instance, injected_files, admin_password, network_info, rescue=False): if CONF.config_drive_format != 'iso9660': - raise vmutils.UnsupportedConfigDriveFormatException( - _('Invalid config_drive_format "%s"') % - CONF.config_drive_format) + raise exception.ConfigDriveUnsupportedFormat( + format=CONF.config_drive_format) LOG.info(_LI('Using config drive for instance'), instance=instance) @@ -570,15 +568,17 @@ class VMOps(object): def _configure_remotefx(self, instance, config): if not CONF.hyperv.enable_remotefx: - raise vmutils.HyperVException( - _("enable_remotefx configuration option needs to be set to " - "True in order to use RemoteFX")) + reason = _("enable_remotefx configuration option needs to be set " + "to True in order to use RemoteFX") + raise exception.InstanceUnacceptable(instance_id=instance.uuid, + reason=reason) if not self._hostutils.check_server_feature( self._hostutils.FEATURE_RDS_VIRTUALIZATION): - raise vmutils.HyperVException( - _("The RDS-Virtualization feature must be installed " - "in order to use RemoteFX")) + reason = _("The RDS-Virtualization feature must be installed in " + "order to use RemoteFX") + raise exception.InstanceUnacceptable(instance_id=instance.uuid, + reason=reason) instance_name = instance.name LOG.debug('Configuring RemoteFX for instance: %s', instance_name) @@ -837,9 +837,9 @@ class VMOps(object): if port_number not in [1, 2]: err_msg = _("Invalid serial port number: %(port_number)s. " - "Only COM 1 and COM 2 are available.") - raise vmutils.HyperVException( - err_msg % {'port_number': port_number}) + "Only COM 1 and COM 2 are available.") % dict( + port_number=port_number) + raise exception.ImageSerialPortNumberInvalid(err_msg) existing_type = serial_ports.get(port_number) if (not existing_type or @@ -854,24 +854,27 @@ class VMOps(object): rescue_vhd_path = self._create_root_vhd( context, instance, rescue_image_id=rescue_image_id) - rescue_vm_gen = self.get_image_vm_generation(image_meta) + rescue_vm_gen = self.get_image_vm_generation(instance.uuid, image_meta) vm_gen = self._vmutils.get_vm_gen(instance.name) if rescue_vm_gen != vm_gen: err_msg = _('The requested rescue image requires a different VM ' 'generation than the actual rescued instance. ' 'Rescue image VM generation: %(rescue_vm_gen)s. ' - 'Rescued instance VM generation: %(vm_gen)s.') - raise vmutils.HyperVException(err_msg % - {'rescue_vm_gen': rescue_vm_gen, - 'vm_gen': vm_gen}) - self.check_vm_image_type(rescue_vm_gen, rescue_vhd_path) + 'Rescued instance VM generation: %(vm_gen)s.') % dict( + rescue_vm_gen=rescue_vm_gen, + vm_gen=vm_gen) + raise exception.ImageUnacceptable(reason=err_msg, + image_id=rescue_image_id) + + self.check_vm_image_type(instance.uuid, rescue_vm_gen, rescue_vhd_path) root_vhd_path = self._pathutils.lookup_root_vhd_path(instance.name) if not root_vhd_path: err_msg = _('Instance root disk image could not be found. ' 'Rescuing instances booted from volume is ' 'not supported.') - raise vmutils.HyperVException(err_msg) + raise exception.InstanceNotRescuable(reason=err_msg, + instance_id=instance.uuid) controller_type = VM_GENERATIONS_CONTROLLER_TYPES[vm_gen] @@ -904,9 +907,9 @@ class VMOps(object): if (instance.vm_state == vm_states.RESCUED and not (rescue_vhd_path and root_vhd_path)): - err_msg = _('Missing instance root and/or rescue image. ' - 'The instance cannot be unrescued.') - raise vmutils.HyperVException(err_msg) + err_msg = _('Missing instance root and/or rescue image.') + raise exception.InstanceNotRescuable(reason=err_msg, + instance_id=instance.uuid) vm_gen = self._vmutils.get_vm_gen(instance.name) controller_type = VM_GENERATIONS_CONTROLLER_TYPES[vm_gen] diff --git a/hyperv/nova/volumeops.py b/hyperv/nova/volumeops.py index ae655125..c7726b8d 100644 --- a/hyperv/nova/volumeops.py +++ b/hyperv/nova/volumeops.py @@ -177,7 +177,7 @@ class VolumeOps(object): "Requested maximum IOPS: %(total_iops)s.") % {'min_iops': min_iops, 'total_iops': total_iops}) - raise vmutils.HyperVException(err_msg) + raise exception.Invalid(err_msg) unsupported_specs = [spec for spec in qos_specs if spec not in self._SUPPORTED_QOS_SPECS] @@ -224,11 +224,12 @@ class ISCSIVolumeDriver(object): auth_password = data.get('auth_password') if auth_method and auth_method.upper() != 'CHAP': - raise vmutils.HyperVException( - _("Cannot log in target %(target_iqn)s. Unsupported iSCSI " - "authentication method: %(auth_method)s.") % - {'target_iqn': target_iqn, - 'auth_method': auth_method}) + LOG.error(_LE("Cannot log in target %(target_iqn)s. Unsupported " + "iSCSI authentication method: %(auth_method)s."), + {'target_iqn': target_iqn, + 'auth_method': auth_method}) + raise exception.UnsupportedBDMVolumeAuthMethod( + auth_method=auth_method) # Check if we already logged in if self._volutils.get_device_number_for_target(target_iqn, target_lun): @@ -443,9 +444,12 @@ class SMBFSVolumeDriver(object): ctrller_path, slot) except vmutils.HyperVException as exn: - LOG.exception(_LE('Attach volume failed: %s'), exn) - raise vmutils.HyperVException(_('Unable to attach volume ' - 'to instance %s') % instance_name) + LOG.exception(_LE('Attach volume failed to %(instance_name)s: ' + '%(exn)s'), {'instance_name': instance_name, + 'exn': exn}) + raise exception.VolumeAttachFailed( + volume_id=connection_info['data']['volume_id'], + reason=exn.message) def detach_volume(self, connection_info, instance_name): LOG.debug("Detaching volume: %(connection_info)s " diff --git a/hyperv/tests/unit/test_blockdevicemanager.py b/hyperv/tests/unit/test_blockdevicemanager.py index d0b5d853..bf6d1802 100644 --- a/hyperv/tests/unit/test_blockdevicemanager.py +++ b/hyperv/tests/unit/test_blockdevicemanager.py @@ -14,10 +14,10 @@ import mock +from nova import exception from hyperv.nova import block_device_manager from hyperv.nova import constants -from hyperv.nova import vmutils from hyperv.tests.unit import test_base @@ -106,7 +106,7 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): mock_get_avail_ctrl_slot, disk_format, vm_gen=constants.VM_GEN_1, - exception=False, + fail=False, boot_from_volume=False): image_meta = {'disk_format': disk_format} bdi = {'root_device': '/dev/sda', @@ -116,8 +116,8 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): mock_is_boot_from_vol.return_value = boot_from_volume mock_get_avail_ctrl_slot.return_value = (0, 0) - if exception: - self.assertRaises(vmutils.HyperVException, + if fail: + self.assertRaises(exception.InvalidDiskFormat, self._bdman._check_and_update_root_device, vm_gen, image_meta, bdi, mock.sentinel.SLOT_MAP) @@ -148,7 +148,7 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): def test_check_and_update_root_device_exception(self): self._test_check_and_update_root_device(disk_format='fake_format', - exception=True) + fail=True) def test_check_and_update_root_device_gen1(self): self._test_check_and_update_root_device(disk_format='vhd') @@ -172,15 +172,15 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): @mock.patch('nova.virt.configdrive.required_by', return_value=True) def _test_get_available_controller_slot(self, mock_config_drive_req, bus=constants.CTRL_TYPE_IDE, - exception=False): + fail=False): slot_map = self._bdman._initialize_controller_slot_counter( mock.sentinel.FAKE_VM, constants.VM_GEN_1) - if exception: + if fail: slot_map[constants.CTRL_TYPE_IDE][0] = 0 slot_map[constants.CTRL_TYPE_IDE][1] = 0 - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.Invalid, self._bdman._get_available_controller_slot, constants.CTRL_TYPE_IDE, slot_map) @@ -196,7 +196,7 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): self._test_get_available_controller_slot() def test_get_available_controller_slot_exception(self): - self._test_get_available_controller_slot(exception=True) + self._test_get_available_controller_slot(fail=True) def test_get_available_controller_slot_scsi_ctrl(self): self._test_get_available_controller_slot(bus=constants.CTRL_TYPE_SCSI) @@ -265,13 +265,13 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): @mock.patch.object(block_device_manager.BlockDeviceInfoManager, '_get_available_controller_slot') def _test_check_and_update_bdm(self, mock_get_ctrl_slot, - bdm, exception=False, + bdm, fail=False, vm_gen=constants.VM_GEN_1, slot_map=None): mock_get_ctrl_slot.return_value = ((mock.sentinel.DRIVE_ADDR, mock.sentinel.CTRL_DISK_ADDR)) - if exception: - self.assertRaises(vmutils.HyperVException, + if fail: + self.assertRaises(exception.InvalidDiskInfo, self._bdman._check_and_update_bdm, slot_map, vm_gen, bdm) else: @@ -297,14 +297,14 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): bdm = {'device_type': 'cdrom', 'disk_bus': 'IDE'} - self._test_check_and_update_bdm(bdm=bdm, exception=True, + self._test_check_and_update_bdm(bdm=bdm, fail=True, slot_map=mock.sentinel.FAKE_SLOT_MAP) def test_check_and_update_bdm_exception_disk_bus(self): bdm = {'device_type': 'disk', 'disk_bus': 'fake_bus'} - self._test_check_and_update_bdm(bdm=bdm, exception=True, + self._test_check_and_update_bdm(bdm=bdm, fail=True, slot_map=mock.sentinel.FAKE_SLOT_MAP) def test_sort_by_boot_order(self): diff --git a/hyperv/tests/unit/test_driver.py b/hyperv/tests/unit/test_driver.py index c3dead84..5f3e360f 100644 --- a/hyperv/tests/unit/test_driver.py +++ b/hyperv/tests/unit/test_driver.py @@ -20,10 +20,10 @@ Unit tests for the Hyper-V Driver. import platform import mock +from nova import exception from nova.virt import driver as base_driver from hyperv.nova import driver -from hyperv.nova import vmutils from hyperv.tests.unit import test_base @@ -51,7 +51,7 @@ class HyperVDriverTestCase(test_base.HyperVBaseTestCase): def test_check_minimum_windows_version(self, mock_check_min_win_version): mock_check_min_win_version.return_value = False - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.HypervisorTooOld, self.driver._check_minimum_windows_version) def test_public_api_signatures(self): diff --git a/hyperv/tests/unit/test_hostops.py b/hyperv/tests/unit/test_hostops.py index 90df7080..11e16891 100644 --- a/hyperv/tests/unit/test_hostops.py +++ b/hyperv/tests/unit/test_hostops.py @@ -26,7 +26,6 @@ import six from hyperv.nova import constants from hyperv.nova import hostops -from hyperv.nova import vmutils from hyperv.tests.unit import test_base CONF = cfg.CONF @@ -254,7 +253,7 @@ class HostOpsTestCase(test_base.HyperVBaseTestCase): host=mock.sentinel.HOST, mode=True) self.assertEqual('on_maintenance', result) else: - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.MigrationError, self._hostops.host_maintenance_mode, host=mock.sentinel.HOST, mode=True) diff --git a/hyperv/tests/unit/test_imagecache.py b/hyperv/tests/unit/test_imagecache.py index c0a995f8..eeb8de3a 100644 --- a/hyperv/tests/unit/test_imagecache.py +++ b/hyperv/tests/unit/test_imagecache.py @@ -20,10 +20,10 @@ from nova import exception from nova import objects from nova.tests.unit.objects import test_flavor from oslo_config import cfg +from oslo_utils import units from hyperv.nova import constants from hyperv.nova import imagecache -from hyperv.nova import vmutils from hyperv.tests import fake_instance from hyperv.tests.unit import test_base @@ -36,6 +36,7 @@ class ImageCacheTestCase(test_base.HyperVBaseTestCase): FAKE_BASE_DIR = 'fake/base/dir' FAKE_FORMAT = 'fake_format' FAKE_IMAGE_REF = 'fake_image_ref' + FAKE_VHD_SIZE_GB = 1 def setUp(self): super(ImageCacheTestCase, self).setUp() @@ -47,6 +48,27 @@ class ImageCacheTestCase(test_base.HyperVBaseTestCase): self.imagecache._pathutils = mock.MagicMock() self.imagecache._vhdutils = mock.MagicMock() + @mock.patch.object(imagecache.ImageCache, '_get_root_vhd_size_gb') + def test_resize_and_cache_vhd_smaller(self, mock_get_vhd_size_gb): + self.imagecache._vhdutils.get_vhd_info.return_value = { + 'MaxInternalSize': (self.FAKE_VHD_SIZE_GB + 1) * units.Gi + } + mock_get_vhd_size_gb.return_value = self.FAKE_VHD_SIZE_GB + mock_internal_vhd_size = ( + self.imagecache._vhdutils.get_internal_vhd_size_by_file_size) + mock_internal_vhd_size.return_value = self.FAKE_VHD_SIZE_GB * units.Gi + + self.assertRaises(exception.FlavorDiskSmallerThanImage, + self.imagecache._resize_and_cache_vhd, + mock.sentinel.instance, + mock.sentinel.vhd_path) + + self.imagecache._vhdutils.get_vhd_info.assert_called_once_with( + mock.sentinel.vhd_path) + mock_get_vhd_size_gb.assert_called_once_with(mock.sentinel.instance) + mock_internal_vhd_size.assert_called_once_with( + mock.sentinel.vhd_path, self.FAKE_VHD_SIZE_GB * units.Gi) + def _test_get_root_vhd_size_gb(self, old_flavor=True): if old_flavor: mock_flavor = objects.Flavor(**test_flavor.fake_flavor) @@ -145,7 +167,7 @@ class ImageCacheTestCase(test_base.HyperVBaseTestCase): expected_vhd_path) = self._prepare_get_cached_image( rescue_image_id=fake_rescue_image_id, image_format=constants.DISK_FORMAT_VHD) - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.FlavorDiskSmallerThanImage, self.imagecache.get_cached_image, self.context, self.instance, fake_rescue_image_id) diff --git a/hyperv/tests/unit/test_migrationops.py b/hyperv/tests/unit/test_migrationops.py index 423395b0..29f4a1f4 100644 --- a/hyperv/tests/unit/test_migrationops.py +++ b/hyperv/tests/unit/test_migrationops.py @@ -171,7 +171,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): instance.config_drive = 'True' self._migrationops._pathutils.lookup_configdrive_path.return_value = ( None) - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.ConfigDriveNotFound, self._migrationops._check_and_attach_config_drive, instance, mock.sentinel.FAKE_VM_GEN) @@ -260,7 +260,8 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): image_meta = ( self._migrationops._imagecache.get_image_details.return_value) get_image_vm_gen = self._migrationops._vmops.get_image_vm_generation - get_image_vm_gen.assert_called_once_with(image_meta) + get_image_vm_gen.assert_called_once_with( + mock_instance.uuid, image_meta) self._migrationops._vmops.create_instance.assert_called_once_with( mock_instance, mock.sentinel.network_info, root_device, block_device_info, get_image_vm_gen.return_value, @@ -294,7 +295,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): self._migrationops._pathutils.lookup_root_vhd_path.return_value = None self.assertRaises( - vmutils.HyperVException, + exception.DiskNotFound, self._migrationops.finish_revert_migration, self.context, mock_instance, mock.sentinel.network_info, bdi, True) @@ -345,7 +346,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): mock_resize_vhd.assert_called_once_with(mock.sentinel.vhd_path, 2) def test_check_resize_vhd_exception(self): - self.assertRaises(vmutils.VHDResizeException, + self.assertRaises(exception.CannotResizeDisk, self._migrationops._check_resize_vhd, mock.sentinel.vhd_path, {'MaxInternalSize': 1}, 0) @@ -436,7 +437,8 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): self._migrationops._vhdutils.get_vhd_info.assert_has_calls( expected_get_info) get_image_vm_gen = self._migrationops._vmops.get_image_vm_generation - get_image_vm_gen.assert_called_once_with(mock.sentinel.image_meta) + get_image_vm_gen.assert_called_once_with(mock_instance.uuid, + mock.sentinel.image_meta) self._migrationops._vmops.create_instance.assert_called_once_with( mock_instance, mock.sentinel.network_info, root_device, block_device_info, get_image_vm_gen.return_value, @@ -473,7 +475,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): mock_instance = fake_instance.fake_instance_obj(self.context) self._migrationops._pathutils.lookup_root_vhd_path.return_value = None - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.DiskNotFound, self._migrationops.finish_migration, self.context, mock.sentinel.migration, mock_instance, mock.sentinel.disk_info, @@ -481,7 +483,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): mock.sentinel.image_meta, True, bdi, True) - def _test_check_ephemeral_disks(self, exception, resize): + def _test_check_ephemeral_disks(self, exc, resize): mock_ephemerals = [dict(), dict()] mock_instance = fake_instance.fake_instance_obj(self.context) mock_instance.ephemeral_gb = 2 @@ -496,8 +498,8 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): mock_get_vhd_format = mock_vhdutils.get_best_supported_vhd_format mock_get_vhd_format.return_value = mock.sentinel.VHD_FORMAT - if exception: - self.assertRaises(vmutils.HyperVException, + if exc: + self.assertRaises(exception.DiskNotFound, self._migrationops._check_ephemeral_disks, mock_instance, mock_ephemerals) else: @@ -518,7 +520,7 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): mock_instance.name, mock_ephemerals[1]) def test_check_ephemeral_disks_exception(self): - self._test_check_ephemeral_disks(exception=True, resize=False) + self._test_check_ephemeral_disks(exc=True, resize=False) def test_check_ephemeral_disks(self): - self._test_check_ephemeral_disks(exception=False, resize=True) + self._test_check_ephemeral_disks(exc=False, resize=True) diff --git a/hyperv/tests/unit/test_pathutils.py b/hyperv/tests/unit/test_pathutils.py index 17c19072..7049e0c2 100644 --- a/hyperv/tests/unit/test_pathutils.py +++ b/hyperv/tests/unit/test_pathutils.py @@ -16,6 +16,7 @@ import os import time import mock +from nova import exception from six.moves import builtins from hyperv.nova import constants @@ -200,7 +201,7 @@ class PathUtilsTestCase(test_base.HyperVBaseTestCase): side_effect=WindowsError(pathutils.ERROR_INVALID_NAME)) with mock.patch.object(builtins, 'WindowsError', fake_windows_error, create=True): - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.AdminRequired, self._pathutils._get_instances_sub_dir, fake_dir_name) diff --git a/hyperv/tests/unit/test_serialconsolehandler.py b/hyperv/tests/unit/test_serialconsolehandler.py index 7af88f7f..6a3be84c 100644 --- a/hyperv/tests/unit/test_serialconsolehandler.py +++ b/hyperv/tests/unit/test_serialconsolehandler.py @@ -23,7 +23,6 @@ from hyperv.nova import namedpipe from hyperv.nova import serialconsolehandler from hyperv.nova import serialproxy from hyperv.nova import utilsfactory -from hyperv.nova import vmutils from hyperv.tests.unit import test_base @@ -228,7 +227,7 @@ class SerialConsoleHandlerTestCase(test_base.HyperVBaseTestCase): def test_get_vm_serial_port_mapping_exception(self): self._mock_get_port_connections([]) - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.NovaException, self._consolehandler._get_vm_serial_port_mapping) @mock.patch('nova.console.type.ConsoleSerial') diff --git a/hyperv/tests/unit/test_serialconsoleops.py b/hyperv/tests/unit/test_serialconsoleops.py index bdede152..a7a140ff 100644 --- a/hyperv/tests/unit/test_serialconsoleops.py +++ b/hyperv/tests/unit/test_serialconsoleops.py @@ -20,7 +20,6 @@ from nova import exception from hyperv.nova import serialconsolehandler from hyperv.nova import serialconsoleops -from hyperv.nova import vmutils from hyperv.tests.unit import test_base @@ -98,7 +97,7 @@ class SerialConsoleOpsTestCase(test_base.HyperVBaseTestCase): fake_open.side_effect = IOError fake_path_exists.return_value = True - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.ConsoleLogOutputException, self._serialops.get_console_output, mock.sentinel.instance_name) fake_open.assert_called_once_with(mock.sentinel.log_path, 'rb') diff --git a/hyperv/tests/unit/test_serialproxy.py b/hyperv/tests/unit/test_serialproxy.py index acf4d31a..5e5c95b3 100644 --- a/hyperv/tests/unit/test_serialproxy.py +++ b/hyperv/tests/unit/test_serialproxy.py @@ -14,10 +14,10 @@ # under the License. import mock +from nova import exception import socket from hyperv.nova import serialproxy -from hyperv.nova import vmutils from hyperv.tests.unit import test_base @@ -49,7 +49,7 @@ class SerialProxyTestCase(test_base.HyperVBaseTestCase): fake_socket.listen.side_effect = socket.error - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.NovaException, self._proxy._setup_socket) fake_socket.setsockopt.assert_called_once_with(socket.SOL_SOCKET, diff --git a/hyperv/tests/unit/test_vmops.py b/hyperv/tests/unit/test_vmops.py index b338e601..49277a94 100644 --- a/hyperv/tests/unit/test_vmops.py +++ b/hyperv/tests/unit/test_vmops.py @@ -154,7 +154,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_get_cached_image.return_value = fake_vhd_path fake_root_path = self._vmops._pathutils.get_root_vhd_path.return_value - self.assertRaises(vmutils.VHDResizeException, + self.assertRaises(exception.FlavorDiskSmallerThanImage, self._vmops._create_root_vhd, self.context, mock_instance) @@ -256,7 +256,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): def test_is_resize_needed_exception(self): inst = mock.MagicMock() self.assertRaises( - vmutils.VHDResizeException, self._vmops._is_resize_needed, + exception.FlavorDiskSmallerThanImage, + self._vmops._is_resize_needed, mock.sentinel.FAKE_PATH, self.FAKE_SIZE, self.FAKE_SIZE - 1, inst) def test_is_resize_needed_true(self): @@ -284,7 +285,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_create_root_device.assert_called_once_with(self.context, mock_instance) mock_check_vm_image_type.assert_called_once_with( - mock.sentinel.VM_GEN_1, mock.sentinel.VHD_PATH) + mock_instance.uuid, mock.sentinel.VM_GEN_1, mock.sentinel.VHD_PATH) @mock.patch.object(vmops.VMOps, '_create_root_iso') def test_create_root_device_type_iso(self, mock_create_root_iso): @@ -427,7 +428,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): fake_vm_gen) mock_create_ephemerals.assert_called_once_with(mock_instance, block_device_info['ephemerals']) - mock_get_image_vm_gen.assert_called_once_with(mock_image_meta) + mock_get_image_vm_gen.assert_called_once_with( + mock_instance.uuid, mock_image_meta) mock_create_instance.assert_called_once_with( mock_instance, [fake_network_info], root_device_info, block_device_info, fake_vm_gen, mock_image_meta) @@ -696,8 +698,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._hostutils.get_supported_vm_types.return_value = [ constants.IMAGE_PROP_VM_GEN_1, constants.IMAGE_PROP_VM_GEN_2] - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.InstanceUnacceptable, self._vmops.get_image_vm_generation, + mock.sentinel.instance_id, image_meta) def test_get_image_vm_generation_default(self): @@ -707,7 +710,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._hostutils.get_supported_vm_types.return_value = [ constants.IMAGE_PROP_VM_GEN_1, constants.IMAGE_PROP_VM_GEN_2] - response = self._vmops.get_image_vm_generation(image_meta) + response = self._vmops.get_image_vm_generation( + mock.sentinel.instance_id, image_meta) self.assertEqual(constants.VM_GEN_1, response) @@ -717,7 +721,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._hostutils.get_supported_vm_types.return_value = [ constants.IMAGE_PROP_VM_GEN_1, constants.IMAGE_PROP_VM_GEN_2] - response = self._vmops.get_image_vm_generation(image_meta) + response = self._vmops.get_image_vm_generation( + mock.sentinel.instance_id, image_meta) self.assertEqual(constants.VM_GEN_2, response) @@ -728,9 +733,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._vhdutils.get_vhd_format = mock.MagicMock( return_value=constants.DISK_FORMAT_VHD) - self.assertRaises(vmutils.HyperVException, - self._vmops.check_vm_image_type, constants.VM_GEN_2, - mock.sentinel.FAKE_VHD_PATH) + self.assertRaises(exception.InstanceUnacceptable, + self._vmops.check_vm_image_type, mock.sentinel.instance_id, + constants.VM_GEN_2, mock.sentinel.FAKE_VHD_PATH) @mock.patch('nova.api.metadata.base.InstanceMetadata') @mock.patch('nova.virt.configdrive.ConfigDriveBuilder') @@ -766,7 +771,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): expected_get_configdrive_path_calls.append(expected_call) if config_drive_format != self.ISO9660: - self.assertRaises(vmutils.UnsupportedConfigDriveFormatException, + self.assertRaises(exception.ConfigDriveUnsupportedFormat, self._vmops._create_config_drive, mock_instance, [mock.sentinel.FILE], mock.sentinel.PASSWORD, @@ -1278,36 +1283,39 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): @mock.patch.object(vmops.VMOps, '_create_root_vhd') @mock.patch.object(vmops.VMOps, 'get_image_vm_generation') - def _test_rescue_instance_exception(self, mock_get_image_vm_gen, - mock_create_root_vhd, - wrong_vm_gen=False, - boot_from_volume=False): - mock_vm_gen = constants.VM_GEN_1 - image_vm_gen = (mock_vm_gen - if not wrong_vm_gen else constants.VM_GEN_2) + def test_rescue_instance_boot_from_volume(self, mock_get_image_vm_gen, + mock_create_root_vhd): mock_image_meta = {'id': mock.sentinel.rescue_image_id} mock_instance = fake_instance.fake_instance_obj(self.context) - mock_get_image_vm_gen.return_value = image_vm_gen - self._vmops._vmutils.get_vm_gen.return_value = mock_vm_gen - self._vmops._pathutils.lookup_root_vhd_path.return_value = ( - mock.sentinel.root_vhd_path if not boot_from_volume else None) + mock_get_image_vm_gen.return_value = constants.VM_GEN_1 + self._vmops._vmutils.get_vm_gen.return_value = constants.VM_GEN_1 + self._vmops._pathutils.lookup_root_vhd_path.return_value = None - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.InstanceNotRescuable, self._vmops.rescue_instance, self.context, mock_instance, mock.sentinel.network_info, mock_image_meta, mock.sentinel.rescue_password) - def test_rescue_instance_wrong_vm_gen(self): + @mock.patch.object(vmops.VMOps, '_create_root_vhd') + @mock.patch.object(vmops.VMOps, 'get_image_vm_generation') + def test_rescue_instance_wrong_vm_gen(self, mock_get_image_vm_gen, + mock_create_root_vhd): # Test the case when the rescue image requires a different # vm generation than the actual rescued instance. - self._test_rescue_instance_exception(wrong_vm_gen=True) + mock_image_meta = {'id': mock.sentinel.rescue_image_id} + mock_instance = fake_instance.fake_instance_obj(self.context) + mock_get_image_vm_gen.return_value = constants.VM_GEN_1 + self._vmops._vmutils.get_vm_gen.return_value = constants.VM_GEN_2 - def test_rescue_instance_boot_from_volume(self): - # Rescuing instances booted from volume is not supported. - self._test_rescue_instance_exception(boot_from_volume=True) + self.assertRaises(exception.ImageUnacceptable, + self._vmops.rescue_instance, + self.context, mock_instance, + mock.sentinel.network_info, + mock_image_meta, + mock.sentinel.rescue_password) @mock.patch.object(fileutils, 'delete_if_exists') @mock.patch.object(vmops.VMOps, '_attach_drive') @@ -1363,7 +1371,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_instance.vm_state = vm_states.RESCUED self._vmops._pathutils.lookup_root_vhd_path.return_value = None - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.InstanceNotRescuable, self._vmops.unrescue_instance, mock_instance) @@ -1423,7 +1431,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): def test_get_instance_vnuma_config_no_topology(self): self._check_get_instance_vnuma_config() - def _test_configure_remotefx(self, exception=False): + def _test_configure_remotefx(self, fail=False): self.flags(enable_remotefx=True, group='hyperv') mock_instance = fake_instance.fake_instance_obj(self.context) @@ -1435,9 +1443,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): enable_remotefx = self._vmops._vmutils.enable_remotefx_video_adapter self._vmops._hostutils.check_server_feature = mock.MagicMock() - if exception: + if fail: self._vmops._hostutils.check_server_feature.return_value = False - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.InstanceUnacceptable, self._vmops._configure_remotefx, mock_instance, fake_config) else: @@ -1447,7 +1455,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): fake_resolution) def test_configure_remotefx_exception(self): - self._test_configure_remotefx(exception=True) + self._test_configure_remotefx(fail=True) def test_configure_remotefx(self): self._test_configure_remotefx() @@ -1570,7 +1578,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): expected_exception = not (logging_port in acceptable_ports and interactive_port in acceptable_ports) if expected_exception: - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.ImageSerialPortNumberInvalid, self._vmops._get_image_serial_port_settings, mock_image_meta) else: @@ -1707,11 +1715,13 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): def _test_requires_certificate(self, os_type): image_meta = {'properties': {'os_type': os_type}} if not os_type: - self.assertRaises(vmutils.HyperVException, - self._vmops._requires_certificate, image_meta) + self.assertRaises(exception.InstanceUnacceptable, + self._vmops._requires_certificate, + mock.sentinel.instance_id, image_meta) else: expected_result = os_type == 'linux' - result = self._vmops._requires_certificate(image_meta) + result = self._vmops._requires_certificate( + mock.sentinel.instance_id, image_meta) self.assertEqual(expected_result, result) def test_requires_certificate_windows(self): diff --git a/hyperv/tests/unit/test_volumeops.py b/hyperv/tests/unit/test_volumeops.py index c36be0a2..788ca6f6 100644 --- a/hyperv/tests/unit/test_volumeops.py +++ b/hyperv/tests/unit/test_volumeops.py @@ -31,7 +31,8 @@ from hyperv.tests.unit import test_base CONF = cfg.CONF -connection_data = {'target_lun': mock.sentinel.fake_lun, +connection_data = {'volume_id': 'fake_vol_id', + 'target_lun': mock.sentinel.fake_lun, 'target_iqn': mock.sentinel.fake_iqn, 'target_portal': mock.sentinel.fake_portal, 'auth_method': 'chap', @@ -217,7 +218,7 @@ class VolumeOpsTestCase(test_base.HyperVBaseTestCase): 'min_iops_sec': 2 } - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.Invalid, self._volumeops.parse_disk_qos_specs, fake_qos_specs) @@ -244,7 +245,7 @@ class ISCSIVolumeDriverTestCase(test_base.HyperVBaseTestCase): connection_info = get_fake_connection_info( auth_method='fake_auth_method') - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.UnsupportedBDMVolumeAuthMethod, self._volume_driver.login_storage_target, connection_info) @@ -483,7 +484,8 @@ class SMBFSVolumeDriverTestCase(test_base.HyperVBaseTestCase): _FAKE_PASSWORD) _FAKE_CONNECTION_INFO = {'data': {'export': _FAKE_SHARE, 'name': _FAKE_DISK_NAME, - 'options': _FAKE_SMB_OPTIONS}} + 'options': _FAKE_SMB_OPTIONS, + 'volume_id': 'fake_vol_id'}} def setUp(self): super(SMBFSVolumeDriverTestCase, self).setUp() @@ -542,7 +544,7 @@ class SMBFSVolumeDriverTestCase(test_base.HyperVBaseTestCase): mock_ensure_share_mounted): self._volume_driver._vmutils.attach_drive.side_effect = ( vmutils.HyperVException()) - self.assertRaises(vmutils.HyperVException, + self.assertRaises(exception.VolumeAttachFailed, self._volume_driver.attach_volume, self._FAKE_CONNECTION_INFO, mock.sentinel.instance_name)