Make compute_api use InstanceAction object
This makes the compute_api instance action code use objects instead of direct-to-database calls. This should open the door for deprecating some conductor proxies for compute_api that help compute manager avoid the database hit required for the instance action to complete. Related to blueprint compute-api-objects Change-Id: If622d8079ca2897b0d5094e9341e29cde7c1ff59
This commit is contained in:
parent
845c1deb38
commit
8a13967f12
@ -53,6 +53,7 @@ from nova.network.security_group import security_group_base
|
||||
from nova import notifications
|
||||
from nova.objects import base as obj_base
|
||||
from nova.objects import instance as instance_obj
|
||||
from nova.objects import instance_action
|
||||
from nova.objects import instance_info_cache
|
||||
from nova.objects import security_group
|
||||
from nova.openstack.common import excutils
|
||||
@ -277,9 +278,10 @@ class API(base.Base):
|
||||
return instance_ref
|
||||
|
||||
def _record_action_start(self, context, instance, action):
|
||||
act = compute_utils.pack_action_start(context, instance['uuid'],
|
||||
action)
|
||||
self.db.action_start(context, act)
|
||||
instance_action.InstanceAction.action_start(context,
|
||||
instance['uuid'],
|
||||
action,
|
||||
want_result=False)
|
||||
|
||||
def _check_injected_file_quota(self, context, injected_files):
|
||||
"""Enforce quota limits on injected files.
|
||||
@ -2949,14 +2951,16 @@ class InstanceActionAPI(base.Base):
|
||||
"""Sub-set of the Compute Manager API for managing instance actions."""
|
||||
|
||||
def actions_get(self, context, instance):
|
||||
return self.db.actions_get(context, instance['uuid'])
|
||||
return instance_action.InstanceActionList.get_by_instance_uuid(
|
||||
context, instance['uuid'])
|
||||
|
||||
def action_get_by_request_id(self, context, instance, request_id):
|
||||
return self.db.action_get_by_request_id(context, instance['uuid'],
|
||||
request_id)
|
||||
return instance_action.InstanceAction.get_by_request_id(
|
||||
context, instance['uuid'], request_id)
|
||||
|
||||
def action_events_get(self, context, instance, action_id):
|
||||
return self.db.action_events_get(context, action_id)
|
||||
return instance_action.InstanceActionEventList.get_by_action(
|
||||
context, action_id)
|
||||
|
||||
|
||||
class AggregateAPI(base.Base):
|
||||
|
@ -36,13 +36,14 @@ FAKE_REQUEST_ID = fake_instance_actions.FAKE_REQUEST_ID1
|
||||
|
||||
def format_action(action):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
if 'id' in action:
|
||||
del(action['id'])
|
||||
if 'finish_time' in action:
|
||||
del(action['finish_time'])
|
||||
to_delete = ('id', 'finish_time', 'created_at', 'updated_at', 'deleted_at',
|
||||
'deleted')
|
||||
for key in to_delete:
|
||||
if key in action:
|
||||
del(action[key])
|
||||
if 'start_time' in action:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
action['start_time'] = str(action['start_time'])
|
||||
action['start_time'] = str(action['start_time'].replace(tzinfo=None))
|
||||
for event in action.get('events', []):
|
||||
format_event(event)
|
||||
return action
|
||||
@ -50,14 +51,17 @@ def format_action(action):
|
||||
|
||||
def format_event(event):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
if 'id' in event:
|
||||
del(event['id'])
|
||||
to_delete = ('id', 'created_at', 'updated_at', 'deleted_at', 'deleted',
|
||||
'action_id')
|
||||
for key in to_delete:
|
||||
if key in event:
|
||||
del(event[key])
|
||||
if 'start_time' in event:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
event['start_time'] = str(event['start_time'])
|
||||
event['start_time'] = str(event['start_time'].replace(tzinfo=None))
|
||||
if 'finish_time' in event:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
event['finish_time'] = str(event['finish_time'])
|
||||
event['finish_time'] = str(event['finish_time'].replace(tzinfo=None))
|
||||
return event
|
||||
|
||||
|
||||
@ -156,8 +160,6 @@ class InstanceActionsTest(test.TestCase):
|
||||
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
|
||||
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
|
||||
fake_events = self.fake_events[fake_action['id']]
|
||||
fake_events = [format_event(event) for event in fake_events]
|
||||
fake_action = format_action(fake_action)
|
||||
fake_action['events'] = fake_events
|
||||
self.assertEqual(format_action(fake_action),
|
||||
format_action(res_dict['instanceAction']))
|
||||
@ -239,7 +241,7 @@ class InstanceActionsSerializerTest(test.TestCase):
|
||||
serializer = instance_actions.InstanceActionTemplate()
|
||||
action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
|
||||
event = self.fake_events[action['id']][0]
|
||||
action['events'] = [event, event]
|
||||
action['events'] = [dict(event), dict(event)]
|
||||
text = serializer.serialize({'instanceAction': action})
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
|
@ -36,13 +36,15 @@ FAKE_REQUEST_ID = fake_instance_actions.FAKE_REQUEST_ID1
|
||||
|
||||
def format_action(action):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
if 'id' in action:
|
||||
del(action['id'])
|
||||
if 'finish_time' in action:
|
||||
del(action['finish_time'])
|
||||
to_delete = ('id', 'finish_time', 'created_at', 'updated_at', 'deleted_at',
|
||||
'deleted')
|
||||
for key in to_delete:
|
||||
if key in action:
|
||||
del(action[key])
|
||||
if 'start_time' in action:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
action['start_time'] = str(action['start_time'])
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified,
|
||||
# and objects will have added a timezone, so strip that for comparison
|
||||
action['start_time'] = str(action['start_time'].replace(tzinfo=None))
|
||||
for event in action.get('events', []):
|
||||
format_event(event)
|
||||
return action
|
||||
@ -50,14 +52,19 @@ def format_action(action):
|
||||
|
||||
def format_event(event):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
if 'id' in event:
|
||||
del(event['id'])
|
||||
to_delete = ('id', 'created_at', 'updated_at', 'deleted_at', 'deleted',
|
||||
'action_id')
|
||||
for key in to_delete:
|
||||
if key in event:
|
||||
del(event[key])
|
||||
if 'start_time' in event:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
event['start_time'] = str(event['start_time'])
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified,
|
||||
# and objects will have added a timezone, so strip that for comparison
|
||||
event['start_time'] = str(event['start_time'].replace(tzinfo=None))
|
||||
if 'finish_time' in event:
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
event['finish_time'] = str(event['finish_time'])
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified,
|
||||
# and objects will have added a timezone, so strip that for comparison
|
||||
event['finish_time'] = str(event['finish_time'].replace(tzinfo=None))
|
||||
return event
|
||||
|
||||
|
||||
@ -160,7 +167,6 @@ class InstanceActionsTest(test.TestCase):
|
||||
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
|
||||
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
|
||||
fake_events = self.fake_events[fake_action['id']]
|
||||
fake_events = [format_event(event) for event in fake_events]
|
||||
fake_action['events'] = fake_events
|
||||
self.assertEqual(format_action(fake_action),
|
||||
format_action(res_dict['instance_action']))
|
||||
@ -251,7 +257,7 @@ class InstanceActionsSerializerTest(test.TestCase):
|
||||
serializer = instance_actions.InstanceActionTemplate()
|
||||
action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
|
||||
event = self.fake_events[action['id']][0]
|
||||
action['events'] = [event, event]
|
||||
action['events'] = [dict(event), dict(event)]
|
||||
text = serializer.serialize({'instance_action': action})
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
|
@ -37,6 +37,10 @@ FAKE_ACTIONS = {
|
||||
2012, 12, 5, 0, 0, 0, 0),
|
||||
'finish_time': None,
|
||||
'message': '',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
},
|
||||
FAKE_REQUEST_ID2: {'id': FAKE_ACTION_ID2,
|
||||
'action': 'resize',
|
||||
@ -48,12 +52,17 @@ FAKE_ACTIONS = {
|
||||
2012, 12, 5, 1, 0, 0, 0),
|
||||
'finish_time': None,
|
||||
'message': '',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FAKE_EVENTS = {
|
||||
FAKE_ACTION_ID1: [{'id': 1,
|
||||
'action_id': FAKE_ACTION_ID1,
|
||||
'event': 'schedule',
|
||||
'start_time': datetime.datetime(
|
||||
2012, 12, 5, 1, 0, 2, 0),
|
||||
@ -61,8 +70,13 @@ FAKE_EVENTS = {
|
||||
2012, 12, 5, 1, 2, 0, 0),
|
||||
'result': 'Success',
|
||||
'traceback': '',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
},
|
||||
{'id': 2,
|
||||
'action_id': FAKE_ACTION_ID1,
|
||||
'event': 'compute_create',
|
||||
'start_time': datetime.datetime(
|
||||
2012, 12, 5, 1, 3, 0, 0),
|
||||
@ -70,16 +84,25 @@ FAKE_EVENTS = {
|
||||
2012, 12, 5, 1, 4, 0, 0),
|
||||
'result': 'Success',
|
||||
'traceback': '',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
}
|
||||
],
|
||||
FAKE_ACTION_ID2: [{'id': 3,
|
||||
'action_id': FAKE_ACTION_ID2,
|
||||
'event': 'schedule',
|
||||
'start_time': datetime.datetime(
|
||||
2012, 12, 5, 3, 0, 0, 0),
|
||||
'finish_time': datetime.datetime(
|
||||
2012, 12, 5, 3, 2, 0, 0),
|
||||
'result': 'Error',
|
||||
'traceback': ''
|
||||
'traceback': '',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user