diff --git a/lib/bdev.py b/lib/bdev.py
index b0ed7c0..7a27b7b 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -2797,8 +2797,24 @@ class ExtStorageDevice(BlockDev):
_ExtStorageAction(constants.ES_ACTION_GROW, self.unique_id,
str(self.size), grow=str(new_size))
+ def SetInfo(self, text):
+ """Update metadata with info text.
-def _ExtStorageAction(action, unique_id, size=None, grow=None):
+ """
+ # Replace invalid characters
+ text = re.sub("^[^A-Za-z0-9_+.]", "_", text)
+ text = re.sub("[^-A-Za-z0-9_+.]", "_", text)
+
+ # Only up to 128 characters are allowed
+ text = text[:128]
+
+ # Call the External Storage's setinfo script,
+ # to set metadata for an existing Volume inside the External Storage
+ _ExtStorageAction(constants.ES_ACTION_SETINFO, self.unique_id,
+ metadata=text)
+
+
+def _ExtStorageAction(action, unique_id, size=None, grow=None, metadata=None):
"""Take an External Storage action.
Take an External Storage action concerning or affecting
@@ -2814,6 +2830,8 @@ def _ExtStorageAction(action, unique_id, size=None,
grow=None):
@param size: the size of the Volume in mebibytes
@type grow: integer
@param grow: the new size in mebibytes (after grow)
+ @type metadata: string
+ @param metadata: metadata info of the Volume, for use by the provider
@rtype: None or a block device path (during attach)
"""
@@ -2825,7 +2843,7 @@ def _ExtStorageAction(action, unique_id, size=None,
grow=None):
_ThrowError("%s" % inst_es)
# Create the basic environment for the driver's scripts
- create_env = _ExtStorageEnvironment(unique_id, size, grow)
+ create_env = _ExtStorageEnvironment(unique_id, size, grow, metadata)
# Do not use log file for action `attach' as we need
# to get the output from RunResult
@@ -2834,6 +2852,12 @@ def _ExtStorageAction(action, unique_id, size=None,
grow=None):
if action is not constants.ES_ACTION_ATTACH:
logfile = _VolumeLogName(action, driver, vol_name)
+ # Make sure the given action results in a valid script
+ target_script = action
+ if target_script not in constants.ES_SCRIPTS:
+ _ThrowError("Action '%s' doesn't result in a valid ExtStorage script" %
+ action)
+
# Find out which external script to run according the given action
script_name = action + "_script"
script = getattr(inst_es, script_name)
@@ -2852,12 +2876,12 @@ def _ExtStorageAction(action, unique_id, size=None,
grow=None):
if action is not constants.ES_ACTION_ATTACH:
lines = [utils.SafeEncode(val)
for val in utils.TailFile(logfile, lines=20)]
- _ThrowError("External storage's %s script failed (%s), last"
- " lines in the log file:\n%s",
- action, result.fail_reason, "\n".join(lines))
else:
- _ThrowError("External storage's %s script failed (%s)",
- action, result.fail_reason)
+ lines = result.output[-20:]
+
+ _ThrowError("External storage's %s script failed (%s), last"
+ " lines of output:\n%s",
+ action, result.fail_reason, "\n".join(lines))
if action == constants.ES_ACTION_ATTACH:
return result.stdout
@@ -2878,9 +2902,11 @@ def ExtStorageFromDisk(name, base_dir=None):
"""
if base_dir is None:
- es_dir = utils.FindFile(name, pathutils.ES_SEARCH_PATH, os.path.isdir)
+ es_base_dir = pathutils.ES_SEARCH_PATH
else:
- es_dir = utils.FindFile(name, [base_dir], os.path.isdir)
+ es_base_dir = [base_dir]
+
+ es_dir = utils.FindFile(name, es_base_dir, os.path.isdir)
if es_dir is None:
return False, ("Directory for External Storage Provider %s not"
@@ -2915,17 +2941,22 @@ def ExtStorageFromDisk(name, base_dir=None):
remove_script=es_files[constants.ES_SCRIPT_REMOVE],
grow_script=es_files[constants.ES_SCRIPT_GROW],
attach_script=es_files[constants.ES_SCRIPT_ATTACH],
- detach_script=es_files[constants.ES_SCRIPT_DETACH])
+ detach_script=es_files[constants.ES_SCRIPT_DETACH],
+ setinfo_script=es_files[constants.ES_SCRIPT_SETINFO])
return True, es_obj
-def _ExtStorageEnvironment(unique_id, size=None, grow=None):
+def _ExtStorageEnvironment(unique_id, size=None, grow=None, metadata=None):
"""Calculate the environment for an External Storage script.
@type unique_id: tuple (driver, vol_name)
@param unique_id: ExtStorage pool and name of the Volume
- @type size: integer
- @param size: size of the Volume in mebibytes
+ @type size: string
+ @param size: size of the Volume (in mebibytes)
+ @type grow: string
+ @param grow: new size of Volume after grow (in mebibytes)
+ @type metadata: string
+ @param metadata: metadata info of the Volume
@rtype: dict
@return: dict of environment variables
@@ -2933,13 +2964,16 @@ def _ExtStorageEnvironment(unique_id, size=None, grow=None):
vol_name = unique_id[1]
result = {}
- result['VOL_NAME'] = vol_name
+ result["VOL_NAME"] = vol_name
if size is not None:
- result['VOL_SIZE'] = size
+ result["VOL_SIZE"] = size
if grow is not None:
- result['VOL_NEW_SIZE'] = grow
+ result["VOL_NEW_SIZE"] = grow
+
+ if metadata is not None:
+ result["VOL_METADATA"] = metadata
return result
diff --git a/lib/constants.py b/lib/constants.py
index 1cb7196..942859b 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -615,18 +615,21 @@ ES_ACTION_REMOVE = "remove"
ES_ACTION_GROW = "grow"
ES_ACTION_ATTACH = "attach"
ES_ACTION_DETACH = "detach"
+ES_ACTION_SETINFO = "setinfo"
ES_SCRIPT_CREATE = ES_ACTION_CREATE
ES_SCRIPT_REMOVE = ES_ACTION_REMOVE
ES_SCRIPT_GROW = ES_ACTION_GROW
ES_SCRIPT_ATTACH = ES_ACTION_ATTACH
ES_SCRIPT_DETACH = ES_ACTION_DETACH
+ES_SCRIPT_SETINFO = ES_ACTION_SETINFO
ES_SCRIPTS = frozenset([
ES_SCRIPT_CREATE,
ES_SCRIPT_REMOVE,
ES_SCRIPT_GROW,
ES_SCRIPT_ATTACH,
- ES_SCRIPT_DETACH
+ ES_SCRIPT_DETACH,
+ ES_SCRIPT_SETINFO
])
# ssh constants
@@ -2042,7 +2045,6 @@ VALID_ALLOC_POLICIES = [
# Temporary external/shared storage parameters
BLOCKDEV_DRIVER_MANUAL = "manual"
-EXTSTORAGE_SAMPLE_PROVIDER = "rbd"
# qemu-img path, required for ovfconverter
QEMUIMG_PATH = _autoconf.QEMUIMG_PATH
diff --git a/lib/objects.py b/lib/objects.py
index da5bc5b..9332afc 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -1244,6 +1244,7 @@ class ExtStorage(ConfigObject):
"grow_script",
"attach_script",
"detach_script",
+ "setinfo_script",
]