diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-02-12 22:17:54 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-02-12 22:17:54 +0000 |
| commit | 9994a9161d0acac216b3441233eae1f7238db889 (patch) | |
| tree | e48074d9c4f96490b51ae80eacee9bda4f088c23 | |
| parent | 65241f96f900fd1eaad9c2731fda7d63b18a8f11 (diff) | |
| parent | 91db10a0fd43c30ed088082583b7d43667339ac5 (diff) | |
| download | nova-9994a9161d0acac216b3441233eae1f7238db889.tar.gz nova-9994a9161d0acac216b3441233eae1f7238db889.tar.xz nova-9994a9161d0acac216b3441233eae1f7238db889.zip | |
Merge "Make the metadata paths use conductor"
| -rw-r--r-- | nova/api/ec2/ec2utils.py | 4 | ||||
| -rw-r--r-- | nova/api/metadata/base.py | 53 | ||||
| -rw-r--r-- | nova/api/metadata/handler.py | 7 | ||||
| -rw-r--r-- | nova/availability_zones.py | 10 | ||||
| -rw-r--r-- | nova/conductor/api.py | 18 | ||||
| -rw-r--r-- | nova/conductor/manager.py | 24 | ||||
| -rw-r--r-- | nova/conductor/rpcapi.py | 11 | ||||
| -rw-r--r-- | nova/tests/conductor/test_conductor.py | 43 | ||||
| -rw-r--r-- | nova/tests/test_metadata.py | 14 |
9 files changed, 144 insertions, 40 deletions
diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index bc47b3e0d..bb0f7245a 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -115,10 +115,10 @@ def get_ip_info_for_instance(context, instance): return get_ip_info_for_instance_from_nw_info(nw_info) -def get_availability_zone_by_host(services, host): +def get_availability_zone_by_host(services, host, conductor_api=None): if len(services) > 0: return availability_zones.get_host_availability_zone( - context.get_admin_context(), host) + context.get_admin_context(), host, conductor_api) return 'unknown zone' diff --git a/nova/api/metadata/base.py b/nova/api/metadata/base.py index 34d412268..275af2b32 100644 --- a/nova/api/metadata/base.py +++ b/nova/api/metadata/base.py @@ -26,8 +26,8 @@ import posixpath from nova.api.ec2 import ec2utils from nova.api.metadata import password from nova import block_device +from nova import conductor from nova import context -from nova import db from nova import network from nova.openstack.common import cfg from nova.openstack.common import timeutils @@ -83,7 +83,8 @@ class InvalidMetadataPath(Exception): class InstanceMetadata(): """Instance metadata.""" - def __init__(self, instance, address=None, content=[], extra_md=None): + def __init__(self, instance, address=None, content=[], extra_md=None, + conductor_api=None): """Creation of this object should basically cover all time consuming collection. Methods after that should not cause time delays due to network operations or lengthy cpu operations. @@ -95,39 +96,32 @@ class InstanceMetadata(): self.instance = instance self.extra_md = extra_md + if conductor_api: + self.conductor_api = conductor_api + else: + self.conductor_api = conductor.API() + ctxt = context.get_admin_context() - services = db.service_get_all_by_host(ctxt.elevated(), - instance['host']) + capi = self.conductor_api + services = capi.service_get_all_by_host(ctxt.elevated(), + instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( - services, instance['host']) + services, instance['host'], capi) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) - self.security_groups = db.security_group_get_by_instance(ctxt, - instance['id']) + self.security_groups = capi.security_group_get_by_instance(ctxt, + instance) - self.mappings = _format_instance_mapping(ctxt, instance) + self.mappings = _format_instance_mapping(capi, ctxt, instance) if instance.get('user_data', None) is not None: self.userdata_raw = base64.b64decode(instance['user_data']) else: self.userdata_raw = None - self.ec2_ids = {} - - self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_inst_id( - instance['uuid']) - self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(ctxt, - instance['image_ref']) - - for image_type in ['kernel', 'ramdisk']: - if self.instance.get('%s_id' % image_type): - image_id = self.instance['%s_id' % image_type] - ec2_image_type = ec2utils.image_type(image_type) - ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, - ec2_image_type) - self.ec2_ids['%s-id' % image_type] = ec2_id + self.ec2_ids = capi.get_ec2_ids(ctxt, instance) self.address = address @@ -404,23 +398,26 @@ class InstanceMetadata(): yield ('%s/%s/%s' % ("openstack", CONTENT_DIR, cid), content) -def get_metadata_by_address(address): +def get_metadata_by_address(conductor_api, address): ctxt = context.get_admin_context() fixed_ip = network.API().get_fixed_ip_by_address(ctxt, address) - return get_metadata_by_instance_id(fixed_ip['instance_uuid'], + return get_metadata_by_instance_id(conductor_api, + fixed_ip['instance_uuid'], address, ctxt) -def get_metadata_by_instance_id(instance_id, address, ctxt=None): +def get_metadata_by_instance_id(conductor_api, instance_id, address, + ctxt=None): ctxt = ctxt or context.get_admin_context() - instance = db.instance_get_by_uuid(ctxt, instance_id) + instance = conductor_api.instance_get_by_uuid(ctxt, instance_id) return InstanceMetadata(instance, address) -def _format_instance_mapping(ctxt, instance): - bdms = db.block_device_mapping_get_all_by_instance(ctxt, instance['uuid']) +def _format_instance_mapping(conductor_api, ctxt, instance): + bdms = conductor_api.block_device_mapping_get_all_by_instance( + ctxt, instance) return block_device.instance_block_mapping(instance, bdms) diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py index 4a425f876..cedb27370 100644 --- a/nova/api/metadata/handler.py +++ b/nova/api/metadata/handler.py @@ -26,6 +26,7 @@ import webob.exc from nova.api.metadata import base from nova.common import memorycache +from nova import conductor from nova import exception from nova.openstack.common import cfg from nova.openstack.common import log as logging @@ -58,6 +59,7 @@ class MetadataRequestHandler(wsgi.Application): def __init__(self): self._cache = memorycache.get_client() + self.conductor_api = conductor.API() def get_metadata_by_remote_address(self, address): if not address: @@ -69,7 +71,7 @@ class MetadataRequestHandler(wsgi.Application): return data try: - data = base.get_metadata_by_address(address) + data = base.get_metadata_by_address(self.conductor_api, address) except exception.NotFound: return None @@ -84,7 +86,8 @@ class MetadataRequestHandler(wsgi.Application): return data try: - data = base.get_metadata_by_instance_id(instance_id, address) + data = base.get_metadata_by_instance_id(self.conductor_api, + instance_id, address) except exception.NotFound: return None diff --git a/nova/availability_zones.py b/nova/availability_zones.py index 97faccc9f..8c9d4acf7 100644 --- a/nova/availability_zones.py +++ b/nova/availability_zones.py @@ -52,9 +52,13 @@ def set_availability_zones(context, services): return services -def get_host_availability_zone(context, host): - metadata = db.aggregate_metadata_get_by_host( - context, host, key='availability_zone') +def get_host_availability_zone(context, host, conductor_api=None): + if conductor_api: + metadata = conductor_api.aggregate_metadata_get_by_host( + context, host, key='availability_zone') + else: + metadata = db.aggregate_metadata_get_by_host( + context, host, key='availability_zone') if 'availability_zone' in metadata: return list(metadata['availability_zone'])[0] else: diff --git a/nova/conductor/api.py b/nova/conductor/api.py index 50f59d9d6..435cc062a 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -154,6 +154,12 @@ class LocalAPI(object): aggregate, key) + def aggregate_metadata_get_by_host(self, context, host, + key='availability_zone'): + return self._manager.aggregate_metadata_get_by_host(context, + host, + key) + def bw_usage_get(self, context, uuid, start_period, mac): return self._manager.bw_usage_update(context, uuid, mac, start_period) @@ -319,6 +325,9 @@ class LocalAPI(object): def quota_rollback(self, context, reservations): return self._manager.quota_rollback(context, reservations) + def get_ec2_ids(self, context, instance): + return self._manager.get_ec2_ids(context, instance) + class API(object): """Conductor API that does updates via RPC to the ConductorManager.""" @@ -463,6 +472,12 @@ class API(object): aggregate, key) + def aggregate_metadata_get_by_host(self, context, host, + key='availability_zone'): + return self.conductor_rpcapi.aggregate_metadata_get_by_host(context, + host, + key) + def bw_usage_get(self, context, uuid, start_period, mac): return self.conductor_rpcapi.bw_usage_update(context, uuid, mac, start_period) @@ -636,3 +651,6 @@ class API(object): def quota_rollback(self, context, reservations): return self.conductor_rpcapi.quota_rollback(context, reservations) + + def get_ec2_ids(self, context, instance): + return self.conductor_rpcapi.get_ec2_ids(context, instance) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 905d2e2cd..e8a0cbc28 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -14,6 +14,7 @@ """Handles database requests from other nova services.""" +from nova.api.ec2 import ec2utils from nova.compute import api as compute_api from nova.compute import utils as compute_utils from nova import exception @@ -47,7 +48,7 @@ datetime_fields = ['launched_at', 'terminated_at'] class ConductorManager(manager.SchedulerDependentManager): """Mission: TBD.""" - RPC_API_VERSION = '1.41' + RPC_API_VERSION = '1.42' def __init__(self, *args, **kwargs): super(ConductorManager, self).__init__(service_name='conductor', @@ -175,6 +176,11 @@ class ConductorManager(manager.SchedulerDependentManager): self.db.aggregate_metadata_delete(context.elevated(), aggregate['id'], key) + def aggregate_metadata_get_by_host(self, context, host, + key='availability_zone'): + result = self.db.aggregate_metadata_get_by_host(context, host, key) + return jsonutils.to_primitive(result) + def bw_usage_update(self, context, uuid, mac, start_period, bw_in=None, bw_out=None, last_ctr_in=None, last_ctr_out=None, @@ -384,3 +390,19 @@ class ConductorManager(manager.SchedulerDependentManager): def quota_rollback(self, context, reservations): quota.QUOTAS.rollback(context, reservations) + + def get_ec2_ids(self, context, instance): + ec2_ids = {} + + ec2_ids['instance-id'] = ec2utils.id_to_ec2_inst_id(instance['uuid']) + ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(context, + instance['image_ref']) + for image_type in ['kernel', 'ramdisk']: + if '%s_id' % image_type in instance: + image_id = instance['%s_id' % image_type] + ec2_image_type = ec2utils.image_type(image_type) + ec2_id = ec2utils.glance_id_to_ec2_id(context, image_id, + ec2_image_type) + ec2_ids['%s-id' % image_type] = ec2_id + + return ec2_ids diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py index 58613e59a..d832b4f31 100644 --- a/nova/conductor/rpcapi.py +++ b/nova/conductor/rpcapi.py @@ -78,6 +78,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.41 - Added fixed_ip_get_by_instance, network_get, instance_floating_address_get_all, quota_commit, quota_rollback + 1.42 - Added get_ec2_ids, aggregate_metadata_get_by_host """ BASE_RPC_API_VERSION = '1.0' @@ -176,6 +177,11 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): key=key) return self.call(context, msg, version='1.7') + def aggregate_metadata_get_by_host(self, context, host, key): + msg = self.make_msg('aggregate_metadata_get_by_host', host=host, + key=key) + return self.call(context, msg, version='1.42') + def bw_usage_update(self, context, uuid, mac, start_period, bw_in=None, bw_out=None, last_ctr_in=None, last_ctr_out=None, @@ -409,3 +415,8 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): reservations_p = jsonutils.to_primitive(reservations) msg = self.make_msg('quota_rollback', reservations=reservations_p) return self.call(context, msg, version='1.41') + + def get_ec2_ids(self, context, instance): + instance_p = jsonutils.to_primitive(instance) + msg = self.make_msg('get_ec2_ids', instance=instance_p) + return self.call(context, msg, version='1.42') diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py index 5c9ce9e5f..41554e79a 100644 --- a/nova/tests/conductor/test_conductor.py +++ b/nova/tests/conductor/test_conductor.py @@ -16,6 +16,7 @@ import mox +from nova.api.ec2 import ec2utils from nova.compute import instance_types from nova.compute import utils as compute_utils from nova.compute import vm_states @@ -241,6 +242,15 @@ class _BaseTestCase(object): aggregate, 'fake') + def test_aggregate_metadata_get_by_host(self): + self.mox.StubOutWithMock(db, 'aggregate_metadata_get_by_host') + db.aggregate_metadata_get_by_host(self.context, 'host', + 'key').AndReturn('result') + self.mox.ReplayAll() + result = self.conductor.aggregate_metadata_get_by_host(self.context, + 'host', 'key') + self.assertEqual(result, 'result') + def test_bw_usage_update(self): self.mox.StubOutWithMock(db, 'bw_usage_update') self.mox.StubOutWithMock(db, 'bw_usage_get') @@ -537,6 +547,39 @@ class _BaseTestCase(object): self.mox.ReplayAll() self.conductor.quota_rollback(self.context, 'reservations') + def test_get_ec2_ids(self): + expected = { + 'instance-id': 'ec2-inst-id', + 'ami-id': 'ec2-ami-id', + 'kernel-id': 'ami-kernel-ec2-kernelid', + 'ramdisk-id': 'ami-ramdisk-ec2-ramdiskid', + } + inst = { + 'uuid': 'fake-uuid', + 'kernel_id': 'ec2-kernelid', + 'ramdisk_id': 'ec2-ramdiskid', + 'image_ref': 'fake-image', + } + self.mox.StubOutWithMock(ec2utils, 'id_to_ec2_inst_id') + self.mox.StubOutWithMock(ec2utils, 'glance_id_to_ec2_id') + self.mox.StubOutWithMock(ec2utils, 'image_type') + + ec2utils.id_to_ec2_inst_id(inst['uuid']).AndReturn( + expected['instance-id']) + ec2utils.glance_id_to_ec2_id(self.context, + inst['image_ref']).AndReturn( + expected['ami-id']) + for image_type in ['kernel', 'ramdisk']: + image_id = inst['%s_id' % image_type] + ec2utils.image_type(image_type).AndReturn('ami-' + image_type) + ec2utils.glance_id_to_ec2_id(self.context, image_id, + 'ami-' + image_type).AndReturn( + 'ami-%s-ec2-%sid' % (image_type, image_type)) + + self.mox.ReplayAll() + result = self.conductor.get_ec2_ids(self.context, inst) + self.assertEqual(result, expected) + class ConductorTestCase(_BaseTestCase, test.TestCase): """Conductor Manager Tests.""" diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 827bfb398..95399e33d 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -31,6 +31,7 @@ from nova.api.metadata import base from nova.api.metadata import handler from nova.api.metadata import password from nova import block_device +from nova.conductor import api as conductor_api from nova import db from nova.db.sqlalchemy import api from nova import exception @@ -118,6 +119,7 @@ class MetadataTestCase(test.TestCase): def setUp(self): super(MetadataTestCase, self).setUp() self.instance = INSTANCES[0] + self.flags(use_local=True, group='conductor') fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs, spectacular=True) @@ -191,10 +193,11 @@ class MetadataTestCase(test.TestCase): 'swap': '/dev/sdc', 'ebs0': '/dev/sdh'} - self.assertEqual(base._format_instance_mapping(ctxt, instance_ref0), - block_device._DEFAULT_MAPPINGS) - self.assertEqual(base._format_instance_mapping(ctxt, instance_ref1), - expected) + capi = conductor_api.LocalAPI() + self.assertEqual(base._format_instance_mapping(capi, ctxt, + instance_ref0), block_device._DEFAULT_MAPPINGS) + self.assertEqual(base._format_instance_mapping(capi, ctxt, + instance_ref1), expected) def test_pubkey(self): md = fake_InstanceMetadata(self.stubs, copy.copy(self.instance)) @@ -247,6 +250,7 @@ class OpenStackMetadataTestCase(test.TestCase): def setUp(self): super(OpenStackMetadataTestCase, self).setUp() self.instance = INSTANCES[0] + self.flags(use_local=True, group='conductor') fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs, spectacular=True) @@ -382,6 +386,7 @@ class MetadataHandlerTestCase(test.TestCase): fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs, spectacular=True) self.instance = INSTANCES[0] + self.flags(use_local=True, group='conductor') self.mdinst = fake_InstanceMetadata(self.stubs, self.instance, address=None, sgroups=None) @@ -547,6 +552,7 @@ class MetadataPasswordTestCase(test.TestCase): fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs, spectacular=True) self.instance = copy.copy(INSTANCES[0]) + self.flags(use_local=True, group='conductor') self.mdinst = fake_InstanceMetadata(self.stubs, self.instance, address=None, sgroups=None) self.flags(use_local=True, group='conductor') |
