Revision b21d488b
b/lib/client/gnt_instance.py | ||
---|---|---|
1216 | 1216 |
""" |
1217 | 1217 |
result = [] |
1218 | 1218 |
|
1219 |
for (idx, params) in mods:
|
|
1220 |
if idx == constants.DDM_ADD:
|
|
1219 |
for (identifier, params) in mods:
|
|
1220 |
if identifier == constants.DDM_ADD:
|
|
1221 | 1221 |
# Add item as last item (legacy interface) |
1222 | 1222 |
action = constants.DDM_ADD |
1223 |
idxno = -1
|
|
1224 |
elif idx == constants.DDM_REMOVE:
|
|
1223 |
identifier = -1
|
|
1224 |
elif identifier == constants.DDM_REMOVE:
|
|
1225 | 1225 |
# Remove last item (legacy interface) |
1226 | 1226 |
action = constants.DDM_REMOVE |
1227 |
idxno = -1
|
|
1227 |
identifier = -1
|
|
1228 | 1228 |
else: |
1229 | 1229 |
# Modifications and adding/removing at arbitrary indices |
1230 |
try: |
|
1231 |
idxno = int(idx) |
|
1232 |
except (TypeError, ValueError): |
|
1233 |
raise errors.OpPrereqError("Non-numeric index '%s'" % idx, |
|
1234 |
errors.ECODE_INVAL) |
|
1235 |
|
|
1236 | 1230 |
add = params.pop(constants.DDM_ADD, _MISSING) |
1237 | 1231 |
remove = params.pop(constants.DDM_REMOVE, _MISSING) |
1238 | 1232 |
modify = params.pop(constants.DDM_MODIFY, _MISSING) |
... | ... | |
1260 | 1254 |
raise errors.OpPrereqError("Not accepting parameters on removal", |
1261 | 1255 |
errors.ECODE_INVAL) |
1262 | 1256 |
|
1263 |
result.append((action, idxno, params))
|
|
1257 |
result.append((action, identifier, params))
|
|
1264 | 1258 |
|
1265 | 1259 |
return result |
1266 | 1260 |
|
b/lib/cmdlib.py | ||
---|---|---|
13123 | 13123 |
return [(op, idx, params, fn()) for (op, idx, params) in mods] |
13124 | 13124 |
|
13125 | 13125 |
|
13126 |
def GetItemFromContainer(identifier, kind, container): |
|
13127 |
"""Return the item refered by the identifier. |
|
13128 |
|
|
13129 |
@type identifier: string |
|
13130 |
@param identifier: Item index or name or UUID |
|
13131 |
@type kind: string |
|
13132 |
@param kind: One-word item description |
|
13133 |
@type container: list |
|
13134 |
@param container: Container to get the item from |
|
13135 |
|
|
13136 |
""" |
|
13137 |
# Index |
|
13138 |
try: |
|
13139 |
idx = int(identifier) |
|
13140 |
if idx == -1: |
|
13141 |
# Append |
|
13142 |
absidx = len(container) - 1 |
|
13143 |
elif idx < 0: |
|
13144 |
raise IndexError("Not accepting negative indices other than -1") |
|
13145 |
elif idx > len(container): |
|
13146 |
raise IndexError("Got %s index %s, but there are only %s" % |
|
13147 |
(kind, idx, len(container))) |
|
13148 |
else: |
|
13149 |
absidx = idx |
|
13150 |
return (absidx, container[idx]) |
|
13151 |
except ValueError: |
|
13152 |
pass |
|
13153 |
|
|
13154 |
for idx, item in enumerate(container): |
|
13155 |
if item.uuid == identifier or item.name == identifier: |
|
13156 |
return (idx, item) |
|
13157 |
|
|
13158 |
raise errors.OpPrereqError("Cannot find %s with identifier %s" % |
|
13159 |
(kind, identifier), errors.ECODE_NOENT) |
|
13160 |
|
|
13161 |
|
|
13126 | 13162 |
#: Type description for changes as returned by L{ApplyContainerMods}'s |
13127 | 13163 |
#: callbacks |
13128 | 13164 |
_TApplyContModsCbChanges = \ |
... | ... | |
13159 | 13195 |
item and private data object as added by L{PrepareContainerMods} |
13160 | 13196 |
|
13161 | 13197 |
""" |
13162 |
for (op, idx, params, private) in mods: |
|
13163 |
if idx == -1: |
|
13164 |
# Append |
|
13165 |
absidx = len(container) - 1 |
|
13166 |
elif idx < 0: |
|
13167 |
raise IndexError("Not accepting negative indices other than -1") |
|
13168 |
elif idx > len(container): |
|
13169 |
raise IndexError("Got %s index %s, but there are only %s" % |
|
13170 |
(kind, idx, len(container))) |
|
13171 |
else: |
|
13172 |
absidx = idx |
|
13173 |
|
|
13198 |
for (op, identifier, params, private) in mods: |
|
13174 | 13199 |
changes = None |
13175 | 13200 |
|
13176 | 13201 |
if op == constants.DDM_ADD: |
13177 | 13202 |
# Calculate where item will be added |
13203 |
# When adding an item, identifier can only be an index |
|
13204 |
try: |
|
13205 |
idx = int(identifier) |
|
13206 |
except ValueError: |
|
13207 |
raise errors.OpPrereqError("Only possitive integer or -1 is accepted as" |
|
13208 |
" identifier for %s" % constants.DDM_ADD, |
|
13209 |
errors.ECODE_INVAL) |
|
13178 | 13210 |
if idx == -1: |
13179 | 13211 |
addidx = len(container) |
13180 | 13212 |
else: |
13213 |
if idx < 0: |
|
13214 |
raise IndexError("Not accepting negative indices other than -1") |
|
13215 |
elif idx > len(container): |
|
13216 |
raise IndexError("Got %s index %s, but there are only %s" % |
|
13217 |
(kind, idx, len(container))) |
|
13181 | 13218 |
addidx = idx |
13182 | 13219 |
|
13183 | 13220 |
if create_fn is None: |
... | ... | |
13194 | 13231 |
container.insert(idx, item) |
13195 | 13232 |
else: |
13196 | 13233 |
# Retrieve existing item |
13197 |
try: |
|
13198 |
item = container[absidx] |
|
13199 |
except IndexError: |
|
13200 |
raise IndexError("Invalid %s index %s" % (kind, idx)) |
|
13234 |
(absidx, item) = GetItemFromContainer(identifier, kind, container) |
|
13201 | 13235 |
|
13202 | 13236 |
if op == constants.DDM_REMOVE: |
13203 | 13237 |
assert not params |
b/lib/opcodes.py | ||
---|---|---|
1645 | 1645 |
mod_item_fn = \ |
1646 | 1646 |
ht.TAnd(ht.TIsLength(3), ht.TItems([ |
1647 | 1647 |
ht.TElemOf(constants.DDMS_VALUES_WITH_MODIFY), |
1648 |
ht.Comment("Disk index, can be negative, e.g. -1 for last disk")(ht.TInt), |
|
1648 |
ht.Comment("Device index, can be negative, e.g. -1 for last disk") |
|
1649 |
(ht.TOr(ht.TInt, ht.TString)), |
|
1649 | 1650 |
fn, |
1650 | 1651 |
])) |
1651 | 1652 |
|
... | ... | |
1667 | 1668 |
_PForceVariant, |
1668 | 1669 |
_PIgnoreIpolicy, |
1669 | 1670 |
("nics", ht.EmptyList, TestNicModifications, |
1670 |
"List of NIC changes: each item is of the form ``(op, index, settings)``," |
|
1671 |
" ``op`` is one of ``%s``, ``%s`` or ``%s``, ``index`` can be either -1" |
|
1672 |
" to refer to the last position, or a zero-based index number; a" |
|
1671 |
"List of NIC changes: each item is of the form" |
|
1672 |
" ``(op, identifier, settings)``, ``op`` is one of ``%s``, ``%s`` or" |
|
1673 |
" ``%s``, ``identifier`` can be a zero-based index number (or -1 to refer" |
|
1674 |
" to the last position), the NIC's UUID of the NIC's name; a" |
|
1673 | 1675 |
" deprecated version of this parameter used the form ``(op, settings)``," |
1674 | 1676 |
" where ``op`` can be ``%s`` to add a new NIC with the specified" |
1675 | 1677 |
" settings, ``%s`` to remove the last NIC or a number to modify the" |
b/test/py/ganeti.client.gnt_instance_unittest.py | ||
---|---|---|
133 | 133 |
(0, { constants.DDM_REMOVE: True, "param": "value", }), |
134 | 134 |
]) |
135 | 135 |
self.assertRaises(errors.OpPrereqError, fn, [ |
136 |
("Hello", {}), |
|
137 |
]) |
|
138 |
self.assertRaises(errors.OpPrereqError, fn, [ |
|
139 | 136 |
(0, { |
140 | 137 |
constants.DDM_REMOVE: True, |
141 | 138 |
constants.DDM_ADD: True, |
... | ... | |
207 | 204 |
}), |
208 | 205 |
]) |
209 | 206 |
|
207 |
# Names and UUIDs |
|
208 |
self.assertEqual(fn([ |
|
209 |
('name', { |
|
210 |
constants.IDISK_MODE: constants.DISK_RDWR, |
|
211 |
constants.IDISK_NAME: "rename", |
|
212 |
}), |
|
213 |
]), [ |
|
214 |
(constants.DDM_MODIFY, 'name', { |
|
215 |
constants.IDISK_MODE: constants.DISK_RDWR, |
|
216 |
constants.IDISK_NAME: "rename", |
|
217 |
}), |
|
218 |
]) |
|
219 |
self.assertEqual(fn([ |
|
220 |
('024ef14d-4879-400e-8767-d61c051950bf', { |
|
221 |
constants.DDM_MODIFY: True, |
|
222 |
constants.IDISK_SIZE: 1024, |
|
223 |
constants.IDISK_NAME: "name", |
|
224 |
}), |
|
225 |
]), [ |
|
226 |
(constants.DDM_MODIFY, '024ef14d-4879-400e-8767-d61c051950bf', { |
|
227 |
constants.IDISK_SIZE: 1024, |
|
228 |
constants.IDISK_NAME: "name", |
|
229 |
}), |
|
230 |
]) |
|
231 |
self.assertEqual(fn([ |
|
232 |
('name', { |
|
233 |
constants.DDM_REMOVE: True, |
|
234 |
}), |
|
235 |
]), [ |
|
236 |
(constants.DDM_REMOVE, 'name', {}), |
|
237 |
]) |
|
238 |
|
|
210 | 239 |
|
211 | 240 |
class TestParseDiskSizes(unittest.TestCase): |
212 | 241 |
def test(self): |
Also available in: Unified diff