Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ 2f79bd34

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