Revision 08db7c5c

b/lib/cmdlib.py
3141 3141

  
3142 3142
def _GenerateDiskTemplate(lu, template_name,
3143 3143
                          instance_name, primary_node,
3144
                          secondary_nodes, disk_sz, swap_sz,
3144
                          secondary_nodes, disk_info,
3145 3145
                          file_storage_dir, file_driver):
3146 3146
  """Generate the entire disk layout for a given template type.
3147 3147

  
......
3149 3149
  #TODO: compute space requirements
3150 3150

  
3151 3151
  vgname = lu.cfg.GetVGName()
3152
  disk_count = len(disk_info)
3153
  disks = []
3152 3154
  if template_name == constants.DT_DISKLESS:
3153
    disks = []
3155
    pass
3154 3156
  elif template_name == constants.DT_PLAIN:
3155 3157
    if len(secondary_nodes) != 0:
3156 3158
      raise errors.ProgrammerError("Wrong template configuration")
3157 3159

  
3158
    names = _GenerateUniqueNames(lu, [".sda", ".sdb"])
3159
    sda_dev = objects.Disk(dev_type=constants.LD_LV, size=disk_sz,
3160
                           logical_id=(vgname, names[0]),
3161
                           iv_name = "sda")
3162
    sdb_dev = objects.Disk(dev_type=constants.LD_LV, size=swap_sz,
3163
                           logical_id=(vgname, names[1]),
3164
                           iv_name = "sdb")
3165
    disks = [sda_dev, sdb_dev]
3160
    names = _GenerateUniqueNames(lu, [".disk%d" % i
3161
                                      for i in range(disk_count)])
3162
    for idx, disk in enumerate(disk_info):
3163
      disk_dev = objects.Disk(dev_type=constants.LD_LV, size=disk["size"],
3164
                              logical_id=(vgname, names[idx]),
3165
                              iv_name = "disk/%d" % idx)
3166
      disks.append(disk_dev)
3166 3167
  elif template_name == constants.DT_DRBD8:
3167 3168
    if len(secondary_nodes) != 1:
3168 3169
      raise errors.ProgrammerError("Wrong template configuration")
3169 3170
    remote_node = secondary_nodes[0]
3170
    (minor_pa, minor_pb,
3171
     minor_sa, minor_sb) = lu.cfg.AllocateDRBDMinor(
3172
      [primary_node, primary_node, remote_node, remote_node], instance_name)
3173

  
3174
    names = _GenerateUniqueNames(lu, [".sda_data", ".sda_meta",
3175
                                      ".sdb_data", ".sdb_meta"])
3176
    drbd_sda_dev = _GenerateDRBD8Branch(lu, primary_node, remote_node,
3177
                                        disk_sz, names[0:2], "sda",
3178
                                        minor_pa, minor_sa)
3179
    drbd_sdb_dev = _GenerateDRBD8Branch(lu, primary_node, remote_node,
3180
                                        swap_sz, names[2:4], "sdb",
3181
                                        minor_pb, minor_sb)
3182
    disks = [drbd_sda_dev, drbd_sdb_dev]
3171
    minors = lu.cfg.AllocateDRBDMinor(
3172
      [primary_node, remote_node] * len(disk_info), instance_name)
3173

  
3174
    names = _GenerateUniqueNames(lu,
3175
                                 [".disk%d_%s" % (i, s)
3176
                                  for i in range(disk_count)
3177
                                  for s in ("data", "meta")
3178
                                  ])
3179
    for idx, disk in enumerate(disk_info):
3180
      disk_dev = _GenerateDRBD8Branch(lu, primary_node, remote_node,
3181
                                      disk["size"], names[idx*2:idx*2+2],
3182
                                      "disk/%d" % idx,
3183
                                      minors[idx*2], minors[idx*2+1])
3184
      disks.append(disk_dev)
3183 3185
  elif template_name == constants.DT_FILE:
3184 3186
    if len(secondary_nodes) != 0:
3185 3187
      raise errors.ProgrammerError("Wrong template configuration")
3186 3188

  
3187
    file_sda_dev = objects.Disk(dev_type=constants.LD_FILE, size=disk_sz,
3188
                                iv_name="sda", logical_id=(file_driver,
3189
                                "%s/sda" % file_storage_dir))
3190
    file_sdb_dev = objects.Disk(dev_type=constants.LD_FILE, size=swap_sz,
3191
                                iv_name="sdb", logical_id=(file_driver,
3192
                                "%s/sdb" % file_storage_dir))
3193
    disks = [file_sda_dev, file_sdb_dev]
3189
    for idx, disk in enumerate(disk_info):
3190

  
3191
      disk_dev = objects.Disk(dev_type=constants.LD_FILE, size=disk["size"],
3192
                              iv_name="disk/%d" % idx,
3193
                              logical_id=(file_driver,
3194
                                          "%s/disk%d" % (file_storage_dir,
3195
                                                         idx)))
3196
      disks.append(disk_dev)
3194 3197
  else:
3195 3198
    raise errors.ProgrammerError("Invalid disk template '%s'" % template_name)
3196 3199
  return disks
......
3285 3288
  return result
3286 3289

  
3287 3290

  
3288
def _ComputeDiskSize(disk_template, disk_size, swap_size):
3291
def _ComputeDiskSize(disk_template, disks):
3289 3292
  """Compute disk size requirements in the volume group
