Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ ea3a925f

History | View | Annotate | Download (19.8 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
import sys
23 a8083063 Iustin Pop
from optparse import make_option
24 a8083063 Iustin Pop
import pprint
25 b3989551 Iustin Pop
import os.path
26 a8083063 Iustin Pop
27 a8083063 Iustin Pop
from ganeti.cli import *
28 a8083063 Iustin Pop
from ganeti import opcodes
29 c2a62a33 Michael Hanselmann
from ganeti import constants
30 f4d4e184 Iustin Pop
from ganeti import errors
31 b63ed789 Iustin Pop
from ganeti import utils
32 a0c9f010 Michael Hanselmann
from ganeti import bootstrap
33 b3989551 Iustin Pop
from ganeti import ssh
34 b3989551 Iustin Pop
from ganeti import ssconf
35 a8083063 Iustin Pop
36 a8083063 Iustin Pop
37 a8083063 Iustin Pop
def InitCluster(opts, args):
38 a8083063 Iustin Pop
  """Initialize the cluster.
39 a8083063 Iustin Pop
40 a8083063 Iustin Pop
  Args:
41 a8083063 Iustin Pop
    opts - class with options as members
42 a8083063 Iustin Pop
    args - list of arguments, expected to be [clustername]
43 a8083063 Iustin Pop
44 a8083063 Iustin Pop
  """
45 90b6aa3a Manuel Franceschini
  if not opts.lvm_storage and opts.vg_name:
46 90b6aa3a Manuel Franceschini
    print ("Options --no-lvm-storage and --vg-name conflict.")
47 90b6aa3a Manuel Franceschini
    return 1
48 90b6aa3a Manuel Franceschini
49 90b6aa3a Manuel Franceschini
  vg_name = opts.vg_name
50 90b6aa3a Manuel Franceschini
  if opts.lvm_storage and not opts.vg_name:
51 90b6aa3a Manuel Franceschini
    vg_name = constants.DEFAULT_VG
52 90b6aa3a Manuel Franceschini
53 ea3a925f Alexander Schreiber
  hvlist = opts.enabled_hypervisors
54 ea3a925f Alexander Schreiber
  if hvlist is not None:
55 ea3a925f Alexander Schreiber
    hvlist = hvlist.split(",")
56 ea3a925f Alexander Schreiber
  else:
57 ea3a925f Alexander Schreiber
    hvlist = constants.DEFAULT_ENABLED_HYPERVISOR
58 ea3a925f Alexander Schreiber
59 ea3a925f Alexander Schreiber
  hvparams = opts.hvparams
60 ea3a925f Alexander Schreiber
  if hvparams:
61 ea3a925f Alexander Schreiber
    # a list of (name, dict) we can pass directly to dict()
62 ea3a925f Alexander Schreiber
    hvparams = dict(opts.hvparams)
63 ea3a925f Alexander Schreiber
  else:
64 ea3a925f Alexander Schreiber
    # otherwise init as empty dict
65 ea3a925f Alexander Schreiber
    hvparams = {}
66 ea3a925f Alexander Schreiber
67 ea3a925f Alexander Schreiber
  beparams = opts.beparams
68 ea3a925f Alexander Schreiber
  # check for invalid parameters
69 ea3a925f Alexander Schreiber
  for parameter in beparams:
70 ea3a925f Alexander Schreiber
    if parameter not in constants.BES_PARAMETERS:
71 ea3a925f Alexander Schreiber
      print "Invalid backend parameter: %s" % parameter
72 ea3a925f Alexander Schreiber
      return 1
73 ea3a925f Alexander Schreiber
74 ea3a925f Alexander Schreiber
  # prepare beparams dict
75 ea3a925f Alexander Schreiber
  for parameter in constants.BES_PARAMETERS:
76 ea3a925f Alexander Schreiber
    if parameter not in beparams:
77 ea3a925f Alexander Schreiber
      beparams[parameter] = constants.BEC_DEFAULTS[parameter]
78 ea3a925f Alexander Schreiber
79 ea3a925f Alexander Schreiber
  # type wrangling
80 ea3a925f Alexander Schreiber
  try:
81 ea3a925f Alexander Schreiber
    beparams[constants.BE_VCPUS] = int(beparams[constants.BE_VCPUS])
82 ea3a925f Alexander Schreiber
  except ValueError:
83 ea3a925f Alexander Schreiber
    print "%s must be an integer" % constants.BE_VCPUS
84 ea3a925f Alexander Schreiber
    return 1
85 ea3a925f Alexander Schreiber
86 ea3a925f Alexander Schreiber
  beparams[constants.BE_MEMORY] = utils.ParseUnit(beparams[constants.BE_MEMORY])
87 ea3a925f Alexander Schreiber
88 ea3a925f Alexander Schreiber
  # prepare hvparams dict
89 ea3a925f Alexander Schreiber
  for hv in constants.HYPER_TYPES:
90 ea3a925f Alexander Schreiber
    if hv not in hvparams:
91 ea3a925f Alexander Schreiber
      hvparams[hv] = {}
92 ea3a925f Alexander Schreiber
    for parameter in constants.HVC_DEFAULTS[hv]:
93 ea3a925f Alexander Schreiber
      if parameter not in hvparams[hv]:
94 ea3a925f Alexander Schreiber
        hvparams[hv][parameter] = constants.HVC_DEFAULTS[hv][parameter]
95 ea3a925f Alexander Schreiber
96 ea3a925f Alexander Schreiber
  for hv in hvlist:
97 ea3a925f Alexander Schreiber
    if hv not in constants.HYPER_TYPES:
98 ea3a925f Alexander Schreiber
      print "invalid hypervisor: %s" % hv
99 ea3a925f Alexander Schreiber
      return 1
100 ea3a925f Alexander Schreiber
101 a0c9f010 Michael Hanselmann
  bootstrap.InitCluster(cluster_name=args[0],
102 a0c9f010 Michael Hanselmann
                        secondary_ip=opts.secondary_ip,
103 a0c9f010 Michael Hanselmann
                        hypervisor_type=opts.hypervisor_type,
104 a0c9f010 Michael Hanselmann
                        vg_name=vg_name,
105 a0c9f010 Michael Hanselmann
                        mac_prefix=opts.mac_prefix,
106 a0c9f010 Michael Hanselmann
                        def_bridge=opts.def_bridge,
107 a0c9f010 Michael Hanselmann
                        master_netdev=opts.master_netdev,
108 ea3a925f Alexander Schreiber
                        file_storage_dir=opts.file_storage_dir,
109 ea3a925f Alexander Schreiber
                        enabled_hypervisors=hvlist,
110 ea3a925f Alexander Schreiber
                        hvparams=hvparams,
111 ea3a925f Alexander Schreiber
                        beparams=beparams)
112 a8083063 Iustin Pop
  return 0
113 a8083063 Iustin Pop
114 a8083063 Iustin Pop
115 a8083063 Iustin Pop
def DestroyCluster(opts, args):
116 a8083063 Iustin Pop
  """Destroy the cluster.
117 a8083063 Iustin Pop
118 a8083063 Iustin Pop
  Args:
119 a8083063 Iustin Pop
    opts - class with options as members
120 098c0958 Michael Hanselmann
121 a8083063 Iustin Pop
  """
122 a8083063 Iustin Pop
  if not opts.yes_do_it:
123 a8083063 Iustin Pop
    print ("Destroying a cluster is irreversibly. If you really want destroy"
124 79f7be7b Iustin Pop
           " this cluster, supply the --yes-do-it option.")
125 a8083063 Iustin Pop
    return 1
126 a8083063 Iustin Pop
127 a8083063 Iustin Pop
  op = opcodes.OpDestroyCluster()
128 140aa4a8 Iustin Pop
  master = SubmitOpCode(op)
129 140aa4a8 Iustin Pop
  # if we reached this, the opcode didn't fail; we can proceed to
130 140aa4a8 Iustin Pop
  # shutdown all the daemons
131 140aa4a8 Iustin Pop
  bootstrap.FinalizeClusterDestroy(master)
132 a8083063 Iustin Pop
  return 0
133 a8083063 Iustin Pop
134 a8083063 Iustin Pop
135 07bd8a51 Iustin Pop
def RenameCluster(opts, args):
136 07bd8a51 Iustin Pop
  """Rename the cluster.
137 07bd8a51 Iustin Pop
138 07bd8a51 Iustin Pop
  Args:
139 07bd8a51 Iustin Pop
    opts - class with options as members, we use force only
140 07bd8a51 Iustin Pop
    args - list of arguments, expected to be [new_name]
141 07bd8a51 Iustin Pop
142 07bd8a51 Iustin Pop
  """
143 07bd8a51 Iustin Pop
  name = args[0]
144 07bd8a51 Iustin Pop
  if not opts.force:
145 07bd8a51 Iustin Pop
    usertext = ("This will rename the cluster to '%s'. If you are connected"
146 07bd8a51 Iustin Pop
                " over the network to the cluster name, the operation is very"
147 07bd8a51 Iustin Pop
                " dangerous as the IP address will be removed from the node"
148 07bd8a51 Iustin Pop
                " and the change may not go through. Continue?") % name
149 47988778 Iustin Pop
    if not AskUser(usertext):
150 07bd8a51 Iustin Pop
      return 1
151 07bd8a51 Iustin Pop
152 07bd8a51 Iustin Pop
  op = opcodes.OpRenameCluster(name=name)
153 07bd8a51 Iustin Pop
  SubmitOpCode(op)
154 07bd8a51 Iustin Pop
  return 0
155 07bd8a51 Iustin Pop
156 07bd8a51 Iustin Pop
157 a8083063 Iustin Pop
def ShowClusterVersion(opts, args):
158 a8083063 Iustin Pop
  """Write version of ganeti software to the standard output.
159 a8083063 Iustin Pop
160 a8083063 Iustin Pop
  Args:
161 a8083063 Iustin Pop
    opts - class with options as members
162 a8083063 Iustin Pop
163 a8083063 Iustin Pop
  """
164 a8083063 Iustin Pop
  op = opcodes.OpQueryClusterInfo()
165 a8083063 Iustin Pop
  result = SubmitOpCode(op)
166 a8083063 Iustin Pop
  print ("Software version: %s" % result["software_version"])
167 a8083063 Iustin Pop
  print ("Internode protocol: %s" % result["protocol_version"])
168 a8083063 Iustin Pop
  print ("Configuration format: %s" % result["config_version"])
169 a8083063 Iustin Pop
  print ("OS api version: %s" % result["os_api_version"])
170 a8083063 Iustin Pop
  print ("Export interface: %s" % result["export_version"])
171 a8083063 Iustin Pop
  return 0
172 a8083063 Iustin Pop
173 a8083063 Iustin Pop
174 a8083063 Iustin Pop
def ShowClusterMaster(opts, args):
175 a8083063 Iustin Pop
  """Write name of master node to the standard output.
176 a8083063 Iustin Pop
177 a8083063 Iustin Pop
  Args:
178 a8083063 Iustin Pop
    opts - class with options as members
179 a8083063 Iustin Pop
180 a8083063 Iustin Pop
  """
181 e00ea635 Michael Hanselmann
  print GetClient().QueryConfigValues(["master_node"])[0]
182 a8083063 Iustin Pop
  return 0
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
185 a8083063 Iustin Pop
def ShowClusterConfig(opts, args):
186 a8083063 Iustin Pop
  """Shows cluster information.
187 a8083063 Iustin Pop
188 a8083063 Iustin Pop
  """
189 a8083063 Iustin Pop
  op = opcodes.OpQueryClusterInfo()
190 a8083063 Iustin Pop
  result = SubmitOpCode(op)
191 a8083063 Iustin Pop
192 a8083063 Iustin Pop
  print ("Cluster name: %s" % result["name"])
193 a8083063 Iustin Pop
194 a8083063 Iustin Pop
  print ("Master node: %s" % result["master"])
195 a8083063 Iustin Pop
196 59322403 Iustin Pop
  print ("Architecture (this node): %s (%s)" %
197 59322403 Iustin Pop
         (result["architecture"][0], result["architecture"][1]))
198 a8083063 Iustin Pop
199 469f88e1 Iustin Pop
  print ("Default hypervisor: %s" % result["hypervisor_type"])
200 469f88e1 Iustin Pop
  print ("Enabled hypervisors: %s" % ", ".join(result["enabled_hypervisors"]))
201 469f88e1 Iustin Pop
202 469f88e1 Iustin Pop
  print "Hypervisor parameters:"
203 469f88e1 Iustin Pop
  for hv_name, hv_dict in result["hvparams"].items():
204 469f88e1 Iustin Pop
    print "  - %s:" % hv_name
205 469f88e1 Iustin Pop
    for item, val in hv_dict.iteritems():
206 469f88e1 Iustin Pop
      print "      %s: %s" % (item, val)
207 469f88e1 Iustin Pop
208 469f88e1 Iustin Pop
  print "Cluster parameters:"
209 469f88e1 Iustin Pop
  for gr_name, gr_dict in result["beparams"].items():
210 469f88e1 Iustin Pop
    print "  - %s:" % gr_name
211 469f88e1 Iustin Pop
    for item, val in gr_dict.iteritems():
212 469f88e1 Iustin Pop
      print "      %s: %s" % (item, val)
213 8a12ce45 Iustin Pop
214 a8083063 Iustin Pop
  return 0
215 a8083063 Iustin Pop
216 a8083063 Iustin Pop
217 a8083063 Iustin Pop
def ClusterCopyFile(opts, args):
218 a8083063 Iustin Pop
  """Copy a file from master to some nodes.
219 a8083063 Iustin Pop
220 a8083063 Iustin Pop
  Args:
221 a8083063 Iustin Pop
    opts - class with options as members
222 a8083063 Iustin Pop
    args - list containing a single element, the file name
223 a8083063 Iustin Pop
  Opts used:
224 a8083063 Iustin Pop
    nodes - list containing the name of target nodes; if empty, all nodes
225 a8083063 Iustin Pop
226 a8083063 Iustin Pop
  """
227 b3989551 Iustin Pop
  filename = args[0]
228 b3989551 Iustin Pop
  if not os.path.exists(filename):
229 b3989551 Iustin Pop
    raise errors.OpPrereqError("No such filename '%s'" % filename)
230 b3989551 Iustin Pop
231 56bece1f Iustin Pop
  cl = GetClient()
232 56bece1f Iustin Pop
233 b3989551 Iustin Pop
  myname = utils.HostInfo().name
234 b3989551 Iustin Pop
235 56bece1f Iustin Pop
  cluster_name = cl.QueryConfigValues(["cluster_name"])[0]
236 56bece1f Iustin Pop
237 b3989551 Iustin Pop
  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
238 56bece1f Iustin Pop
  results = [row[0] for row in SubmitOpCode(op, cl=cl) if row[0] != myname]
239 e00ea635 Michael Hanselmann
240 56bece1f Iustin Pop
  srun = ssh.SshRunner(cluster_name=cluster_name)
241 b3989551 Iustin Pop
  for node in results:
242 b3989551 Iustin Pop
    if not srun.CopyFileToNode(node, filename):
243 b3989551 Iustin Pop
      print >> sys.stderr, ("Copy of file %s to node %s failed" %
244 b3989551 Iustin Pop
                            (filename, node))
245 b3989551 Iustin Pop
246 a8083063 Iustin Pop
  return 0
247 a8083063 Iustin Pop
248 a8083063 Iustin Pop
249 a8083063 Iustin Pop
def RunClusterCommand(opts, args):
250 a8083063 Iustin Pop
  """Run a command on some nodes.
251 a8083063 Iustin Pop
252 a8083063 Iustin Pop
  Args:
253 a8083063 Iustin Pop
    opts - class with options as members
254 a8083063 Iustin Pop
    args - the command list as a list
255 a8083063 Iustin Pop
  Opts used:
256 a8083063 Iustin Pop
    nodes: list containing the name of target nodes; if empty, all nodes
257 a8083063 Iustin Pop
258 a8083063 Iustin Pop
  """
259 56bece1f Iustin Pop
  cl = GetClient()
260 7688d0d3 Michael Hanselmann
261 a8083063 Iustin Pop
  command = " ".join(args)
262 b3989551 Iustin Pop
  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
263 56bece1f Iustin Pop
  nodes = [row[0] for row in SubmitOpCode(op, cl=cl)]
264 56bece1f Iustin Pop
265 56bece1f Iustin Pop
  cluster_name, master_node = cl.QueryConfigValues(["cluster_name",
266 56bece1f Iustin Pop
                                                    "master_node"])
267 b3989551 Iustin Pop
268 56bece1f Iustin Pop
  srun = ssh.SshRunner(cluster_name=cluster_name)
269 b3989551 Iustin Pop
270 7688d0d3 Michael Hanselmann
  # Make sure master node is at list end
271 b3989551 Iustin Pop
  if master_node in nodes:
272 b3989551 Iustin Pop
    nodes.remove(master_node)
273 b3989551 Iustin Pop
    nodes.append(master_node)
274 b3989551 Iustin Pop
275 b3989551 Iustin Pop
  for name in nodes:
276 b3989551 Iustin Pop
    result = srun.Run(name, "root", command)
277 a8083063 Iustin Pop
    print ("------------------------------------------------")
278 b3989551 Iustin Pop
    print ("node: %s" % name)
279 b3989551 Iustin Pop
    print ("%s" % result.output)
280 b3989551 Iustin Pop
    print ("return code = %s" % result.exit_code)
281 b3989551 Iustin Pop
282 b3989551 Iustin Pop
  return 0
283 a8083063 Iustin Pop
284 a8083063 Iustin Pop
285 a8083063 Iustin Pop
def VerifyCluster(opts, args):
286 a8083063 Iustin Pop
  """Verify integrity of cluster, performing various test on nodes.
287 a8083063 Iustin Pop
288 a8083063 Iustin Pop
  Args:
289 a8083063 Iustin Pop
    opts - class with options as members
290 a8083063 Iustin Pop
291 a8083063 Iustin Pop
  """
292 8d59409f Iustin Pop
  skip_checks = []
293 e54c4c5e Guido Trotter
  if opts.skip_nplusone_mem:
294 e54c4c5e Guido Trotter
    skip_checks.append(constants.VERIFY_NPLUSONE_MEM)
295 e54c4c5e Guido Trotter
  op = opcodes.OpVerifyCluster(skip_checks=skip_checks)
296 34290825 Michael Hanselmann
  if SubmitOpCode(op):
297 34290825 Michael Hanselmann
    return 0
298 34290825 Michael Hanselmann
  else:
299 34290825 Michael Hanselmann
    return 1
300 a8083063 Iustin Pop
301 a8083063 Iustin Pop
302 f4d4e184 Iustin Pop
def VerifyDisks(opts, args):
303 f4d4e184 Iustin Pop
  """Verify integrity of cluster disks.
304 f4d4e184 Iustin Pop
305 f4d4e184 Iustin Pop
  Args:
306 f4d4e184 Iustin Pop
    opts - class with options as members
307 f4d4e184 Iustin Pop
308 f4d4e184 Iustin Pop
  """
309 f4d4e184 Iustin Pop
  op = opcodes.OpVerifyDisks()
310 f4d4e184 Iustin Pop
  result = SubmitOpCode(op)
311 dcde0241 Guido Trotter
  if not isinstance(result, (list, tuple)) or len(result) != 4:
312 f4d4e184 Iustin Pop
    raise errors.ProgrammerError("Unknown result type for OpVerifyDisks")
313 f4d4e184 Iustin Pop
314 b63ed789 Iustin Pop
  nodes, nlvm, instances, missing = result
315 b63ed789 Iustin Pop
316 f4d4e184 Iustin Pop
  if nodes:
317 f4d4e184 Iustin Pop
    print "Nodes unreachable or with bad data:"
318 f4d4e184 Iustin Pop
    for name in nodes:
319 f4d4e184 Iustin Pop
      print "\t%s" % name
320 f4d4e184 Iustin Pop
  retcode = constants.EXIT_SUCCESS
321 b63ed789 Iustin Pop
322 b63ed789 Iustin Pop
  if nlvm:
323 b63ed789 Iustin Pop
    for node, text in nlvm.iteritems():
324 b63ed789 Iustin Pop
      print ("Error on node %s: LVM error: %s" %
325 b63ed789 Iustin Pop
             (node, text[-400:].encode('string_escape')))
326 b63ed789 Iustin Pop
      retcode |= 1
327 b63ed789 Iustin Pop
      print "You need to fix these nodes first before fixing instances"
328 b63ed789 Iustin Pop
329 f4d4e184 Iustin Pop
  if instances:
330 f4d4e184 Iustin Pop
    for iname in instances:
331 b63ed789 Iustin Pop
      if iname in missing:
332 b63ed789 Iustin Pop
        continue
333 f4d4e184 Iustin Pop
      op = opcodes.OpActivateInstanceDisks(instance_name=iname)
334 f4d4e184 Iustin Pop
      try:
335 f4d4e184 Iustin Pop
        print "Activating disks for instance '%s'" % iname
336 f4d4e184 Iustin Pop
        SubmitOpCode(op)
337 f4d4e184 Iustin Pop
      except errors.GenericError, err:
338 f4d4e184 Iustin Pop
        nret, msg = FormatError(err)
339 f4d4e184 Iustin Pop
        retcode |= nret
340 b63ed789 Iustin Pop
        print >> sys.stderr, ("Error activating disks for instance %s: %s" %
341 b63ed789 Iustin Pop
                              (iname, msg))
342 b63ed789 Iustin Pop
343 b63ed789 Iustin Pop
  if missing:
344 b63ed789 Iustin Pop
    for iname, ival in missing.iteritems():
345 b63ed789 Iustin Pop
      all_missing = utils.all(ival, lambda x: x[0] in nlvm)
346 b63ed789 Iustin Pop
      if all_missing:
347 b63ed789 Iustin Pop
        print ("Instance %s cannot be verified as it lives on"
348 b63ed789 Iustin Pop
               " broken nodes" % iname)
349 b63ed789 Iustin Pop
      else:
350 b63ed789 Iustin Pop
        print "Instance %s has missing logical volumes:" % iname
351 b63ed789 Iustin Pop
        ival.sort()
352 b63ed789 Iustin Pop
        for node, vol in ival:
353 b63ed789 Iustin Pop
          if node in nlvm:
354 b63ed789 Iustin Pop
            print ("\tbroken node %s /dev/xenvg/%s" % (node, vol))
355 b63ed789 Iustin Pop
          else:
356 b63ed789 Iustin Pop
            print ("\t%s /dev/xenvg/%s" % (node, vol))
357 b63ed789 Iustin Pop
    print ("You need to run replace_disks for all the above"
358 b63ed789 Iustin Pop
           " instances, if this message persist after fixing nodes.")
359 b63ed789 Iustin Pop
    retcode |= 1
360 f4d4e184 Iustin Pop
361 f4d4e184 Iustin Pop
  return retcode
362 f4d4e184 Iustin Pop
363 f4d4e184 Iustin Pop
364 a8083063 Iustin Pop
def MasterFailover(opts, args):
365 a8083063 Iustin Pop
  """Failover the master node.
366 a8083063 Iustin Pop
367 a8083063 Iustin Pop
  This command, when run on a non-master node, will cause the current
368 a8083063 Iustin Pop
  master to cease being master, and the non-master to become new
369 a8083063 Iustin Pop
  master.
370 a8083063 Iustin Pop
371 a8083063 Iustin Pop
  """
372 b1b6ea87 Iustin Pop
  return bootstrap.MasterFailover()
373 a8083063 Iustin Pop
374 a8083063 Iustin Pop
375 73415719 Iustin Pop
def SearchTags(opts, args):
376 73415719 Iustin Pop
  """Searches the tags on all the cluster.
377 73415719 Iustin Pop
378 73415719 Iustin Pop
  """
379 73415719 Iustin Pop
  op = opcodes.OpSearchTags(pattern=args[0])
380 73415719 Iustin Pop
  result = SubmitOpCode(op)
381 73415719 Iustin Pop
  if not result:
382 73415719 Iustin Pop
    return 1
383 73415719 Iustin Pop
  result = list(result)
384 73415719 Iustin Pop
  result.sort()
385 73415719 Iustin Pop
  for path, tag in result:
386 73415719 Iustin Pop
    print "%s %s" % (path, tag)
387 73415719 Iustin Pop
388 73415719 Iustin Pop
389 90b6aa3a Manuel Franceschini
def SetClusterParams(opts, args):
390 90b6aa3a Manuel Franceschini
  """Modify the cluster.
391 90b6aa3a Manuel Franceschini
392 90b6aa3a Manuel Franceschini
  Args:
393 90b6aa3a Manuel Franceschini
    opts - class with options as members
394 90b6aa3a Manuel Franceschini
395 90b6aa3a Manuel Franceschini
  """
396 779c15bb Iustin Pop
  if not (not opts.lvm_storage or opts.vg_name or
397 779c15bb Iustin Pop
          opts.enabled_hypervisors or opts.hvparams or
398 779c15bb Iustin Pop
          opts.beparams):
399 90b6aa3a Manuel Franceschini
    print "Please give at least one of the parameters."
400 90b6aa3a Manuel Franceschini
    return 1
401 90b6aa3a Manuel Franceschini
402 90b6aa3a Manuel Franceschini
  vg_name = opts.vg_name
403 90b6aa3a Manuel Franceschini
  if not opts.lvm_storage and opts.vg_name:
404 90b6aa3a Manuel Franceschini
    print ("Options --no-lvm-storage and --vg-name conflict.")
405 90b6aa3a Manuel Franceschini
    return 1
406 90b6aa3a Manuel Franceschini
407 779c15bb Iustin Pop
  hvlist = opts.enabled_hypervisors
408 779c15bb Iustin Pop
  if hvlist is not None:
409 779c15bb Iustin Pop
    hvlist = hvlist.split(",")
410 779c15bb Iustin Pop
411 779c15bb Iustin Pop
  hvparams = opts.hvparams
412 779c15bb Iustin Pop
  if hvparams:
413 779c15bb Iustin Pop
    # a list of (name, dict) we can pass directly to dict()
414 779c15bb Iustin Pop
    hvparams = dict(opts.hvparams)
415 779c15bb Iustin Pop
416 779c15bb Iustin Pop
  beparams = opts.beparams
417 779c15bb Iustin Pop
418 779c15bb Iustin Pop
  op = opcodes.OpSetClusterParams(vg_name=opts.vg_name,
419 779c15bb Iustin Pop
                                  enabled_hypervisors=hvlist,
420 779c15bb Iustin Pop
                                  hvparams=hvparams,
421 779c15bb Iustin Pop
                                  beparams=beparams)
422 90b6aa3a Manuel Franceschini
  SubmitOpCode(op)
423 90b6aa3a Manuel Franceschini
  return 0
424 90b6aa3a Manuel Franceschini
425 90b6aa3a Manuel Franceschini
426 3ccafd0e Iustin Pop
def QueueOps(opts, args):
427 3ccafd0e Iustin Pop
  """Queue operations.
428 3ccafd0e Iustin Pop
429 3ccafd0e Iustin Pop
  """
430 3ccafd0e Iustin Pop
  command = args[0]
431 3ccafd0e Iustin Pop
  client = GetClient()
432 3ccafd0e Iustin Pop
  if command in ("drain", "undrain"):
433 3ccafd0e Iustin Pop
    drain_flag = command == "drain"
434 3ccafd0e Iustin Pop
    client.SetQueueDrainFlag(drain_flag)
435 3ccafd0e Iustin Pop
  elif command == "info":
436 3ccafd0e Iustin Pop
    result = client.QueryConfigValues(["drain_flag"])
437 3ccafd0e Iustin Pop
    print "The drain flag is",
438 3ccafd0e Iustin Pop
    if result[0]:
439 3ccafd0e Iustin Pop
      print "set"
440 3ccafd0e Iustin Pop
    else:
441 3ccafd0e Iustin Pop
      print "unset"
442 3ccafd0e Iustin Pop
  return 0
443 3ccafd0e Iustin Pop
444 a8083063 Iustin Pop
# this is an option common to more than one command, so we declare
445 a8083063 Iustin Pop
# it here and reuse it
446 a8083063 Iustin Pop
node_option = make_option("-n", "--node", action="append", dest="nodes",
447 f4bc1f2c Michael Hanselmann
                          help="Node to copy to (if not given, all nodes),"
448 f4bc1f2c Michael Hanselmann
                               " can be given multiple times",
449 f4bc1f2c Michael Hanselmann
                          metavar="<node>", default=[])
450 a8083063 Iustin Pop
451 a8083063 Iustin Pop
commands = {
452 a8083063 Iustin Pop
  'init': (InitCluster, ARGS_ONE,
453 a8083063 Iustin Pop
           [DEBUG_OPT,
454 a8083063 Iustin Pop
            make_option("-s", "--secondary-ip", dest="secondary_ip",
455 a8083063 Iustin Pop
                        help="Specify the secondary ip for this node;"
456 a8083063 Iustin Pop
                        " if given, the entire cluster must have secondary"
457 a8083063 Iustin Pop
                        " addresses",
458 a8083063 Iustin Pop
                        metavar="ADDRESS", default=None),
459 a8083063 Iustin Pop
            make_option("-t", "--hypervisor-type", dest="hypervisor_type",
460 2a6469d5 Alexander Schreiber
                        help="Specify the hypervisor type "
461 e49099a4 Alexander Schreiber
                        "(xen-pvm, kvm, fake, xen-hvm)",
462 e49099a4 Alexander Schreiber
                        metavar="TYPE", choices=["xen-pvm",
463 7a151789 Guido Trotter
                                                 "kvm",
464 2a6469d5 Alexander Schreiber
                                                 "fake",
465 e49099a4 Alexander Schreiber
                                                 "xen-hvm"],
466 e49099a4 Alexander Schreiber
                        default="xen-pvm",),
467 a8083063 Iustin Pop
            make_option("-m", "--mac-prefix", dest="mac_prefix",
468 a8083063 Iustin Pop
                        help="Specify the mac prefix for the instance IP"
469 a8083063 Iustin Pop
                        " addresses, in the format XX:XX:XX",
470 a8083063 Iustin Pop
                        metavar="PREFIX",
471 a8083063 Iustin Pop
                        default="aa:00:00",),
472 a8083063 Iustin Pop
            make_option("-g", "--vg-name", dest="vg_name",
473 a8083063 Iustin Pop
                        help="Specify the volume group name "
474 a8083063 Iustin Pop
                        " (cluster-wide) for disk allocation [xenvg]",
475 a8083063 Iustin Pop
                        metavar="VG",
476 90b6aa3a Manuel Franceschini
                        default=None,),
477 a8083063 Iustin Pop
            make_option("-b", "--bridge", dest="def_bridge",
478 a8083063 Iustin Pop
                        help="Specify the default bridge name (cluster-wide)"
479 cf62a272 Michael Hanselmann
                          " to connect the instances to [%s]" %
480 cf62a272 Michael Hanselmann
                          constants.DEFAULT_BRIDGE,
481 a8083063 Iustin Pop
                        metavar="BRIDGE",
482 cf62a272 Michael Hanselmann
                        default=constants.DEFAULT_BRIDGE,),
483 880478f8 Iustin Pop
            make_option("--master-netdev", dest="master_netdev",
484 880478f8 Iustin Pop
                        help="Specify the node interface (cluster-wide)"
485 cf62a272 Michael Hanselmann
                          " on which the master IP address will be added "
486 cf62a272 Michael Hanselmann
                          " [%s]" % constants.DEFAULT_BRIDGE,
487 880478f8 Iustin Pop
                        metavar="NETDEV",
488 cf62a272 Michael Hanselmann
                        default=constants.DEFAULT_BRIDGE,),
489 79e82404 Manuel Franceschini
            make_option("--file-storage-dir", dest="file_storage_dir",
490 79e82404 Manuel Franceschini
                        help="Specify the default directory (cluster-wide)"
491 79e82404 Manuel Franceschini
                             " for storing the file-based disks [%s]" %
492 79e82404 Manuel Franceschini
                             constants.DEFAULT_FILE_STORAGE_DIR,
493 79e82404 Manuel Franceschini
                        metavar="DIR",
494 79e82404 Manuel Franceschini
                        default=constants.DEFAULT_FILE_STORAGE_DIR,),
495 90b6aa3a Manuel Franceschini
            make_option("--no-lvm-storage", dest="lvm_storage",
496 90b6aa3a Manuel Franceschini
                        help="No support for lvm based instances"
497 90b6aa3a Manuel Franceschini
                             " (cluster-wide)",
498 90b6aa3a Manuel Franceschini
                        action="store_false", default=True,),
499 ea3a925f Alexander Schreiber
            make_option("--enabled-hypervisors", dest="enabled_hypervisors",
500 ea3a925f Alexander Schreiber
                        help="Comma-separated list of hypervisors",
501 ea3a925f Alexander Schreiber
                        type="string", default=None),
502 ea3a925f Alexander Schreiber
            ikv_option("-H", "--hypervisor-parameters", dest="hvparams",
503 ea3a925f Alexander Schreiber
                       help="Hypervisor and hypervisor options, in the"
504 ea3a925f Alexander Schreiber
                         " format"
505 ea3a925f Alexander Schreiber
                       " hypervisor:option=value,option=value,...",
506 ea3a925f Alexander Schreiber
                       default=[],
507 ea3a925f Alexander Schreiber
                       action="append",
508 ea3a925f Alexander Schreiber
                       type="identkeyval"),
509 ea3a925f Alexander Schreiber
            keyval_option("-B", "--backend-parameters", dest="beparams",
510 ea3a925f Alexander Schreiber
                          type="keyval", default={},
511 ea3a925f Alexander Schreiber
                          help="Backend parameters"),
512 a8083063 Iustin Pop
            ],
513 9a033156 Iustin Pop
           "[opts...] <cluster_name>",
514 a8083063 Iustin Pop
           "Initialises a new cluster configuration"),
515 a8083063 Iustin Pop
  'destroy': (DestroyCluster, ARGS_NONE,
516 a8083063 Iustin Pop
              [DEBUG_OPT,
517 a8083063 Iustin Pop
               make_option("--yes-do-it", dest="yes_do_it",
518 a8083063 Iustin Pop
                           help="Destroy cluster",
519 a8083063 Iustin Pop
                           action="store_true"),
520 a8083063 Iustin Pop
              ],
521 9a033156 Iustin Pop
              "", "Destroy cluster"),
522 07bd8a51 Iustin Pop
  'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
523 9a033156 Iustin Pop
               "<new_name>",
524 07bd8a51 Iustin Pop
               "Renames the cluster"),
525 e54c4c5e Guido Trotter
  'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT,
526 e54c4c5e Guido Trotter
             make_option("--no-nplus1-mem", dest="skip_nplusone_mem",
527 e54c4c5e Guido Trotter
                         help="Skip N+1 memory redundancy tests",
528 e54c4c5e Guido Trotter
                         action="store_true",
529 e54c4c5e Guido Trotter
                         default=False,),
530 e54c4c5e Guido Trotter
             ],
