scheduler prep_resize should not update instance['host']
This is done by the manager once things are ready on the destination compute node. Fixes bug 1034593 Also removes now-unneeded update_db argument passed via rpcapi and bumps scheduler rpcapi version for prep_resize to 1.4 Change-Id: I0ac3be39877f3afcf42f5996d0da90042fe7c6e3
This commit is contained in:
@@ -1447,7 +1447,6 @@ class API(base.Base):
|
||||
"instance": instance,
|
||||
"instance_type": new_instance_type,
|
||||
"image": image,
|
||||
"update_db": False,
|
||||
"request_spec": jsonutils.to_primitive(request_spec),
|
||||
"filter_properties": filter_properties,
|
||||
}
|
||||
|
||||
@@ -89,12 +89,10 @@ class ChanceScheduler(driver.Scheduler):
|
||||
del request_spec['instance_properties']['uuid']
|
||||
return instances
|
||||
|
||||
def schedule_prep_resize(self, context, image, update_db, request_spec,
|
||||
def schedule_prep_resize(self, context, image, request_spec,
|
||||
filter_properties, instance, instance_type):
|
||||
"""Select a target for resize."""
|
||||
host = self._schedule(context, 'compute', request_spec,
|
||||
filter_properties)
|
||||
updated_instance = driver.instance_update_db(context, instance['uuid'],
|
||||
host.host_state.host)
|
||||
self.compute_rpcapi.prep_resize(context, image, updated_instance,
|
||||
self.compute_rpcapi.prep_resize(context, image, instance,
|
||||
instance_type, host)
|
||||
|
||||
@@ -55,15 +55,14 @@ flags.DECLARE('instances_path', 'nova.compute.manager')
|
||||
flags.DECLARE('libvirt_type', 'nova.virt.libvirt.driver')
|
||||
|
||||
|
||||
def cast_to_volume_host(context, host, method, update_db=True, **kwargs):
|
||||
def cast_to_volume_host(context, host, method, **kwargs):
|
||||
"""Cast request to a volume host queue"""
|
||||
|
||||
if update_db:
|
||||
volume_id = kwargs.get('volume_id', None)
|
||||
if volume_id is not None:
|
||||
now = timeutils.utcnow()
|
||||
db.volume_update(context, volume_id,
|
||||
{'host': host, 'scheduled_at': now})
|
||||
volume_id = kwargs.get('volume_id', None)
|
||||
if volume_id is not None:
|
||||
now = timeutils.utcnow()
|
||||
db.volume_update(context, volume_id,
|
||||
{'host': host, 'scheduled_at': now})
|
||||
rpc.cast(context,
|
||||
rpc.queue_get_for(context, 'volume', host),
|
||||
{"method": method, "args": kwargs})
|
||||
@@ -80,13 +79,12 @@ def instance_update_db(context, instance_uuid, host):
|
||||
return db.instance_update(context, instance_uuid, values)
|
||||
|
||||
|
||||
def cast_to_compute_host(context, host, method, update_db=True, **kwargs):
|
||||
def cast_to_compute_host(context, host, method, **kwargs):
|
||||
"""Cast request to a compute host queue"""
|
||||
|
||||
if update_db:
|
||||
instance_uuid = kwargs.get('instance_uuid', None)
|
||||
if instance_uuid:
|
||||
instance_update_db(context, instance_uuid, host)
|
||||
instance_uuid = kwargs.get('instance_uuid', None)
|
||||
if instance_uuid:
|
||||
instance_update_db(context, instance_uuid, host)
|
||||
|
||||
rpc.cast(context,
|
||||
rpc.queue_get_for(context, 'compute', host),
|
||||
@@ -94,7 +92,7 @@ def cast_to_compute_host(context, host, method, update_db=True, **kwargs):
|
||||
LOG.debug(_("Casted '%(method)s' to compute '%(host)s'") % locals())
|
||||
|
||||
|
||||
def cast_to_network_host(context, host, method, update_db=False, **kwargs):
|
||||
def cast_to_network_host(context, host, method, **kwargs):
|
||||
"""Cast request to a network host queue"""
|
||||
|
||||
rpc.cast(context,
|
||||
@@ -103,7 +101,7 @@ def cast_to_network_host(context, host, method, update_db=False, **kwargs):
|
||||
LOG.debug(_("Casted '%(method)s' to network '%(host)s'") % locals())
|
||||
|
||||
|
||||
def cast_to_host(context, topic, host, method, update_db=True, **kwargs):
|
||||
def cast_to_host(context, topic, host, method, **kwargs):
|
||||
"""Generic cast to host"""
|
||||
|
||||
topic_mapping = {
|
||||
@@ -113,7 +111,7 @@ def cast_to_host(context, topic, host, method, update_db=True, **kwargs):
|
||||
|
||||
func = topic_mapping.get(topic)
|
||||
if func:
|
||||
func(context, host, method, update_db=update_db, **kwargs)
|
||||
func(context, host, method, **kwargs)
|
||||
else:
|
||||
rpc.cast(context,
|
||||
rpc.queue_get_for(context, topic, host),
|
||||
@@ -186,7 +184,7 @@ class Scheduler(object):
|
||||
"""Must override schedule method for scheduler to work."""
|
||||
raise NotImplementedError(_("Must implement a fallback schedule"))
|
||||
|
||||
def schedule_prep_resize(self, context, image, update_db, request_spec,
|
||||
def schedule_prep_resize(self, context, image, request_spec,
|
||||
filter_properties, instance, instance_type):
|
||||
"""Must override schedule_prep_resize method for scheduler to work."""
|
||||
msg = _("Driver must implement schedule_prep_resize")
|
||||
|
||||
@@ -107,7 +107,7 @@ class FilterScheduler(driver.Scheduler):
|
||||
|
||||
return instances
|
||||
|
||||
def schedule_prep_resize(self, context, image, update_db, request_spec,
|
||||
def schedule_prep_resize(self, context, image, request_spec,
|
||||
filter_properties, instance, instance_type):
|
||||
"""Select a target for resize.
|
||||
|
||||
@@ -122,9 +122,7 @@ class FilterScheduler(driver.Scheduler):
|
||||
host = hosts.pop(0)
|
||||
|
||||
# Forward off to the host
|
||||
updated_instance = driver.instance_update_db(context, instance['uuid'],
|
||||
host.host_state.host)
|
||||
self.compute_rpcapi.prep_resize(context, image, updated_instance,
|
||||
self.compute_rpcapi.prep_resize(context, image, instance,
|
||||
instance_type, host.host_state.host)
|
||||
|
||||
def _provision_resource(self, context, weighted_host, request_spec,
|
||||
|
||||
@@ -53,7 +53,7 @@ QUOTAS = quota.QUOTAS
|
||||
class SchedulerManager(manager.Manager):
|
||||
"""Chooses a host to run instances on."""
|
||||
|
||||
RPC_API_VERSION = '1.3'
|
||||
RPC_API_VERSION = '1.4'
|
||||
|
||||
def __init__(self, scheduler_driver=None, *args, **kwargs):
|
||||
if not scheduler_driver:
|
||||
@@ -142,6 +142,8 @@ class SchedulerManager(manager.Manager):
|
||||
if reservations:
|
||||
QUOTAS.rollback(context, reservations)
|
||||
|
||||
# FIXME(comstud): Remove 'update_db' in a future version. It's only
|
||||
# here for rpcapi backwards compatibility.
|
||||
def prep_resize(self, context, image, update_db, request_spec,
|
||||
filter_properties, instance=None, instance_uuid=None,
|
||||
instance_type=None, instance_type_id=None, topic=None):
|
||||
@@ -159,7 +161,6 @@ class SchedulerManager(manager.Manager):
|
||||
kwargs = {
|
||||
'context': context,
|
||||
'image': image,
|
||||
'update_db': update_db,
|
||||
'request_spec': request_spec,
|
||||
'filter_properties': filter_properties,
|
||||
'instance': instance,
|
||||
|
||||
@@ -38,6 +38,7 @@ class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
- remove topic, it was unused
|
||||
1.2 - Remove topic from run_instance, it was unused
|
||||
1.3 - Remove instance_id, add instance to live_migration
|
||||
1.4 - Remove update_db from prep_resize
|
||||
'''
|
||||
|
||||
BASE_RPC_API_VERSION = '1.0'
|
||||
@@ -59,13 +60,13 @@ class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
reservations=reservations), version='1.2')
|
||||
|
||||
def prep_resize(self, ctxt, instance, instance_type, image,
|
||||
update_db, request_spec, filter_properties):
|
||||
request_spec, filter_properties):
|
||||
instance_p = jsonutils.to_primitive(instance)
|
||||
instance_type_p = jsonutils.to_primitive(instance_type)
|
||||
self.cast(ctxt, self.make_msg('prep_resize',
|
||||
instance=instance_p, instance_type=instance_type_p,
|
||||
image=image, update_db=update_db, request_spec=request_spec,
|
||||
filter_properties=filter_properties), version='1.1')
|
||||
image=image, request_spec=request_spec,
|
||||
filter_properties=filter_properties), version='1.4')
|
||||
|
||||
def show_host_resources(self, ctxt, host):
|
||||
return self.call(ctxt, self.make_msg('show_host_resources', host=host))
|
||||
|
||||
@@ -253,3 +253,27 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
||||
self.assertRaises(exception.NoValidHost,
|
||||
self.driver.schedule, ctxt, topic, method,
|
||||
*fake_args, **fake_kwargs)
|
||||
|
||||
def test_schedule_prep_resize_doesnt_update_host(self):
|
||||
fake_context = context.RequestContext('user', 'project',
|
||||
is_admin=True)
|
||||
|
||||
def _return_host(*args, **kwargs):
|
||||
return 'host2'
|
||||
|
||||
self.stubs.Set(self.driver, '_schedule', _return_host)
|
||||
|
||||
info = {'called': 0}
|
||||
|
||||
def _fake_instance_update_db(*args, **kwargs):
|
||||
# This should not be called
|
||||
info['called'] = 1
|
||||
|
||||
self.stubs.Set(driver, 'instance_update_db',
|
||||
_fake_instance_update_db)
|
||||
|
||||
instance = {'uuid': 'fake-uuid', 'host': 'host1'}
|
||||
|
||||
self.driver.schedule_prep_resize(fake_context, {}, {}, {},
|
||||
instance, {})
|
||||
self.assertEqual(info['called'], 0)
|
||||
|
||||
@@ -20,6 +20,7 @@ import mox
|
||||
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.scheduler import driver
|
||||
from nova.scheduler import filter_scheduler
|
||||
from nova.scheduler import host_manager
|
||||
from nova.scheduler import least_cost
|
||||
@@ -167,6 +168,32 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
||||
for weighted_host in weighted_hosts:
|
||||
self.assertTrue(weighted_host.host_state is not None)
|
||||
|
||||
def test_schedule_prep_resize_doesnt_update_host(self):
|
||||
fake_context = context.RequestContext('user', 'project',
|
||||
is_admin=True)
|
||||
|
||||
sched = fakes.FakeFilterScheduler()
|
||||
|
||||
def _return_hosts(*args, **kwargs):
|
||||
host_state = host_manager.HostState('host2', 'compute')
|
||||
return [least_cost.WeightedHost(1.0, host_state=host_state)]
|
||||
|
||||
self.stubs.Set(sched, '_schedule', _return_hosts)
|
||||
|
||||
info = {'called': 0}
|
||||
|
||||
def _fake_instance_update_db(*args, **kwargs):
|
||||
# This should not be called
|
||||
info['called'] = 1
|
||||
|
||||
self.stubs.Set(driver, 'instance_update_db',
|
||||
_fake_instance_update_db)
|
||||
|
||||
instance = {'uuid': 'fake-uuid', 'host': 'host1'}
|
||||
|
||||
sched.schedule_prep_resize(fake_context, {}, {}, {}, instance, {})
|
||||
self.assertEqual(info['called'], 0)
|
||||
|
||||
def test_get_cost_functions(self):
|
||||
self.flags(reserved_host_memory_mb=128)
|
||||
fixture = fakes.FakeFilterScheduler()
|
||||
|
||||
@@ -84,8 +84,8 @@ class SchedulerRpcAPITestCase(test.TestCase):
|
||||
self._test_scheduler_api('prep_resize', rpc_method='cast',
|
||||
instance='fake_instance',
|
||||
instance_type='fake_type', image='fake_image',
|
||||
update_db='fake_update_db', request_spec='fake_request_spec',
|
||||
filter_properties='fake_props', version='1.1')
|
||||
request_spec='fake_request_spec',
|
||||
filter_properties='fake_props', version='1.4')
|
||||
|
||||
def test_show_host_resources(self):
|
||||
self._test_scheduler_api('show_host_resources', rpc_method='call',
|
||||
|
||||
@@ -247,7 +247,6 @@ class SchedulerManagerTestCase(test.TestCase):
|
||||
kwargs = {
|
||||
'context': self.context,
|
||||
'image': 'fake_image',
|
||||
'update_db': True,
|
||||
'request_spec': request_spec,
|
||||
'filter_properties': 'fake_props',
|
||||
'instance': 'fake_instance',
|
||||
@@ -260,7 +259,8 @@ class SchedulerManagerTestCase(test.TestCase):
|
||||
(inst, inst))
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.manager.prep_resize(**kwargs)
|
||||
# FIXME(comstud): Remove 'update_db' on future RPC version bump.
|
||||
self.manager.prep_resize(update_db=False, **kwargs)
|
||||
|
||||
def test_prep_resize_exception_host_in_error_state_and_raise(self):
|
||||
"""Test that a NoValidHost exception for prep_resize puts
|
||||
@@ -277,7 +277,6 @@ class SchedulerManagerTestCase(test.TestCase):
|
||||
kwargs = {
|
||||
'context': self.context,
|
||||
'image': 'fake_image',
|
||||
'update_db': True,
|
||||
'request_spec': request_spec,
|
||||
'filter_properties': 'fake_props',
|
||||
'instance': 'fake_instance',
|
||||
@@ -296,7 +295,9 @@ class SchedulerManagerTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
# FIXME(comstud): Remove 'update_db' on future RPC version bump.
|
||||
self.assertRaises(self.AnException, self.manager.prep_resize,
|
||||
update_db=False,
|
||||
**kwargs)
|
||||
|
||||
|
||||
@@ -774,7 +775,7 @@ class SchedulerDriverBaseTestCase(SchedulerTestCase):
|
||||
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.driver.schedule_prep_resize,
|
||||
self.context, {}, False,
|
||||
self.context, {},
|
||||
fake_request_spec, {}, {}, {})
|
||||
|
||||
|
||||
@@ -807,7 +808,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_volume_host(self.context, host, method,
|
||||
update_db=True, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_volume_host_update_db_without_volume_id(self):
|
||||
host = 'fake_host1'
|
||||
@@ -825,25 +826,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_volume_host(self.context, host, method,
|
||||
update_db=True, **fake_kwargs)
|
||||
|
||||
def test_cast_to_volume_host_no_update_db(self):
|
||||
host = 'fake_host1'
|
||||
method = 'fake_method'
|
||||
fake_kwargs = {'extra_arg': 'meow'}
|
||||
queue = 'fake_queue'
|
||||
|
||||
self.mox.StubOutWithMock(rpc, 'queue_get_for')
|
||||
self.mox.StubOutWithMock(rpc, 'cast')
|
||||
|
||||
rpc.queue_get_for(self.context, 'volume', host).AndReturn(queue)
|
||||
rpc.cast(self.context, queue,
|
||||
{'method': method,
|
||||
'args': fake_kwargs})
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_volume_host(self.context, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_compute_host_update_db_with_instance_uuid(self):
|
||||
host = 'fake_host1'
|
||||
@@ -867,7 +850,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_compute_host(self.context, host, method,
|
||||
update_db=True, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_compute_host_update_db_without_instance_uuid(self):
|
||||
host = 'fake_host1'
|
||||
@@ -885,25 +868,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_compute_host(self.context, host, method,
|
||||
update_db=True, **fake_kwargs)
|
||||
|
||||
def test_cast_to_compute_host_no_update_db(self):
|
||||
host = 'fake_host1'
|
||||
method = 'fake_method'
|
||||
fake_kwargs = {'extra_arg': 'meow'}
|
||||
queue = 'fake_queue'
|
||||
|
||||
self.mox.StubOutWithMock(rpc, 'queue_get_for')
|
||||
self.mox.StubOutWithMock(rpc, 'cast')
|
||||
|
||||
rpc.queue_get_for(self.context, 'compute', host).AndReturn(queue)
|
||||
rpc.cast(self.context, queue,
|
||||
{'method': method,
|
||||
'args': fake_kwargs})
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_compute_host(self.context, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_network_host(self):
|
||||
host = 'fake_host1'
|
||||
@@ -921,7 +886,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_network_host(self.context, host, method,
|
||||
update_db=True, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_host_compute_topic(self):
|
||||
host = 'fake_host1'
|
||||
@@ -930,11 +895,11 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.StubOutWithMock(driver, 'cast_to_compute_host')
|
||||
driver.cast_to_compute_host(self.context, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_host(self.context, 'compute', host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_host_volume_topic(self):
|
||||
host = 'fake_host1'
|
||||
@@ -943,11 +908,11 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.StubOutWithMock(driver, 'cast_to_volume_host')
|
||||
driver.cast_to_volume_host(self.context, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_host(self.context, 'volume', host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_host_network_topic(self):
|
||||
host = 'fake_host1'
|
||||
@@ -956,11 +921,11 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.StubOutWithMock(driver, 'cast_to_network_host')
|
||||
driver.cast_to_network_host(self.context, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_host(self.context, 'network', host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_cast_to_host_unknown_topic(self):
|
||||
host = 'fake_host1'
|
||||
@@ -979,7 +944,7 @@ class SchedulerDriverModuleTestCase(test.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
driver.cast_to_host(self.context, topic, host, method,
|
||||
update_db=False, **fake_kwargs)
|
||||
**fake_kwargs)
|
||||
|
||||
def test_encode_instance(self):
|
||||
instance = {'id': 31337,
|
||||
|
||||
Reference in New Issue
Block a user