3290 3293

  
3291 3294
  This is currently hard-coded for the two-drive layout.
......
3294 3297
  # Required free disk space as a function of disk and swap space
3295 3298
  req_size_dict = {
3296 3299
    constants.DT_DISKLESS: None,
3297
    constants.DT_PLAIN: disk_size + swap_size,
3298
    # 256 MB are added for drbd metadata, 128MB for each drbd device
3299
    constants.DT_DRBD8: disk_size + swap_size + 256,
3300
    constants.DT_PLAIN: sum(d["size"] for d in disks),
3301
    # 128 MB are added for drbd metadata for each disk
3302
    constants.DT_DRBD8: sum(d["size"] + 128 for d in disks),
3300 3303
    constants.DT_FILE: None,
3301 3304
  }
3302 3305

  
......
3343 3346
  """
3344 3347
  HPATH = "instance-add"
3345 3348
  HTYPE = constants.HTYPE_INSTANCE
3346
  _OP_REQP = ["instance_name", "disk_size",
3347
              "disk_template", "swap_size", "mode", "start",
3348
              "wait_for_sync", "ip_check", "mac",
3349
  _OP_REQP = ["instance_name", "disks", "disk_template",
3350
              "mode", "start",
3351
              "wait_for_sync", "ip_check", "nics",
3349 3352
              "hvparams", "beparams"]
3350 3353
  REQ_BGL = False
3351 3354

  
......
3418 3421

  
3419 3422
    self.add_locks[locking.LEVEL_INSTANCE] = instance_name
3420 3423

  
3421
    # ip validity checks
3422
    ip = getattr(self.op, "ip", None)
3423
    if ip is None or ip.lower() == "none":
3424
      inst_ip = None
3425
    elif ip.lower() == constants.VALUE_AUTO:
3426
      inst_ip = hostname1.ip
3427
    else:
3428
      if not utils.IsValidIP(ip):
3429
        raise errors.OpPrereqError("given IP address '%s' doesn't look"
3430
                                   " like a valid IP" % ip)
3431
      inst_ip = ip
3432
    self.inst_ip = self.op.ip = inst_ip
3424
    # NIC buildup
3425
    self.nics = []
3426
    for nic in self.op.nics:
3427
      # ip validity checks
3428
      ip = nic.get("ip", None)
3429
      if ip is None or ip.lower() == "none":
3430
        nic_ip = None
3431
      elif ip.lower() == constants.VALUE_AUTO:
3432
        nic_ip = hostname1.ip
3433
      else:
3434
        if not utils.IsValidIP(ip):
3435
          raise errors.OpPrereqError("Given IP address '%s' doesn't look"
3436
                                     " like a valid IP" % ip)
3437
        nic_ip = ip
3438

  
3439
      # MAC address verification
3440
      mac = nic.get("mac", constants.VALUE_AUTO)
3441
      if mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
3442
        if not utils.IsValidMac(mac.lower()):
3443
          raise errors.OpPrereqError("Invalid MAC address specified: %s" %
3444
                                     mac)
3445
      # bridge verification
3446
      bridge = nic.get("bridge", self.cfg.GetDefBridge())
3447
      self.nics.append(objects.NIC(mac=mac, ip=nic_ip, bridge=bridge))
3448

  
3449
    # disk checks/pre-build
3450
    self.disks = []
3451
    for disk in self.op.disks:
3452
      mode = disk.get("mode", constants.DISK_RDWR)
3453
      if mode not in constants.DISK_ACCESS_SET:
3454
        raise errors.OpPrereqError("Invalid disk access mode '%s'" %
3455
                                   mode)
3456
      size = disk.get("size", None)
3457
      if size is None:
3458
        raise errors.OpPrereqError("Missing disk size")
3459
      try:
3460
        size = int(size)
3461
      except ValueError:
3462
        raise errors.OpPrereqError("Invalid disk size '%s'" % size)
3463
      self.disks.append({"size": size, "mode": mode})
3464

  
3433 3465
    # used in CheckPrereq for ip ping check
3434 3466
    self.check_ip = hostname1.ip
3435 3467

  
3436
    # MAC address verification
3437
    if self.op.mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
3438
      if not utils.IsValidMac(self.op.mac.lower()):
3439
        raise errors.OpPrereqError("invalid MAC address specified: %s" %
3440
                                   self.op.mac)
3441

  
3442 3468
    # file storage checks
3443 3469
    if (self.op.file_driver and
3444 3470
        not self.op.file_driver in constants.FILE_DRIVER):
......
3487 3513
    """Run the allocator based on input opcode.
