"""
result = []
- for (idx, params) in mods:
- if idx == constants.DDM_ADD:
+ for (identifier, params) in mods:
+ if identifier == constants.DDM_ADD:
# Add item as last item (legacy interface)
action = constants.DDM_ADD
- idxno = -1
- elif idx == constants.DDM_REMOVE:
+ identifier = -1
+ elif identifier == constants.DDM_REMOVE:
# Remove last item (legacy interface)
action = constants.DDM_REMOVE
- idxno = -1
+ identifier = -1
else:
# Modifications and adding/removing at arbitrary indices
- try:
- idxno = int(idx)
- except (TypeError, ValueError):
- raise errors.OpPrereqError("Non-numeric index '%s'" % idx,
- errors.ECODE_INVAL)
-
add = params.pop(constants.DDM_ADD, _MISSING)
remove = params.pop(constants.DDM_REMOVE, _MISSING)
modify = params.pop(constants.DDM_MODIFY, _MISSING)
raise errors.OpPrereqError("Not accepting parameters on removal",
errors.ECODE_INVAL)
- result.append((action, idxno, params))
+ result.append((action, identifier, params))
return result
return [(op, idx, params, fn()) for (op, idx, params) in mods]
+def GetItemFromContainer(identifier, kind, container):
+ """Return the item refered by the identifier.
+
+ @type identifier: string
+ @param identifier: Item index or name or UUID
+ @type kind: string
+ @param kind: One-word item description
+ @type container: list
+ @param container: Container to get the item from
+
+ """
+ # Index
+ try:
+ idx = int(identifier)
+ if idx == -1:
+ # Append
+ absidx = len(container) - 1
+ elif idx < 0:
+ raise IndexError("Not accepting negative indices other than -1")
+ elif idx > len(container):
+ raise IndexError("Got %s index %s, but there are only %s" %
+ (kind, idx, len(container)))
+ else:
+ absidx = idx
+ return (absidx, container[idx])
+ except ValueError:
+ pass
+
+ for idx, item in enumerate(container):
+ if item.uuid == identifier or item.name == identifier:
+ return (idx, item)
+
+ raise errors.OpPrereqError("Cannot find %s with identifier %s" %
+ (kind, identifier), errors.ECODE_NOENT)
+
+
#: Type description for changes as returned by L{ApplyContainerMods}'s
#: callbacks
_TApplyContModsCbChanges = \
item and private data object as added by L{PrepareContainerMods}
"""
- for (op, idx, params, private) in mods:
- if idx == -1:
- # Append
- absidx = len(container) - 1
- elif idx < 0:
- raise IndexError("Not accepting negative indices other than -1")
- elif idx > len(container):
- raise IndexError("Got %s index %s, but there are only %s" %
- (kind, idx, len(container)))
- else:
- absidx = idx
-
+ for (op, identifier, params, private) in mods:
changes = None
if op == constants.DDM_ADD:
# Calculate where item will be added
+ # When adding an item, identifier can only be an index
+ try:
+ idx = int(identifier)
+ except ValueError:
+ raise errors.OpPrereqError("Only possitive integer or -1 is accepted as"
+ " identifier for %s" % constants.DDM_ADD,
+ errors.ECODE_INVAL)
if idx == -1:
addidx = len(container)
else:
+ if idx < 0:
+ raise IndexError("Not accepting negative indices other than -1")
+ elif idx > len(container):
+ raise IndexError("Got %s index %s, but there are only %s" %
+ (kind, idx, len(container)))
addidx = idx
if create_fn is None:
container.insert(idx, item)
else:
# Retrieve existing item
- try:
- item = container[absidx]
- except IndexError:
- raise IndexError("Invalid %s index %s" % (kind, idx))
+ (absidx, item) = GetItemFromContainer(identifier, kind, container)
if op == constants.DDM_REMOVE:
assert not params
mod_item_fn = \
ht.TAnd(ht.TIsLength(3), ht.TItems([
ht.TElemOf(constants.DDMS_VALUES_WITH_MODIFY),
- ht.Comment("Disk index, can be negative, e.g. -1 for last disk")(ht.TInt),
+ ht.Comment("Device index, can be negative, e.g. -1 for last disk")
+ (ht.TOr(ht.TInt, ht.TString)),
fn,
]))
_PForceVariant,
_PIgnoreIpolicy,
("nics", ht.EmptyList, TestNicModifications,
- "List of NIC changes: each item is of the form ``(op, index, settings)``,"
- " ``op`` is one of ``%s``, ``%s`` or ``%s``, ``index`` can be either -1"
- " to refer to the last position, or a zero-based index number; a"
+ "List of NIC changes: each item is of the form"
+ " ``(op, identifier, settings)``, ``op`` is one of ``%s``, ``%s`` or"
+ " ``%s``, ``identifier`` can be a zero-based index number (or -1 to refer"
+ " to the last position), the NIC's UUID of the NIC's name; a"
" deprecated version of this parameter used the form ``(op, settings)``,"
" where ``op`` can be ``%s`` to add a new NIC with the specified"
" settings, ``%s`` to remove the last NIC or a number to modify the"
(0, { constants.DDM_REMOVE: True, "param": "value", }),
])
self.assertRaises(errors.OpPrereqError, fn, [
- ("Hello", {}),
- ])
- self.assertRaises(errors.OpPrereqError, fn, [
(0, {
constants.DDM_REMOVE: True,
constants.DDM_ADD: True,
}),
])
+ # Names and UUIDs
+ self.assertEqual(fn([
+ ('name', {
+ constants.IDISK_MODE: constants.DISK_RDWR,
+ constants.IDISK_NAME: "rename",
+ }),
+ ]), [
+ (constants.DDM_MODIFY, 'name', {
+ constants.IDISK_MODE: constants.DISK_RDWR,
+ constants.IDISK_NAME: "rename",
+ }),
+ ])
+ self.assertEqual(fn([
+ ('024ef14d-4879-400e-8767-d61c051950bf', {
+ constants.DDM_MODIFY: True,
+ constants.IDISK_SIZE: 1024,
+ constants.IDISK_NAME: "name",
+ }),
+ ]), [
+ (constants.DDM_MODIFY, '024ef14d-4879-400e-8767-d61c051950bf', {
+ constants.IDISK_SIZE: 1024,
+ constants.IDISK_NAME: "name",
+ }),
+ ])
+ self.assertEqual(fn([
+ ('name', {
+ constants.DDM_REMOVE: True,
+ }),
+ ]), [
+ (constants.DDM_REMOVE, 'name', {}),
+ ])
+
class TestParseDiskSizes(unittest.TestCase):
def test(self):