summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2013-06-25 20:00:02 +0000
committerChris Behrens <cbehrens@codestud.com>2013-06-26 19:58:16 +0000
commitf0cf1c0fc14ba44ae6af5aad93ccd2fe010094a5 (patch)
treea803f7a00fdfdb1318f7503f2e3383118abc92fe /nova/compute
parent9331c5c1115c7d8cc5bcab71b1100eeea1ce72fe (diff)
downloadnova-f0cf1c0fc14ba44ae6af5aad93ccd2fe010094a5.tar.gz
nova-f0cf1c0fc14ba44ae6af5aad93ccd2fe010094a5.tar.xz
nova-f0cf1c0fc14ba44ae6af5aad93ccd2fe010094a5.zip
Allow retrying network allocations separately
Introduce a new config option, 'network_allocate_retries', that allows one to retry network allocations. The default is 0 for no retries to match the current behavior. The network allocations currently get retried by a full retry of a build via the scheduler, if those are enabled. This patch reduces the need to re-schedule for simple network allocation issues. The retrying happens in the network alloc async greenthread, so for virt drivers that support the new NetworkModel, the retrying potentially happens in the background while the image is being downloaded, etc. DocImpact Change-Id: I1a5fdcccbb736fc0b1d8c0cbc3b45a8372a6aef7
Diffstat (limited to 'nova/compute')
-rwxr-xr-xnova/compute/manager.py69
1 files changed, 50 insertions, 19 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 22881f5bd..e3d84b1fd 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -106,6 +106,9 @@ compute_opts = [
default=False,
help='Whether to start guests that were running before the '
'host rebooted'),
+ cfg.IntOpt('network_allocate_retries',
+ default=0,
+ help="Number of times to retry network allocation on failures"),
]
interval_opts = [
@@ -1147,6 +1150,50 @@ class ComputeManager(manager.SchedulerDependentManager):
expected_task_state=(task_states.SCHEDULING,
None))
+ def _allocate_network_async(self, context, instance, requested_networks,
+ macs, security_groups, is_vpn):
+ """Method used to allocate networks in the background.
+
+ Broken out for testing.
+ """
+ LOG.debug(_("Allocating IP information in the background."),
+ instance=instance)
+ retries = CONF.network_allocate_retries
+ if retries < 0:
+ LOG.warn(_("Treating negative config value (%(retries)s) for "
+ "'network_allocate_retries' as 0."),
+ {'retries': retries})
+ attempts = retries > 1 and retries + 1 or 1
+ retry_time = 1
+ for attempt in range(1, attempts + 1):
+ try:
+ nwinfo = self.network_api.allocate_for_instance(
+ context, instance, vpn=is_vpn,
+ requested_networks=requested_networks,
+ macs=macs,
+ conductor_api=self.conductor_api,
+ security_groups=security_groups)
+ LOG.debug(_('Instance network_info: |%s|'), nwinfo,
+ instance=instance)
+ return nwinfo
+ except Exception:
+ exc_info = sys.exc_info()
+ log_info = {'attempt': attempt,
+ 'attempts': attempts}
+ if attempt == attempts:
+ LOG.exception(_('Instance failed network setup '
+ 'after %(attempts)d attempt(s)'),
+ log_info)
+ raise exc_info[0], exc_info[1], exc_info[2]
+ LOG.warn(_('Instance failed network setup '
+ '(attempt %(attempt)d of %(attempts)d)'),
+ log_info, instance=instance)
+ time.sleep(retry_time)
+ retry_time *= 2
+ if retry_time > 30:
+ retry_time = 30
+ # Not reached.
+
def _allocate_network(self, context, instance, requested_networks, macs,
security_groups):
"""Start network allocation asynchronously. Return an instance
@@ -1161,25 +1208,9 @@ class ComputeManager(manager.SchedulerDependentManager):
task_state=task_states.NETWORKING,
expected_task_state=None)
is_vpn = pipelib.is_vpn_image(instance['image_ref'])
-
- def async_alloc():
- LOG.debug(_("Allocating IP information in the background."),
- instance=instance)
- try:
- nwinfo = self.network_api.allocate_for_instance(
- context, instance, vpn=is_vpn,
- requested_networks=requested_networks,
- macs=macs,
- conductor_api=self.conductor_api,
- security_groups=security_groups)
- except Exception:
- with excutils.save_and_reraise_exception():
- LOG.exception(_('Instance failed network setup'),
- instance=instance)
- LOG.debug(_('Instance network_info: |%s|'), nwinfo,
- instance=instance)
- return nwinfo
- return network_model.NetworkInfoAsyncWrapper(async_alloc)
+ return network_model.NetworkInfoAsyncWrapper(
+ self._allocate_network_async, context, instance,
+ requested_networks, macs, security_groups, is_vpn)
def _prep_block_device(self, context, instance, bdms):
"""Set up the block device for an instance with error logging."""