Revision d353ec8f lib/cmdlib.py

b/lib/cmdlib.py
9261 9261
                 osname, node)
9262 9262

  
9263 9263

  
9264
def _CreateInstanceAllocRequest(op, disks, nics, beparams):
9265
  """Wrapper around IAReqInstanceAlloc.
9266

  
9267
  @param op: The instance opcode
9268
  @param disks: The computed disks
9269
  @param nics: The computed nics
9270
  @param beparams: The full filled beparams
9271

  
9272
  @returns: A filled L{iallocator.IAReqInstanceAlloc}
9273

  
9274
  """
9275
  spindle_use = beparams[constants.BE_SPINDLE_USE]
9276
  return iallocator.IAReqInstanceAlloc(name=op.instance_name,
9277
                                       disk_template=op.disk_template,
9278
                                       tags=op.tags,
9279
                                       os=op.os_type,
9280
                                       vcpus=beparams[constants.BE_VCPUS],
9281
                                       memory=beparams[constants.BE_MAXMEM],
9282
                                       spindle_use=spindle_use,
9283
                                       disks=disks,
9284
                                       nics=[n.ToDict() for n in nics],
9285
                                       hypervisor=op.hypervisor)
9286

  
9287

  
9288
def _ComputeNics(op, cluster, default_ip, cfg, proc):
9289
  """Computes the nics.
9290

  
9291
  @param op: The instance opcode
9292
  @param cluster: Cluster configuration object
9293
  @param default_ip: The default ip to assign
9294
  @param cfg: An instance of the configuration object
9295
  @param proc: The executer instance
9296

  
9297
  @returns: The build up nics
9298

  
9299
  """
9300
  nics = []
9301
  for idx, nic in enumerate(op.nics):
9302
    nic_mode_req = nic.get(constants.INIC_MODE, None)
9303
    nic_mode = nic_mode_req
9304
    if nic_mode is None or nic_mode == constants.VALUE_AUTO:
9305
      nic_mode = cluster.nicparams[constants.PP_DEFAULT][constants.NIC_MODE]
9306

  
9307
    # in routed mode, for the first nic, the default ip is 'auto'
9308
    if nic_mode == constants.NIC_MODE_ROUTED and idx == 0:
9309
      default_ip_mode = constants.VALUE_AUTO
9310
    else:
9311
      default_ip_mode = constants.VALUE_NONE
9312

  
9313
    # ip validity checks
9314
    ip = nic.get(constants.INIC_IP, default_ip_mode)
9315
    if ip is None or ip.lower() == constants.VALUE_NONE:
9316
      nic_ip = None
9317
    elif ip.lower() == constants.VALUE_AUTO:
9318
      if not op.name_check:
9319
        raise errors.OpPrereqError("IP address set to auto but name checks"
9320
                                   " have been skipped",
9321
                                   errors.ECODE_INVAL)
9322
      nic_ip = default_ip
9323
    else:
9324
      if not netutils.IPAddress.IsValid(ip):
9325
        raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
9326
                                   errors.ECODE_INVAL)
9327
      nic_ip = ip
9328

  
9329
    # TODO: check the ip address for uniqueness
9330
    if nic_mode == constants.NIC_MODE_ROUTED and not nic_ip:
9331
      raise errors.OpPrereqError("Routed nic mode requires an ip address",
9332
                                 errors.ECODE_INVAL)
9333

  
9334
    # MAC address verification
9335
    mac = nic.get(constants.INIC_MAC, constants.VALUE_AUTO)
9336
    if mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
9337
      mac = utils.NormalizeAndValidateMac(mac)
9338

  
9339
      try:
9340
        # TODO: We need to factor this out
9341
        cfg.ReserveMAC(mac, proc.GetECId())
9342
      except errors.ReservationError:
9343
        raise errors.OpPrereqError("MAC address %s already in use"
9344
                                   " in cluster" % mac,
9345
                                   errors.ECODE_NOTUNIQUE)
9346

  
9347
    #  Build nic parameters
9348
    link = nic.get(constants.INIC_LINK, None)
9349
    if link == constants.VALUE_AUTO:
9350
      link = cluster.nicparams[constants.PP_DEFAULT][constants.NIC_LINK]
9351
    nicparams = {}
9352
    if nic_mode_req:
9353
      nicparams[constants.NIC_MODE] = nic_mode
9354
    if link:
9355
      nicparams[constants.NIC_LINK] = link
9356

  
9357
    check_params = cluster.SimpleFillNIC(nicparams)
9358
    objects.NIC.CheckParameterSyntax(check_params)
9359
    nics.append(objects.NIC(mac=mac, ip=nic_ip, nicparams=nicparams))
9360

  
9361
  return nics
