diff --git a/nova/compute/api.py b/nova/compute/api.py index 67730250e1a3..b276ecf7aac9 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1416,7 +1416,6 @@ class API(base.Base): @scheduler_api.reroute_compute("rescue") def rescue(self, context, instance, rescue_password=None): """Rescue the given instance.""" - instance_id = instance['id'] self.update(context, instance, vm_state=vm_states.ACTIVE, @@ -1425,18 +1424,19 @@ class API(base.Base): rescue_params = { "rescue_password": rescue_password } - self._cast_compute_message('rescue_instance', context, instance_id, - params=rescue_params) + self._cast_compute_message('rescue_instance', context, + instance['uuid'], + params=rescue_params) @scheduler_api.reroute_compute("unrescue") def unrescue(self, context, instance): """Unrescue the given instance.""" - instance_id = instance['id'] self.update(context, instance, vm_state=vm_states.RESCUED, task_state=task_states.UNRESCUING) - self._cast_compute_message('unrescue_instance', context, instance_id) + self._cast_compute_message('unrescue_instance', context, + instance['uuid']) @scheduler_api.reroute_compute("set_admin_password") def set_admin_password(self, context, instance, password=None): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 1ced5ea54cdb..7cd76f35d107 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -925,17 +925,17 @@ class ComputeManager(manager.SchedulerDependentManager): self.driver.agent_update(instance_ref, url, md5hash) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - @checks_instance_lock - def rescue_instance(self, context, instance_id, **kwargs): + @checks_instance_lock_uuid + def rescue_instance(self, context, instance_uuid, **kwargs): """ Rescue an instance on this host. :param rescue_password: password to set on rescue instance """ - LOG.audit(_('instance %s: rescuing'), instance_id, context=context) + LOG.audit(_('instance %s: rescuing'), instance_uuid, context=context) context = context.elevated() - instance_ref = self.db.instance_get(context, instance_id) + instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) instance_ref.admin_pass = kwargs.get('rescue_password', utils.generate_password(FLAGS.password_length)) network_info = self._get_instance_nw_info(context, instance_ref) @@ -944,26 +944,26 @@ class ComputeManager(manager.SchedulerDependentManager): current_power_state = self._get_power_state(context, instance_ref) self._instance_update(context, - instance_id, + instance_uuid, vm_state=vm_states.RESCUED, task_state=None, power_state=current_power_state) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - @checks_instance_lock - def unrescue_instance(self, context, instance_id): + @checks_instance_lock_uuid + def unrescue_instance(self, context, instance_uuid): """Rescue an instance on this host.""" - LOG.audit(_('instance %s: unrescuing'), instance_id, context=context) + LOG.audit(_('instance %s: unrescuing'), instance_uuid, context=context) context = context.elevated() - instance_ref = self.db.instance_get(context, instance_id) + instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) network_info = self._get_instance_nw_info(context, instance_ref) self.driver.unrescue(instance_ref, network_info) current_power_state = self._get_power_state(context, instance_ref) self._instance_update(context, - instance_id, + instance_uuid, vm_state=vm_states.ACTIVE, task_state=None, power_state=current_power_state) diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 365527223aca..6e1302520329 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -246,6 +246,33 @@ class ComputeTestCase(BaseTestCase): self.compute.start_instance(self.context, instance_id) self.compute.terminate_instance(self.context, instance_id) + def test_rescue(self): + """Ensure instance can be rescued and unrescued""" + + called = {'rescued': False, + 'unrescued': False} + + def fake_rescue(self, context, instance_ref, network_info): + called['rescued'] = True + + self.stubs.Set(nova.virt.fake.FakeConnection, 'rescue', fake_rescue) + + def fake_unrescue(self, instance_ref, network_info): + called['unrescued'] = True + + self.stubs.Set(nova.virt.fake.FakeConnection, 'unrescue', + fake_unrescue) + + instance = self._create_fake_instance() + instance_id = instance['id'] + instance_uuid = instance['uuid'] + self.compute.run_instance(self.context, instance_id) + self.compute.rescue_instance(self.context, instance_uuid) + self.assertTrue(called['rescued']) + self.compute.unrescue_instance(self.context, instance_uuid) + self.assertTrue(called['unrescued']) + self.compute.terminate_instance(self.context, instance_id) + def test_pause(self): """Ensure instance can be paused and unpaused""" instance = self._create_fake_instance() @@ -1299,27 +1326,29 @@ class ComputeAPITestCase(BaseTestCase): self.compute.terminate_instance(self.context, instance_id) def test_rescue_unrescue(self): - instance_id = self._create_instance() + instance = self._create_fake_instance() + instance_id = instance['id'] + instance_uuid = instance['uuid'] self.compute.run_instance(self.context, instance_id) - inst_ref = db.instance_get(self.context, instance_id) - self.assertEqual(inst_ref['vm_state'], vm_states.ACTIVE) - self.assertEqual(inst_ref['task_state'], None) + instance = db.instance_get_by_uuid(self.context, instance_uuid) + self.assertEqual(instance['vm_state'], vm_states.ACTIVE) + self.assertEqual(instance['task_state'], None) - self.compute_api.rescue(self.context, inst_ref) + self.compute_api.rescue(self.context, instance) - inst_ref = db.instance_get(self.context, instance_id) - self.assertEqual(inst_ref['vm_state'], vm_states.ACTIVE) - self.assertEqual(inst_ref['task_state'], task_states.RESCUING) + instance = db.instance_get_by_uuid(self.context, instance_uuid) + self.assertEqual(instance['vm_state'], vm_states.ACTIVE) + self.assertEqual(instance['task_state'], task_states.RESCUING) params = {'vm_state': vm_states.RESCUED, 'task_state': None} - db.instance_update(self.context, instance_id, params) + db.instance_update(self.context, instance_uuid, params) - self.compute_api.unrescue(self.context, inst_ref) + self.compute_api.unrescue(self.context, instance) - inst_ref = db.instance_get(self.context, instance_id) - self.assertEqual(inst_ref['vm_state'], vm_states.RESCUED) - self.assertEqual(inst_ref['task_state'], task_states.UNRESCUING) + instance = db.instance_get_by_uuid(self.context, instance_uuid) + self.assertEqual(instance['vm_state'], vm_states.RESCUED) + self.assertEqual(instance['task_state'], task_states.UNRESCUING) self.compute.terminate_instance(self.context, instance_id)