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:
Kevin_Zheng 2017-04-25 15:29:36 +08:00 committed by Zhenyu Zheng
parent 3ce0a050e1
commit 18c61263a3
5 changed files with 57 additions and 4 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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:

View File

@ -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):

View File

@ -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',