Merge "Don't deallocate/reallocate networks on reschedules"
This commit is contained in:
@@ -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)
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user