summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJohn Griffith <john.griffith@solidfire.com>2012-04-12 20:36:48 -0600
committerJohn Griffith <john.griffith@solidfire.com>2012-05-02 13:32:19 -0600
commit407e16b863bac1dfbf4e954837009abf9c17f018 (patch)
tree10af13810b6746c0fad249b42d3f71466ca87428 /nova/api
parentca2bb061a728bb5db8781f298c18c980d9d91863 (diff)
downloadnova-407e16b863bac1dfbf4e954837009abf9c17f018.tar.gz
nova-407e16b863bac1dfbf4e954837009abf9c17f018.tar.xz
nova-407e16b863bac1dfbf4e954837009abf9c17f018.zip
Convert Volume and Snapshot IDs to use UUID
* Three migrations 1. create id mappings 2. convert volume_id and snapshot_id from int to string 3. change volume/snapshot id's from int to uuid * DB migration for Volume and Related tables * Addition of new volume id mapping tables * Added methods in ec2utils * Minor tweaks to unit tests * Other changes to migration to ensure consistency in id's * Fixed bug in the block-device-mapping table (wasn't setting autoinc) Change-Id: Ic6c3646e0f01c26467a4a3c20e13eebaa2baa97e
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/ec2/cloud.py18
-rw-r--r--nova/api/ec2/ec2utils.py70
2 files changed, 71 insertions, 17 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 8c6a1fdc3..26cc4a70c 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -131,7 +131,7 @@ def _parse_block_device_mapping(bdm):
if ebs:
ec2_id = ebs.pop('snapshot_id', None)
if ec2_id:
- id = ec2utils.ec2_id_to_id(ec2_id)
+ id = ec2utils.ec2_vol_id_to_uuid(ec2_id)
if ec2_id.startswith('snap-'):
bdm['snapshot_id'] = id
elif ec2_id.startswith('vol-'):
@@ -310,7 +310,7 @@ class CloudController(object):
if snapshot_id:
snapshots = []
for ec2_id in snapshot_id:
- internal_id = ec2utils.ec2_id_to_id(ec2_id)
+ internal_id = ec2utils.ec2_snap_id_to_uuid(ec2_id)
snapshot = self.volume_api.get_snapshot(
context,
snapshot_id=internal_id)
@@ -336,7 +336,7 @@ class CloudController(object):
validate_ec2_id(volume_id)
LOG.audit(_("Create snapshot of volume %s"), volume_id,
context=context)
- volume_id = ec2utils.ec2_id_to_id(volume_id)
+ volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
volume = self.volume_api.get(context, volume_id)
snapshot = self.volume_api.create_snapshot(
context,
@@ -346,7 +346,7 @@ class CloudController(object):
return self._format_snapshot(context, snapshot)
def delete_snapshot(self, context, snapshot_id, **kwargs):
- snapshot_id = ec2utils.ec2_id_to_id(snapshot_id)
+ snapshot_id = ec2utils.ec2_snap_id_to_uuid(snapshot_id)
snapshot = self.volume_api.get_snapshot(context, snapshot_id)
self.volume_api.delete_snapshot(context, snapshot)
return True
@@ -853,7 +853,7 @@ class CloudController(object):
volumes = []
for ec2_id in volume_id:
validate_ec2_id(ec2_id)
- internal_id = ec2utils.ec2_id_to_id(ec2_id)
+ internal_id = ec2utils.ec2_vol_id_to_uuid(ec2_id)
volume = self.volume_api.get(context, internal_id)
volumes.append(volume)
else:
@@ -901,7 +901,7 @@ class CloudController(object):
def create_volume(self, context, **kwargs):
size = kwargs.get('size')
if kwargs.get('snapshot_id') is not None:
- snapshot_id = ec2utils.ec2_id_to_id(kwargs['snapshot_id'])
+ snapshot_id = ec2utils.ec2_snap_id_to_uuid(kwargs['snapshot_id'])
snapshot = self.volume_api.get_snapshot(context, snapshot_id)
LOG.audit(_("Create volume from snapshot %s"), snapshot_id,
context=context)
@@ -924,7 +924,7 @@ class CloudController(object):
def delete_volume(self, context, volume_id, **kwargs):
validate_ec2_id(volume_id)
- volume_id = ec2utils.ec2_id_to_id(volume_id)
+ volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
try:
volume = self.volume_api.get(context, volume_id)
@@ -937,7 +937,7 @@ class CloudController(object):
def attach_volume(self, context, volume_id, instance_id, device, **kwargs):
validate_ec2_id(instance_id)
validate_ec2_id(volume_id)
- volume_id = ec2utils.ec2_id_to_id(volume_id)
+ volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
instance_id = ec2utils.ec2_id_to_id(instance_id)
instance = self.compute_api.get(context, instance_id)
msg = _("Attach volume %(volume_id)s to instance %(instance_id)s"
@@ -960,7 +960,7 @@ class CloudController(object):
def detach_volume(self, context, volume_id, **kwargs):
validate_ec2_id(volume_id)
- volume_id = ec2utils.ec2_id_to_id(volume_id)
+ volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
LOG.audit(_("Detach volume %s"), volume_id, context=context)
volume = self.volume_api.get(context, volume_id)
diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py
index 1a6bb96bd..045ee12d3 100644
--- a/nova/api/ec2/ec2utils.py
+++ b/nova/api/ec2/ec2utils.py
@@ -18,12 +18,13 @@
import re
+from nova import context
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
-from nova import network
from nova.network import model as network_model
+from nova import utils
FLAGS = flags.FLAGS
@@ -132,15 +133,68 @@ def id_to_ec2_id(instance_id, template='i-%08x'):
return template % int(instance_id)
-def id_to_ec2_snap_id(instance_id):
- """Convert an snapshot ID (int) to an ec2 snapshot ID
- (snap-[base 16 number])"""
- return id_to_ec2_id(instance_id, 'snap-%08x')
+def id_to_ec2_snap_id(snapshot_id):
+ """Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
+ if utils.is_uuid_like(snapshot_id):
+ ctxt = context.get_admin_context()
+ int_id = get_int_id_from_snapshot_uuid(ctxt, snapshot_id)
+ return id_to_ec2_id(int_id)
+ else:
+ return id_to_ec2_id(snapshot_id, 'snap-%08x')
-def id_to_ec2_vol_id(instance_id):
- """Convert an volume ID (int) to an ec2 volume ID (vol-[base 16 number])"""
- return id_to_ec2_id(instance_id, 'vol-%08x')
+def id_to_ec2_vol_id(volume_id):
+ """Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
+ if utils.is_uuid_like(volume_id):
+ ctxt = context.get_admin_context()
+ int_id = get_int_id_from_volume_uuid(ctxt, volume_id)
+ return id_to_ec2_id(int_id)
+ else:
+ return id_to_ec2_id(volume_id, 'vol-%08x')
+
+
+def ec2_vol_id_to_uuid(ec2_id):
+ """Get the cooresponding UUID for the given ec2-id."""
+ ctxt = context.get_admin_context()
+
+ # NOTE(jgriffith) first strip prefix to get just the numeric
+ int_id = ec2_id_to_id(ec2_id)
+ return get_volume_uuid_from_int_id(ctxt, int_id)
+
+
+def get_int_id_from_volume_uuid(context, volume_uuid):
+ if volume_uuid is None:
+ return
+ try:
+ return db.get_ec2_volume_id_by_uuid(context, volume_uuid)
+ except exception.NotFound:
+ raise exception.VolumeNotFound()
+
+
+def get_volume_uuid_from_int_id(context, int_id):
+ return db.get_volume_uuid_by_ec2_id(context, int_id)
+
+
+def ec2_snap_id_to_uuid(ec2_id):
+ """Get the cooresponding UUID for the given ec2-id."""
+ ctxt = context.get_admin_context()
+
+ # NOTE(jgriffith) first strip prefix to get just the numeric
+ int_id = ec2_id_to_id(ec2_id)
+ return get_snapshot_uuid_from_int_id(ctxt, int_id)
+
+
+def get_int_id_from_snapshot_uuid(context, snapshot_uuid):
+ if snapshot_uuid is None:
+ return
+ try:
+ return db.get_ec2_snapshot_id_by_uuid(context, snapshot_uuid)
+ except exception.NotFound:
+ raise exception.SnapshotNotFound()
+
+
+def get_snapshot_uuid_from_int_id(context, int_id):
+ return db.get_snapshot_uuid_by_ec2_id(context, int_id)
_c2u = re.compile('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')