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:
Dan Smith 2013-08-07 09:12:44 -07:00
parent 845c1deb38
commit 8a13967f12
4 changed files with 69 additions and 34 deletions

View File

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

View File

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

View File

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

View File

@ -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,
}
]
}