diff options
| author | Dan Smith <danms@us.ibm.com> | 2012-10-31 11:51:05 -0700 |
|---|---|---|
| committer | Dan Smith <danms@us.ibm.com> | 2012-11-01 12:26:07 -0700 |
| commit | 081b652ce471c6c8c3de11edfc9deb47c48b2182 (patch) | |
| tree | 7b6af7b64672a919339a8a1a18abde6d37c8b7ee /nova/virt | |
| parent | c49d96e08121c89d42a3bcbcece63fd671f1a63d (diff) | |
Introduce VirtAPI to nova/virt
This patch introduces a VirtAPI class which will house
callbacks provided by the manager to the virt drivers, allowing
things such as direct database accesses to be pulled out of
the virt drivers and delegated to another service.
As a first step, this introduces an instance_update() method
and makes all the virt drivers use it instead of direct calls
to db.instance_update.*().
Change-Id: I2e40831f5cfb20a03b304097d84d592aab035ef1
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/baremetal/driver.py | 11 | ||||
| -rw-r--r-- | nova/virt/driver.py | 3 | ||||
| -rw-r--r-- | nova/virt/fake.py | 11 | ||||
| -rw-r--r-- | nova/virt/hyperv/driver.py | 4 | ||||
| -rw-r--r-- | nova/virt/libvirt/driver.py | 18 | ||||
| -rw-r--r-- | nova/virt/powervm/driver.py | 5 | ||||
| -rw-r--r-- | nova/virt/virtapi.py | 30 | ||||
| -rw-r--r-- | nova/virt/vmwareapi/driver.py | 4 | ||||
| -rw-r--r-- | nova/virt/xenapi/driver.py | 6 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 16 |
10 files changed, 76 insertions, 32 deletions
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py index 166eacba6..c38b0f98b 100644 --- a/nova/virt/baremetal/driver.py +++ b/nova/virt/baremetal/driver.py @@ -37,7 +37,6 @@ from nova.compute import instance_types from nova.compute import power_state from nova.compute import vm_states from nova import context as nova_context -from nova import db from nova import exception from nova import flags from nova import notifications @@ -78,11 +77,11 @@ def _late_load_cheetah(): class BareMetalDriver(driver.ComputeDriver): - def __init__(self, read_only): + def __init__(self, virtapi, read_only): _late_load_cheetah() # Note that baremetal doesn't have a read-only connection # mode, so the read_only parameter is ignored - super(BareMetalDriver, self).__init__() + super(BareMetalDriver, self).__init__(virtapi) self.baremetal_nodes = nodes.get_baremetal_nodes() self._wrapped_conn = None self._host_state = None @@ -230,7 +229,7 @@ class BareMetalDriver(driver.ComputeDriver): try: LOG.debug(_("Key is injected but instance is not running yet"), instance=instance) - (old_ref, new_ref) = db.instance_update_and_get_original( + (old_ref, new_ref) = self.virtapi.instance_update( context, instance['uuid'], {'vm_state': vm_states.BUILDING}) notifications.send_update(context, old_ref, new_ref) @@ -239,7 +238,7 @@ class BareMetalDriver(driver.ComputeDriver): if state == power_state.RUNNING: LOG.debug(_('instance %s: booted'), instance['name'], instance=instance) - (old_ref, new_ref) = db.instance_update_and_get_original( + (old_ref, new_ref) = self.virtapi.instance_update( context, instance['uuid'], {'vm_state': vm_states.ACTIVE}) notifications.send_update(context, old_ref, new_ref) @@ -254,7 +253,7 @@ class BareMetalDriver(driver.ComputeDriver): except Exception: LOG.exception(_("Baremetal assignment is overcommitted."), instance=instance) - (old_ref, new_ref) = db.instance_update_and_get_original( + (old_ref, new_ref) = self.virtapi.instance_update( context, instance['uuid'], {'vm_state': vm_states.ERROR, 'power_state': power_state.FAILED}) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index c78d063f9..a2e48508c 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -92,6 +92,9 @@ class ComputeDriver(object): "has_imagecache": False, } + def __init__(self, virtapi): + self.virtapi = virtapi + def init_host(self, host): """Initialize anything that is necessary for the driver to function, including catching up with currently running VM's on the given host.""" diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 8c3253adc..4be240792 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -30,6 +30,7 @@ from nova import db from nova import exception from nova.openstack.common import log as logging from nova.virt import driver +from nova.virt import virtapi LOG = logging.getLogger(__name__) @@ -52,7 +53,8 @@ class FakeDriver(driver.ComputeDriver): """Fake hypervisor driver""" - def __init__(self, read_only=False): + def __init__(self, virtapi, read_only=False): + super(FakeDriver, self).__init__(virtapi) self.instances = {} self.host_status = { 'host_name-description': 'Fake Host', @@ -329,3 +331,10 @@ class FakeDriver(driver.ComputeDriver): def get_volume_connector(self, instance): return {'ip': '127.0.0.1', 'initiator': 'fake', 'host': 'fakehost'} + + +class FakeVirtAPI(virtapi.VirtAPI): + def instance_update(self, context, instance_uuid, updates): + return db.instance_update_and_get_original(context, + instance_uuid, + updates) diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py index 3f43ca0a6..6d9f66ff8 100644 --- a/nova/virt/hyperv/driver.py +++ b/nova/virt/hyperv/driver.py @@ -73,8 +73,8 @@ LOG = logging.getLogger(__name__) class HyperVDriver(driver.ComputeDriver): - def __init__(self): - super(HyperVDriver, self).__init__() + def __init__(self, virtapi): + super(HyperVDriver, self).__init__(virtapi) self._hostops = hostops.HostOps() self._volumeops = volumeops.VolumeOps() diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 132a4b744..97ce1710c 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -61,7 +61,6 @@ from nova.compute import instance_types from nova.compute import power_state from nova.compute import vm_mode from nova import context as nova_context -from nova import db from nova import exception from nova import flags from nova.image import glance @@ -257,8 +256,8 @@ class LibvirtDriver(driver.ComputeDriver): "has_imagecache": True, } - def __init__(self, read_only=False): - super(LibvirtDriver, self).__init__() + def __init__(self, virtapi, read_only=False): + super(LibvirtDriver, self).__init__(virtapi) global libvirt if libvirt is None: @@ -311,7 +310,7 @@ class LibvirtDriver(driver.ComputeDriver): @property def host_state(self): if not self._host_state: - self._host_state = HostState(self.read_only) + self._host_state = HostState(self.virtapi, self.read_only) return self._host_state def has_min_version(self, ver): @@ -1621,7 +1620,7 @@ class LibvirtDriver(driver.ComputeDriver): if ephemeral_device is not None: swap_device = self.default_third_device - db.instance_update( + self.virtapi.instance_update( nova_context.get_admin_context(), instance['uuid'], {'default_ephemeral_device': '/dev/' + self.default_second_device}) @@ -1646,7 +1645,7 @@ class LibvirtDriver(driver.ComputeDriver): block_device_info)): diskswap = disk_info('disk.swap', swap_device) devices.append(diskswap) - db.instance_update( + self.virtapi.instance_update( nova_context.get_admin_context(), instance['uuid'], {'default_swap_device': '/dev/' + swap_device}) @@ -1700,7 +1699,7 @@ class LibvirtDriver(driver.ComputeDriver): # NOTE(yamahata): # for nova.api.ec2.cloud.CloudController.get_metadata() root_device = self.default_root_device - db.instance_update( + self.virtapi.instance_update( nova_context.get_admin_context(), instance['uuid'], {'root_device_name': '/dev/' + self.default_root_device}) @@ -3008,11 +3007,12 @@ class LibvirtDriver(driver.ComputeDriver): class HostState(object): """Manages information about the compute node through libvirt""" - def __init__(self, read_only): + def __init__(self, virtapi, read_only): super(HostState, self).__init__() self.read_only = read_only self._stats = {} self.connection = None + self.virtapi = virtapi self.update_status() def get_host_stats(self, refresh=False): @@ -3027,7 +3027,7 @@ class HostState(object): """Retrieve status info from libvirt.""" LOG.debug(_("Updating host stats")) if self.connection is None: - self.connection = LibvirtDriver(self.read_only) + self.connection = LibvirtDriver(self.virtapi, self.read_only) data = {} data["vcpus"] = self.connection.get_vcpu_total() data["vcpus_used"] = self.connection.get_vcpu_used() diff --git a/nova/virt/powervm/driver.py b/nova/virt/powervm/driver.py index cd91a7299..f4f26045e 100644 --- a/nova/virt/powervm/driver.py +++ b/nova/virt/powervm/driver.py @@ -18,7 +18,6 @@ from nova.compute import task_states from nova.compute import vm_states from nova import context as nova_context -from nova import db from nova import flags from nova.openstack.common import cfg @@ -59,8 +58,8 @@ class PowerVMDriver(driver.ComputeDriver): """PowerVM Implementation of Compute Driver.""" - def __init__(self): - super(PowerVMDriver, self).__init__() + def __init__(self, virtapi): + super(PowerVMDriver, self).__init__(virtapi) self._powervm = operator.PowerVMOperator() @property diff --git a/nova/virt/virtapi.py b/nova/virt/virtapi.py new file mode 100644 index 000000000..15a45b7d9 --- /dev/null +++ b/nova/virt/virtapi.py @@ -0,0 +1,30 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from nova import db + + +class VirtAPI(object): + def instance_update(self, context, instance_uuid, updates): + """Perform an instance update operation on behalf of a virt driver + :param context: security context + :param instance_uuid: uuid of the instance to be updated + :param updates: dict of attribute=value pairs to change + + Returns: orig_instance, new_instance + """ + raise NotImplementedError() diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index ec8673418..e56f81213 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -100,8 +100,8 @@ class Failure(Exception): class VMWareESXDriver(driver.ComputeDriver): """The ESX host connection object.""" - def __init__(self, read_only=False, scheme="https"): - super(VMWareESXDriver, self).__init__() + def __init__(self, virtapi, read_only=False, scheme="https"): + super(VMWareESXDriver, self).__init__(virtapi) host_ip = FLAGS.vmwareapi_host_ip host_username = FLAGS.vmwareapi_host_username diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py index 2ae4c27e9..612ae7f41 100644 --- a/nova/virt/xenapi/driver.py +++ b/nova/virt/xenapi/driver.py @@ -125,8 +125,8 @@ FLAGS.register_opts(xenapi_opts) class XenAPIDriver(driver.ComputeDriver): """A connection to XenServer or Xen Cloud Platform""" - def __init__(self, read_only=False): - super(XenAPIDriver, self).__init__() + def __init__(self, virtapi, read_only=False): + super(XenAPIDriver, self).__init__(virtapi) url = FLAGS.xenapi_connection_url username = FLAGS.xenapi_connection_username @@ -141,7 +141,7 @@ class XenAPIDriver(driver.ComputeDriver): self._volumeops = volumeops.VolumeOps(self._session) self._host_state = None self._host = host.Host(self._session) - self._vmops = vmops.VMOps(self._session) + self._vmops = vmops.VMOps(self._session, self.virtapi) self._initiator = None self._hypervisor_hostname = None self._pool = pool.ResourcePool(self._session) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 1f8cafa3b..7ccb23283 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -93,7 +93,7 @@ def cmp_version(a, b): return len(a) - len(b) -def make_step_decorator(context, instance): +def make_step_decorator(context, instance, instance_update): """Factory to create a decorator that records instance progress as a series of discrete steps. @@ -125,7 +125,7 @@ def make_step_decorator(context, instance): step_info['total'] * 100) LOG.debug(_("Updating progress to %(progress)d"), locals(), instance=instance) - db.instance_update(context, instance['uuid'], {'progress': progress}) + instance_update(context, instance['uuid'], {'progress': progress}) def step_decorator(f): step_info['total'] += 1 @@ -145,9 +145,10 @@ class VMOps(object): """ Management class for VM-related tasks """ - def __init__(self, session): + def __init__(self, session, virtapi): self.compute_api = compute.API() self._session = session + self._virtapi = virtapi self.poll_rescue_last_ran = None self.firewall_driver = firewall.load_driver( default=DEFAULT_FIREWALL_DRIVER, @@ -254,7 +255,8 @@ class VMOps(object): if name_label is None: name_label = instance['name'] - step = make_step_decorator(context, instance) + step = make_step_decorator(context, instance, + self._virtapi.instance_update) @step def determine_disk_image_type_step(undo_mgr): @@ -454,7 +456,8 @@ class VMOps(object): if instance['vm_mode'] != mode: # Update database with normalized (or determined) value - db.instance_update(context, instance['uuid'], {'vm_mode': mode}) + self._virtapi.instance_update(context, + instance['uuid'], {'vm_mode': mode}) vm_ref = vm_utils.create_vm(self._session, instance, name_label, kernel_file, ramdisk_file, use_pv_kernel) @@ -661,7 +664,8 @@ class VMOps(object): progress = round(float(step) / total_steps * 100) LOG.debug(_("Updating progress to %(progress)d"), locals(), instance=instance) - db.instance_update(context, instance['uuid'], {'progress': progress}) + self._virtapi.instance_update(context, instance['uuid'], + {'progress': progress}) def _migrate_disk_resizing_down(self, context, instance, dest, instance_type, vm_ref, sr_path): |
