Merge "Don't deallocate/reallocate networks on reschedules"

This commit is contained in:
Jenkins
2014-01-08 21:10:20 +00:00
committed by Gerrit Code Review
2 changed files with 47 additions and 13 deletions

View File

@@ -73,6 +73,7 @@ from nova.openstack.common import log as logging
from nova.openstack.common import periodic_task
from nova.openstack.common import rpc
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import strutils
from nova.openstack.common import timeutils
from nova import paths
from nova import safe_utils
@@ -1238,6 +1239,12 @@ class ComputeManager(manager.Manager):
dhcp_options=dhcp_options)
LOG.debug(_('Instance network_info: |%s|'), nwinfo,
instance=instance)
# NOTE(alaski): This can be done more cleanly once we're sure
# we'll receive an object.
sys_meta = utils.metadata_to_dict(instance['system_metadata'])
sys_meta['network_allocated'] = 'True'
self._instance_update(context, instance['uuid'],
system_metadata=sys_meta)
return nwinfo
except Exception:
exc_info = sys.exc_info()
@@ -1260,10 +1267,10 @@ class ComputeManager(manager.Manager):
def _build_networks_for_instance(self, context, instance,
requested_networks, security_groups):
# May have been allocated previously and rescheduled to this host
network_info = self._get_instance_nw_info(context, instance)
if len(network_info) > 0:
return network_info
# If we're here from a reschedule the network may already be allocated.
if strutils.bool_from_string(
instance.system_metadata.get('network_allocated', 'False')):
return self._get_instance_nw_info(context, instance)
if not self.is_neutron_security_groups:
security_groups = []
@@ -1722,6 +1729,9 @@ class ComputeManager(manager.Manager):
raise exception.RescheduledException(
instance_uuid=instance.uuid, reason=str(e))
# NOTE(alaski): This is only useful during reschedules, remove it now.
instance.system_metadata.pop('network_allocated', None)
instance.power_state = self._get_power_state(context, instance)
instance.vm_state = vm_states.ACTIVE
instance.task_state = None
@@ -1799,6 +1809,8 @@ class ComputeManager(manager.Manager):
requested_networks):
try:
self._deallocate_network(context, instance, requested_networks)
instance.system_metadata['network_allocated'] = 'False'
instance.save()
except Exception:
msg = _('Failed to deallocate networks')
LOG.exception(msg, instance=instance)

View File

@@ -53,9 +53,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
nwapi = self.compute.network_api
self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
self.mox.StubOutWithMock(self.compute, '_instance_update')
self.mox.StubOutWithMock(time, 'sleep')
instance = {}
instance = fake_instance.fake_db_instance(system_metadata={})
is_vpn = 'fake-is-vpn'
req_networks = 'fake-req-networks'
macs = 'fake-macs'
@@ -79,6 +80,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
requested_networks=req_networks, macs=macs,
security_groups=sec_groups,
dhcp_options=dhcp_options).AndReturn(final_result)
self.compute._instance_update(self.context, instance['uuid'],
system_metadata={'network_allocated': 'True'})
self.mox.ReplayAll()
@@ -1383,28 +1386,47 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
self.compute._cleanup_build_resources, self.context,
self.instance, self.block_device_mapping)
def test_build_networks_if_none_found(self):
def test_build_networks_if_not_allocated(self):
instance = fake_instance.fake_instance_obj(self.context,
system_metadata={},
expected_attrs=['system_metadata'])
self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
self.mox.StubOutWithMock(self.compute, '_allocate_network')
self.compute._get_instance_nw_info(self.context,
self.instance).AndReturn(self.network_info)
self.compute._allocate_network(self.context, self.instance,
self.compute._allocate_network(self.context, instance,
self.requested_networks, None, self.security_groups, None)
self.mox.ReplayAll()
self.compute._build_networks_for_instance(self.context, self.instance,
self.compute._build_networks_for_instance(self.context, instance,
self.requested_networks, self.security_groups)
def test_build_networks_if_allocated_false(self):
instance = fake_instance.fake_instance_obj(self.context,
system_metadata=dict(network_allocated='False'),
expected_attrs=['system_metadata'])
self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
self.mox.StubOutWithMock(self.compute, '_allocate_network')
self.compute._allocate_network(self.context, instance,
self.requested_networks, None, self.security_groups, None)
self.mox.ReplayAll()
self.compute._build_networks_for_instance(self.context, instance,
self.requested_networks, self.security_groups)
def test_return_networks_if_found(self):
instance = fake_instance.fake_instance_obj(self.context,
system_metadata=dict(network_allocated='True'),
expected_attrs=['system_metadata'])
def fake_network_info():
return network_model.NetworkInfo([{'address': '123.123.123.123'}])
self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
self.mox.StubOutWithMock(self.compute, '_allocate_network')
self.compute._get_instance_nw_info(self.context,
self.instance).AndReturn(
self.compute._get_instance_nw_info(self.context, instance).AndReturn(
network_model.NetworkInfoAsyncWrapper(fake_network_info))
self.mox.ReplayAll()
self.compute._build_networks_for_instance(self.context, self.instance,
self.compute._build_networks_for_instance(self.context, instance,
self.requested_networks, self.security_groups)