diff options
| author | John Griffith <john.griffith@solidfire.com> | 2012-04-12 20:36:48 -0600 |
|---|---|---|
| committer | John Griffith <john.griffith@solidfire.com> | 2012-05-02 13:32:19 -0600 |
| commit | 407e16b863bac1dfbf4e954837009abf9c17f018 (patch) | |
| tree | 10af13810b6746c0fad249b42d3f71466ca87428 /nova/api | |
| parent | ca2bb061a728bb5db8781f298c18c980d9d91863 (diff) | |
| download | nova-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.py | 18 | ||||
| -rw-r--r-- | nova/api/ec2/ec2utils.py | 70 |
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]|$)))') |