531 9a033156 Iustin Pop
             "", "Does a check on the cluster configuration"),
532 f4d4e184 Iustin Pop
  'verify-disks': (VerifyDisks, ARGS_NONE, [DEBUG_OPT],
533 9a033156 Iustin Pop
                   "", "Does a check on the cluster disk status"),
534 a8083063 Iustin Pop
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT],
535 9a033156 Iustin Pop
                     "", "Makes the current node the master"),
536 a8083063 Iustin Pop
  'version': (ShowClusterVersion, ARGS_NONE, [DEBUG_OPT],
537 9a033156 Iustin Pop
              "", "Shows the cluster version"),
538 a8083063 Iustin Pop
  'getmaster': (ShowClusterMaster, ARGS_NONE, [DEBUG_OPT],
539 9a033156 Iustin Pop
                "", "Shows the cluster master"),
540 a8083063 Iustin Pop
  'copyfile': (ClusterCopyFile, ARGS_ONE, [DEBUG_OPT, node_option],
541 9a033156 Iustin Pop
               "[-n node...] <filename>",
542 a8083063 Iustin Pop
               "Copies a file to all (or only some) nodes"),
543 a8083063 Iustin Pop
  'command': (RunClusterCommand, ARGS_ATLEAST(1), [DEBUG_OPT, node_option],
544 9a033156 Iustin Pop
              "[-n node...] <command>",
545 a8083063 Iustin Pop
              "Runs a command on all (or only some) nodes"),
