Revision 845c573d

b/lib/client/gnt_instance.py
1211 1211
  """
1212 1212
  result = []
1213 1213

  
1214
  for (idx, params) in mods:
1215
    if idx == constants.DDM_ADD:
1214
  for (identifier, params) in mods:
1215
    if identifier == constants.DDM_ADD:
1216 1216
      # Add item as last item (legacy interface)
1217 1217
      action = constants.DDM_ADD
1218
      idxno = -1
1219
    elif idx == constants.DDM_REMOVE:
1218
      identifier = -1
1219
    elif identifier == constants.DDM_REMOVE:
1220 1220
      # Remove last item (legacy interface)
1221 1221
      action = constants.DDM_REMOVE
1222
      idxno = -1
1222
      identifier = -1
1223 1223
    else:
1224 1224
      # Modifications and adding/removing at arbitrary indices
1225
      try:
1226
        idxno = int(idx)
1227
      except (TypeError, ValueError):
1228
        raise errors.OpPrereqError("Non-numeric index '%s'" % idx,
1229
                                   errors.ECODE_INVAL)
1230

  
1231 1225
      add = params.pop(constants.DDM_ADD, _MISSING)
1232 1226
      remove = params.pop(constants.DDM_REMOVE, _MISSING)
1233 1227
      modify = params.pop(constants.DDM_MODIFY, _MISSING)
......
1255 1249
      raise errors.OpPrereqError("Not accepting parameters on removal",
1256 1250
                                 errors.ECODE_INVAL)
1257 1251

  
1258
    result.append((action, idxno, params))
1252
    result.append((action, identifier, params))
1259 1253

  
1260 1254
  return result
1261 1255

  
b/lib/cmdlib.py
13062 13062
  return [(op, idx, params, fn()) for (op, idx, params) in mods]
13063 13063

  
13064 13064

  
13065
def GetItemFromContainer(identifier, kind, container):
13066
  """Return the item refered by the identifier.
13067

  
13068
  @type identifier: string
13069
  @param identifier: Item index or name or UUID
13070
  @type kind: string
13071
  @param kind: One-word item description
13072
  @type container: list
13073
  @param container: Container to get the item from
13074

  
13075
  """
13076
  # Index
13077
  try:
13078
    idx = int(identifier)
13079
    if idx == -1:
13080
      # Append
13081
      absidx = len(container) - 1
13082
    elif idx < 0:
13083
      raise IndexError("Not accepting negative indices other than -1")
13084
    elif idx > len(container):
13085
      raise IndexError("Got %s index %s, but there are only %s" %
13086
                       (kind, idx, len(container)))
13087
    else:
13088
      absidx = idx
13089
    return (absidx, container[idx])
13090
  except ValueError:
13091
    pass
13092

  
13093
  for idx, item in enumerate(container):
13094
    if item.uuid == identifier or item.name == identifier:
13095
      return (idx, item)
13096

  
13097
  raise errors.OpPrereqError("Cannot find %s with identifier %s" %
13098
                             (kind, identifier), errors.ECODE_NOENT)
13099

  
13100

  
13065 13101
#: Type description for changes as returned by L{ApplyContainerMods}'s
13066 13102
#: callbacks
13067 13103
_TApplyContModsCbChanges = \
......
13098 13134
    item and private data object as added by L{PrepareContainerMods}
13099 13135

  
13100 13136
  """
13101
  for (op, idx, params, private) in mods:
13102
    if idx == -1:
13103
      # Append
13104
      absidx = len(container) - 1
13105
    elif idx < 0:
13106
      raise IndexError("Not accepting negative indices other than -1")
13107
    elif idx > len(container):
13108
      raise IndexError("Got %s index %s, but there are only %s" %
13109
                       (kind, idx, len(container)))
13110
    else:
13111
      absidx = idx
13112

  
13137
  for (op, identifier, params, private) in mods:
13113 13138
    changes = None
13114 13139

  
13115 13140
    if op == constants.DDM_ADD:
13116 13141
      # Calculate where item will be added
13142
      # When adding an item, identifier can only be an index
13143
      try:
13144
        idx = int(identifier)
13145
      except ValueError:
13146
        raise errors.OpPrereqError("Only possitive integer or -1 is accepted as"
13147
                                   " identifier for %s" % constants.DDM_ADD,
13148
                                   errors.ECODE_INVAL)
13117 13149
      if idx == -1:
13118 13150
        addidx = len(container)
13119 13151
      else:
13152
        if idx < 0:
13153
          raise IndexError("Not accepting negative indices other than -1")
13154
        elif idx > len(container):
13155
          raise IndexError("Got %s index %s, but there are only %s" %
13156
                           (kind, idx, len(container)))
13120 13157
        addidx = idx
13121 13158

  
13122 13159
      if create_fn is None:
......
13133 13170
        container.insert(idx, item)
13134 13171
    else:
13135 13172
      # Retrieve existing item
13136
      try:
13137
        item = container[absidx]
13138
      except IndexError:
13139
        raise IndexError("Invalid %s index %s" % (kind, idx))
13173
      (absidx, item) = GetItemFromContainer(identifier, kind, container)
13140 13174

  
13141 13175
      if op == constants.DDM_REMOVE:
13142 13176
        assert not params
b/lib/opcodes.py
1622 1622
    ht.TAnd(ht.TIsLength(3), ht.TItems([
1623 1623
      ht.TElemOf(constants.DDMS_VALUES_WITH_MODIFY),
1624 1624
      ht.Comment("Device index, can be negative, e.g. -1 for last disk")
1625
                 (ht.TInt),
1625
                 (ht.TOr(ht.TInt, ht.TString)),
1626 1626
      fn,
1627 1627
      ]))
1628 1628

  
......
1643 1643
    _PForceVariant,
1644 1644
    _PIgnoreIpolicy,
1645 1645
    ("nics", ht.EmptyList, TestNicModifications,
1646
     "List of NIC changes: each item is of the form ``(op, index, settings)``,"
1647
     " ``op`` is one of ``%s``, ``%s`` or ``%s``, ``index`` can be either -1"
1648
     " to refer to the last position, or a zero-based index number" %
1646
     "List of NIC changes: each item is of the form"
1647
     " ``(op, identifier, settings)``, ``op`` is one of ``%s``, ``%s`` or"
1648
     " ``%s``, ``identifier`` can be either a zero-based index number"
1649
     " (-1 to refer to the last position), or the NIC UUID or the NIC name" %
1649 1650
     (constants.DDM_ADD, constants.DDM_MODIFY, constants.DDM_REMOVE)),
1650 1651
    ("disks", ht.EmptyList, TestDiskModifications,
1651 1652
     "List of disk changes; see ``nics``"),

Also available in: Unified diff