From 4156f5a1da98bc2002d20e70996b27839588c76f Mon Sep 17 00:00:00 2001 From: Andrew Melton Date: Fri, 1 Nov 2013 10:55:06 -0400 Subject: [PATCH] Better handling of resize issues Populating flavor details from prep.end turns out to be a bit too early. If the compute is restarted before the resize has finished the instance will still be the old size. Thus, an exist after that will be for the old (and actual) size of the instance. --- stacktach/views.py | 20 ++++++++++++++------ tests/unit/test_stacktach.py | 16 ++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/stacktach/views.py b/stacktach/views.py index f3dacef..f92688d 100644 --- a/stacktach/views.py +++ b/stacktach/views.py @@ -154,7 +154,6 @@ INSTANCE_EVENT = { 'rebuild_start': 'compute.instance.rebuild.start', 'rebuild_end': 'compute.instance.rebuild.end', 'resize_prep_start': 'compute.instance.resize.prep.start', - 'resize_prep_end': 'compute.instance.resize.prep.end', 'resize_revert_start': 'compute.instance.resize.revert.start', 'resize_revert_end': 'compute.instance.resize.revert.end', 'resize_finish_end': 'compute.instance.finish_resize.end', @@ -189,6 +188,18 @@ def _process_usage_for_new_launch(raw, notification): # though, because we may have already received the end event usage.launched_at = utils.str_time_to_unix(notification.launched_at) + if raw.event in [INSTANCE_EVENT['resize_prep_start'], + INSTANCE_EVENT['resize_revert_start']] and\ + usage.instance_type_id is None and\ + usage.instance_flavor_id is None: + # Grab the flavor details and populate them if they aren't + # already. This should happen just in case we get an exists + # mid resize/revert. That can happen if the action spans + # multiple audit periods, or if the compute node is restarted + # mid action and another resize is kicked off. + usage.instance_type_id = notification.instance_type_id + usage.instance_flavor_id = notification.instance_flavor_id + usage.tenant = notification.tenant usage.rax_options = notification.rax_options usage.os_architecture = notification.os_architecture @@ -214,12 +225,10 @@ def _process_usage_for_updates(raw, notification): INSTANCE_EVENT['rescue_end']]: usage.launched_at = utils.str_time_to_unix(notification.launched_at) - if raw.event == INSTANCE_EVENT['resize_revert_end']: + if raw.event in [INSTANCE_EVENT['resize_revert_end'], + INSTANCE_EVENT['resize_finish_end']]: usage.instance_type_id = notification.instance_type_id usage.instance_flavor_id = notification.instance_flavor_id - elif raw.event == INSTANCE_EVENT['resize_prep_end']: - usage.instance_type_id = notification.new_instance_type_id - usage.instance_flavor_id = notification.instance_flavor_id usage.tenant = notification.tenant usage.rax_options = notification.rax_options @@ -312,7 +321,6 @@ USAGE_PROCESS_MAPPING = { INSTANCE_EVENT['rescue_start']: _process_usage_for_new_launch, INSTANCE_EVENT['create_end']: _process_usage_for_updates, INSTANCE_EVENT['rebuild_end']: _process_usage_for_updates, - INSTANCE_EVENT['resize_prep_end']: _process_usage_for_updates, INSTANCE_EVENT['resize_finish_end']: _process_usage_for_updates, INSTANCE_EVENT['resize_revert_end']: _process_usage_for_updates, INSTANCE_EVENT['rescue_end']: _process_usage_for_updates, diff --git a/tests/unit/test_stacktach.py b/tests/unit/test_stacktach.py index f823b63..60e36f4 100644 --- a/tests/unit/test_stacktach.py +++ b/tests/unit/test_stacktach.py @@ -26,6 +26,7 @@ import mox import utils from utils import BANDWIDTH_PUBLIC_OUTBOUND from utils import INSTANCE_FLAVOR_ID_1 +from utils import INSTANCE_FLAVOR_ID_2 from utils import INSTANCE_ID_1 from utils import OS_VERSION_1 from utils import OS_ARCH_1 @@ -321,6 +322,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase): notification.instance = INSTANCE_ID_1 notification.request_id = REQUEST_ID_1 notification.instance_type_id = INSTANCE_TYPE_ID_1 + notification.instance_flavor_id = INSTANCE_FLAVOR_ID_1 return notification def test_process_usage_for_new_launch_create_start(self): @@ -632,18 +634,15 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase): self.mox.VerifyAll() - def _create_notification_with_new_instance_type_id(self): + def test_process_usage_for_updates_finish_resize_end(self): notification = self._create_mock_notification() - notification.new_instance_type_id = INSTANCE_TYPE_ID_2 - return notification - - def test_process_usage_for_updates_prep_end(self): - notification = self._create_notification_with_new_instance_type_id() raw = self.mox.CreateMockAnything() - raw.event = 'compute.instance.resize.prep.end' + raw.event = 'compute.instance.finish_resize.end' usage = self.mox.CreateMockAnything() usage.launched_at = None + usage.instance_type_id = INSTANCE_TYPE_ID_2 + usage.instance_flavor_id = INSTANCE_FLAVOR_ID_2 views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1, request_id=REQUEST_ID_1) \ .AndReturn((usage, True)) @@ -652,7 +651,8 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase): views._process_usage_for_updates(raw, notification) - self.assertEqual(usage.instance_type_id, INSTANCE_TYPE_ID_2) + self.assertEqual(usage.instance_type_id, INSTANCE_TYPE_ID_1) + self.assertEqual(usage.instance_flavor_id, INSTANCE_FLAVOR_ID_1) self.assertEquals(usage.tenant, TENANT_ID_1) self.assertEquals(usage.os_architecture, OS_ARCH_1) self.assertEquals(usage.os_version, OS_VERSION_1)