3488 3514

  
3489 3515
    """
3490
    disks = [{"size": self.op.disk_size, "mode": "w"},
3491
             {"size": self.op.swap_size, "mode": "w"}]
3492
    nics = [{"mac": self.op.mac, "ip": getattr(self.op, "ip", None),
3493
             "bridge": self.op.bridge}]
3516
    nics = [n.ToDict() for n in self.nics]
3494 3517
    ial = IAllocator(self,
3495 3518
                     mode=constants.IALLOCATOR_MODE_ALLOC,
3496 3519
                     name=self.op.instance_name,
......
3499 3522
                     os=self.op.os_type,
3500 3523
                     vcpus=self.be_full[constants.BE_VCPUS],
3501 3524
                     mem_size=self.be_full[constants.BE_MEMORY],
3502
                     disks=disks,
3525
                     disks=self.disks,
3503 3526
                     nics=nics,
3504 3527
                     )
3505 3528

  
......
3529 3552
    """
3530 3553
    env = {
3531 3554
      "INSTANCE_DISK_TEMPLATE": self.op.disk_template,
3532
      "INSTANCE_DISK_SIZE": self.op.disk_size,
3533
      "INSTANCE_SWAP_SIZE": self.op.swap_size,
3555
      "INSTANCE_DISK_SIZE": ",".join(str(d["size"]) for d in self.disks),
3534 3556
      "INSTANCE_ADD_MODE": self.op.mode,
3535 3557
      }
3536 3558
    if self.op.mode == constants.INSTANCE_IMPORT:
......
3545 3567
      os_type=self.op.os_type,
3546 3568
      memory=self.be_full[constants.BE_MEMORY],
3547 3569
      vcpus=self.be_full[constants.BE_VCPUS],
3548
      nics=[(self.inst_ip, self.op.bridge, self.op.mac)],
3570
      nics=[(n.ip, n.bridge, n.mac) for n in self.nics],
3549 3571
    ))
3550 3572

  
3551 3573
    nl = ([self.cfg.GetMasterNode(), self.op.pnode] +
......
3581 3603
                                   (ei_version, constants.EXPORT_VERSION))
3582 3604

  
3583 3605
      # Check that the new instance doesn't have less disks than the export
3584
      # TODO: substitute "2" with the actual number of disks requested
3585
      instance_disks = 2
3606
      instance_disks = len(self.disks)
3586 3607
      export_disks = export_info.getint(constants.INISECT_INS, 'disk_count')
3587 3608
      if instance_disks < export_disks:
3588 3609
        raise errors.OpPrereqError("Not enough disks to import."
......
3622 3643
        raise errors.OpPrereqError("IP %s of instance %s already in use" %
3623 3644
                                   (self.check_ip, self.op.instance_name))
3624 3645

  
3625
    # bridge verification
3626
    bridge = getattr(self.op, "bridge", None)
3627
    if bridge is None:
3628
      self.op.bridge = self.cfg.GetDefBridge()
3629
    else:
3630
      self.op.bridge = bridge
3631

  
3632 3646
    #### allocator run
3633 3647

  
3634 3648
    if self.op.iallocator is not None:
......
3655 3669
    nodenames = [pnode.name] + self.secondaries
3656 3670

  
3657 3671
    req_size = _ComputeDiskSize(self.op.disk_template,
3658
                                self.op.disk_size, self.op.swap_size)
3672
                                self.disks)
3659 3673

  
3660 3674
    # Check lv size requirements
