Revision bd315bfa

b/lib/cmdlib.py
3626 3626
      _ShutdownInstanceDisks(self, inst)
3627 3627

  
3628 3628

  
3629
class LURecreateInstanceDisks(LogicalUnit):
3630
  """Recreate an instance's missing disks.
3631

  
3632
  """
3633
  HPATH = "instance-recreate-disks"
3634
  HTYPE = constants.HTYPE_INSTANCE
3635
  _OP_REQP = ["instance_name", "disks"]
3636
  REQ_BGL = False
3637

  
3638
  def CheckArguments(self):
3639
    """Check the arguments.
3640

  
3641
    """
3642
    if not isinstance(self.op.disks, list):
3643
      raise errors.OpPrereqError("Invalid disks parameter")
3644
    for item in self.op.disks:
3645
      if (not isinstance(item, int) or
3646
          item < 0):
3647
        raise errors.OpPrereqError("Invalid disk specification '%s'" %
3648
                                   str(item))
3649

  
3650
  def ExpandNames(self):
3651
    self._ExpandAndLockInstance()
3652

  
3653
  def BuildHooksEnv(self):
3654
    """Build hooks env.
3655

  
3656
    This runs on master, primary and secondary nodes of the instance.
3657

  
3658
    """
3659
    env = _BuildInstanceHookEnvByObject(self, self.instance)
3660
    nl = [self.cfg.GetMasterNode()] + list(self.instance.all_nodes)
3661
    return env, nl, nl
3662

  
3663
  def CheckPrereq(self):
3664
    """Check prerequisites.
3665

  
3666
    This checks that the instance is in the cluster and is not running.
3667

  
3668
    """
3669
    instance = self.cfg.GetInstanceInfo(self.op.instance_name)
3670
    assert instance is not None, \
3671
      "Cannot retrieve locked instance %s" % self.op.instance_name
3672
    _CheckNodeOnline(self, instance.primary_node)
3673

  
3674
    if instance.disk_template == constants.DT_DISKLESS:
3675
      raise errors.OpPrereqError("Instance '%s' has no disks" %
3676
                                 self.op.instance_name)
3677
    if instance.admin_up:
3678
      raise errors.OpPrereqError("Instance '%s' is marked to be up" %
3679
                                 self.op.instance_name)
3680
    remote_info = self.rpc.call_instance_info(instance.primary_node,
3681
                                              instance.name,
3682
                                              instance.hypervisor)
3683
    remote_info.Raise("Error checking node %s" % instance.primary_node,
3684
                      prereq=True)
3685
    if remote_info.payload:
3686
      raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
3687
                                 (self.op.instance_name,
3688
                                  instance.primary_node))
3689

  
3690
    if not self.op.disks:
3691
      self.op.disks = range(len(instance.disks))
3692
    else:
3693
      for idx in self.op.disks:
3694
        if idx >= len(instance.disks):
3695
          raise errors.OpPrereqError("Invalid disk index passed '%s'" % idx)
3696

  
3697
    self.instance = instance
3698

  
3699
  def Exec(self, feedback_fn):
3700
    """Recreate the disks.
3701

  
3702
    """
3703
    to_skip = []
3704
    for idx, disk in enumerate(self.instance.disks):
3705
      if idx not in self.op.disks: # disk idx has not been passed in
3706
        to_skip.append(idx)
3707
        continue
3708

  
3709
    _CreateDisks(self, self.instance, to_skip=to_skip)
3710

  
3711

  
3629 3712
class LURenameInstance(LogicalUnit):
3630 3713
  """Rename an instance.
3631 3714

  
......
4818 4901
  return "originstname+%s" % instance.name
4819 4902

  
4820 4903

  
4821
def _CreateDisks(lu, instance):
4904
def _CreateDisks(lu, instance, to_skip=None):
4822 4905
  """Create all disks for an instance.
4823 4906

  
4824 4907
  This abstracts away some work from AddInstance.
......
4827 4910
  @param lu: the logical unit on whose behalf we execute
4828 4911
  @type instance: L{objects.Instance}
4829 4912
  @param instance: the instance whose disks we should create
4913
  @type to_skip: list
4914
  @param to_skip: list of indices to skip
4830 4915
  @rtype: boolean
4831 4916
  @return: the success of the creation
4832 4917

  
......
4843 4928

  
4844 4929
  # Note: this needs to be kept in sync with adding of disks in
4845 4930
  # LUSetInstanceParams
4846
  for device in instance.disks:
4931
  for idx, device in enumerate(instance.disks):
4932
    if to_skip and idx in to_skip:
4933
      continue
4847 4934
    logging.info("Creating volume %s for instance %s",
4848 4935
                 device.iv_name, instance.name)
