summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-12 22:17:54 +0000
committerGerrit Code Review <review@openstack.org>2013-02-12 22:17:54 +0000
commit9994a9161d0acac216b3441233eae1f7238db889 (patch)
treee48074d9c4f96490b51ae80eacee9bda4f088c23
parent65241f96f900fd1eaad9c2731fda7d63b18a8f11 (diff)
parent91db10a0fd43c30ed088082583b7d43667339ac5 (diff)
downloadnova-9994a9161d0acac216b3441233eae1f7238db889.tar.gz
nova-9994a9161d0acac216b3441233eae1f7238db889.tar.xz
nova-9994a9161d0acac216b3441233eae1f7238db889.zip
Merge "Make the metadata paths use conductor"
-rw-r--r--nova/api/ec2/ec2utils.py4
-rw-r--r--nova/api/metadata/base.py53
-rw-r--r--nova/api/metadata/handler.py7
-rw-r--r--nova/availability_zones.py10
-rw-r--r--nova/conductor/api.py18
-rw-r--r--nova/conductor/manager.py24
-rw-r--r--nova/conductor/rpcapi.py11
-rw-r--r--nova/tests/conductor/test_conductor.py43
-rw-r--r--nova/tests/test_metadata.py14
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')