From 91cfa62b4a09cafa8af0772c68d36de9216dc440 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Fri, 2 Dec 2011 11:36:38 -0500 Subject: [PATCH] EC2 rescue/unrescue is broken, bug 899225 Change-Id: I5a0b9c08a43e8c606d1c885cf7f47382fa4664a8 --- nova/api/ec2/cloud.py | 18 ++++++++---------- nova/tests/api/ec2/test_cloud.py | 29 +++++++++++++++++++++++++++++ nova/tests/test_virt_drivers.py | 4 ++-- nova/virt/driver.py | 2 +- nova/virt/fake.py | 2 +- nova/virt/libvirt/connection.py | 2 +- 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index eb49454128b..17a1ff63485 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -1289,14 +1289,6 @@ def run_instances(self, context, **kwargs): block_device_mapping=kwargs.get('block_device_mapping', {})) return self._format_run_instances(context, resv_id) - def _do_instance(self, action, context, ec2_id): - instance_id = ec2utils.ec2_id_to_id(ec2_id) - action(context, instance_id=instance_id) - - def _do_instances(self, action, context, instance_id): - for ec2_id in instance_id: - self._do_instance(action, context, ec2_id) - def terminate_instances(self, context, instance_id, **kwargs): """Terminate each instance in instance_id, which is a list of ec2 ids. instance_id is a kwarg so its name cannot be modified.""" @@ -1338,12 +1330,18 @@ def start_instances(self, context, instance_id, **kwargs): def rescue_instance(self, context, instance_id, **kwargs): """This is an extension to the normal ec2_api""" - self._do_instance(self.compute_api.rescue, context, instance_id) + LOG.debug(_("Going to rescue instance %s") % instance_id) + _instance_id = ec2utils.ec2_id_to_id(instance_id) + instance = self.compute_api.get(context, _instance_id) + self.compute_api.rescue(context, instance) return True def unrescue_instance(self, context, instance_id, **kwargs): """This is an extension to the normal ec2_api""" - self._do_instance(self.compute_api.unrescue, context, instance_id) + LOG.debug(_("Going to unrescue instance %s") % instance_id) + _instance_id = ec2utils.ec2_id_to_id(instance_id) + instance = self.compute_api.get(context, _instance_id) + self.compute_api.unrescue(context, instance) return True def update_instance(self, context, instance_id, **kwargs): diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py index 47100b7beee..c206f070f78 100644 --- a/nova/tests/api/ec2/test_cloud.py +++ b/nova/tests/api/ec2/test_cloud.py @@ -1376,6 +1376,35 @@ def _restart_compute_service(self, periodic_interval=None): else: self.compute = self.start_service('compute') + def test_rescue_instances(self): + kwargs = {'image_id': 'ami-1', + 'instance_type': FLAGS.default_instance_type, + 'max_count': 1, } + instance_id = self._run_instance(**kwargs) + + result = self.cloud.stop_instances(self.context, [instance_id]) + self.assertTrue(result) + + result = self.cloud.rescue_instance(self.context, instance_id) + self.assertTrue(result) + + result = self.cloud.terminate_instances(self.context, [instance_id]) + self.assertTrue(result) + self._restart_compute_service() + + def test_unrescue_instances(self): + kwargs = {'image_id': 'ami-1', + 'instance_type': FLAGS.default_instance_type, + 'max_count': 1, } + instance_id = self._run_instance(**kwargs) + + result = self.cloud.unrescue_instance(self.context, instance_id) + self.assertTrue(result) + + result = self.cloud.terminate_instances(self.context, [instance_id]) + self.assertTrue(result) + self._restart_compute_service() + def test_stop_start_instance(self): """Makes sure stop/start instance works""" # enforce periodic tasks run in short time to avoid wait for 60s. diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py index 137d6c9ca8f..8b4fa177f00 100644 --- a/nova/tests/test_virt_drivers.py +++ b/nova/tests/test_virt_drivers.py @@ -145,7 +145,7 @@ def test_agent_update(self): @catch_notimplementederror def test_rescue(self): instance_ref, network_info = self._get_running_instance() - self.connection.rescue(self.ctxt, instance_ref, network_info) + self.connection.rescue(self.ctxt, instance_ref, network_info, None) @catch_notimplementederror def test_unrescue_unrescued_instance(self): @@ -155,7 +155,7 @@ def test_unrescue_unrescued_instance(self): @catch_notimplementederror def test_unrescue_rescued_instance(self): instance_ref, network_info = self._get_running_instance() - self.connection.rescue(self.ctxt, instance_ref, network_info) + self.connection.rescue(self.ctxt, instance_ref, network_info, None) self.connection.unrescue(instance_ref, network_info) @catch_notimplementederror diff --git a/nova/virt/driver.py b/nova/virt/driver.py index c2056f19d80..e12be1f0e4f 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -296,7 +296,7 @@ def resume(self, instance): # TODO(Vek): Need to pass context in for access to auth_token raise NotImplementedError() - def rescue(self, context, instance, network_info): + def rescue(self, context, instance, network_info, image_meta): """Rescue the specified instance""" raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index e860f72d5a8..feb85b7f1b1 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -126,7 +126,7 @@ def inject_file(self, instance, b64_path, b64_contents): def agent_update(self, instance, url, md5hash): pass - def rescue(self, context, instance, network_info): + def rescue(self, context, instance, network_info, image_meta): pass def unrescue(self, instance, network_info): diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index edaa11cbbd4..93507f6c087 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -595,7 +595,7 @@ def resume(self, instance): dom.create() @exception.wrap_exception() - def rescue(self, context, instance, network_info): + def rescue(self, context, instance, network_info, image_meta): """Loads a VM using rescue images. A rescue is normally performed when something goes wrong with the