546 a8083063 Iustin Pop
  'info': (ShowClusterConfig, ARGS_NONE, [DEBUG_OPT],
547 9a033156 Iustin Pop
                 "", "Show cluster configuration"),
548 846baef9 Iustin Pop
  'list-tags': (ListTags, ARGS_NONE,
549 9a033156 Iustin Pop
                [DEBUG_OPT], "", "List the tags of the cluster"),
550 810c50b7 Iustin Pop
  'add-tags': (AddTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
551 9a033156 Iustin Pop
               "tag...", "Add tags to the cluster"),
552 810c50b7 Iustin Pop
  'remove-tags': (RemoveTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
553 9a033156 Iustin Pop
                  "tag...", "Remove tags from the cluster"),
554 73415719 Iustin Pop
  'search-tags': (SearchTags, ARGS_ONE,
555 9a033156 Iustin Pop
                  [DEBUG_OPT], "", "Searches the tags on all objects on"
556 73415719 Iustin Pop
                  " the cluster for a given pattern (regex)"),
557 3ccafd0e Iustin Pop
  'queue': (QueueOps, ARGS_ONE, [DEBUG_OPT],
558 3ccafd0e Iustin Pop
            "drain|undrain|info", "Change queue properties"),
559 90b6aa3a Manuel Franceschini
  'modify': (SetClusterParams, ARGS_NONE,
560 90b6aa3a Manuel Franceschini
             [DEBUG_OPT,
561 90b6aa3a Manuel Franceschini
              make_option("-g", "--vg-name", dest="vg_name",
562 90b6aa3a Manuel Franceschini
                          help="Specify the volume group name "
563 90b6aa3a Manuel Franceschini
                          " (cluster-wide) for disk allocation "
564 90b6aa3a Manuel Franceschini
                          "and enable lvm based storage",
565 90b6aa3a Manuel Franceschini
                          metavar="VG",),
566 90b6aa3a Manuel Franceschini
              make_option("--no-lvm-storage", dest="lvm_storage",
567 90b6aa3a Manuel Franceschini
                          help="Disable support for lvm based instances"
568 90b6aa3a Manuel Franceschini
                               " (cluster-wide)",
569 90b6aa3a Manuel Franceschini
                          action="store_false", default=True,),
570 779c15bb Iustin Pop
              make_option("--enabled-hypervisors", dest="enabled_hypervisors",
571 779c15bb Iustin Pop
                          help="Comma-separated list of hypervisors",
572 779c15bb Iustin Pop
                          type="string", default=None),
573 779c15bb Iustin Pop
              ikv_option("-H", "--hypervisor-parameters", dest="hvparams",
574 779c15bb Iustin Pop
                         help="Hypervisor and hypervisor options, in the"
575 779c15bb Iustin Pop
                         " format"
576 779c15bb Iustin Pop
                         " hypervisor:option=value,option=value,...",
577 779c15bb Iustin Pop
                         default=[],
578 779c15bb Iustin Pop
                         action="append",
579 779c15bb Iustin Pop
                         type="identkeyval"),
580 779c15bb Iustin Pop
              keyval_option("-B", "--backend-parameters", dest="beparams",
581 779c15bb Iustin Pop
                            type="keyval", default={},
582 779c15bb Iustin Pop
                            help="Backend parameters"),
583 90b6aa3a Manuel Franceschini
              ],
584 90b6aa3a Manuel Franceschini
             "[opts...]",
585 90b6aa3a Manuel Franceschini
             "Alters the parameters of the cluster"),
586 a8083063 Iustin Pop
  }
587 a8083063 Iustin Pop
588 a8083063 Iustin Pop
if __name__ == '__main__':
589 846baef9 Iustin Pop
  sys.exit(GenericMain(commands, override={"tag_type": constants.TAG_CLUSTER}))