3661 3675
    if req_size is not None:
......
3684 3698
                                 " primary node"  % self.op.os_type)
3685 3699

  
3686 3700
    # bridge check on primary node
3687
    if not self.rpc.call_bridges_exist(self.pnode.name, [self.op.bridge]):
3688
      raise errors.OpPrereqError("target bridge '%s' does not exist on"
3701
    bridges = [n.bridge for n in self.nics]
3702
    if not self.rpc.call_bridges_exist(self.pnode.name, bridges):
3703
      raise errors.OpPrereqError("one of the target bridges '%s' does not"
3704
                                 " exist on"
3689 3705
                                 " destination node '%s'" %
3690
                                 (self.op.bridge, pnode.name))
3706
                                 (",".join(bridges), pnode.name))
3691 3707

  
3692 3708
    # memory check on primary node
3693 3709
    if self.op.start:
......
3708 3724
    instance = self.op.instance_name
3709 3725
    pnode_name = self.pnode.name
3710 3726

  
3711
    if self.op.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
3712
      mac_address = self.cfg.GenerateMAC()
3713
    else:
3714
      mac_address = self.op.mac
3715

  
3716
    nic = objects.NIC(bridge=self.op.bridge, mac=mac_address)
3717
    if self.inst_ip is not None:
3718
      nic.ip = self.inst_ip
3727
    for nic in self.nics:
3728
      if nic.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
3729
        nic.mac = self.cfg.GenerateMAC()
3719 3730

  
3720 3731
    ht_kind = self.op.hypervisor
3721 3732
    if ht_kind in constants.HTS_REQ_PORT:
......
3741 3752
    disks = _GenerateDiskTemplate(self,
3742 3753
                                  self.op.disk_template,
3743 3754
                                  instance, pnode_name,
3744
                                  self.secondaries, self.op.disk_size,
3745
                                  self.op.swap_size,
3755
                                  self.secondaries,
3756
                                  self.disks,
3746 3757
                                  file_storage_dir,
3747 3758
                                  self.op.file_driver)
3748 3759

  
3749 3760
    iobj = objects.Instance(name=instance, os=self.op.os_type,
3750 3761
                            primary_node=pnode_name,
3751
                            nics=[nic], disks=disks,
3762
                            nics=self.nics, disks=disks,
3752 3763
                            disk_template=self.op.disk_template,
3753 3764
                            status=self.instance_status,
3754 3765
                            network_port=network_port,
b/lib/constants.py
190 190
# the set of drbd-like disk types
191 191
LDS_DRBD = frozenset([LD_DRBD8])
192 192

  
193
# disk access mode
194
DISK_RDONLY = "r"
195
DISK_RDWR = "w"
196
DISK_ACCESS_SET = frozenset([DISK_RDONLY, DISK_RDWR])
197

  
193 198
# disk replacement mode
194 199
REPLACE_DISK_PRI = "replace_primary"
195 200
REPLACE_DISK_SEC = "replace_secondary"
b/lib/objects.py
274 274
class Disk(ConfigObject):
275 275
  """Config object representing a block device."""
276 276
  __slots__ = ["dev_type", "logical_id", "physical_id",
277
               "children", "iv_name", "size"]
277
               "children", "iv_name", "size", "mode"]
278 278

  
279 279
  def CreateOnSecondary(self):
280 280
    """Test if this device needs to be created on a secondary node."""
b/lib/opcodes.py
319 319
  OP_ID = "OP_INSTANCE_CREATE"
320 320
  OP_DSC_FIELD = "instance_name"
