Revision 7bb60c2d

b/lib/cmdlib.py
9921 9921
                                   (self.op.iallocator, ial.info),
9922 9922
                                   errors.ECODE_NORES)
9923 9923

  
9924
      jobs = [[opcodes.OpCode.LoadOpCode(state) for state in jobset]
9925
              for jobset in ial.result]
9926

  
9927
      # Set "early_release" flag on opcodes where available
9928
      early_release = self.op.early_release
9929
      for op in itertools.chain(*jobs): # pylint: disable-msg=W0142
9930
        try:
9931
          op.early_release = early_release
9932
        except AttributeError:
9933
          assert not isinstance(op, opcodes.OpInstanceReplaceDisks)
9924
      jobs = _LoadNodeEvacResult(self, ial.result, self.op.early_release, True)
9934 9925

  
9935 9926
    elif self.op.remote_node is not None:
9936 9927
      assert self.op.mode == constants.IALLOCATOR_NEVAC_SEC
......
9949 9940
    return ResultWithJobs(jobs)
9950 9941

  
9951 9942

  
9943
def _SetOpEarlyRelease(early_release, op):
9944
  """Sets C{early_release} flag on opcodes if available.
9945

  
9946
  """
9947
  try:
9948
    op.early_release = early_release
9949
  except AttributeError:
9950
    assert not isinstance(op, opcodes.OpInstanceReplaceDisks)
9951

  
9952
  return op
9953

  
9954

  
9955
def _NodeEvacDest(use_nodes, group, nodes):
9956
  """Returns group or nodes depending on caller's choice.
9957

  
9958
  """
9959
  if use_nodes:
9960
    return utils.CommaJoin(nodes)
9961
  else:
9962
    return group
9963

  
9964

  
9965
def _LoadNodeEvacResult(lu, alloc_result, early_release, use_nodes):
9966
  """Unpacks the result of change-group and node-evacuate iallocator requests.
9967

  
9968
  Iallocator modes L{constants.IALLOCATOR_MODE_NODE_EVAC} and
9969
  L{constants.IALLOCATOR_MODE_CHG_GROUP}.
9970

  
9971
  @type lu: L{LogicalUnit}
9972
  @param lu: Logical unit instance
9973
  @type alloc_result: tuple/list
9974
  @param alloc_result: Result from iallocator
9975
  @type early_release: bool
9976
  @param early_release: Whether to release locks early if possible
9977
  @type use_nodes: bool
9978
  @param use_nodes: Whether to display node names instead of groups
9979

  
9980
  """
9981
  (moved, failed, jobs) = alloc_result
9982

  
9983
  if failed:
9984
    lu.LogWarning("Unable to evacuate instances %s",
9985
                  utils.CommaJoin("%s (%s)" % (name, reason)
9986
                                  for (name, reason) in failed))
9987

  
9988
  if moved:
9989
    lu.LogInfo("Instances to be moved: %s",
9990
               utils.CommaJoin("%s (to %s)" %
9991
                               (name, _NodeEvacDest(use_nodes, group, nodes))
9992
                               for (name, group, nodes) in moved))
9993

  
9994
  return [map(compat.partial(_SetOpEarlyRelease, early_release),
9995
              map(opcodes.OpCode.LoadOpCode, ops))
9996
          for ops in jobs]
9997

  
9998

  
9952 9999
class LUInstanceGrowDisk(LogicalUnit):
9953 10000
  """Grow a disk of an instance.
9954 10001

  
......
12531 12578
    self.in_text = serializer.Dump(self.in_data)
12532 12579

  
12533 12580
  _STRING_LIST = ht.TListOf(ht.TString)
12534
  _JOBSET_LIST = ht.TListOf(ht.TListOf(ht.TStrictDict(True, False, {
12581
  _JOB_LIST = ht.TListOf(ht.TListOf(ht.TStrictDict(True, False, {
12535 12582
     # pylint: disable-msg=E1101
12536 12583
     # Class '...' has no 'OP_ID' member
12537 12584
     "OP_ID": ht.TElemOf([opcodes.OpInstanceFailover.OP_ID,
12538 12585
                          opcodes.OpInstanceMigrate.OP_ID,
12539 12586
                          opcodes.OpInstanceReplaceDisks.OP_ID])
12540 12587
     })))
12588

  
12589
  _NEVAC_MOVED = \
12590
    ht.TListOf(ht.TAnd(ht.TIsLength(3),
12591
                       ht.TItems([ht.TNonEmptyString,
12592
                                  ht.TNonEmptyString,
12593
                                  ht.TListOf(ht.TNonEmptyString),
12594
                                 ])))
12595
  _NEVAC_FAILED = \
12596
    ht.TListOf(ht.TAnd(ht.TIsLength(2),
12597
                       ht.TItems([ht.TNonEmptyString,
12598
                                  ht.TMaybeString,
12599
                                 ])))
12600
  _NEVAC_RESULT = ht.TAnd(ht.TIsLength(3),
12601
                          ht.TItems([_NEVAC_MOVED, _NEVAC_FAILED, _JOB_LIST]))
12602

  
12541 12603
  _MODE_DATA = {
12542 12604
    constants.IALLOCATOR_MODE_ALLOC:
12543 12605
      (_AddNewInstance,
......
12563 12625
      (_AddNodeEvacuate, [
12564 12626
        ("instances", _STRING_LIST),
12565 12627
        ("evac_mode", ht.TElemOf(constants.IALLOCATOR_NEVAC_MODES)),
12566
        ], _JOBSET_LIST),
12628
        ], _NEVAC_RESULT),
12567 12629
     constants.IALLOCATOR_MODE_CHG_GROUP:
12568 12630
      (_AddChangeGroup, [
12569 12631
        ("instances", _STRING_LIST),
12570 12632
        ("target_groups", _STRING_LIST),
12571
        ], _JOBSET_LIST),
12633
        ], _NEVAC_RESULT),
12572 12634
    }
12573 12635

  
12574 12636
  def Run(self, name, validate=True, call_fn=None):

Also available in: Unified diff