summaryrefslogtreecommitdiffstats
path: root/nova/volume/api.py
diff options
context:
space:
mode:
authorvladimir.p <vladimir@zadarastorage.com>2011-08-23 20:22:27 -0700
committervladimir.p <vladimir@zadarastorage.com>2011-08-23 20:22:27 -0700
commit29940dd27f3a40a4ad54bc2f7a4cea5ac2226b83 (patch)
tree9f67cccca209f1eada4e2fa699f2a50852bde20c /nova/volume/api.py
parentddc7d9470674a4d7300d15e5c6fa54b784b6a36f (diff)
downloadnova-29940dd27f3a40a4ad54bc2f7a4cea5ac2226b83.tar.gz
nova-29940dd27f3a40a4ad54bc2f7a4cea5ac2226b83.tar.xz
nova-29940dd27f3a40a4ad54bc2f7a4cea5ac2226b83.zip
added volume metadata APIs (OS & volume layers), search volume by metadata & other
Diffstat (limited to 'nova/volume/api.py')
-rw-r--r--nova/volume/api.py73
1 files changed, 69 insertions, 4 deletions
diff --git a/nova/volume/api.py b/nova/volume/api.py
index 80e8bd85f..195ab24aa 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -61,6 +61,11 @@ class API(base.Base):
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,
@@ -71,7 +76,7 @@ class API(base.Base):
'attach_status': "detached",
'display_name': name,
'display_description': description,
- 'volume_type_id': volume_type.get('id', None),
+ 'volume_type_id': volume_type_id,
'metadata': metadata,
}
@@ -112,10 +117,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_snapshot(self, context, snapshot_id):
rv = self.db.snapshot_get(context, snapshot_id)
@@ -190,3 +229,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