summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrent Eagles <beagles@redhat.com>2013-06-06 15:33:42 -0230
committerBrent Eagles <beagles@redhat.com>2013-06-25 15:43:27 -0230
commitdb3989586a8d5bbbcf857b9294a124ecc5fc57e8 (patch)
treeca857e6ef4dbd6074a54259b6e94543e29e88372
parent9331c5c1115c7d8cc5bcab71b1100eeea1ce72fe (diff)
downloadnova-db3989586a8d5bbbcf857b9294a124ecc5fc57e8.tar.gz
nova-db3989586a8d5bbbcf857b9294a124ecc5fc57e8.tar.xz
nova-db3989586a8d5bbbcf857b9294a124ecc5fc57e8.zip
Refresh volume connections when starting instances
This patches adds network and block device information to the signature of the power_on method on the virtualization driver. The relevant call sites are also modified to provide the required information. The libvirt implementation of power_on has been altered to re-establish network and volume related connections. Fixes bug: 1188326 Change-Id: If617b570e082e3aa321414a2680a3aa0754f6153
-rwxr-xr-xnova/compute/manager.py16
-rw-r--r--nova/tests/api/ec2/test_cloud.py3
-rw-r--r--nova/tests/compute/test_compute.py3
-rw-r--r--nova/tests/virt/hyperv/test_hypervapi.py21
-rw-r--r--nova/tests/virt/test_virt_drivers.py24
-rw-r--r--nova/tests/virt/vmwareapi/test_vmwareapi.py14
-rwxr-xr-xnova/virt/baremetal/driver.py6
-rwxr-xr-xnova/virt/driver.py3
-rwxr-xr-xnova/virt/fake.py2
-rwxr-xr-xnova/virt/hyperv/driver.py3
-rwxr-xr-xnova/virt/libvirt/driver.py12
-rwxr-xr-xnova/virt/powervm/driver.py3
-rwxr-xr-xnova/virt/vmwareapi/driver.py10
-rw-r--r--nova/virt/vmwareapi/vmops.py16
-rwxr-xr-xnova/virt/xenapi/driver.py3
15 files changed, 100 insertions, 39 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 22881f5bd..a242a121d 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1540,7 +1540,14 @@ class ComputeManager(manager.SchedulerDependentManager):
def start_instance(self, context, instance):
"""Starting an instance on this host."""
self._notify_about_instance_usage(context, instance, "power_on.start")
- self.driver.power_on(instance)
+
+ network_info = self._get_instance_nw_info(context, instance)
+ block_device_info = self._get_instance_volume_block_device_info(
+ context, instance)
+ self.driver.power_on(context, instance,
+ self._legacy_nw_info(network_info),
+ block_device_info)
+
current_power_state = self._get_power_state(context, instance)
instance.power_state = current_power_state
instance.vm_state = vm_states.ACTIVE
@@ -1595,7 +1602,12 @@ class ComputeManager(manager.SchedulerDependentManager):
except NotImplementedError:
# Fallback to just powering on the instance if the hypervisor
# doesn't implement the restore method
- self.driver.power_on(instance)
+ network_info = self._get_instance_nw_info(context, instance)
+ block_device_info = self._get_instance_volume_block_device_info(
+ context, instance)
+ self.driver.power_on(context, instance,
+ self._legacy_nw_info(network_info),
+ block_device_info)
current_power_state = self._get_power_state(context, instance)
instance = self._instance_update(context, instance['uuid'],
power_state=current_power_state,
diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py
index 22a6947f2..560474847 100644
--- a/nova/tests/api/ec2/test_cloud.py
+++ b/nova/tests/api/ec2/test_cloud.py
@@ -2137,7 +2137,8 @@ class CloudTestCase(test.TestCase):
virt_driver = {}
- def fake_power_on(self, instance):
+ def fake_power_on(self, context, instance, network_info,
+ block_device_info):
virt_driver['powered_on'] = True
self.stubs.Set(fake_virt.FakeDriver, 'power_on', fake_power_on)
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 7953f8b63..ee3f1e28a 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -1427,7 +1427,8 @@ class ComputeTestCase(BaseTestCase):
called = {'power_on': False}
- def fake_driver_power_on(self, instance):
+ def fake_driver_power_on(self, context, instance, network_info,
+ block_device_info):
called['power_on'] = True
self.stubs.Set(nova.virt.fake.FakeDriver, 'power_on',
diff --git a/nova/tests/virt/hyperv/test_hypervapi.py b/nova/tests/virt/hyperv/test_hypervapi.py
index cfc79c388..9f2d745ff 100644
--- a/nova/tests/virt/hyperv/test_hypervapi.py
+++ b/nova/tests/virt/hyperv/test_hypervapi.py
@@ -495,13 +495,24 @@ class HyperVAPITestCase(test.TestCase):
constants.HYPERV_VM_STATE_DISABLED)
def test_power_on(self):
- self._test_vm_state_change(self._conn.power_on,
- constants.HYPERV_VM_STATE_DISABLED,
- constants.HYPERV_VM_STATE_ENABLED)
+ self._instance_data = self._get_instance_data()
+ network_info = fake_network.fake_get_instance_nw_info(self.stubs,
+ spectacular=True)
+ vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
+ constants.HYPERV_VM_STATE_ENABLED)
+ self._mox.ReplayAll()
+ self._conn.power_on(self._context, self._instance_data, network_info)
+ self._mox.VerifyAll()
def test_power_on_already_running(self):
- self._test_vm_state_change(self._conn.power_on, None,
- constants.HYPERV_VM_STATE_ENABLED)
+ self._instance_data = self._get_instance_data()
+ network_info = fake_network.fake_get_instance_nw_info(self.stubs,
+ spectacular=True)
+ vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
+ constants.HYPERV_VM_STATE_ENABLED)
+ self._mox.ReplayAll()
+ self._conn.power_on(self._context, self._instance_data, network_info)
+ self._mox.VerifyAll()
def test_reboot(self):
diff --git a/nova/tests/virt/test_virt_drivers.py b/nova/tests/virt/test_virt_drivers.py
index 47f983258..5c2df9854 100644
--- a/nova/tests/virt/test_virt_drivers.py
+++ b/nova/tests/virt/test_virt_drivers.py
@@ -311,13 +311,14 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
@catch_notimplementederror
def test_power_on_running(self):
instance_ref, network_info = self._get_running_instance()
- self.connection.power_on(instance_ref)
+ self.connection.power_on(self.ctxt, instance_ref,
+ network_info, None)
@catch_notimplementederror
def test_power_on_powered_off(self):
instance_ref, network_info = self._get_running_instance()
self.connection.power_off(instance_ref)
- self.connection.power_on(instance_ref)
+ self.connection.power_on(self.ctxt, instance_ref, network_info, None)
@catch_notimplementederror
def test_soft_delete(self):
@@ -407,7 +408,24 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
self.connection.attach_volume({'driver_volume_type': 'fake'},
instance_ref,
'/dev/sda')
- self.connection.power_on(instance_ref)
+
+ bdm = {
+ 'root_device_name': None,
+ 'swap': None,
+ 'ephemerals': [],
+ 'block_device_mapping': [{
+ 'instance_uuid': instance_ref['uuid'],
+ 'connection_info': {'driver_volume_type': 'fake'},
+ 'mount_device': '/dev/sda',
+ 'delete_on_termination': False,
+ 'virtual_name': None,
+ 'snapshot_id': None,
+ 'volume_id': 'abcdedf',
+ 'volume_size': None,
+ 'no_device': None
+ }]
+ }
+ self.connection.power_on(self.ctxt, instance_ref, network_info, bdm)
self.connection.detach_volume({'driver_volume_type': 'fake'},
instance_ref,
'/dev/sda')
diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py
index 5ba2f98af..62db10535 100644
--- a/nova/tests/virt/vmwareapi/test_vmwareapi.py
+++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py
@@ -335,14 +335,14 @@ class VMwareAPIVMTestCase(test.TestCase):
self.conn.power_off(self.instance)
info = self.conn.get_info({'uuid': 'fake-uuid'})
self._check_vm_info(info, power_state.SHUTDOWN)
- self.conn.power_on(self.instance)
+ self.conn.power_on(self.context, self.instance, self.network_info)
info = self.conn.get_info({'uuid': 'fake-uuid'})
self._check_vm_info(info, power_state.RUNNING)
def test_power_on_non_existent(self):
self._create_instance_in_the_db()
self.assertRaises(exception.InstanceNotFound, self.conn.power_on,
- self.instance)
+ self.context, self.instance, self.network_info)
def test_power_off(self):
self._create_vm()
@@ -427,7 +427,7 @@ class VMwareAPIVMTestCase(test.TestCase):
self.assertEquals(4, step)
self.assertEqual(vmops.RESIZE_TOTAL_STEPS, total_steps)
- self.stubs.Set(self.conn._vmops, "power_on", fake_power_on)
+ self.stubs.Set(self.conn._vmops, "_power_on", fake_power_on)
self.stubs.Set(self.conn._vmops, "_update_instance_progress",
fake_vmops_update_instance_progress)
@@ -439,6 +439,7 @@ class VMwareAPIVMTestCase(test.TestCase):
instance=self.instance,
disk_info=None,
network_info=None,
+ block_device_info=None,
image_meta=None,
power_on=power_on)
# verify the results
@@ -475,15 +476,20 @@ class VMwareAPIVMTestCase(test.TestCase):
self.assertEquals(self.vm_name, vm_name)
return vmwareapi_fake._get_objects("VirtualMachine")[0]
+ def fake_get_vm_ref_from_uuid(session, vm_uuid):
+ return vmwareapi_fake._get_objects("VirtualMachine")[0]
+
def fake_call_method(*args, **kwargs):
pass
def fake_wait_for_task(*args, **kwargs):
pass
- self.stubs.Set(self.conn._vmops, "power_on", fake_power_on)
+ self.stubs.Set(self.conn._vmops, "_power_on", fake_power_on)
self.stubs.Set(self.conn._vmops, "_get_orig_vm_name_label",
fake_get_orig_vm_name_label)
+ self.stubs.Set(vm_util, "get_vm_ref_from_uuid",
+ fake_get_vm_ref_from_uuid)
self.stubs.Set(vm_util, "get_vm_ref_from_name",
fake_get_vm_ref_from_name)
self.stubs.Set(self.conn._session, "_call_method", fake_call_method)
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py
index 4e8543c3e..703cc0980 100755
--- a/nova/virt/baremetal/driver.py
+++ b/nova/virt/baremetal/driver.py
@@ -250,7 +250,8 @@ class BareMetalDriver(driver.ComputeDriver):
)
self.driver.activate_bootloader(context, node, instance,
network_info=network_info)
- self.power_on(instance, node)
+ self.power_on(context, instance, network_info, block_device_info,
+ node)
self.driver.activate_node(context, node, instance)
_update_state(context, node, instance, baremetal_states.ACTIVE)
except Exception:
@@ -331,7 +332,8 @@ class BareMetalDriver(driver.ComputeDriver):
"for instance %r") % instance['uuid'])
pm.stop_console()
- def power_on(self, instance, node=None):
+ def power_on(self, context, instance, network_info, block_device_info=None,
+ node=None):
"""Power on the specified instance."""
if not node:
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index fbc2a5640..7b2185f52 100755
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -425,7 +425,8 @@ class ComputeDriver(object):
"""Power off the specified instance."""
raise NotImplementedError()
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
"""Power on the specified instance."""
raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 801c8e827..1d8943101 100755
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -182,7 +182,7 @@ class FakeDriver(driver.ComputeDriver):
def power_off(self, instance):
pass
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info, block_device_info):
pass
def soft_delete(self, instance):
diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py
index 675f36f54..e0f533db6 100755
--- a/nova/virt/hyperv/driver.py
+++ b/nova/virt/hyperv/driver.py
@@ -103,7 +103,8 @@ class HyperVDriver(driver.ComputeDriver):
def power_off(self, instance):
self._vmops.power_off(instance)
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
self._vmops.power_on(instance)
def live_migration(self, context, instance_ref, dest, post_method,
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 6a93d92ae..f4ba24cc4 100755
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -1465,13 +1465,13 @@ class LibvirtDriver(driver.ComputeDriver):
"""Power off the specified instance."""
self._destroy(instance)
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
"""Power on the specified instance."""
- dom = self._lookup_by_name(instance['name'])
- self._create_domain(domain=dom, instance=instance)
- timer = loopingcall.FixedIntervalLoopingCall(self._wait_for_running,
- instance)
- timer.start(interval=0.5).wait()
+ # We use _hard_reboot here to ensure that all backing files,
+ # network, and block device connections, etc. are established
+ # and available before we attempt to start the instance.
+ self._hard_reboot(context, instance, network_info, block_device_info)
def suspend(self, instance):
"""Suspend the specified instance."""
diff --git a/nova/virt/powervm/driver.py b/nova/virt/powervm/driver.py
index c2cee276d..e49bbb209 100755
--- a/nova/virt/powervm/driver.py
+++ b/nova/virt/powervm/driver.py
@@ -191,7 +191,8 @@ class PowerVMDriver(driver.ComputeDriver):
"""Power off the specified instance."""
self._powervm.power_off(instance['name'])
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
"""Power on the specified instance."""
self._powervm.power_on(instance['name'])
diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py
index 3cf9d32b4..1f91e5ab2 100755
--- a/nova/virt/vmwareapi/driver.py
+++ b/nova/virt/vmwareapi/driver.py
@@ -218,9 +218,10 @@ class VMwareESXDriver(driver.ComputeDriver):
"""Power off the specified instance."""
self._vmops.power_off(instance)
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
"""Power on the specified instance."""
- self._vmops.power_on(instance)
+ self._vmops._power_on(instance)
def poll_rebooting_instances(self, timeout, instances):
"""Poll for rebooting instances."""
@@ -379,7 +380,8 @@ class VMwareVCDriver(VMwareESXDriver):
def finish_revert_migration(self, instance, network_info,
block_device_info=None, power_on=True):
"""Finish reverting a resize, powering back on the instance."""
- self._vmops.finish_revert_migration(instance, power_on)
+ self._vmops.finish_revert_migration(instance, network_info,
+ block_device_info, power_on)
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance=False,
@@ -387,7 +389,7 @@ class VMwareVCDriver(VMwareESXDriver):
"""Completes a resize, turning on the migrated instance."""
self._vmops.finish_migration(context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
- power_on)
+ block_device_info, power_on)
def live_migration(self, context, instance_ref, dest,
post_method, recover_method, block_migration=False,
diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py
index c58aac219..1afead6b9 100644
--- a/nova/virt/vmwareapi/vmops.py
+++ b/nova/virt/vmwareapi/vmops.py
@@ -807,7 +807,7 @@ class VMwareVMOps(object):
instance['name'] = instance['name'] + self._rescue_suffix
self.destroy(instance, None)
instance['name'] = instance_orig_name
- self.power_on(instance)
+ self._power_on(instance)
def power_off(self, instance):
"""Power off the specified instance."""
@@ -832,7 +832,7 @@ class VMwareVMOps(object):
LOG.debug(_("VM was already in powered off state. So returning "
"without doing anything"), instance=instance)
- def power_on(self, instance):
+ def _power_on(self, instance):
"""Power on the specified instance."""
vm_ref = vm_util.get_vm_ref(self._session, instance)
@@ -851,6 +851,9 @@ class VMwareVMOps(object):
self._session._wait_for_task(instance['uuid'], poweron_task)
LOG.debug(_("Powered on the VM"), instance=instance)
+ def power_on(self, context, instance, network_info, block_device_info):
+ self._power_on(instance)
+
def _get_orig_vm_name_label(self, instance):
return instance['name'] + '-orig'
@@ -954,7 +957,8 @@ class VMwareVMOps(object):
if network_info:
self.unplug_vifs(instance, network_info)
- def finish_revert_migration(self, instance, power_on=True):
+ def finish_revert_migration(self, instance, network_info,
+ block_device_info, power_on=True):
"""Finish reverting a resize."""
# The original vm was suffixed with '-orig'; find it using
# the old suffix, remove the suffix, then power it back on.
@@ -972,15 +976,15 @@ class VMwareVMOps(object):
LOG.debug(_("Renamed the VM from %s") % name_label,
instance=instance)
if power_on:
- self.power_on(instance)
+ self._power_on(instance)
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance=False,
- power_on=True):
+ block_device_info=None, power_on=True):
"""Completes a resize, turning on the migrated instance."""
# 4. Start VM
if power_on:
- self.power_on(instance)
+ self._power_on(instance)
self._update_instance_progress(context, instance,
step=4,
total_steps=RESIZE_TOTAL_STEPS)
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 12a087929..37aed9812 100755
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -266,7 +266,8 @@ class XenAPIDriver(driver.ComputeDriver):
"""Power off the specified instance."""
self._vmops.power_off(instance)
- def power_on(self, instance):
+ def power_on(self, context, instance, network_info,
+ block_device_info=None):
"""Power on the specified instance."""
self._vmops.power_on(instance)