Skip to content

Commit

Permalink
Disable retry filter with force_hosts or force_nodes
Browse files Browse the repository at this point in the history
If customer deploy a VM with force_hosts or force_nodes options,
then there is no need to retry even if retry filter was enabled.

Fix bug 1211597

Change-Id: I2948f48b5c4982cc29899b76889d7d8f0db47449
  • Loading branch information
Jay Lau committed Aug 30, 2013
1 parent 86c97ff commit 90620a2
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
6 changes: 4 additions & 2 deletions nova/scheduler/filter_scheduler.py
Expand Up @@ -245,12 +245,14 @@ def _populate_retry(self, filter_properties, instance_properties):
request. If maximum retries is exceeded, raise NoValidHost.
"""
max_attempts = self._max_attempts()
retry = filter_properties.pop('retry', {})
force_hosts = filter_properties.get('force_hosts', [])
force_nodes = filter_properties.get('force_nodes', [])

if max_attempts == 1:
if max_attempts == 1 or force_hosts or force_nodes:
# re-scheduling is disabled.
return

retry = filter_properties.pop('retry', {})
# retry is enabled, update attempt count:
if retry:
retry['num_attempts'] += 1
Expand Down
4 changes: 3 additions & 1 deletion nova/scheduler/utils.py
Expand Up @@ -121,7 +121,9 @@ def _add_retry_host(filter_properties, host, node):
node has already been tried.
"""
retry = filter_properties.get('retry', None)
if not retry:
force_hosts = filter_properties.get('force_hosts', [])
force_nodes = filter_properties.get('force_nodes', [])
if not retry or force_hosts or force_nodes:
return
hosts = retry['hosts']
hosts.append([host, node])
38 changes: 38 additions & 0 deletions nova/tests/scheduler/test_filter_scheduler.py
Expand Up @@ -229,6 +229,44 @@ def test_retry_disabled(self):
# should not have retry info in the populated filter properties:
self.assertFalse("retry" in filter_properties)

def test_retry_force_hosts(self):
# Retry info should not get populated when re-scheduling is off.
self.flags(scheduler_max_attempts=2)
sched = fakes.FakeFilterScheduler()

instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
request_spec = dict(instance_properties=instance_properties)
filter_properties = dict(force_hosts=['force_host'])

self.mox.StubOutWithMock(db, 'compute_node_get_all')
db.compute_node_get_all(mox.IgnoreArg()).AndReturn([])
self.mox.ReplayAll()

sched._schedule(self.context, request_spec,
filter_properties=filter_properties)

# should not have retry info in the populated filter properties:
self.assertFalse("retry" in filter_properties)

def test_retry_force_nodes(self):
# Retry info should not get populated when re-scheduling is off.
self.flags(scheduler_max_attempts=2)
sched = fakes.FakeFilterScheduler()

instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
request_spec = dict(instance_properties=instance_properties)
filter_properties = dict(force_nodes=['force_node'])

self.mox.StubOutWithMock(db, 'compute_node_get_all')
db.compute_node_get_all(mox.IgnoreArg()).AndReturn([])
self.mox.ReplayAll()

sched._schedule(self.context, request_spec,
filter_properties=filter_properties)

# should not have retry info in the populated filter properties:
self.assertFalse("retry" in filter_properties)

def test_retry_attempt_one(self):
# Test retry logic on initial scheduling attempt.
self.flags(scheduler_max_attempts=2)
Expand Down
20 changes: 16 additions & 4 deletions nova/tests/scheduler/test_scheduler_utils.py
Expand Up @@ -92,9 +92,15 @@ def test_set_vm_state_and_notify_uuid_from_instance_props(self):
self._test_set_vm_state_and_notify(request_spec, expected_uuids)

def _test_populate_filter_props(self, host_state_obj=True,
with_retry=True):
with_retry=True,
force_hosts=[],
force_nodes=[]):
if with_retry:
filter_properties = dict(retry=dict(hosts=[]))
if not force_hosts and not force_nodes:
filter_properties = dict(retry=dict(hosts=[]))
else:
filter_properties = dict(force_hosts=force_hosts,
force_nodes=force_nodes)
else:
filter_properties = dict()

Expand All @@ -110,13 +116,13 @@ class host_state(object):

scheduler_utils.populate_filter_properties(filter_properties,
host_state)
if with_retry:
if with_retry and not force_hosts and not force_nodes:
# So we can check for 2 hosts
scheduler_utils.populate_filter_properties(filter_properties,
host_state)

self.assertEqual('fake-limits', filter_properties['limits'])
if with_retry:
if with_retry and not force_hosts and not force_nodes:
self.assertEqual([['fake-host', 'fake-node'],
['fake-host', 'fake-node']],
filter_properties['retry']['hosts'])
Expand All @@ -131,3 +137,9 @@ def test_populate_filter_props_host_dict(self):

def test_populate_filter_props_no_retry(self):
self._test_populate_filter_props(with_retry=False)

def test_populate_filter_props_force_hosts_no_retry(self):
self._test_populate_filter_props(force_hosts=['force-host'])

def test_populate_filter_props_force_nodes_no_retry(self):
self._test_populate_filter_props(force_nodes=['force-node'])

0 comments on commit 90620a2

Please sign in to comment.