Skip to content

Commit

Permalink
Rehydrate NetworkInfo in reboot_instance()
Browse files Browse the repository at this point in the history
In the process of implementing no-db-compute, the compute manager's
reboot_instance() was stripped of its database accesses for getting
an instance's block and network device info. That information is
now passed in from the API layer over RPC.

In the offending changeset (), the network_info was getting coerced
to a list and thus calls to NetworkInfo.legacy() were failing in the
manager's _legacy_nw_info() method. This patch rehydrates the
NetworkInfo using the existing method for doing so, which fixes
bug 1071017. A test is also added to prevent future regressions.

Change-Id: I8fd1c2dde573bb7da3bfe1ee3193f9ba1167aaa7
  • Loading branch information
kk7ds committed Oct 25, 2012
1 parent 4f6571b commit 03105bf
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
4 changes: 4 additions & 0 deletions nova/compute/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,12 @@ def reboot_instance(self, context, instance,
if block_device_info is None:
block_device_info = self._get_instance_volume_block_device_info(
context, instance['uuid'])
# NOTE(danms): remove this when RPC API < 2.5 compatibility
# is no longer needed
if network_info is None:
network_info = self._get_instance_nw_info(context, instance)
else:
network_info = network_model.NetworkInfo.hydrate(network_info)

self._notify_about_instance_usage(context, instance, "reboot.start")

Expand Down
42 changes: 40 additions & 2 deletions nova/tests/compute/test_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from nova import exception
from nova import flags
from nova.network import api as network_api
from nova.network import model as network_model
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
Expand All @@ -57,6 +58,7 @@
from nova.tests.compute import fake_resource_tracker
from nova.tests.db.fakes import FakeModel
from nova.tests import fake_network
from nova.tests import fake_network_cache_model
from nova.tests.image import fake as fake_image
from nova import utils
import nova.volume
Expand Down Expand Up @@ -929,7 +931,7 @@ def test_reboot_soft(self):
{'task_state': task_states.REBOOTING})

reboot_type = "SOFT"
fake_net_info = {'bar': 'baz'}
fake_net_info = []
fake_block_dev_info = {'foo': 'bar'}
self._stub_out_reboot(fake_net_info, fake_block_dev_info)
self.compute.reboot_instance(self.context, instance=instance,
Expand All @@ -952,7 +954,7 @@ def test_reboot_hard(self):
{'task_state': task_states.REBOOTING_HARD})

reboot_type = "HARD"
fake_net_info = {'bar': 'baz'}
fake_net_info = []
fake_block_dev_info = {'foo': 'bar'}
self._stub_out_reboot(fake_net_info, fake_block_dev_info)
self.compute.reboot_instance(self.context, instance=instance,
Expand All @@ -967,6 +969,42 @@ def test_reboot_hard(self):
self.compute.terminate_instance(self.context,
instance=jsonutils.to_primitive(inst_ref))

def test_reboot_nwinfo(self):
"""Ensure instance network info is rehydrated in reboot"""
instance = jsonutils.to_primitive(self._create_fake_instance())
self.compute.run_instance(self.context, instance=instance)
db.instance_update(self.context, instance['uuid'],
{'task_state': task_states.REBOOTING_HARD})

result = {'was_instance': []}

# NOTE(danms): Beware the dragons ahead:
# Since the _legacy_nw_info() method in manager runs inside a
# try..except block, we can't assert from here. Further, this
# will be run more than once during the operation we're about
# to fire off, which means we need to make sure that it doesn't
# fail any of the times it is run. Hence the obscurity below.
def fake_legacy_nw_info(network_info):
result['was_instance'].append(
isinstance(network_info, network_model.NetworkInfo))
self.stubs.Set(self.compute, '_legacy_nw_info', fake_legacy_nw_info)

fake_net_info = network_model.NetworkInfo([
fake_network_cache_model.new_vif(),
fake_network_cache_model.new_vif(
{'address': 'bb:bb:bb:bb:bb:bb'})])
fake_net_info_p = jsonutils.to_primitive(fake_net_info)
fake_block_dev_info = {'foo': 'bar'}
self.compute.reboot_instance(self.context, instance=instance,
network_info=fake_net_info_p,
block_device_info=fake_block_dev_info,
reboot_type="SOFT")

inst_ref = db.instance_get_by_uuid(self.context, instance['uuid'])
self.compute.terminate_instance(self.context,
instance=jsonutils.to_primitive(inst_ref))
self.assertFalse(False in result['was_instance'])

def test_set_admin_password(self):
"""Ensure instance can have its admin password set"""
instance = jsonutils.to_primitive(self._create_fake_instance())
Expand Down

0 comments on commit 03105bf

Please sign in to comment.