From 30631d0077424001e2fa57674e6e9f2a12f0683e Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 27 Mar 2013 11:30:49 -0700 Subject: Make tenant_usage fall back to instance_type_id In order to expose historical usage information about instances that were deleted at the time migration #153 was run, we need to fall back to looking up type information by instance_type_id. This patch does that (only for deleted instances) and replicates the previous behavior of skipping instances that have an instance_type_id that points to a non-existent type. Fixes bug 1161022 Change-Id: I39d30c59d1711d8f2a61c7a5e2545b3952e55dbe --- .../compute/contrib/simple_tenant_usage.py | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/compute/contrib/simple_tenant_usage.py b/nova/api/openstack/compute/contrib/simple_tenant_usage.py index 0fa9b9e40..0428c8a77 100644 --- a/nova/api/openstack/compute/contrib/simple_tenant_usage.py +++ b/nova/api/openstack/compute/contrib/simple_tenant_usage.py @@ -25,6 +25,7 @@ from nova.api.openstack import wsgi from nova.api.openstack import xmlutil from nova.compute import api from nova.compute import instance_types +from nova import exception from nova.openstack.common import timeutils authorize_show = extensions.extension_authorizer('compute', @@ -103,6 +104,30 @@ class SimpleTenantUsageController(object): # instance hasn't launched, so no charge return 0 + def _get_flavor(self, context, compute_api, instance, flavors_cache): + """Get flavor information from the instance's system_metadata, + allowing a fallback to lookup by-id for deleted instances only""" + try: + return instance_types.extract_instance_type(instance) + except KeyError: + if not instance['deleted']: + # Only support the fallback mechanism for deleted instances + # that would have been skipped by migration #153 + raise + + flavor_type = instance['instance_type_id'] + if flavor_type in flavors_cache: + return flavors_cache[flavor_type] + + try: + it_ref = compute_api.get_instance_type(context, flavor_type) + flavors_cache[flavor_type] = it_ref + except exception.InstanceTypeNotFound: + # can't bill if there is no instance type + it_ref = None + + return it_ref + def _tenant_usages_for_period(self, context, period_start, period_stop, tenant_id=None, detailed=True): @@ -119,7 +144,9 @@ class SimpleTenantUsageController(object): info['hours'] = self._hours_for(instance, period_start, period_stop) - flavor = instance_types.extract_instance_type(instance) + flavor = self._get_flavor(context, compute_api, instance, flavors) + if not flavor: + continue info['instance_id'] = instance['uuid'] info['name'] = instance['display_name'] -- cgit