summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJustin Santa Barbara <justin@fathomdb.com>2011-02-17 15:00:18 -0800
committerJustin Santa Barbara <justin@fathomdb.com>2011-02-17 15:00:18 -0800
commit9a7213b615bcaa2127f76146d594f5247ea0d0a4 (patch)
tree6097ca3030b06100233989a3f43c56a740dd20b0 /nova/api
parent5688fbd7a06ea47e18f38e4c900be4dbb50b921c (diff)
downloadnova-9a7213b615bcaa2127f76146d594f5247ea0d0a4.tar.gz
nova-9a7213b615bcaa2127f76146d594f5247ea0d0a4.tar.xz
nova-9a7213b615bcaa2127f76146d594f5247ea0d0a4.zip
Initial support for per-instance metadata, though the OpenStack API. Key/value pairs can be specified at instance creation time and are returned in the details view. Support limits based on quota system.
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/ec2/cloud.py6
-rw-r--r--nova/api/openstack/servers.py30
2 files changed, 29 insertions, 7 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 6919cd8d2..33eba5028 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -783,6 +783,9 @@ class CloudController(object):
def run_instances(self, context, **kwargs):
max_count = int(kwargs.get('max_count', 1))
+ # NOTE(justinsb): the EC2 API doesn't support metadata here, but this
+ # is needed for the unit tests. Maybe the unit tests shouldn't be
+ # calling the EC2 code
instances = self.compute_api.create(context,
instance_type=instance_types.get_by_type(
kwargs.get('instance_type', None)),
@@ -797,7 +800,8 @@ class CloudController(object):
user_data=kwargs.get('user_data'),
security_group=kwargs.get('security_group'),
availability_zone=kwargs.get('placement', {}).get(
- 'AvailabilityZone'))
+ 'AvailabilityZone'),
+ metadata=kwargs.get('metadata', []))
return self._format_run_instances(context,
instances[0]['reservation_id'])
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 009ef6db1..49611703a 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -78,9 +78,14 @@ def _translate_detail_keys(inst):
except KeyError:
LOG.debug(_("Failed to read public ip(s)"))
- inst_dict['metadata'] = {}
inst_dict['hostId'] = ''
+ # Return the metadata as a dictionary
+ metadata = {}
+ for item in inst['metadata']:
+ metadata[item['key']] = item['value']
+ inst_dict['metadata'] = metadata
+
return dict(server=inst_dict)
@@ -162,14 +167,26 @@ class Controller(wsgi.Controller):
if not env:
return faults.Fault(exc.HTTPUnprocessableEntity())
- key_pair = auth_manager.AuthManager.get_key_pairs(
- req.environ['nova.context'])[0]
+ context = req.environ['nova.context']
+
+ key_pair = auth_manager.AuthManager.get_key_pairs(context)[0]
image_id = common.get_image_id_from_image_hash(self._image_service,
- req.environ['nova.context'], env['server']['imageId'])
+ context, env['server']['imageId'])
kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(
req, image_id)
+
+ # Metadata is a list, not a Dictionary, because we allow duplicate keys
+ # (even though JSON can't encode this)
+ # In future, we may not allow duplicate keys.
+ # However, the CloudServers API is not definitive on this front,
+ # and we want to be compatible.
+ metadata = []
+ if env['server']['metadata']:
+ for k, v in env['server']['metadata'].items():
+ metadata.append({'key': k, 'value': v})
+
instances = self.compute_api.create(
- req.environ['nova.context'],
+ context,
instance_types.get_by_flavor_id(env['server']['flavorId']),
image_id,
kernel_id=kernel_id,
@@ -177,7 +194,8 @@ class Controller(wsgi.Controller):
display_name=env['server']['name'],
display_description=env['server']['name'],
key_name=key_pair['name'],
- key_data=key_pair['public_key'])
+ key_data=key_pair['public_key'],
+ metadata=metadata)
return _translate_keys(instances[0])
def update(self, req, id):