Add tags to instance.create Notification
This patch added a new field 'tags' to InstanceCreatePayload. Partial-implement: bp additional-notification-fields-for-searchlight Partial-implement: blueprint support-tag-instance-when-boot Change-Id: Iefaa9da4e136fd5e823bf7b11c8aa5b4cd6d7de8
This commit is contained in:
parent
0cb765b19b
commit
f665565d69
|
@ -52,6 +52,7 @@
|
||||||
"state":"active",
|
"state":"active",
|
||||||
"task_state":null,
|
"task_state":null,
|
||||||
"power_state":"running",
|
"power_state":"running",
|
||||||
|
"tags":["tag"],
|
||||||
"tenant_id":"6f70656e737461636b20342065766572",
|
"tenant_id":"6f70656e737461636b20342065766572",
|
||||||
"terminated_at":null,
|
"terminated_at":null,
|
||||||
"auto_disk_config":"MANUAL",
|
"auto_disk_config":"MANUAL",
|
||||||
|
@ -82,7 +83,7 @@
|
||||||
},
|
},
|
||||||
"nova_object.name":"InstanceCreatePayload",
|
"nova_object.name":"InstanceCreatePayload",
|
||||||
"nova_object.namespace":"nova",
|
"nova_object.namespace":"nova",
|
||||||
"nova_object.version":"1.5"
|
"nova_object.version":"1.6"
|
||||||
},
|
},
|
||||||
"priority":"INFO",
|
"priority":"INFO",
|
||||||
"publisher_id":"nova-compute:compute"
|
"publisher_id":"nova-compute:compute"
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"state":"building",
|
"state":"building",
|
||||||
"task_state":null,
|
"task_state":null,
|
||||||
"power_state":"pending",
|
"power_state":"pending",
|
||||||
|
"tags":["tag"],
|
||||||
"tenant_id":"6f70656e737461636b20342065766572",
|
"tenant_id":"6f70656e737461636b20342065766572",
|
||||||
"terminated_at":null,
|
"terminated_at":null,
|
||||||
"auto_disk_config":"MANUAL",
|
"auto_disk_config":"MANUAL",
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
},
|
},
|
||||||
"nova_object.name":"InstanceCreatePayload",
|
"nova_object.name":"InstanceCreatePayload",
|
||||||
"nova_object.namespace":"nova",
|
"nova_object.namespace":"nova",
|
||||||
"nova_object.version":"1.5"
|
"nova_object.version":"1.6"
|
||||||
},
|
},
|
||||||
"priority":"ERROR",
|
"priority":"ERROR",
|
||||||
"publisher_id":"nova-compute:compute"
|
"publisher_id":"nova-compute:compute"
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
"state":"building",
|
"state":"building",
|
||||||
"task_state":null,
|
"task_state":null,
|
||||||
"power_state":"pending",
|
"power_state":"pending",
|
||||||
|
"tags":["tag"],
|
||||||
"tenant_id":"6f70656e737461636b20342065766572",
|
"tenant_id":"6f70656e737461636b20342065766572",
|
||||||
"terminated_at":null,
|
"terminated_at":null,
|
||||||
"auto_disk_config":"MANUAL",
|
"auto_disk_config":"MANUAL",
|
||||||
|
@ -69,7 +70,7 @@
|
||||||
},
|
},
|
||||||
"nova_object.name":"InstanceCreatePayload",
|
"nova_object.name":"InstanceCreatePayload",
|
||||||
"nova_object.namespace":"nova",
|
"nova_object.namespace":"nova",
|
||||||
"nova_object.version":"1.5"
|
"nova_object.version":"1.6"
|
||||||
},
|
},
|
||||||
"priority":"INFO",
|
"priority":"INFO",
|
||||||
"publisher_id":"nova-compute:compute"
|
"publisher_id":"nova-compute:compute"
|
||||||
|
|
|
@ -1011,6 +1011,12 @@ class ComputeTaskManager(base.Base):
|
||||||
cell, instance.flavor, instance.uuid, block_device_mapping)
|
cell, instance.flavor, instance.uuid, block_device_mapping)
|
||||||
instance_tags = self._create_tags(cctxt, instance.uuid, tags)
|
instance_tags = self._create_tags(cctxt, instance.uuid, tags)
|
||||||
|
|
||||||
|
# TODO(Kevin Zheng): clean this up once instance.create() handles
|
||||||
|
# tags; we do this so the instance.create notification in
|
||||||
|
# build_and_run_instance in nova-compute doesn't lazy-load tags
|
||||||
|
instance.tags = instance_tags if instance_tags \
|
||||||
|
else objects.TagList()
|
||||||
|
|
||||||
# Update mapping for instance. Normally this check is guarded by
|
# Update mapping for instance. Normally this check is guarded by
|
||||||
# a try/except but if we're here we know that a newer nova-api
|
# a try/except but if we're here we know that a newer nova-api
|
||||||
# handled the build process and would have created the mapping
|
# handled the build process and would have created the mapping
|
||||||
|
|
|
@ -187,10 +187,12 @@ class InstanceCreatePayload(InstanceActionPayload):
|
||||||
# 1.3: Add keypairs field
|
# 1.3: Add keypairs field
|
||||||
# 1.4: Add key_name field to InstancePayload
|
# 1.4: Add key_name field to InstancePayload
|
||||||
# 1.5: Add BDM related data to InstancePayload
|
# 1.5: Add BDM related data to InstancePayload
|
||||||
VERSION = '1.5'
|
# 1.6: Add tags field to InstanceCreatePayload
|
||||||
|
VERSION = '1.6'
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'keypairs': fields.ListOfObjectsField('KeypairPayload')
|
'keypairs': fields.ListOfObjectsField('KeypairPayload'),
|
||||||
|
'tags': fields.ListOfStringsField(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, instance, fault):
|
def __init__(self, instance, fault):
|
||||||
|
@ -199,6 +201,8 @@ class InstanceCreatePayload(InstanceActionPayload):
|
||||||
fault=fault)
|
fault=fault)
|
||||||
self.keypairs = [keypair_payload.KeypairPayload(keypair=keypair)
|
self.keypairs = [keypair_payload.KeypairPayload(keypair=keypair)
|
||||||
for keypair in instance.keypairs]
|
for keypair in instance.keypairs]
|
||||||
|
self.tags = [instance_tag.tag
|
||||||
|
for instance_tag in instance.tags]
|
||||||
|
|
||||||
|
|
||||||
@nova_base.NovaObjectRegistry.register_notification
|
@nova_base.NovaObjectRegistry.register_notification
|
||||||
|
|
|
@ -156,7 +156,8 @@ class TestInstanceNotificationSample(
|
||||||
|
|
||||||
def test_create_delete_server(self):
|
def test_create_delete_server(self):
|
||||||
server = self._boot_a_server(
|
server = self._boot_a_server(
|
||||||
extra_params={'networks': [{'port': self.neutron.port_1['id']}]})
|
extra_params={'networks': [{'port': self.neutron.port_1['id']}],
|
||||||
|
'tags': ['tag']})
|
||||||
self._attach_volume_to_server(server, self.cinder.SWAP_OLD_VOL)
|
self._attach_volume_to_server(server, self.cinder.SWAP_OLD_VOL)
|
||||||
self.api.delete_server(server['id'])
|
self.api.delete_server(server['id'])
|
||||||
self._wait_until_deleted(server)
|
self._wait_until_deleted(server)
|
||||||
|
@ -191,7 +192,8 @@ class TestInstanceNotificationSample(
|
||||||
|
|
||||||
server = self._boot_a_server(
|
server = self._boot_a_server(
|
||||||
expected_status='ERROR',
|
expected_status='ERROR',
|
||||||
extra_params={'networks': [{'port': self.neutron.port_1['id']}]})
|
extra_params={'networks': [{'port': self.neutron.port_1['id']}],
|
||||||
|
'tags': ['tag']})
|
||||||
|
|
||||||
self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||||
|
|
||||||
|
|
|
@ -5265,7 +5265,7 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
|
||||||
mock.ANY, 'expected_task_state': 'spawning'}
|
mock.ANY, 'expected_task_state': 'spawning'}
|
||||||
expected_call = mock.call(self.context, self.instance.uuid,
|
expected_call = mock.call(self.context, self.instance.uuid,
|
||||||
updates, columns_to_join=['metadata', 'system_metadata',
|
updates, columns_to_join=['metadata', 'system_metadata',
|
||||||
'info_cache'])
|
'info_cache', 'tags'])
|
||||||
last_update_call = mock_db_update.call_args_list[
|
last_update_call = mock_db_update.call_args_list[
|
||||||
mock_db_update.call_count - 1]
|
mock_db_update.call_count - 1]
|
||||||
self.assertEqual(expected_call, last_update_call)
|
self.assertEqual(expected_call, last_update_call)
|
||||||
|
|
|
@ -603,6 +603,47 @@ class UsageInfoTestCase(test.TestCase):
|
||||||
|
|
||||||
self.assertEqual(uuids.fake_image_ref, payload['image_uuid'])
|
self.assertEqual(uuids.fake_image_ref, payload['image_uuid'])
|
||||||
|
|
||||||
|
def test_notify_about_instance_create_with_tags(self):
|
||||||
|
instance = create_instance(self.context)
|
||||||
|
|
||||||
|
# TODO(Kevin Zheng): clean this up to pass tags as params to
|
||||||
|
# create_instance() once instance.create() handles tags.
|
||||||
|
instance.tags = objects.TagList(
|
||||||
|
objects=[objects.Tag(self.context, tag='tag1')])
|
||||||
|
|
||||||
|
compute_utils.notify_about_instance_create(
|
||||||
|
self.context,
|
||||||
|
instance,
|
||||||
|
host='fake-compute',
|
||||||
|
phase='start')
|
||||||
|
|
||||||
|
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||||
|
notification = fake_notifier.VERSIONED_NOTIFICATIONS[0]
|
||||||
|
|
||||||
|
self.assertEqual('INFO', notification['priority'])
|
||||||
|
self.assertEqual('instance.create.start', notification['event_type'])
|
||||||
|
self.assertEqual('nova-compute:fake-compute',
|
||||||
|
notification['publisher_id'])
|
||||||
|
|
||||||
|
payload = notification['payload']['nova_object.data']
|
||||||
|
self.assertEqual('fake', payload['tenant_id'])
|
||||||
|
self.assertEqual('fake', payload['user_id'])
|
||||||
|
self.assertEqual(instance.uuid, payload['uuid'])
|
||||||
|
|
||||||
|
flavorid = flavors.get_flavor_by_name('m1.tiny')['flavorid']
|
||||||
|
flavor = payload['flavor']['nova_object.data']
|
||||||
|
self.assertEqual(flavorid, str(flavor['flavorid']))
|
||||||
|
|
||||||
|
self.assertEqual(0, len(payload['keypairs']))
|
||||||
|
for attr in ('display_name', 'created_at', 'launched_at',
|
||||||
|
'state', 'task_state', 'display_description', 'locked',
|
||||||
|
'auto_disk_config', 'tags'):
|
||||||
|
self.assertIn(attr, payload, "Key %s not in payload" % attr)
|
||||||
|
|
||||||
|
self.assertEqual(1, len(payload['tags']))
|
||||||
|
self.assertEqual('tag1', payload['tags'][0])
|
||||||
|
self.assertEqual(uuids.fake_image_ref, payload['image_uuid'])
|
||||||
|
|
||||||
def test_notify_about_volume_swap(self):
|
def test_notify_about_volume_swap(self):
|
||||||
instance = create_instance(self.context)
|
instance = create_instance(self.context)
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,7 @@ def fake_instance_obj(context, obj_instance_class=None, **updates):
|
||||||
obj_instance_class(), fake_db_instance(**updates),
|
obj_instance_class(), fake_db_instance(**updates),
|
||||||
expected_attrs=expected_attrs)
|
expected_attrs=expected_attrs)
|
||||||
inst.keypairs = objects.KeyPairList(objects=[])
|
inst.keypairs = objects.KeyPairList(objects=[])
|
||||||
|
inst.tags = objects.TagList()
|
||||||
if flavor:
|
if flavor:
|
||||||
inst.flavor = flavor
|
inst.flavor = flavor
|
||||||
# This is needed for instance quota counting until we have the
|
# This is needed for instance quota counting until we have the
|
||||||
|
|
|
@ -385,7 +385,7 @@ notification_object_data = {
|
||||||
'1.0-a73147b93b520ff0061865849d3dfa56',
|
'1.0-a73147b93b520ff0061865849d3dfa56',
|
||||||
'InstanceActionVolumeSwapPayload': '1.4-8b82cef523c62020c24b3eb1c39ea2ef',
|
'InstanceActionVolumeSwapPayload': '1.4-8b82cef523c62020c24b3eb1c39ea2ef',
|
||||||
'InstanceCreateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
|
'InstanceCreateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
|
||||||
'InstanceCreatePayload': '1.5-97e9c0f516a68f20b25ce2f994cab081',
|
'InstanceCreatePayload': '1.6-b117dd709616d60cf5e126b983c72cd2',
|
||||||
'InstancePayload': '1.4-46d922bd0a5cce46398b0cf7e8735fc4',
|
'InstancePayload': '1.4-46d922bd0a5cce46398b0cf7e8735fc4',
|
||||||
'InstanceStateUpdatePayload': '1.0-07e111c0fa0f6db0f79b0726d593e3da',
|
'InstanceStateUpdatePayload': '1.0-07e111c0fa0f6db0f79b0726d593e3da',
|
||||||
'InstanceUpdateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
|
'InstanceUpdateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
|
||||||
|
|
|
@ -140,6 +140,9 @@ class _TestBuildRequestObject(object):
|
||||||
# on build_request
|
# on build_request
|
||||||
fake_req = fake_build_request.fake_db_req()
|
fake_req = fake_build_request.fake_db_req()
|
||||||
fields = jsonutils.loads(fake_req['instance'])['nova_object.data']
|
fields = jsonutils.loads(fake_req['instance'])['nova_object.data']
|
||||||
|
# TODO(Kevin Zheng): clean up this workaround once
|
||||||
|
# build_request.get_new_instance() can handle tags.
|
||||||
|
fields.pop('tags', None)
|
||||||
build_request = objects.BuildRequest._from_db_object(
|
build_request = objects.BuildRequest._from_db_object(
|
||||||
self.context, objects.BuildRequest(), fake_req)
|
self.context, objects.BuildRequest(), fake_req)
|
||||||
self.assertEqual(0, len(build_request.instance.obj_what_changed()))
|
self.assertEqual(0, len(build_request.instance.obj_what_changed()))
|
||||||
|
|
|
@ -733,11 +733,11 @@ class _TestInstanceObject(object):
|
||||||
mock.call(self.context, inst.uuid,
|
mock.call(self.context, inst.uuid,
|
||||||
{'vm_state': 'foo', 'task_state': 'bar',
|
{'vm_state': 'foo', 'task_state': 'bar',
|
||||||
'cell_name': 'foo!bar@baz'},
|
'cell_name': 'foo!bar@baz'},
|
||||||
columns_to_join=['system_metadata', 'extra',
|
columns_to_join=['tags', 'system_metadata',
|
||||||
'extra.flavor']),
|
'extra', 'extra.flavor']),
|
||||||
mock.call(self.context, inst.uuid,
|
mock.call(self.context, inst.uuid,
|
||||||
{'vm_state': 'bar', 'task_state': 'foo'},
|
{'vm_state': 'bar', 'task_state': 'foo'},
|
||||||
columns_to_join=['system_metadata'])]
|
columns_to_join=['system_metadata', 'tags'])]
|
||||||
mock_db_update.assert_has_calls(expected_calls)
|
mock_db_update.assert_has_calls(expected_calls)
|
||||||
|
|
||||||
def test_skip_cells_api(self):
|
def test_skip_cells_api(self):
|
||||||
|
|
Loading…
Reference in New Issue