321 321
  __slots__ = [
322
    "instance_name", "disk_size", "os_type", "pnode",
323
    "disk_template", "snode", "swap_size", "mode",
324
    "ip", "bridge", "src_node", "src_path", "start",
325
    "wait_for_sync", "ip_check", "mac",
322
    "instance_name", "os_type", "pnode",
323
    "disk_template", "snode", "mode",
324
    "disks", "nics",
325
    "src_node", "src_path", "start",
326
    "wait_for_sync", "ip_check",
326 327
    "file_storage_dir", "file_driver",
327 328
    "iallocator",
328 329
    "hypervisor", "hvparams", "beparams",
b/scripts/gnt-instance
293 293
  if opts.hypervisor:
294 294
    hypervisor, hvparams = opts.hypervisor
295 295

  
296
  if opts.nics:
297
    try:
298
      nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
299
    except ValueError, err:
300
      raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
301
    nics = [{}] * nic_max
302
    for nidx, ndict in opts.nics.items():
303
      nidx = int(nidx)
304
      nics[nidx] = ndict
305
  else:
306
    # default of one nic, all auto
307
    nics = [{}]
308

  
309
  if not opts.disks and opts.disk_template != constants.DT_DISKLESS:
310
    raise errors.OpPrereqError("No disk information specified")
311
  elif opts.disks and opts.disk_template == constants.DT_DISKLESS:
312
    raise errors.OpPrereqError("Diskless instance but disk information passeD")
313
  else:
314
    try:
315
      disk_max = max(int(didx[0])+1 for didx in opts.disks)
316
    except ValueError, err:
317
      raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
318
    disks = [{}] * disk_max
319
    for didx, ddict in opts.disks:
320
      didx = int(didx)
321
      if "size" not in ddict:
322
        raise errors.OpPrereqError("Missing size for disk %d" % didx)
323
      try:
324
        ddict["size"] = utils.ParseUnit(ddict["size"])
325
      except ValueError, err:
326
        raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
327
                                   (didx, err))
328
      disks[didx] = ddict
329

  
296 330
  ValidateBeParams(opts.beparams)
