Support tag instances when boot(2/4)
This is the second patch of the series, this patch adds tags to build_request object. Change-Id: I1121eaf24856dcb74f07c224531a821b3cdc46fc Part of blueprint support-tag-instance-when-boot
This commit is contained in:
parent
3ce0a050e1
commit
18c61263a3
@ -36,7 +36,8 @@ class BuildRequest(base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added block_device_mappings
|
||||
# Version 1.2: Added save() method
|
||||
VERSION = '1.2'
|
||||
# Version 1.3: Added tags
|
||||
VERSION = '1.3'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
@ -49,6 +50,7 @@ class BuildRequest(base.NovaObject):
|
||||
# created_at/updated_at. There is no soft delete for this object.
|
||||
'created_at': fields.DateTimeField(nullable=True),
|
||||
'updated_at': fields.DateTimeField(nullable=True),
|
||||
'tags': fields.ObjectField('TagList'),
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
@ -57,6 +59,8 @@ class BuildRequest(base.NovaObject):
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 1) and 'block_device_mappings' in primitive:
|
||||
del primitive['block_device_mappings']
|
||||
elif target_version < (1, 3) and 'tags' in primitive:
|
||||
del primitive['tags']
|
||||
|
||||
def _load_instance(self, db_instance):
|
||||
# NOTE(alaski): Be very careful with instance loading because it
|
||||
@ -104,7 +108,7 @@ class BuildRequest(base.NovaObject):
|
||||
# was never persisted.
|
||||
self.instance.created_at = self.created_at
|
||||
self.instance.updated_at = self.updated_at
|
||||
self.instance.tags = objects.TagList([])
|
||||
self.instance.tags = self.tags
|
||||
|
||||
def _load_block_device_mappings(self, db_bdms):
|
||||
# 'db_bdms' is a serialized BlockDeviceMappingList object. If it's None
|
||||
@ -122,6 +126,22 @@ class BuildRequest(base.NovaObject):
|
||||
objects.BlockDeviceMappingList.obj_from_primitive(
|
||||
jsonutils.loads(db_bdms)))
|
||||
|
||||
def _load_tags(self, db_tags):
|
||||
# 'db_tags' is a serialized TagList object. If it's None
|
||||
# we're in a mixed version nova-api scenario and can't retrieve the
|
||||
# actual list. Set it to an empty list here which will cause a
|
||||
# temporary API inconsistency that will be resolved as soon as the
|
||||
# instance is scheduled and on a compute.
|
||||
if db_tags is None:
|
||||
LOG.debug('Failed to load tags from BuildRequest '
|
||||
'for instance %s because it is None', self.instance_uuid)
|
||||
self.tags = objects.TagList()
|
||||
return
|
||||
|
||||
self.tags = (
|
||||
objects.TagList.obj_from_primitive(
|
||||
jsonutils.loads(db_tags)))
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, req, db_req):
|
||||
# Set this up front so that it can be pulled for error messages or
|
||||
@ -225,6 +245,8 @@ class BuildRequest(base.NovaObject):
|
||||
for field in self.instance.obj_fields:
|
||||
# NOTE(danms): Don't copy the defaulted tags field
|
||||
# as instance.create() won't handle it properly.
|
||||
# TODO(zhengzhenyu): Handle this when the API supports creating
|
||||
# servers with tags.
|
||||
if field == 'tags':
|
||||
continue
|
||||
if self.instance.obj_attr_is_set(field):
|
||||
@ -344,6 +366,8 @@ class BuildRequestList(base.ObjectListBase, base.NovaObject):
|
||||
# Fortunately some filters do not apply here.
|
||||
# 'tags' can not be applied at boot time so will not be set for an
|
||||
# instance here.
|
||||
# TODO(zhengzhenyu): Handle this when the API supports creating
|
||||
# servers with tags.
|
||||
# 'changes-since' works off of the updated_at field which has not yet
|
||||
# been set at the point in the boot process where build_request still
|
||||
# exists. So it can be ignored.
|
||||
|
@ -64,7 +64,7 @@ class BuildRequestTestCase(test.NoDBTestCase):
|
||||
if key == 'instance':
|
||||
objects.base.obj_equal_prims(expected, db_value)
|
||||
continue
|
||||
elif key == 'block_device_mappings':
|
||||
elif key in ('block_device_mappings', 'tags'):
|
||||
self.assertEqual(1, len(db_value))
|
||||
# Can't compare list objects directly, just compare the single
|
||||
# item they contain.
|
||||
|
@ -40,6 +40,8 @@ def fake_db_req(**updates):
|
||||
snapshot_id=None, volume_id=None, volume_size=0,
|
||||
image_id='bar', no_device=False, connection_info=None,
|
||||
tag='', instance_uuid=uuids.instance))])
|
||||
tags = objects.TagList(objects=[objects.Tag(tag='tag1',
|
||||
resource_id=instance_uuid)])
|
||||
db_build_request = {
|
||||
'id': 1,
|
||||
'project_id': 'fake-project',
|
||||
@ -47,6 +49,7 @@ def fake_db_req(**updates):
|
||||
'instance': jsonutils.dumps(instance.obj_to_primitive()),
|
||||
'block_device_mappings': jsonutils.dumps(
|
||||
block_devices.obj_to_primitive()),
|
||||
'tags': jsonutils.dumps(tags.obj_to_primitive()),
|
||||
'created_at': datetime.datetime(2016, 1, 16),
|
||||
'updated_at': datetime.datetime(2016, 1, 16),
|
||||
}
|
||||
@ -85,6 +88,9 @@ def fake_req_obj(ctxt, db_req=None):
|
||||
req_obj.block_device_mappings = (
|
||||
objects.BlockDeviceMappingList.obj_from_primitive(
|
||||
jsonutils.loads(value)))
|
||||
elif field == 'tags':
|
||||
req_obj.tags = objects.TagList.obj_from_primitive(
|
||||
jsonutils.loads(value))
|
||||
elif field == 'instance_metadata':
|
||||
setattr(req_obj, field, jsonutils.loads(value))
|
||||
else:
|
||||
|
@ -16,6 +16,7 @@ from oslo_versionedobjects import base as o_vo_base
|
||||
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.objects import base
|
||||
from nova.objects import build_request
|
||||
from nova.tests.unit import fake_build_request
|
||||
from nova.tests.unit import fake_instance
|
||||
@ -159,6 +160,28 @@ class _TestBuildRequestObject(object):
|
||||
mock_obj_set_defaults.assert_called_once_with('deleted')
|
||||
self.assertFalse(build_request.instance.deleted)
|
||||
|
||||
def test_obj_make_compatible_pre_1_3(self):
|
||||
obj = fake_build_request.fake_req_obj(self.context)
|
||||
build_request_obj = objects.BuildRequest(self.context)
|
||||
obj_primitive = obj.obj_to_primitive()
|
||||
build_request_obj.obj_make_compatible(obj_primitive, '1.2')
|
||||
self.assertNotIn('tags', obj_primitive)
|
||||
|
||||
def test_create_with_tags_set(self):
|
||||
# Test that when we set tags on the build request,
|
||||
# create it and reload it from the database that the
|
||||
# build_request.instance.tags is the same thing.
|
||||
build_request_obj = fake_build_request.fake_req_obj(self.context)
|
||||
self.assertEqual(1, len(build_request_obj.tags))
|
||||
build_request_obj.create()
|
||||
self.assertEqual(1, len(build_request_obj.tags))
|
||||
self.assertEqual(len(build_request_obj.tags),
|
||||
len(build_request_obj.instance.tags))
|
||||
# Can't compare list objects directly, just compare the single
|
||||
# item they contain.
|
||||
base.obj_equal_prims(build_request_obj.tags[0],
|
||||
build_request_obj.instance.tags[0])
|
||||
|
||||
|
||||
class TestBuildRequestObject(test_objects._LocalTest,
|
||||
_TestBuildRequestObject):
|
||||
|
@ -1068,7 +1068,7 @@ object_data = {
|
||||
'BandwidthUsageList': '1.2-5fe7475ada6fe62413cbfcc06ec70746',
|
||||
'BlockDeviceMapping': '1.18-ad87cece6f84c65f5ec21615755bc6d3',
|
||||
'BlockDeviceMappingList': '1.17-1e568eecb91d06d4112db9fd656de235',
|
||||
'BuildRequest': '1.2-532d95a88c5fd33e85878e408e5d6e8d',
|
||||
'BuildRequest': '1.3-077dee42bed93f8a5b62be77657b7152',
|
||||
'BuildRequestList': '1.0-cd95608eccb89fbc702c8b52f38ec738',
|
||||
'CellMapping': '1.0-7f1a7e85a22bbb7559fc730ab658b9bd',
|
||||
'CellMappingList': '1.0-4ee0d9efdfd681fed822da88376e04d2',
|
||||
|
Loading…
Reference in New Issue
Block a user