Make ComputeNode.service_id nullable to match db schema

The compute_node table was recently updated to make service_id column
nullable[1]. This mirrors that change to the ComputeNode object.

[1] 551be2c52a

Change-Id: I54e81fe7662039d4bf51babcbd2a0d597f98377a
Related-Bug: #1438189
This commit is contained in:
Hans Lindgren 2015-03-31 13:37:52 +02:00
parent 99ac112db8
commit 0b177f1826
5 changed files with 53 additions and 17 deletions

View File

@ -41,11 +41,12 @@ class ComputeNode(base.NovaPersistentObject, base.NovaObject,
# Version 1.10: Added get_first_node_by_host_for_old_compat()
# Version 1.11: PciDevicePoolList version 1.1
# Version 1.12: HVSpec version 1.1
VERSION = '1.12'
# Version 1.13: Changed service_id field to be nullable
VERSION = '1.13'
fields = {
'id': fields.IntegerField(read_only=True),
'service_id': fields.IntegerField(),
'service_id': fields.IntegerField(nullable=True),
'host': fields.StringField(nullable=True),
'vcpus': fields.IntegerField(),
'memory_mb': fields.IntegerField(),
@ -83,6 +84,19 @@ class ComputeNode(base.NovaPersistentObject, base.NovaObject,
def obj_make_compatible(self, primitive, target_version):
super(ComputeNode, self).obj_make_compatible(primitive, target_version)
target_version = utils.convert_version_to_tuple(target_version)
if target_version < (1, 13) and primitive.get('service_id') is None:
# service_id is non-nullable in versions before 1.13
try:
service = objects.Service.get_by_compute_host(
self._context, primitive['host'])
primitive['service_id'] = service.id
except (exception.ComputeHostNotFound, KeyError):
# NOTE(hanlind): In case anything goes wrong like service not
# found or host not being set, catch and set a fake value just
# to allow for older versions that demand a value to work.
# Setting to -1 will, if value is later used result in a
# ServiceNotFound, so should be safe.
primitive['service_id'] = -1
if target_version < (1, 7) and 'host' in primitive:
del primitive['host']
if target_version < (1, 5) and 'numa_topology' in primitive:
@ -313,7 +327,8 @@ class ComputeNodeList(base.ObjectListBase, base.NovaObject):
# Version 1.10 ComputeNode version 1.10
# Version 1.11 ComputeNode version 1.11
# Version 1.12 ComputeNode version 1.12
VERSION = '1.12'
# Version 1.13 ComputeNode version 1.13
VERSION = '1.13'
fields = {
'objects': fields.ListOfObjectsField('ComputeNode'),
}
@ -323,7 +338,7 @@ class ComputeNodeList(base.ObjectListBase, base.NovaObject):
('1.3', '1.4'), ('1.4', '1.5'), ('1.5', '1.5'),
('1.6', '1.6'), ('1.7', '1.7'), ('1.8', '1.8'),
('1.9', '1.9'), ('1.10', '1.10'), ('1.11', '1.11'),
('1.12', '1.12')],
('1.12', '1.12'), ('1.13', '1.13')],
}
@base.remotable_classmethod

View File

@ -77,7 +77,8 @@ class Service(base.NovaPersistentObject, base.NovaObject,
# Version 1.14: Added forced_down
# Version 1.15: ComputeNode version 1.12
# Version 1.16: Added version
VERSION = '1.16'
# Version 1.17: ComputeNode version 1.13
VERSION = '1.17'
fields = {
'id': fields.IntegerField(read_only=True),
@ -97,7 +98,7 @@ class Service(base.NovaPersistentObject, base.NovaObject,
obj_relationships = {
'compute_node': [('1.1', '1.4'), ('1.3', '1.5'), ('1.5', '1.6'),
('1.7', '1.8'), ('1.8', '1.9'), ('1.9', '1.10'),
('1.12', '1.11'), ('1.15', '1.12')],
('1.12', '1.11'), ('1.15', '1.12'), ('1.17', '1.13')],
}
def __init__(self, *args, **kwargs):
@ -268,7 +269,8 @@ class ServiceList(base.ObjectListBase, base.NovaObject):
# Version 1.12: Service version 1.14
# Version 1.13: Service version 1.15
# Version 1.14: Service version 1.16
VERSION = '1.14'
# Version 1.15: Service version 1.17
VERSION = '1.15'
fields = {
'objects': fields.ListOfObjectsField('Service'),
@ -279,7 +281,8 @@ class ServiceList(base.ObjectListBase, base.NovaObject):
('1.3', '1.5'), ('1.4', '1.6'), ('1.5', '1.7'),
('1.6', '1.8'), ('1.7', '1.9'), ('1.8', '1.10'),
('1.9', '1.11'), ('1.10', '1.12'), ('1.11', '1.13'),
('1.12', '1.14'), ('1.13', '1.15'), ('1.14', '1.16')],
('1.12', '1.14'), ('1.13', '1.15'), ('1.14', '1.16'),
('1.15', '1.17')],
}
@base.remotable_classmethod

View File

