Revision 538475ca lib/cmdlib.py

b/lib/cmdlib.py
3126 3126
  """
3127 3127
  HPATH = "instance-add"
3128 3128
  HTYPE = constants.HTYPE_INSTANCE
3129
  _OP_REQP = ["instance_name", "mem_size", "disk_size", "pnode",
3129
  _OP_REQP = ["instance_name", "mem_size", "disk_size",
3130 3130
              "disk_template", "swap_size", "mode", "start", "vcpus",
3131 3131
              "wait_for_sync", "ip_check", "mac"]
3132 3132

  
3133
  def _RunAllocator(self):
3134
    """Run the allocator based on input opcode.
3135

  
3136
    """
3137
    al_data = _IAllocatorGetClusterData(self.cfg, self.sstore)
3138
    disks = [{"size": self.op.disk_size, "mode": "w"},
3139
             {"size": self.op.swap_size, "mode": "w"}]
3140
    nics = [{"mac": self.op.mac, "ip": getattr(self.op, "ip", None),
3141
             "bridge": self.op.bridge}]
3142
    op = opcodes.OpTestAllocator(name=self.op.instance_name,
3143
                                 disk_template=self.op.disk_template,
3144
                                 tags=[],
3145
                                 os=self.op.os_type,
3146
                                 vcpus=self.op.vcpus,
3147
                                 mem_size=self.op.mem_size,
3148
                                 disks=disks,
3149
                                 nics=nics)
3150

  
3151
    _IAllocatorAddNewInstance(al_data, op)
3152

  
3153
    if _JSON_INDENT is None:
3154
      text = simplejson.dumps(al_data)
3155
    else:
3156
      text = simplejson.dumps(al_data, indent=_JSON_INDENT)
3157

  
3158
    result = _IAllocatorRun(self.op.iallocator, text)
3159

  
3160
    result = _IAllocatorValidateResult(result)
3161

  
3162
    if not result["success"]:
3163
      raise errors.OpPrereqError("Can't compute nodes using"
3164
                                 " iallocator '%s': %s" % (self.op.iallocator,
3165
                                                           result["info"]))
3166
    req_nodes = 1
3167
    if self.op.disk_template in constants.DTS_NET_MIRROR:
3168
      req_nodes += 1
3169

  
3170
    if len(result["nodes"]) != req_nodes:
3171
      raise errors.OpPrereqError("iallocator '%s' returned invalid number"
3172
                                 " of nodes (%s), required %s" %
3173
                                 (len(result["nodes"]), req_nodes))
3174
    self.op.pnode = result["nodes"][0]
3175
    logger.ToStdout("Selected nodes for the instance: %s" %
3176
                    (", ".join(result["nodes"]),))
3177
    logger.Info("Selected nodes for instance %s via iallocator %s: %s" %
3178
                (self.op.instance_name, self.op.iallocator, result["nodes"]))
3179
    if req_nodes == 2:
3180
      self.op.snode = result["nodes"][1]
3181

  
3133 3182
  def BuildHooksEnv(self):
3134 3183
    """Build hooks env.
3135 3184

  
......
3166 3215
    """Check prerequisites.
3167 3216

  
3168 3217
    """
3169
    for attr in ["kernel_path", "initrd_path", "hvm_boot_order"]:
3218
    # set optional parameters to none if they don't exist
3219
    for attr in ["kernel_path", "initrd_path", "hvm_boot_order", "pnode",
3220
                 "iallocator"]:
3170 3221
      if not hasattr(self.op, attr):
3171 3222
        setattr(self.op, attr, None)
3172 3223

  
......
3284 3335
    if self.op.file_storage_dir and os.path.isabs(self.op.file_storage_dir):
3285 3336
        raise errors.OpPrereqError("File storage directory not a relative"
3286 3337
                                   " path")
3338
    #### allocator run
3339

  
3340
    if [self.op.iallocator, self.op.pnode].count(None) != 1:
3341
      raise errors.OpPrereqError("One and only one of iallocator and primary"
3342
                                 " node must be given")
3343

  
3344
    if self.op.iallocator is not None:
3345
      self._RunAllocator()
3287 3346

  
3288 3347
    #### node related checks
3289 3348

  
......
4784 4843
  alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH,
4785 4844
                                os.path.isfile)
4786 4845
  if alloc_script is None:
4787
    raise errors.OpExecError("Can't find allocator")
4846
    raise errors.OpExecError("Can't find allocator '%s'" % name)
4788 4847

  
4789 4848
  fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.")
4790 4849
  try:
......
4800 4859
  return result.stdout
4801 4860

  
4802 4861

  
4862
def _IAllocatorValidateResult(data):
4863
  """Process the allocator results.
4864

  
4865
  """
4866
  try:
4867
    rdict = simplejson.loads(data)
4868
  except Exception, err:
4869
    raise errors.OpExecError("Can't parse iallocator results: %s" % str(err))
4870

  
4871
  if not isinstance(rdict, dict):
4872
    raise errors.OpExecError("Can't parse iallocator results: not a dict")
4873

  
4874
  for key in "success", "info", "nodes":
4875
    if key not in rdict:
4876
      raise errors.OpExecError("Can't parse iallocator results:"
4877
                               " missing key '%s'" % key)
4878

  
4879
  if not isinstance(rdict["nodes"], list):
4880
    raise errors.OpExecError("Can't parse iallocator results: 'nodes' key"
4881
                             " is not a list")
4882
  return rdict
4883

  
4884

  
4803 4885
class LUTestAllocator(NoHooksLU):
4804 4886
  """Run allocator tests.
4805 4887

  

Also available in: Unified diff