9362

  
9363

  
9364
def _ComputeDisks(op, default_vg):
9365
  """Computes the instance disks.
9366

  
9367
  @param op: The instance opcode
9368
  @param default_vg: The default_vg to assume
9369

  
9370
  @return: The computer disks
9371

  
9372
  """
9373
  disks = []
9374
  for disk in op.disks:
9375
    mode = disk.get(constants.IDISK_MODE, constants.DISK_RDWR)
9376
    if mode not in constants.DISK_ACCESS_SET:
9377
      raise errors.OpPrereqError("Invalid disk access mode '%s'" %
9378
                                 mode, errors.ECODE_INVAL)
9379
    size = disk.get(constants.IDISK_SIZE, None)
9380
    if size is None:
9381
      raise errors.OpPrereqError("Missing disk size", errors.ECODE_INVAL)
9382
    try:
9383
      size = int(size)
9384
    except (TypeError, ValueError):
9385
      raise errors.OpPrereqError("Invalid disk size '%s'" % size,
9386
                                 errors.ECODE_INVAL)
9387

  
9388
    data_vg = disk.get(constants.IDISK_VG, default_vg)
9389
    new_disk = {
9390
      constants.IDISK_SIZE: size,
9391
      constants.IDISK_MODE: mode,
9392
      constants.IDISK_VG: data_vg,
9393
      }
9394
    if constants.IDISK_METAVG in disk:
9395
      new_disk[constants.IDISK_METAVG] = disk[constants.IDISK_METAVG]
9396
    if constants.IDISK_ADOPT in disk:
9397
      new_disk[constants.IDISK_ADOPT] = disk[constants.IDISK_ADOPT]
9398
    disks.append(new_disk)
9399

  
9400
  return disks
9401

  
9402

  
9403
def _ComputeFullBeParams(op, cluster):
9404
  """Computes the full beparams.
9405

  
9406
  @param op: The instance opcode
9407
  @param cluster: The cluster config object
9408

  
9409
  @return: The fully filled beparams
9410

  
9411
  """
9412
  default_beparams = cluster.beparams[constants.PP_DEFAULT]
9413
  for param, value in op.beparams.iteritems():
9414
    if value == constants.VALUE_AUTO:
9415
      op.beparams[param] = default_beparams[param]
9416
  objects.UpgradeBeParams(op.beparams)
9417
  utils.ForceDictType(op.beparams, constants.BES_PARAMETER_TYPES)
9418
  return cluster.SimpleFillBE(op.beparams)
9419

  
9420

  
9264 9421
class LUInstanceCreate(LogicalUnit):
9265 9422
  """Create an instance.
9266 9423

  
......
9485 9642
    """Run the allocator based on input opcode.
