Revision 7e9366f7 lib/cmdlib.py

b/lib/cmdlib.py
4255 4255
  _OP_REQP = ["instance_name", "mode", "disks"]
4256 4256
  REQ_BGL = False
4257 4257

  
4258
  def ExpandNames(self):
4259
    self._ExpandAndLockInstance()
4260

  
4258
  def CheckArguments(self):
4261 4259
    if not hasattr(self.op, "remote_node"):
4262 4260
      self.op.remote_node = None
4263

  
4264
    ia_name = getattr(self.op, "iallocator", None)
4265
    if ia_name is not None:
4266
      if self.op.remote_node is not None:
4261
    if not hasattr(self.op, "iallocator"):
4262
      self.op.iallocator = None
4263

  
4264
    # check for valid parameter combination
4265
    cnt = [self.op.remote_node, self.op.iallocator].count(None)
4266
    if self.op.mode == constants.REPLACE_DISK_CHG:
4267
      if cnt == 2:
4268
        raise errors.OpPrereqError("When changing the secondary either an"
4269
                                   " iallocator script must be used or the"
4270
                                   " new node given")
4271
      elif cnt == 0:
4267 4272
        raise errors.OpPrereqError("Give either the iallocator or the new"
4268 4273
                                   " secondary, not both")
4274
    else: # not replacing the secondary
4275
      if cnt != 2:
4276
        raise errors.OpPrereqError("The iallocator and new node options can"
4277
                                   " be used only when changing the"
4278
                                   " secondary node")
4279

  
4280
  def ExpandNames(self):
4281
    self._ExpandAndLockInstance()
4282

  
4283
    if self.op.iallocator is not None:
4269 4284
      self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
4270 4285
    elif self.op.remote_node is not None:
4271 4286
      remote_node = self.cfg.ExpandNodeName(self.op.remote_node)
......
4340 4355
      "Cannot retrieve locked instance %s" % self.op.instance_name
4341 4356
    self.instance = instance
4342 4357

  
4343
    if instance.disk_template not in constants.DTS_NET_MIRROR:
4344
      raise errors.OpPrereqError("Instance's disk layout is not"
4345
                                 " network mirrored.")
4358
    if instance.disk_template != constants.DT_DRBD8:
4359
      raise errors.OpPrereqError("Can only run replace disks for DRBD8-based"
4360
                                 " instances")
4346 4361

  
4347 4362
    if len(instance.secondary_nodes) != 1:
4348 4363
      raise errors.OpPrereqError("The instance has a strange layout,"
......
4351 4366

  
4352 4367
    self.sec_node = instance.secondary_nodes[0]
4353 4368

  
4354
    ia_name = getattr(self.op, "iallocator", None)
4355
    if ia_name is not None:
4369
    if self.op.iallocator is not None:
4356 4370
      self._RunAllocator()
4357 4371

  
4358 4372
    remote_node = self.op.remote_node
......
4366 4380
      raise errors.OpPrereqError("The specified node is the primary node of"
4367 4381
                                 " the instance.")
4368 4382
    elif remote_node == self.sec_node:
4369
      if self.op.mode == constants.REPLACE_DISK_SEC:
4370
        # this is for DRBD8, where we can't execute the same mode of
4371
        # replacement as for drbd7 (no different port allocated)
4372
        raise errors.OpPrereqError("Same secondary given, cannot execute"
4373
                                   " replacement")
4374
    if instance.disk_template == constants.DT_DRBD8:
4375
      if (self.op.mode == constants.REPLACE_DISK_ALL and
4376
          remote_node is not None):
4377
        # switch to replace secondary mode
4378
        self.op.mode = constants.REPLACE_DISK_SEC
4379

  
4380
      if self.op.mode == constants.REPLACE_DISK_ALL:
4381
        raise errors.OpPrereqError("Template 'drbd' only allows primary or"
4382
                                   " secondary disk replacement, not"
4383
                                   " both at once")
4384
      elif self.op.mode == constants.REPLACE_DISK_PRI:
4385
        if remote_node is not None:
4386
          raise errors.OpPrereqError("Template 'drbd' does not allow changing"
4387
                                     " the secondary while doing a primary"
4388
                                     " node disk replacement")
4389
        self.tgt_node = instance.primary_node
4390
        self.oth_node = instance.secondary_nodes[0]
4391
        _CheckNodeOnline(self, self.tgt_node)
4392
        _CheckNodeOnline(self, self.oth_node)
4393
      elif self.op.mode == constants.REPLACE_DISK_SEC:
4394
        self.new_node = remote_node # this can be None, in which case
4395
                                    # we don't change the secondary
4396
        self.tgt_node = instance.secondary_nodes[0]
4397
        self.oth_node = instance.primary_node
4398
        _CheckNodeOnline(self, self.oth_node)
4399
        if self.new_node is not None:
4400
          _CheckNodeOnline(self, self.new_node)
4401
        else:
4402
          _CheckNodeOnline(self, self.tgt_node)
4403
      else:
4404
        raise errors.ProgrammerError("Unhandled disk replace mode")
4383
      raise errors.OpPrereqError("The specified node is already the"
4384
                                 " secondary node of the instance.")
4385

  
4386
    if self.op.mode == constants.REPLACE_DISK_PRI:
4387
      n1 = self.tgt_node = instance.primary_node
4388
      n2 = self.oth_node = self.sec_node
4389
    elif self.op.mode == constants.REPLACE_DISK_SEC:
4390
      n1 = self.tgt_node = self.sec_node
4391
      n2 = self.oth_node = instance.primary_node
4392
    elif self.op.mode == constants.REPLACE_DISK_CHG:
4393
      n1 = self.new_node = remote_node
4394
      n2 = self.oth_node = instance.primary_node
4395
      self.tgt_node = self.sec_node
4396
    else:
4397
      raise errors.ProgrammerError("Unhandled disk replace mode")
4398

  
4399
    _CheckNodeOnline(self, n1)
4400
    _CheckNodeOnline(self, n2)
4405 4401

  
4406 4402
    if not self.op.disks:
4407 4403
      self.op.disks = range(len(instance.disks))
......
4793 4789
    if instance.status == "down":
4794 4790
      _StartInstanceDisks(self, instance, True)
4795 4791

  
4796
    if instance.disk_template == constants.DT_DRBD8:
4797
      if self.op.remote_node is None:
4798
        fn = self._ExecD8DiskOnly
4799
      else:
4800
        fn = self._ExecD8Secondary
4792
    if self.op.mode == constants.REPLACE_DISK_CHG:
4793
      fn = self._ExecD8Secondary
4801 4794
    else:
4802
      raise errors.ProgrammerError("Unhandled disk replacement case")
4795
      fn = self._ExecD8DiskOnly
4803 4796

  
4804 4797
    ret = fn(feedback_fn)
4805 4798

  

Also available in: Unified diff