297 331

  
298 332
##  kernel_path = _TransformPath(opts.kernel_path)
......
308 342
##    hvm_cdrom_image_path = opts.hvm_cdrom_image_path
309 343

  
310 344
  op = opcodes.OpCreateInstance(instance_name=instance,
311
                                disk_size=opts.size, swap_size=opts.swap,
345
                                disks=disks,
312 346
                                disk_template=opts.disk_template,
347
                                nics=nics,
313 348
                                mode=constants.INSTANCE_CREATE,
314 349
                                os_type=opts.os, pnode=pnode,
315 350
                                snode=snode,
316
                                ip=opts.ip, bridge=opts.bridge,
317 351
                                start=opts.start, ip_check=opts.ip_check,
318 352
                                wait_for_sync=opts.wait_for_sync,
319
                                mac=opts.mac,
320 353
                                hypervisor=hypervisor,
321 354
                                hvparams=hvparams,
322 355
                                beparams=opts.beparams,
......
1075 1108
  make_option("-t", "--disk-template", dest="disk_template",
1076 1109
              help="Custom disk setup (diskless, file, plain or drbd)",
1077 1110
              default=None, metavar="TEMPL"),
1078
  make_option("-i", "--ip", dest="ip",
1079
              help="IP address ('none' [default], 'auto', or specify address)",
1080
              default='none', type="string", metavar="<ADDRESS>"),
1081
  make_option("--mac", dest="mac",
1082
              help="MAC address ('auto' [default], or specify address)",
1083
              default='auto', type="string", metavar="<MACADDRESS>"),
1111
  ikv_option("--disk", help="Disk information",
1112
             default=[], dest="disks",
1113
             action="append",
1114
             type="identkeyval"),
1115
  ikv_option("--net", help="NIC information",
1116
             default=[], dest="nics",
1117
             action="append",
1118
             type="identkeyval"),
1084 1119
  make_option("--no-wait-for-sync", dest="wait_for_sync", default=True,
1085 1120
              action="store_false", help="Don't wait for sync (DANGEROUS!)"),
1086
  make_option("-b", "--bridge", dest="bridge",
1087
              help="Bridge to connect this instance to",
1088
              default=None, metavar="<bridge>"),
1089 1121
  make_option("--no-start", dest="start", default=True,
1090 1122
              action="store_false", help="Don't start the instance after"
1091 1123
              " creation"),
b/scripts/gnt-job
280 280
        if key == "OP_ID":
281 281
          continue
282 282
        if isinstance(val, (tuple, list)):
283
          val = ",".join(val)
283
          val = ",".join([str(item) for item in val])
284 284
        format(4, "%s: %s" % (key, val))
285 285
      if result is None:
286 286
        format(3, "No output data")
b/tools/burnin
126 126
    parser.add_option("-o", "--os", dest="os", default=None,
127 127
                      help="OS to use during burnin",
128 128
                      metavar="<OS>")
129
    parser.add_option("--os-size", dest="os_size", help="Disk size",
130
                      default=4 * 1024, type="unit", metavar="<size>")
131
    parser.add_option("--os-growth", dest="sda_growth", help="Disk growth",
132
                      default=1024, type="unit", metavar="<size>")
133
    parser.add_option("--swap-size", dest="swap_size", help="Swap size",
134
                      default=4 * 1024, type="unit", metavar="<size>")
135
    parser.add_option("--swap-growth", dest="sdb_growth", help="Swap growth",
136
                      default=1024, type="unit", metavar="<size>")
129
    parser.add_option("--disk-size", dest="disk_size",
130
                      help="Disk size (determines disk count)",
131
                      default="128m", type="string", metavar="<size,size,...>")
132
    parser.add_option("--disk-growth", dest="disk_growth", help="Disk growth",
133
                      default=128, type="string", metavar="<size,size,...>")
137 134
    parser.add_option("--mem-size", dest="mem_size", help="Memory size",
138 135
                      default=128, type="unit", metavar="<size>")
139 136
    parser.add_option("-v", "--verbose",
......
188 185
      Log("Unknown disk template '%s'" % options.disk_template)
189 186
      sys.exit(1)
190 187

  
188
    disk_size = [utils.ParseUnit(v) for v in options.disk_size.split(",")]
189
    disk_growth = [utils.ParseUnit(v) for v in options.disk_growth.split(",")]
190
    if len(disk_growth) != len(disk_size):
191
      Log("Wrong disk sizes/growth combination")
192
      sys.exit(1)
193
    if ((disk_size and options.disk_template == constants.DT_DISKLESS) or
194
        (not disk_size and options.disk_template != constants.DT_DISKLESS)):
195
      Log("Wrong disk count/disk template combination")
196
      sys.exit(1)
197

  
198
    self.disk_size = disk_size
199
    self.disk_growth = disk_growth
200
    self.disk_count = len(disk_size)
201

  
191 202
    if options.nodes and options.iallocator:
192 203
      Log("Give either the nodes option or the iallocator option, not both")
193 204
      sys.exit(1)
......
251 262
        Log("- Add instance %s on nodes %s/%s" % (instance, pnode, snode))
252 263

  
253 264
      op = opcodes.OpCreateInstance(instance_name=instance,
254
                                    disk_size=self.opts.os_size,
255
                                    swap_size=self.opts.swap_size,
265
                                    disks = [ {"size": size}
266
                                              for size in self.disk_size],
256 267
                                    disk_template=self.opts.disk_template,
268
                                    nics=[{}],
257 269
                                    mode=constants.INSTANCE_CREATE,
258 270
                                    os_type=self.opts.os,
259 271
                                    pnode=pnode,
......
261 273
                                    start=True,
262 274
                                    ip_check=True,
263 275
                                    wait_for_sync=True,
264
                                    mac="auto",
265 276
                                    file_driver="loop",
266 277
                                    file_storage_dir=None,
267 278
                                    iallocator=self.opts.iallocator,
......
283 294
  def GrowDisks(self):
284 295
    """Grow both the os and the swap disks by the requested amount, if any."""
285 296
    for instance in self.instances:
286
      for disk in ['sda', 'sdb']:
287
        growth = getattr(self.opts, '%s_growth' % disk)
297
      for idx, growth in enumerate(self.disk_growth):
288 298
        if growth > 0:
289
          op = opcodes.OpGrowDisk(instance_name=instance, disk=disk,
299
          op = opcodes.OpGrowDisk(instance_name=instance, disk=idx,
290 300
                                  amount=growth, wait_for_sync=True)
291
          Log("- Increase %s's %s disk by %s MB" % (instance, disk, growth))
301
          Log("- Increase %s's %s disk by %s MB" % (instance, idx, growth))
292 302
          self.ExecOp(op)
293 303

  
294 304
  def ReplaceDisks1D8(self):
......
297 307
      for mode in constants.REPLACE_DISK_SEC, constants.REPLACE_DISK_PRI:
298 308
        op = opcodes.OpReplaceDisks(instance_name=instance,
299 309
                                    mode=mode,
300
                                    disks=["sda", "sdb"])
310
                                    disks=[i for i in range(self.disk_count)])
301 311
        Log("- Replace disks (%s) for instance %s" % (mode, instance))
302 312
        self.ExecOp(op)
303 313

  
......
314 324
                                  mode=mode,
315 325
                                  remote_node=tnode,
316 326
                                  iallocator=self.opts.iallocator,
317
                                  disks=["sda", "sdb"])
327
                                  disks=[i for i in range(self.disk_count)])
318 328
      Log("- Replace secondary (%s) for instance %s" % (mode, instance))
319 329
      self.ExecOp(op)
320 330

  

Also available in: Unified diff