summaryrefslogtreecommitdiffstats
path: root/nova/volume/api.py
diff options
context:
space:
mode:
authorvladimir.p <vladimir@zadarastorage.com>2011-08-24 16:48:04 -0700
committervladimir.p <vladimir@zadarastorage.com>2011-08-24 16:48:04 -0700
commit08af6ab6325e27b60d3d036d6e780f8e594234cc (patch)
tree08cf95e9b1a5fd8e2486357a24bab8b07781ac55 /nova/volume/api.py
parent48cd9689de31e408c792052747f714a9dbe1f8f7 (diff)
parent96f85f94f23c9eeac3f43e122d2992b6d0938827 (diff)
downloadnova-08af6ab6325e27b60d3d036d6e780f8e594234cc.tar.gz
nova-08af6ab6325e27b60d3d036d6e780f8e594234cc.tar.xz
nova-08af6ab6325e27b60d3d036d6e780f8e594234cc.zip
merged with volume_types. no code refactoring yet
Diffstat (limited to 'nova/volume/api.py')
-rw-r--r--nova/volume/api.py89
1 files changed, 78 insertions, 11 deletions
diff --git a/nova/volume/api.py b/nova/volume/api.py
index 6b220cc54..e66792373 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -42,8 +42,9 @@ class API(base.Base):
"""API for interacting with the volume manager."""
def create(self, context, size, snapshot_id, name, description,
- to_vsa_id=None, from_vsa_id=None, drive_type_id=None,
- availability_zone=None):
+ volume_type=None, metadata=None,
+ to_vsa_id=None, from_vsa_id=None, drive_type_id=None,
+ availability_zone=None):
if snapshot_id != None:
snapshot = self.get_snapshot(context, snapshot_id)
if snapshot['status'] != "available":
@@ -52,11 +53,7 @@ class API(base.Base):
if not size:
size = snapshot['volume_size']
- if availability_zone is None:
- availability_zone = FLAGS.storage_availability_zone
-
if to_vsa_id is None:
- # Check quotas for non-VSA volumes only
if quota.allowed_volumes(context, 1, size) < 1:
pid = context.project_id
LOG.warn(_("Quota exceeded for %(pid)s, tried to create"
@@ -64,6 +61,14 @@ class API(base.Base):
raise quota.QuotaError(_("Volume quota exceeded. You cannot "
"create a volume of size %sG") % size)
+ if availability_zone is None:
+ availability_zone = FLAGS.storage_availability_zone
+
+ if volume_type is None:
+ volume_type_id = None
+ else:
+ volume_type_id = volume_type.get('id', None)
+
options = {
'size': size,
'user_id': context.user_id,
@@ -74,9 +79,12 @@ class API(base.Base):
'attach_status': "detached",
'display_name': name,
'display_description': description,
+ 'volume_type_id': volume_type_id,
+ 'metadata': metadata,
'to_vsa_id': to_vsa_id,
'from_vsa_id': from_vsa_id,
- 'drive_type_id': drive_type_id}
+ 'drive_type_id': drive_type_id,
+ }
volume = self.db.volume_create(context, options)
if from_vsa_id is not None: # for FE VSA volumes do nothing
@@ -115,7 +123,6 @@ class API(base.Base):
if volume['status'] != "available":
raise exception.ApiError(_("Volume status must be available"))
-
now = utils.utcnow()
self.db.volume_update(context, volume_id, {'status': 'deleting',
'terminated_at': now})
@@ -132,10 +139,44 @@ class API(base.Base):
rv = self.db.volume_get(context, volume_id)
return dict(rv.iteritems())
- def get_all(self, context):
+ def get_all(self, context, search_opts={}):
if context.is_admin:
- return self.db.volume_get_all(context)
- return self.db.volume_get_all_by_project(context, context.project_id)
+ volumes = self.db.volume_get_all(context)
+ else:
+ volumes = self.db.volume_get_all_by_project(context,
+ context.project_id)
+
+ if search_opts:
+ LOG.debug(_("Searching by: %s") % str(search_opts))
+
+ def _check_metadata_match(volume, searchdict):
+ volume_metadata = {}
+ for i in volume.get('volume_metadata'):
+ volume_metadata[i['key']] = i['value']
+
+ for k, v in searchdict:
+ if k not in volume_metadata.keys()\
+ or volume_metadata[k] != v:
+ return False
+ return True
+
+ # search_option to filter_name mapping.
+ filter_mapping = {'metadata': _check_metadata_match}
+
+ for volume in volumes:
+ # go over all filters in the list
+ for opt, values in search_opts.iteritems():
+ try:
+ filter_func = filter_mapping[opt]
+ except KeyError:
+ # no such filter - ignore it, go to next filter
+ continue
+ else:
+ if filter_func(volume, values) == False:
+ # if one of conditions didn't match - remove
+ volumes.remove(volume)
+ break
+ return volumes
def get_all_by_vsa(self, context, vsa_id, direction):
if direction == "to":
@@ -219,3 +260,29 @@ class API(base.Base):
{"method": "delete_snapshot",
"args": {"topic": FLAGS.volume_topic,
"snapshot_id": snapshot_id}})
+
+ def get_volume_metadata(self, context, volume_id):
+ """Get all metadata associated with a volume."""
+ rv = self.db.volume_metadata_get(context, volume_id)
+ return dict(rv.iteritems())
+
+ def delete_volume_metadata(self, context, volume_id, key):
+ """Delete the given metadata item from an volume."""
+ self.db.volume_metadata_delete(context, volume_id, key)
+
+ def update_volume_metadata(self, context, volume_id,
+ metadata, delete=False):
+ """Updates or creates volume metadata.
+
+ If delete is True, metadata items that are not specified in the
+ `metadata` argument will be deleted.
+
+ """
+ if delete:
+ _metadata = metadata
+ else:
+ _metadata = self.get_volume_metadata(context, volume_id)
+ _metadata.update(metadata)
+
+ self.db.volume_metadata_update(context, volume_id, _metadata, True)
+ return _metadata