Update driver interface
spawn() now accepts the "power_on" flag, allowing instances to be created without being turned on. This is part of the cross-cell migration workflow. Change-Id: Ifd18a69f476ebbfb4ee6ec34abb03da0d2e30ceb
This commit is contained in:
parent
20ee0665c5
commit
cb203978f2
|
@ -41,10 +41,10 @@ class HyperVClusterDriver(driver.HyperVDriver):
|
|||
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, allocations, network_info=None,
|
||||
block_device_info=None):
|
||||
block_device_info=None, power_on=True):
|
||||
super(HyperVClusterDriver, self).spawn(
|
||||
context, instance, image_meta, injected_files, admin_password,
|
||||
allocations, network_info, block_device_info)
|
||||
allocations, network_info, block_device_info, power_on)
|
||||
self._clops.add_to_cluster(instance)
|
||||
|
||||
def destroy(self, context, instance, network_info, block_device_info=None,
|
||||
|
|
|
@ -183,10 +183,11 @@ class HyperVDriver(driver.ComputeDriver):
|
|||
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, allocations, network_info=None,
|
||||
block_device_info=None):
|
||||
block_device_info=None, power_on=True):
|
||||
image_meta = self._recreate_image_meta(context, instance, image_meta)
|
||||
self._vmops.spawn(context, instance, image_meta, injected_files,
|
||||
admin_password, network_info, block_device_info)
|
||||
admin_password, network_info, block_device_info,
|
||||
power_on)
|
||||
|
||||
def reboot(self, context, instance, network_info, reboot_type,
|
||||
block_device_info=None, bad_volumes_callback=None):
|
||||
|
|
|
@ -287,7 +287,8 @@ class VMOps(object):
|
|||
|
||||
@check_admin_permissions
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, network_info, block_device_info=None):
|
||||
admin_password, network_info, block_device_info=None,
|
||||
power_on=True):
|
||||
"""Create a new VM and start it."""
|
||||
LOG.info("Spawning new instance", instance=instance)
|
||||
|
||||
|
@ -331,9 +332,10 @@ class VMOps(object):
|
|||
# vifs are already plugged in at this point. We waited on the vif
|
||||
# plug event previously when we created the instance. Skip the
|
||||
# plug vifs during power on in this case
|
||||
self.power_on(instance,
|
||||
network_info=network_info,
|
||||
should_plug_vifs=False)
|
||||
if power_on:
|
||||
self.power_on(instance,
|
||||
network_info=network_info,
|
||||
should_plug_vifs=False)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.destroy(instance, network_info, block_device_info)
|
||||
|
|
|
@ -74,13 +74,15 @@ class HyperVClusterTestCase(test_base.HyperVBaseTestCase):
|
|||
mock.sentinel.admin_pass,
|
||||
mock.sentinel.allocations,
|
||||
mock.sentinel.network_info,
|
||||
mock.sentinel.block_dev_info)
|
||||
mock.sentinel.block_dev_info,
|
||||
mock.sentinel.power_on)
|
||||
|
||||
mock_superclass_spawn.assert_called_once_with(
|
||||
self.context, mock.sentinel.fake_instance,
|
||||
mock.sentinel.image_meta, mock.sentinel.injected_files,
|
||||
mock.sentinel.admin_pass, mock.sentinel.allocations,
|
||||
mock.sentinel.network_info, mock.sentinel.block_dev_info)
|
||||
mock.sentinel.network_info, mock.sentinel.block_dev_info,
|
||||
mock.sentinel.power_on)
|
||||
self.driver._clops.add_to_cluster.assert_called_once_with(
|
||||
mock.sentinel.fake_instance)
|
||||
|
||||
|
|
|
@ -158,7 +158,8 @@ class HyperVDriverTestCase(test_base.HyperVBaseTestCase):
|
|||
mock.sentinel.image_meta, mock.sentinel.injected_files,
|
||||
mock.sentinel.admin_password, mock.sentinel.allocations,
|
||||
mock.sentinel.network_info,
|
||||
mock.sentinel.block_device_info)
|
||||
mock.sentinel.block_device_info,
|
||||
mock.sentinel.power_on)
|
||||
|
||||
mock_recreate_img_meta.assert_called_once_with(
|
||||
mock.sentinel.context, mock.sentinel.instance,
|
||||
|
@ -167,7 +168,8 @@ class HyperVDriverTestCase(test_base.HyperVBaseTestCase):
|
|||
mock.sentinel.context, mock.sentinel.instance,
|
||||
mock_recreate_img_meta.return_value, mock.sentinel.injected_files,
|
||||
mock.sentinel.admin_password, mock.sentinel.network_info,
|
||||
mock.sentinel.block_device_info)
|
||||
mock.sentinel.block_device_info,
|
||||
mock.sentinel.power_on)
|
||||
|
||||
def test_reboot(self):
|
||||
self.driver.reboot(
|
||||
|
|
|
@ -486,8 +486,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
mock_create_config_drive, mock_attach_config_drive,
|
||||
mock_set_boot_order,
|
||||
mock_power_on, mock_destroy, mock_plug_vifs,
|
||||
exists, configdrive_required, fail,
|
||||
fake_vm_gen=constants.VM_GEN_2):
|
||||
exists=False, configdrive_required=True, fail=None,
|
||||
fake_vm_gen=constants.VM_GEN_2,
|
||||
power_on=True):
|
||||
mock_instance = fake_instance.fake_instance_obj(self.context)
|
||||
mock_image_meta = mock.MagicMock()
|
||||
root_device_info = mock.sentinel.ROOT_DEV_INFO
|
||||
|
@ -516,7 +517,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
else:
|
||||
self._vmops.spawn(self.context, mock_instance, mock_image_meta,
|
||||
[mock.sentinel.FILE], mock.sentinel.PASSWORD,
|
||||
mock.sentinel.network_info, block_device_info)
|
||||
mock.sentinel.network_info, block_device_info,
|
||||
power_on=power_on)
|
||||
self._vmops._vmutils.vm_exists.assert_called_once_with(
|
||||
mock_instance.name)
|
||||
self._vmops._pathutils.get_instance_dir.assert_called_once_with(
|
||||
|
@ -552,23 +554,28 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
mock_instance, fake_config_drive_path, fake_vm_gen)
|
||||
mock_set_boot_order.assert_called_once_with(
|
||||
mock_instance.name, fake_vm_gen, block_device_info)
|
||||
mock_power_on.assert_called_once_with(
|
||||
mock_instance,
|
||||
network_info=mock.sentinel.network_info,
|
||||
should_plug_vifs=False)
|
||||
if power_on:
|
||||
mock_power_on.assert_called_once_with(
|
||||
mock_instance,
|
||||
network_info=mock.sentinel.network_info,
|
||||
should_plug_vifs=False)
|
||||
else:
|
||||
mock_power_on.assert_not_called()
|
||||
|
||||
def test_spawn(self):
|
||||
self._test_spawn(exists=False, configdrive_required=True, fail=None)
|
||||
self._test_spawn()
|
||||
|
||||
def test_spawn_instance_exists(self):
|
||||
self._test_spawn(exists=True, configdrive_required=True, fail=None)
|
||||
self._test_spawn(exists=True)
|
||||
|
||||
def test_spawn_create_instance_exception(self):
|
||||
self._test_spawn(exists=False, configdrive_required=True,
|
||||
fail=os_win_exc.HyperVException)
|
||||
self._test_spawn(fail=os_win_exc.HyperVException)
|
||||
|
||||
def test_spawn_not_required(self):
|
||||
self._test_spawn(exists=False, configdrive_required=False, fail=None)
|
||||
def test_spawn_cfgdrive_not_required(self):
|
||||
self._test_spawn(configdrive_required=False)
|
||||
|
||||
def test_spawn_without_powering_on(self):
|
||||
self._test_spawn(power_on=False)
|
||||
|
||||
def test_spawn_no_admin_permissions(self):
|
||||
self._vmops._vmutils.check_admin_permissions.side_effect = (
|
||||
|
|
Loading…
Reference in New Issue