4849 4936
    #HARDCODE
b/lib/mcpu.py
74 74
    opcodes.OpRebootInstance: cmdlib.LURebootInstance,
75 75
    opcodes.OpDeactivateInstanceDisks: cmdlib.LUDeactivateInstanceDisks,
76 76
    opcodes.OpReplaceDisks: cmdlib.LUReplaceDisks,
77
    opcodes.OpRecreateInstanceDisks: cmdlib.LURecreateInstanceDisks,
77 78
    opcodes.OpFailoverInstance: cmdlib.LUFailoverInstance,
78 79
    opcodes.OpMigrateInstance: cmdlib.LUMigrateInstance,
79 80
    opcodes.OpConnectConsole: cmdlib.LUConnectConsole,
b/lib/opcodes.py
540 540
  __slots__ = OpCode.__slots__ + ["instance_name"]
541 541

  
542 542

  
543
class OpRecreateInstanceDisks(OpCode):
544
  """Deactivate an instance's disks."""
545
  OP_ID = "OP_INSTANCE_RECREATE_DISKS"
546
  OP_DSC_FIELD = "instance_name"
547
  __slots__ = OpCode.__slots__ + ["instance_name", "disks"]
548

  
549

  
543 550
class OpQueryInstances(OpCode):
544 551
  """Compute the list of instances."""
545 552
  OP_ID = "OP_INSTANCE_QUERY"
b/man/gnt-instance.sgml
1893 1893
        </para>
1894 1894
      </refsect3>
1895 1895

  
1896
      <refsect3>
1897
        <title>RECREATE-DISKS</title>
1898

  
1899
        <cmdsynopsis>
1900
          <command>recreate-disks</command>
1901
          <arg>--submit</arg>
1902
          <arg>--disks=<option>indices</option></arg>
1903
          <arg choice="req"><replaceable>instance</replaceable></arg>
1904
        </cmdsynopsis>
1905
        <para>
1906
          Recreates the disks of the given instance, or only a subset
1907
          of the disks (if the option <option>disks</option> is
1908
          passed, which must be a comma-separated list of disk
1909
          indices, starting from zero).
1910
        </para>
1911

  
1912
        <para>
1913
          The <option>--submit</option> option is used to send the job to
1914
          the master daemon but not wait for its completion. The job
1915
          ID will be shown so that it can be examined via
1916
          <command>gnt-job info</command>.
1917
        </para>
1918

  
1919
      </refsect3>
1920

  
1896 1921
    </refsect2>
1897 1922

  
1898 1923
    <refsect2>
b/scripts/gnt-instance
660 660

  
661 661

  
662 662
def DeactivateDisks(opts, args):
663
  """Deactivate an instance's disks..
663
  """Deactivate an instance's disks.
664 664

  
665 665
  This function takes the instance name, looks for its primary node
666 666
  and the tries to shutdown its block devices on that node.
......
678 678
  return 0
679 679

  
680 680

  
681
def RecreateDisks(opts, args):
682
  """Recreate an instance's disks.
683

  
684
  @param opts: the command line options selected by the user
685
  @type args: list
686
  @param args: should contain only one element, the instance name
687
  @rtype: int
688
  @return: the desired exit code
689

  
690
  """
691
  instance_name = args[0]
692
  if opts.disks:
693
    try:
694
      opts.disks = [int(v) for v in opts.disks.split(",")]
695
    except (ValueError, TypeError), err:
696
      ToStderr("Invalid disks value: %s" % str(err))
697
      return 1
698
  else:
699
    opts.disks = []
700

  
701
  op = opcodes.OpRecreateInstanceDisks(instance_name=instance_name,
702
                                       disks=opts.disks)
703
  SubmitOrSend(op, opts)
704
  return 0
705

  
706

  
681 707
def GrowDisk(opts, args):
682 708
  """Grow an instance's disks.
683 709

  
......
1553 1579
  'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT, SUBMIT_OPT],
1554 1580
                       "<instance>",
1555 1581
                       "Deactivate an instance's disks"),
1582
  'recreate-disks': (RecreateDisks, ARGS_ONE,
1583
                     [DEBUG_OPT, SUBMIT_OPT,
1584
                     make_option("--disks", dest="disks", default=None,
1585
                                 help="Comma-separated list of disks"
1586
                                 " indices to replace (e.g. 0,2) (optional,"
1587
                                 " defaults to all disks)"),
1588
                      ],
1589
                     "<instance>",
1590
                     "Recreate an instance's disks"),
1556 1591
  'grow-disk': (GrowDisk, ARGS_FIXED(3),
1557 1592
                [DEBUG_OPT, SUBMIT_OPT,
1558 1593
                 make_option("--no-wait-for-sync",

Also available in: Unified diff