Hyper-V: refines the exceptions raised in the driver
The exceptions raised in the HyperVDriver are too generic. This commit addresses this issue. Partially Implements: blueprint add-os-win-library Change-Id: I05f1fa21540dad36bb4b04c8eebe8cc0b8585c1f
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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,21 +113,21 @@ 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,
|
||||
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 "
|
||||
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)s GB") % {
|
||||
'curr_eph_gb': curr_eph_gb,
|
||||
'new_eph_gb': new_eph_gb}))
|
||||
|
||||
def migrate_disk_and_power_off(self, context, instance, dest,
|
||||
@@ -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,7 +298,7 @@ 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 "
|
||||
raise exception.DiskNotFound(_("Cannot find boot VHD "
|
||||
"file for instance: %s") %
|
||||
instance_name)
|
||||
|
||||
@@ -332,7 +334,7 @@ class MigrationOps(object):
|
||||
instance_name, eph_name)
|
||||
|
||||
if not eph['path'] and not resize_instance:
|
||||
raise vmutils.HyperVException(_("Cannot find ephemeral VHD "
|
||||
raise exception.DiskNotFound(_("Cannot find ephemeral VHD "
|
||||
"file for instance: %s") %
|
||||
instance_name)
|
||||
if resize_instance and not eph['path'] and new_eph_gb:
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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.") %
|
||||
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 "
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user