def GenericInstanceCreate(mode, opts, args):
  """Add an instance to the cluster via either creation or import.

  @param mode: constants.INSTANCE_CREATE or constants.INSTANCE_IMPORT
  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the new instance name
  @rtype: int
  @return: the desired exit code

  """
  instance = args[0]
  forthcoming = opts.ensure_value("forthcoming", False)
  commit = opts.ensure_value("commit", False)

  if forthcoming and commit:
    raise errors.OpPrereqError("Creating an instance only forthcoming and"
                               " commiting it are mutally exclusive",
                               errors.ECODE_INVAL)

  (pnode, snode) = SplitNodeOption(opts.node)

  hypervisor = None
  hvparams = {}
  if opts.hypervisor:
    hypervisor, hvparams = opts.hypervisor

  if opts.nics:
    nics = ParseNicOption(opts.nics)
  elif opts.no_nics:
    # no nics
    nics = []
  elif mode == constants.INSTANCE_CREATE:
    # default of one nic, all auto
    nics = [{}]
  else:
    # mode == import
    nics = []

  if opts.disk_template == constants.DT_DISKLESS:
    if opts.disks or opts.sd_size is not None:
      raise errors.OpPrereqError("Diskless instance but disk"
                                 " information passed", errors.ECODE_INVAL)
    disks = []
  else:
    if (not opts.disks and not opts.sd_size
        and mode == constants.INSTANCE_CREATE):
      raise errors.OpPrereqError("No disk information specified",
                                 errors.ECODE_INVAL)
    if opts.disks and opts.sd_size is not None:
      raise errors.OpPrereqError("Please use either the '--disk' or"
                                 " '-s' option", errors.ECODE_INVAL)
    if opts.sd_size is not None:
      opts.disks = [(0, {constants.IDISK_SIZE: opts.sd_size})]

    if opts.disks:
      try:
        disk_max = max(int(didx[0]) + 1 for didx in opts.disks)
      except __HOLE__, err:
        raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err),
                                   errors.ECODE_INVAL)
      disks = [{}] * disk_max
    else:
      disks = []
    for didx, ddict in opts.disks:
      didx = int(didx)
      if not isinstance(ddict, dict):
        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
        raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
      elif constants.IDISK_SIZE in ddict:
        if constants.IDISK_ADOPT in ddict:
          raise errors.OpPrereqError("Only one of 'size' and 'adopt' allowed"
                                     " (disk %d)" % didx, errors.ECODE_INVAL)
        try:
          ddict[constants.IDISK_SIZE] = \
            utils.ParseUnit(ddict[constants.IDISK_SIZE])
        except ValueError, err:
          raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
                                     (didx, err), errors.ECODE_INVAL)
      elif constants.IDISK_ADOPT in ddict:
        if constants.IDISK_SPINDLES in ddict:
          raise errors.OpPrereqError("spindles is not a valid option when"
                                     " adopting a disk", errors.ECODE_INVAL)
        if mode == constants.INSTANCE_IMPORT:
          raise errors.OpPrereqError("Disk adoption not allowed for instance"
                                     " import", errors.ECODE_INVAL)
        ddict[constants.IDISK_SIZE] = 0
      else:
        raise errors.OpPrereqError("Missing size or adoption source for"
                                   " disk %d" % didx, errors.ECODE_INVAL)
      if constants.IDISK_SPINDLES in ddict:
        ddict[constants.IDISK_SPINDLES] = int(ddict[constants.IDISK_SPINDLES])

      disks[didx] = ddict

  if opts.tags is not None:
    tags = opts.tags.split(",")
  else:
    tags = []

  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_COMPAT)
  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
  FixHvParams(hvparams)

  osparams_private = opts.osparams_private or serializer.PrivateDict()
  osparams_secret = opts.osparams_secret or serializer.PrivateDict()

  helper_startup_timeout = opts.helper_startup_timeout
  helper_shutdown_timeout = opts.helper_shutdown_timeout

  if mode == constants.INSTANCE_CREATE:
    start = opts.start
    os_type = opts.os
    force_variant = opts.force_variant
    src_node = None
    src_path = None
    no_install = opts.no_install
    identify_defaults = False
    compress = constants.IEC_NONE
    if opts.instance_communication is None:
      instance_communication = False
    else:
      instance_communication = opts.instance_communication
  elif mode == constants.INSTANCE_IMPORT:
    if forthcoming:
      raise errors.OpPrereqError("forthcoming instances can only be created,"
                                 " not imported")
    start = False
    os_type = None
    force_variant = False
    src_node = opts.src_node
    src_path = opts.src_dir
    no_install = None
    identify_defaults = opts.identify_defaults
    compress = opts.compress
    instance_communication = False
  else:
    raise errors.ProgrammerError("Invalid creation mode %s" % mode)

  op = opcodes.OpInstanceCreate(
    forthcoming=forthcoming,
    commit=commit,
    instance_name=instance,
    disks=disks,
    disk_template=opts.disk_template,
    group_name=opts.nodegroup,
    nics=nics,
    conflicts_check=opts.conflicts_check,
    pnode=pnode, snode=snode,
    ip_check=opts.ip_check,
    name_check=opts.name_check,
    wait_for_sync=opts.wait_for_sync,
    file_storage_dir=opts.file_storage_dir,
    file_driver=opts.file_driver,
    iallocator=opts.iallocator,
    hypervisor=hypervisor,
    hvparams=hvparams,
    beparams=opts.beparams,
    osparams=opts.osparams,
    osparams_private=osparams_private,
    osparams_secret=osparams_secret,
    mode=mode,
    opportunistic_locking=opts.opportunistic_locking,
    start=start,
    os_type=os_type,
    force_variant=force_variant,
    src_node=src_node,
    src_path=src_path,
    compress=compress,
    tags=tags,
    no_install=no_install,
    identify_defaults=identify_defaults,
    ignore_ipolicy=opts.ignore_ipolicy,
    instance_communication=instance_communication,
    helper_startup_timeout=helper_startup_timeout,
    helper_shutdown_timeout=helper_shutdown_timeout)

  SubmitOrSend(op, opts)
  return 0
dataset/ETHPy150Open ganeti/ganeti/lib/cli.py/GenericInstanceCreate