Revision 07bd8a51

b/lib/cmdlib.py
944 944
    return int(bad)
945 945

  
946 946

  
947
class LURenameCluster(LogicalUnit):
948
  """Rename the cluster.
949

  
950
  """
951
  HPATH = "cluster-rename"
952
  HTYPE = constants.HTYPE_CLUSTER
953
  _OP_REQP = ["name"]
954

  
955
  def BuildHooksEnv(self):
956
    """Build hooks env.
957

  
958
    """
959
    env = {
960
      "NEW_NAME": self.op.name,
961
      }
962
    mn = self.sstore.GetMasterNode()
963
    return env, [mn], [mn]
964

  
965
  def CheckPrereq(self):
966
    """Verify that the passed name is a valid one.
967

  
968
    """
969
    hostname = utils.LookupHostname(self.op.name)
970
    if not hostname:
971
      raise errors.OpPrereqError("Cannot resolve the new cluster name ('%s')" %
972
                                 self.op.name)
973

  
974
    new_name = hostname["hostname"]
975
    self.ip = new_ip = hostname["ip"]
976
    old_name = self.sstore.GetClusterName()
977
    old_ip = self.sstore.GetMasterIP()
978
    if new_name == old_name and new_ip == old_ip:
979
      raise errors.OpPrereqError("Neither the name nor the IP address of the"
980
                                 " cluster has changed")
981
    if new_ip != old_ip:
982
      result = utils.RunCmd(["fping", "-q", new_ip])
983
      if not result.failed:
984
        raise errors.OpPrereqError("The given cluster IP address (%s) is"
985
                                   " reachable on the network. Aborting." %
986
                                   new_ip)
987

  
988
    self.op.name = new_name
989

  
990
  def Exec(self, feedback_fn):
991
    """Rename the cluster.
992

  
993
    """
994
    clustername = self.op.name
995
    ip = self.ip
996
    ss = self.sstore
997

  
998
    # shutdown the master IP
999
    master = ss.GetMasterNode()
1000
    if not rpc.call_node_stop_master(master):
1001
      raise errors.OpExecError("Could not disable the master role")
1002

  
1003
    try:
1004
      # modify the sstore
1005
      ss.SetKey(ss.SS_MASTER_IP, ip)
1006
      ss.SetKey(ss.SS_CLUSTER_NAME, clustername)
1007

  
1008
      # Distribute updated ss config to all nodes
1009
      myself = self.cfg.GetNodeInfo(master)
1010
      dist_nodes = self.cfg.GetNodeList()
1011
      if myself.name in dist_nodes:
1012
        dist_nodes.remove(myself.name)
1013

  
1014
      logger.Debug("Copying updated ssconf data to all nodes")
1015
      for keyname in [ss.SS_CLUSTER_NAME, ss.SS_MASTER_IP]:
1016
        fname = ss.KeyToFilename(keyname)
1017
        result = rpc.call_upload_file(dist_nodes, fname)
1018
        for to_node in dist_nodes:
1019
          if not result[to_node]:
1020
            logger.Error("copy of file %s to node %s failed" %
1021
                         (fname, to_node))
1022
    finally:
1023
      if not rpc.call_node_start_master(master):
1024
        logger.Error("Could not re-enable the master role on the master,\n"
1025
                     "please restart manually.")
1026

  
1027

  
947 1028
def _WaitForSync(cfgw, instance, oneshot=False, unlock=False):
948 1029
  """Sleep and poll for an instance's disk to sync.
949 1030

  
b/lib/mcpu.py
49 49
    opcodes.OpVerifyCluster: cmdlib.LUVerifyCluster,
50 50
    opcodes.OpMasterFailover: cmdlib.LUMasterFailover,
51 51
    opcodes.OpDumpClusterConfig: cmdlib.LUDumpClusterConfig,
52
    opcodes.OpRenameCluster: cmdlib.LURenameCluster,
52 53
    # node lu
53 54
    opcodes.OpAddNode: cmdlib.LUAddNode,
54 55
    opcodes.OpQueryNodes: cmdlib.LUQueryNodes,
b/lib/opcodes.py
98 98
  __slots__ = []
99 99

  
100 100

  
101
class OpRenameCluster(OpCode):
102
  """Rename the cluster."""
103
  OP_ID = "OP_CLUSTER_RENAME"
104
  __slots__ = ["name"]
105

  
106

  
107
# node opcodes
108

  
101 109
class OpRemoveNode(OpCode):
102 110
  """Remove a node."""
103 111
  OP_ID = "OP_NODE_REMOVE"
b/man/gnt-cluster.sgml
111 111
    </para>
112 112

  
113 113
    <cmdsynopsis>
114
      <command>destroy</command>
115
    </cmdsynopsis>
116

  
117
    <para>
118
      Remove all configuration files related to the cluster, so that a
119
      <command>gnt-cluster init</command> can be done again afterwards.
120
    </para>
121

  
122
    <cmdsynopsis>
114 123
      <command>getmaster</command>
115 124
    </cmdsynopsis>
116 125

  
......
178 187
    </para>
179 188

  
180 189
    <cmdsynopsis>
181
      <command>destroy</command>
190
      <command>rename</command>
191
      <arg>-f</arg>
192
      <arg choice="req"><replaceable>name</replaceable></arg>
182 193
    </cmdsynopsis>
183 194

  
184 195
    <para>
185
      Remove all configuration files related to the cluster, so that a
186
      <command>gnt-cluster init</command> can be done again afterwards.
196
      Renames the cluster and in the process updates the master IP
197
      address to the one the new name resolves to. At least one of
198
      either the name or the IP address must be different, otherwise
199
      the operation will be aborted.
200
    </para>
201

  
202
    <para>
203
      Note that since this command can be dangerous (especially when
204
      run over SSH), the command will require confirmation unless run
205
      with the <option>-f</option> option.
187 206
    </para>
188 207

  
189 208
    <cmdsynopsis>
b/scripts/gnt-cluster
64 64
  return 0
65 65

  
66 66

  
67
def RenameCluster(opts, args):
68
  """Rename the cluster.
69

  
70
  Args:
71
    opts - class with options as members, we use force only
72
    args - list of arguments, expected to be [new_name]
73

  
74
  """
75
  name = args[0]
76
  if not opts.force:
77
    usertext = ("This will rename the cluster to '%s'. If you are connected"
78
                " over the network to the cluster name, the operation is very"
79
                " dangerous as the IP address will be removed from the node"
80
                " and the change may not go through. Continue?") % name
81
    if not opts._ask_user(usertext):
82
      return 1
83

  
84
  op = opcodes.OpRenameCluster(name=name)
85
  SubmitOpCode(op)
86
  return 0
87

  
88

  
67 89
def ShowClusterVersion(opts, args):
68 90
  """Write version of ganeti software to the standard output.
69 91

  
......
222 244
                           action="store_true"),
223 245
              ],
224 246
              "", "Destroy cluster"),
247
  'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
248
               "<new_name>",
249
               "Renames the cluster"),
225 250
  'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT],
226 251
             "", "Does a check on the cluster configuration"),
227 252
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT],

Also available in: Unified diff