9486 9643

  
9487 9644
    """
9488
    nics = [n.ToDict() for n in self.nics]
9489
    memory = self.be_full[constants.BE_MAXMEM]
9490
    spindle_use = self.be_full[constants.BE_SPINDLE_USE]
9491
    req = iallocator.IAReqInstanceAlloc(name=self.op.instance_name,
9492
                                        disk_template=self.op.disk_template,
9493
                                        tags=self.op.tags,
9494
                                        os=self.op.os_type,
9495
                                        vcpus=self.be_full[constants.BE_VCPUS],
9496
                                        memory=memory,
9497
                                        spindle_use=spindle_use,
9498
                                        disks=self.disks,
9499
                                        nics=nics,
9500
                                        hypervisor=self.op.hypervisor)
9645
    req = _CreateInstanceAllocRequest(self.op, self.disks,
9646
                                      self.nics, self.be_full)
9501 9647
    ial = iallocator.IAllocator(self.cfg, self.rpc, req)
9502 9648

  
9503 9649
    ial.Run(self.op.iallocator)
......
9795 9941
    _CheckGlobalHvParams(self.op.hvparams)
9796 9942

  
9797 9943
    # fill and remember the beparams dict
9798
    default_beparams = cluster.beparams[constants.PP_DEFAULT]
9799
    for param, value in self.op.beparams.iteritems():
9800
      if value == constants.VALUE_AUTO:
9801
        self.op.beparams[param] = default_beparams[param]
9802
    objects.UpgradeBeParams(self.op.beparams)
9803
    utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES)
9804
    self.be_full = cluster.SimpleFillBE(self.op.beparams)
9944
    self.be_full = _ComputeFullBeParams(self.op, cluster)
9805 9945

  
9806 9946
    # build os parameters
9807 9947
    self.os_full = cluster.SimpleFillOS(self.op.os_type, self.op.osparams)
......
9812 9952
      self._RevertToDefaults(cluster)
9813 9953

  
9814 9954
    # NIC buildup
9815
    self.nics = []
9816
    for idx, nic in enumerate(self.op.nics):
9817
      nic_mode_req = nic.get(constants.INIC_MODE, None)
9818
      nic_mode = nic_mode_req
9819
      if nic_mode is None or nic_mode == constants.VALUE_AUTO:
9820
        nic_mode = cluster.nicparams[constants.PP_DEFAULT][constants.NIC_MODE]
9821

  
9822
      # in routed mode, for the first nic, the default ip is 'auto'
9823
      if nic_mode == constants.NIC_MODE_ROUTED and idx == 0:
9824
        default_ip_mode = constants.VALUE_AUTO
9825
      else:
9826
        default_ip_mode = constants.VALUE_NONE
9827

  
9828
      # ip validity checks
9829
      ip = nic.get(constants.INIC_IP, default_ip_mode)
9830
      if ip is None or ip.lower() == constants.VALUE_NONE:
9831
        nic_ip = None
9832
      elif ip.lower() == constants.VALUE_AUTO:
9833
        if not self.op.name_check:
9834
          raise errors.OpPrereqError("IP address set to auto but name checks"
9835
                                     " have been skipped",
9836
                                     errors.ECODE_INVAL)
9837
        nic_ip = self.hostname1.ip
9838
      else:
9839
        if not netutils.IPAddress.IsValid(ip):
9840
          raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
9841
                                     errors.ECODE_INVAL)
9842
        nic_ip = ip
9843

  
9844
      # TODO: check the ip address for uniqueness
9845
      if nic_mode == constants.NIC_MODE_ROUTED and not nic_ip:
9846
        raise errors.OpPrereqError("Routed nic mode requires an ip address",
9847
                                   errors.ECODE_INVAL)
9848

  
9849
      # MAC address verification
9850
      mac = nic.get(constants.INIC_MAC, constants.VALUE_AUTO)
9851
      if mac not in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
9852
        mac = utils.NormalizeAndValidateMac(mac)
9853

  
9854
        try:
9855
          self.cfg.ReserveMAC(mac, self.proc.GetECId())
9856
        except errors.ReservationError:
9857
          raise errors.OpPrereqError("MAC address %s already in use"
9858
                                     " in cluster" % mac,
9859
                                     errors.ECODE_NOTUNIQUE)
9860

  
9861
      #  Build nic parameters
9862
      link = nic.get(constants.INIC_LINK, None)
9863
      if link == constants.VALUE_AUTO:
9864
        link = cluster.nicparams[constants.PP_DEFAULT][constants.NIC_LINK]
9865
      nicparams = {}
9866
      if nic_mode_req:
9867
        nicparams[constants.NIC_MODE] = nic_mode
9868
      if link:
9869
        nicparams[constants.NIC_LINK] = link
9870

  
9871
      check_params = cluster.SimpleFillNIC(nicparams)
9872
      objects.NIC.CheckParameterSyntax(check_params)
9873
      self.nics.append(objects.NIC(mac=mac, ip=nic_ip, nicparams=nicparams))
9955
    self.nics = _ComputeNics(self.op, cluster, self.hostname1.ip, self.cfg,
9956
                             self.proc)
9874 9957

  
9875 9958
    # disk checks/pre-build
9876 9959
    default_vg = self.cfg.GetVGName()
9877
    self.disks = []
9878
    for disk in self.op.disks:
9879
      mode = disk.get(constants.IDISK_MODE, constants.DISK_RDWR)
9880
      if mode not in constants.DISK_ACCESS_SET:
9881
        raise errors.OpPrereqError("Invalid disk access mode '%s'" %
9882
                                   mode, errors.ECODE_INVAL)
9883
      size = disk.get(constants.IDISK_SIZE, None)
9884
      if size is None:
9885
        raise errors.OpPrereqError("Missing disk size", errors.ECODE_INVAL)
9886
      try:
9887
        size = int(size)
9888
      except (TypeError, ValueError):
9889
        raise errors.OpPrereqError("Invalid disk size '%s'" % size,
9890
                                   errors.ECODE_INVAL)
9891

  
9892
      data_vg = disk.get(constants.IDISK_VG, default_vg)
9893
      new_disk = {
9894
        constants.IDISK_SIZE: size,
9895
        constants.IDISK_MODE: mode,
9896
        constants.IDISK_VG: data_vg,
9897
        }
9898
      if constants.IDISK_METAVG in disk:
9899
        new_disk[constants.IDISK_METAVG] = disk[constants.IDISK_METAVG]
9900
      if constants.IDISK_ADOPT in disk:
9901
        new_disk[constants.IDISK_ADOPT] = disk[constants.IDISK_ADOPT]
9902
      self.disks.append(new_disk)
9960
    self.disks = _ComputeDisks(self.op, default_vg)
9903 9961

  
9904 9962
    if self.op.mode == constants.INSTANCE_IMPORT:
9905 9963
      disk_images = []

Also available in: Unified diff