XenAPI: Add option for running nova independently from hypervisor

Add the independent compute option and ensure appropriate failure cases
for all incompatible options.

Change-Id: I76c1e3a80da8142639328b204aea5da59551eea3
Implements-blueprint: xenapi-independent-nova
This commit is contained in:
Bob Ball 2016-06-21 16:36:41 +01:00
parent 5915da7402
commit eac75d49d0
5 changed files with 80 additions and 4 deletions

View File

@ -343,6 +343,20 @@ xenapi_opts = [
default='sd',
help='Specify prefix to remap VBD dev to '
'(ex. /dev/xvdb -> /dev/sdb)'),
cfg.BoolOpt('independent_compute',
default=False,
help="""
Used to prevent attempts to attach VBDs locally, so Nova can
be run in a VM on a different host.
This setting is incompatible with:
* ``CONF.flat_injected`` (Must be False)
* ``CONF.xenserver.check_host`` (Must be False)
* ``CONF.default_ephemeral_format`` (Must be unset or 'ext3')
* Joining host aggregates (will error if attempted)
* Swap disks for Windows VMs (will error if attempted)
* Nova-based auto_configure_disk (will error if attempted)
"""),
]
xenapi_vmops_opts = [

View File

@ -2090,3 +2090,9 @@ class ConcurrentUpdateDetected(NovaException):
class UnsupportedPointerModelRequested(Invalid):
msg_fmt = _("Pointer model '%(model)s' requested is not supported by "
"host.")
class NotSupportedWithOption(Invalid):
msg_fmt = _("%(operation)s is not supported in conjunction with the "
"current %(option)s setting. Please refer to the nova "
"config-reference.")

View File

@ -34,6 +34,7 @@ import six.moves.urllib.parse as urlparse
import nova.conf
from nova.i18n import _, _LE, _LW
from nova import exception
from nova.virt import driver
from nova.virt.xenapi.client import session
from nova.virt.xenapi import host
@ -82,13 +83,35 @@ class XenAPIDriver(driver.ComputeDriver):
return self._host_state
def init_host(self, host):
if CONF.xenserver.independent_compute:
def invalid_option(option_name, recommended_value):
LOG.exception(_LE('Current value of '
'CONF.xenserver.%(option)s option incompatible with '
'CONF.xenserver.independent_compute=True. '
'Consider using "%(recommended)s"') % {
'option': option_name,
'recommended': recommended_value})
raise exception.NotSupportedWithOption(
operation=option_name,
option='CONF.xenserver.independent_compute')
# Check various options are in the correct state:
if CONF.xenserver.check_host:
invalid_option('CONF.xenserver.check_host', False)
if CONF.flat_injected:
invalid_option('CONF.flat_injected', False)
if CONF.default_ephemeral_format and \
CONF.default_ephemeral_format != 'ext3':
invalid_option('CONF.default_ephemeral_format', 'ext3')
if CONF.xenserver.check_host:
vm_utils.ensure_correct_host(self._session)
try:
vm_utils.cleanup_attached_vdis(self._session)
except Exception:
LOG.exception(_LE('Failure while cleaning up attached VDIs'))
if not CONF.xenserver.independent_compute:
try:
vm_utils.cleanup_attached_vdis(self._session)
except Exception:
LOG.exception(_LE('Failure while cleaning up attached VDIs'))
def instance_exists(self, instance):
"""Checks existence of an instance on the host.

View File

@ -63,6 +63,11 @@ class ResourcePool(object):
if not pool_states.is_hv_pool(aggregate.metadata):
return
if CONF.xenserver.independent_compute:
raise exception.NotSupportedWithOption(
operation='adding to a XenServer pool',
option='CONF.xenserver.independent_compute')
invalid = {pool_states.CHANGING: _('setup in progress'),
pool_states.DISMISSED: _('aggregate deleted'),
pool_states.ERROR: _('aggregate in error')}

View File

@ -924,6 +924,10 @@ def _auto_configure_disk(session, vdi_ref, new_gb):
def try_auto_configure_disk(session, vdi_ref, new_gb):
if CONF.xenserver.independent_compute:
raise exception.NotSupportedWithOption(
operation='auto_configure_disk',
option='CONF.xenserver.independent_compute')
try:
_auto_configure_disk(session, vdi_ref, new_gb)
except exception.CannotResizeDisk as e:
@ -1031,6 +1035,11 @@ def generate_swap(session, instance, vm_ref, userdevice, name_label, swap_mb):
is_windows = instance['os_type'] == "windows"
fs_type = "vfat" if is_windows else "swap"
if CONF.xenserver.independent_compute and fs_type != "swap":
raise exception.NotSupportedWithOption(
operation='swap drives for Windows',
option='CONF.xenserver.independent_compute')
_generate_disk(session, instance, vm_ref, userdevice, name_label,
'swap', swap_mb, fs_type)
@ -1139,6 +1148,11 @@ def _create_kernel_image(context, session, instance, name_label, image_id,
Returns: A list of dictionaries that describe VDIs
"""
if CONF.xenserver.independent_compute:
raise exception.NotSupportedWithOption(
operation='Non-VHD images',
option='CONF.xenserver.independent_compute')
filename = ""
if CONF.xenserver.cache_images != 'none':
args = {}
@ -1308,6 +1322,10 @@ def _fetch_image(context, session, instance, name_label, image_id, image_type):
if image_type == ImageType.DISK_VHD:
vdis = _fetch_vhd_image(context, session, instance, image_id)
else:
if CONF.xenserver.independent_compute:
raise exception.NotSupportedWithOption(
operation='Non-VHD images',
option='CONF.xenserver.independent_compute')
vdis = _fetch_disk_image(context, session, instance, name_label,
image_id, image_type)
@ -2198,6 +2216,16 @@ def _get_dom0_ref(session):
def get_this_vm_uuid(session):
if CONF.xenserver.independent_compute:
msg = _LE("This host has been configured with the independent "
"compute flag. An operation has been attempted which is "
"incompatible with this flag, but should have been "
"caught earlier. Please raise a bug against the "
"OpenStack Nova project")
LOG.error(msg)
raise exception.NotSupportedWithOption(
operation='uncaught operation',
option='CONF.xenserver.independent_compute')
if session and session.is_local_connection:
# UUID is the control domain running on this host
vms = session.call_xenapi("VM.get_all_records_where",