Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
EC2 rescue/unrescue is broken, bug 899225
Change-Id: I5a0b9c08a43e8c606d1c885cf7f47382fa4664a8
  • Loading branch information
ameade committed Dec 2, 2011
1 parent 7fc79c4 commit 91cfa62
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 15 deletions.
18 changes: 8 additions & 10 deletions nova/api/ec2/cloud.py
Expand Up @@ -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."""
Expand Down Expand Up @@ -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):
Expand Down
29 changes: 29 additions & 0 deletions nova/tests/api/ec2/test_cloud.py
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions nova/tests/test_virt_drivers.py
Expand Up @@ -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):
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion nova/virt/driver.py
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion nova/virt/fake.py
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion nova/virt/libvirt/connection.py
Expand Up @@ -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
Expand Down

0 comments on commit 91cfa62

Please sign in to comment.