@ -60,7 +60,7 @@ fake_compute_node = {
'deleted_at': None,
'deleted': False,
'id': 123,
'service_id': 456,
'service_id': None,
'host': 'fake',
'vcpus': 4,
'memory_mb': 4096,
@ -156,7 +156,9 @@ class _TestComputeNodeObject(object):
@mock.patch.object(db, 'compute_node_get')
def test_get_by_id_with_host_field_not_in_db(self, mock_cn_get,
mock_obj_svc_get):
fake_compute_node_with_no_host = fake_compute_node.copy()
fake_compute_node_with_svc_id = fake_compute_node.copy()
fake_compute_node_with_svc_id['service_id'] = 123
fake_compute_node_with_no_host = fake_compute_node_with_svc_id.copy()
host = fake_compute_node_with_no_host.pop('host')
fake_service = service.Service(id=123)
fake_service.host = host
@ -165,7 +167,7 @@ class _TestComputeNodeObject(object):
mock_obj_svc_get.return_value = fake_service
compute = compute_node.ComputeNode.get_by_id(self.context, 123)
self.compare_obj(compute, fake_compute_node,
self.compare_obj(compute, fake_compute_node_with_svc_id,
subs=self.subs(),
comparators=self.comparators())
@ -458,6 +460,20 @@ class _TestComputeNodeObject(object):
primitive = compute.obj_to_primitive(target_version='1.8')
self.assertNotIn('pci_device_pools', primitive)
@mock.patch('nova.objects.Service.get_by_compute_host')
def test_compat_service_id(self, mock_get):
mock_get.return_value = objects.Service(id=1)
compute = objects.ComputeNode(host='fake-host', service_id=None)
primitive = compute.obj_to_primitive(target_version='1.12')
self.assertEqual(1, primitive['nova_object.data']['service_id'])
@mock.patch('nova.objects.Service.get_by_compute_host')
def test_compat_service_id_compute_host_not_found(self, mock_get):
mock_get.side_effect = exception.ComputeHostNotFound(host='fake-host')
compute = objects.ComputeNode(host='fake-host', service_id=None)
primitive = compute.obj_to_primitive(target_version='1.12')
self.assertEqual(-1, primitive['nova_object.data']['service_id'])
def test_update_from_virt_driver(self):
# copy in case the update has a side effect
resources = copy.deepcopy(fake_resources)

View File

@ -1095,8 +1095,8 @@ object_data = {
'BlockDeviceMapping': '1.14-d44d8d694619e79c172a99b3c1d6261d',
'BlockDeviceMappingList': '1.15-6fa262c059dad1d519b9fe05b9e4f404',
'CellMapping': '1.0-7f1a7e85a22bbb7559fc730ab658b9bd',
'ComputeNode': '1.12-71784d2e6f2814ab467d4e0f69286843',
'ComputeNodeList': '1.12-3b6f4f5ade621c40e70cb116db237844',
'ComputeNode': '1.13-1e370701d1d10a88d94c02c34098d2a9',
'ComputeNodeList': '1.13-3b6f4f5ade621c40e70cb116db237844',
'DNSDomain': '1.0-7b0b2dab778454b6a7b6c66afe163a1a',
'DNSDomainList': '1.0-4ee0d9efdfd681fed822da88376e04d2',
'EC2Ids': '1.0-474ee1094c7ec16f8ce657595d8c49d9',
@ -1156,8 +1156,8 @@ object_data = {
'SecurityGroupList': '1.0-dc8bbea01ba09a2edb6e5233eae85cbc',
'SecurityGroupRule': '1.1-ae1da17b79970012e8536f88cb3c6b29',
'SecurityGroupRuleList': '1.1-674b323c9ccea02e93b1b40e7fd2091a',
'Service': '1.16-f1c6e82b5479f63e35970fe7625c3878',
'ServiceList': '1.14-b767102cba7cbed290e396114c3f86b3',
'Service': '1.17-f1c6e82b5479f63e35970fe7625c3878',
'ServiceList': '1.15-b767102cba7cbed290e396114c3f86b3',
'TaskLog': '1.0-78b0534366f29aa3eebb01860fbe18fe',
'TaskLogList': '1.0-cc8cce1af8a283b9d28b55fcd682e777',
'Tag': '1.1-8b8d7d5b48887651a0e01241672e2963',

View File

@ -248,7 +248,8 @@ class _TestServiceObject(object):
def test_obj_make_compatible_for_compute_node(self, get_all_by_host):
service_obj = objects.Service(context=self.context)
fake_service_dict = fake_service.copy()
fake_compute_obj = objects.ComputeNode(host=fake_service['host'])
fake_compute_obj = objects.ComputeNode(host=fake_service['host'],
service_id=fake_service['id'])
get_all_by_host.return_value = [fake_compute_obj]
service_obj.obj_make_compatible(fake_service_dict, '1.9')
@ -265,7 +266,8 @@ class _TestServiceObject(object):
service_obj.binary = 'nova-compute'
fake_service_dict = fake_service.copy()
fake_service_dict['binary'] = 'nova-compute'
fake_compute_obj = objects.ComputeNode(host=fake_service['host'])
fake_compute_obj = objects.ComputeNode(host=fake_service['host'],
service_id=fake_service['id'])
get_all_by_host.return_value = [fake_compute_obj]
# Juno versions :