Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ 087ed2ed

History | View | Annotate | Download (25.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 b3989551 Iustin Pop
import os.path
28 95b2e626 Michael Hanselmann
import time
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 d3cfe525 Guido Trotter
from ganeti import objects
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
40 4331f6cd Michael Hanselmann
@UsesRPC
41 a8083063 Iustin Pop
def InitCluster(opts, args):
42 a8083063 Iustin Pop
  """Initialize the cluster.
43 a8083063 Iustin Pop
44 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
45 469ee405 Iustin Pop
  @type args: list
46 469ee405 Iustin Pop
  @param args: should contain only one element, the desired
47 469ee405 Iustin Pop
      cluster name
48 469ee405 Iustin Pop
  @rtype: int
49 469ee405 Iustin Pop
  @return: the desired exit code
50 a8083063 Iustin Pop
51 a8083063 Iustin Pop
  """
52 90b6aa3a Manuel Franceschini
  if not opts.lvm_storage and opts.vg_name:
53 3a24c527 Iustin Pop
    ToStderr("Options --no-lvm-storage and --vg-name conflict.")
54 90b6aa3a Manuel Franceschini
    return 1
55 90b6aa3a Manuel Franceschini
56 90b6aa3a Manuel Franceschini
  vg_name = opts.vg_name
57 90b6aa3a Manuel Franceschini
  if opts.lvm_storage and not opts.vg_name:
58 90b6aa3a Manuel Franceschini
    vg_name = constants.DEFAULT_VG
59 90b6aa3a Manuel Franceschini
60 ea3a925f Alexander Schreiber
  hvlist = opts.enabled_hypervisors
61 066f465d Guido Trotter
  hvlist = hvlist.split(",")
62 ea3a925f Alexander Schreiber
63 f8e7ddca Guido Trotter
  hvparams = dict(opts.hvparams)
64 ea3a925f Alexander Schreiber
  beparams = opts.beparams
65 b6a30b0d Guido Trotter
  nicparams = opts.nicparams
66 ea3a925f Alexander Schreiber
67 ea3a925f Alexander Schreiber
  # prepare beparams dict
68 d3cfe525 Guido Trotter
  beparams = objects.FillDict(constants.BEC_DEFAULTS, beparams)
69 a5728081 Guido Trotter
  utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
70 ea3a925f Alexander Schreiber
71 b6a30b0d Guido Trotter
  # prepare nicparams dict
72 b6a30b0d Guido Trotter
  nicparams = objects.FillDict(constants.NICC_DEFAULTS, nicparams)
73 b6a30b0d Guido Trotter
  utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
74 b6a30b0d Guido Trotter
75 ea3a925f Alexander Schreiber
  # prepare hvparams dict
76 ea3a925f Alexander Schreiber
  for hv in constants.HYPER_TYPES:
77 ea3a925f Alexander Schreiber
    if hv not in hvparams:
78 ea3a925f Alexander Schreiber
      hvparams[hv] = {}
79 d3cfe525 Guido Trotter
    hvparams[hv] = objects.FillDict(constants.HVC_DEFAULTS[hv], hvparams[hv])
80 a5728081 Guido Trotter
    utils.ForceDictType(hvparams[hv], constants.HVS_PARAMETER_TYPES)
81 ea3a925f Alexander Schreiber
82 a0c9f010 Michael Hanselmann
  bootstrap.InitCluster(cluster_name=args[0],
83 a0c9f010 Michael Hanselmann
                        secondary_ip=opts.secondary_ip,
84 a0c9f010 Michael Hanselmann
                        vg_name=vg_name,
85 a0c9f010 Michael Hanselmann
                        mac_prefix=opts.mac_prefix,
86 a0c9f010 Michael Hanselmann
                        master_netdev=opts.master_netdev,
87 ea3a925f Alexander Schreiber
                        file_storage_dir=opts.file_storage_dir,
88 ea3a925f Alexander Schreiber
                        enabled_hypervisors=hvlist,
89 ea3a925f Alexander Schreiber
                        hvparams=hvparams,
90 ce735215 Guido Trotter
                        beparams=beparams,
91 b6a30b0d Guido Trotter
                        nicparams=nicparams,
92 ce735215 Guido Trotter
                        candidate_pool_size=opts.candidate_pool_size,
93 b86a6bcd Guido Trotter
                        modify_etc_hosts=opts.modify_etc_hosts,
94 ce735215 Guido Trotter
                        )
95 3552cd2e Luca Bigliardi
  op = opcodes.OpPostInitCluster()
96 3552cd2e Luca Bigliardi
  SubmitOpCode(op)
97 a8083063 Iustin Pop
  return 0
98 a8083063 Iustin Pop
99 a8083063 Iustin Pop
100 4331f6cd Michael Hanselmann
@UsesRPC
101 a8083063 Iustin Pop
def DestroyCluster(opts, args):
102 a8083063 Iustin Pop
  """Destroy the cluster.
103 a8083063 Iustin Pop
104 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
105 469ee405 Iustin Pop
  @type args: list
106 469ee405 Iustin Pop
  @param args: should be an empty list
107 469ee405 Iustin Pop
  @rtype: int
108 469ee405 Iustin Pop
  @return: the desired exit code
109 098c0958 Michael Hanselmann
110 a8083063 Iustin Pop
  """
111 a8083063 Iustin Pop
  if not opts.yes_do_it:
112 3a24c527 Iustin Pop
    ToStderr("Destroying a cluster is irreversible. If you really want"
113 3a24c527 Iustin Pop
             " destroy this cluster, supply the --yes-do-it option.")
114 a8083063 Iustin Pop
    return 1
115 a8083063 Iustin Pop
116 a8083063 Iustin Pop
  op = opcodes.OpDestroyCluster()
117 140aa4a8 Iustin Pop
  master = SubmitOpCode(op)
118 140aa4a8 Iustin Pop
  # if we reached this, the opcode didn't fail; we can proceed to
119 140aa4a8 Iustin Pop
  # shutdown all the daemons
120 140aa4a8 Iustin Pop
  bootstrap.FinalizeClusterDestroy(master)
121 a8083063 Iustin Pop
  return 0
122 a8083063 Iustin Pop
123 a8083063 Iustin Pop
124 07bd8a51 Iustin Pop
def RenameCluster(opts, args):
125 07bd8a51 Iustin Pop
  """Rename the cluster.
126 07bd8a51 Iustin Pop
127 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
128 469ee405 Iustin Pop
  @type args: list
129 469ee405 Iustin Pop
  @param args: should contain only one element, the new cluster name
130 469ee405 Iustin Pop
  @rtype: int
131 469ee405 Iustin Pop
  @return: the desired exit code
132 07bd8a51 Iustin Pop
133 07bd8a51 Iustin Pop
  """
134 07bd8a51 Iustin Pop
  name = args[0]
135 07bd8a51 Iustin Pop
  if not opts.force:
136 07bd8a51 Iustin Pop
    usertext = ("This will rename the cluster to '%s'. If you are connected"
137 07bd8a51 Iustin Pop
                " over the network to the cluster name, the operation is very"
138 07bd8a51 Iustin Pop
                " dangerous as the IP address will be removed from the node"
139 07bd8a51 Iustin Pop
                " and the change may not go through. Continue?") % name
140 47988778 Iustin Pop
    if not AskUser(usertext):
141 07bd8a51 Iustin Pop
      return 1
142 07bd8a51 Iustin Pop
143 07bd8a51 Iustin Pop
  op = opcodes.OpRenameCluster(name=name)
144 07bd8a51 Iustin Pop
  SubmitOpCode(op)
145 07bd8a51 Iustin Pop
  return 0
146 07bd8a51 Iustin Pop
147 07bd8a51 Iustin Pop
148 afee0879 Iustin Pop
def RedistributeConfig(opts, args):
149 afee0879 Iustin Pop
  """Forces push of the cluster configuration.
150 afee0879 Iustin Pop
151 afee0879 Iustin Pop
  @param opts: the command line options selected by the user
152 afee0879 Iustin Pop
  @type args: list
153 afee0879 Iustin Pop
  @param args: empty list
154 afee0879 Iustin Pop
  @rtype: int
155 afee0879 Iustin Pop
  @return: the desired exit code
156 afee0879 Iustin Pop
157 afee0879 Iustin Pop
  """
158 81a49123 Iustin Pop
  op = opcodes.OpRedistributeConfig()
159 afee0879 Iustin Pop
  SubmitOrSend(op, opts)
160 afee0879 Iustin Pop
  return 0
161 afee0879 Iustin Pop
162 afee0879 Iustin Pop
163 a8083063 Iustin Pop
def ShowClusterVersion(opts, args):
164 a8083063 Iustin Pop
  """Write version of ganeti software to the standard output.
165 a8083063 Iustin Pop
166 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
167 469ee405 Iustin Pop
  @type args: list
168 469ee405 Iustin Pop
  @param args: should be an empty list
169 469ee405 Iustin Pop
  @rtype: int
170 469ee405 Iustin Pop
  @return: the desired exit code
171 a8083063 Iustin Pop
172 a8083063 Iustin Pop
  """
173 2e7b8369 Iustin Pop
  cl = GetClient()
174 2e7b8369 Iustin Pop
  result = cl.QueryClusterInfo()
175 3a24c527 Iustin Pop
  ToStdout("Software version: %s", result["software_version"])
176 3a24c527 Iustin Pop
  ToStdout("Internode protocol: %s", result["protocol_version"])
177 3a24c527 Iustin Pop
  ToStdout("Configuration format: %s", result["config_version"])
178 3a24c527 Iustin Pop
  ToStdout("OS api version: %s", result["os_api_version"])
179 3a24c527 Iustin Pop
  ToStdout("Export interface: %s", result["export_version"])
180 a8083063 Iustin Pop
  return 0
181 a8083063 Iustin Pop
182 a8083063 Iustin Pop
183 a8083063 Iustin Pop
def ShowClusterMaster(opts, args):
184 a8083063 Iustin Pop
  """Write name of master node to the standard output.
185 a8083063 Iustin Pop
186 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
187 469ee405 Iustin Pop
  @type args: list
188 469ee405 Iustin Pop
  @param args: should be an empty list
189 469ee405 Iustin Pop
  @rtype: int
190 469ee405 Iustin Pop
  @return: the desired exit code
191 a8083063 Iustin Pop
192 a8083063 Iustin Pop
  """
193 8eb148ae Iustin Pop
  master = bootstrap.GetMaster()
194 8eb148ae Iustin Pop
  ToStdout(master)
195 a8083063 Iustin Pop
  return 0
196 a8083063 Iustin Pop
197 1094acda Guido Trotter
def _PrintGroupedParams(paramsdict):
198 1094acda Guido Trotter
  """Print Grouped parameters (be, nic, disk) by group.
199 1094acda Guido Trotter
200 1094acda Guido Trotter
  @type paramsdict: dict of dicts
201 1094acda Guido Trotter
  @param paramsdict: {group: {param: value, ...}, ...}
202 1094acda Guido Trotter
203 1094acda Guido Trotter
  """
204 1094acda Guido Trotter
  for gr_name, gr_dict in paramsdict.items():
205 1094acda Guido Trotter
    ToStdout("  - %s:", gr_name)
206 1094acda Guido Trotter
    for item, val in gr_dict.iteritems():
207 1094acda Guido Trotter
      ToStdout("      %s: %s", item, val)
208 a8083063 Iustin Pop
209 a8083063 Iustin Pop
def ShowClusterConfig(opts, args):
210 a8083063 Iustin Pop
  """Shows cluster information.
211 a8083063 Iustin Pop
212 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
213 469ee405 Iustin Pop
  @type args: list
214 469ee405 Iustin Pop
  @param args: should be an empty list
215 469ee405 Iustin Pop
  @rtype: int
216 469ee405 Iustin Pop
  @return: the desired exit code
217 469ee405 Iustin Pop
218 a8083063 Iustin Pop
  """
219 2e7b8369 Iustin Pop
  cl = GetClient()
220 2e7b8369 Iustin Pop
  result = cl.QueryClusterInfo()
221 a8083063 Iustin Pop
222 3a24c527 Iustin Pop
  ToStdout("Cluster name: %s", result["name"])
223 a8083063 Iustin Pop
224 90f72445 Iustin Pop
  ToStdout("Creation time: %s", utils.FormatTime(result["ctime"]))
225 90f72445 Iustin Pop
  ToStdout("Modification time: %s", utils.FormatTime(result["mtime"]))
226 90f72445 Iustin Pop
227 3a24c527 Iustin Pop
  ToStdout("Master node: %s", result["master"])
228 a8083063 Iustin Pop
229 3a24c527 Iustin Pop
  ToStdout("Architecture (this node): %s (%s)",
230 3a24c527 Iustin Pop
           result["architecture"][0], result["architecture"][1])
231 a8083063 Iustin Pop
232 c118d1f4 Michael Hanselmann
  if result["tags"]:
233 c118d1f4 Michael Hanselmann
    tags = ", ".join(utils.NiceSort(result["tags"]))
234 c118d1f4 Michael Hanselmann
  else:
235 c118d1f4 Michael Hanselmann
    tags = "(none)"
236 c118d1f4 Michael Hanselmann
237 c118d1f4 Michael Hanselmann
  ToStdout("Tags: %s", tags)
238 c118d1f4 Michael Hanselmann
239 02691904 Alexander Schreiber
  ToStdout("Default hypervisor: %s", result["default_hypervisor"])
240 3a24c527 Iustin Pop
  ToStdout("Enabled hypervisors: %s", ", ".join(result["enabled_hypervisors"]))
241 469f88e1 Iustin Pop
242 3a24c527 Iustin Pop
  ToStdout("Hypervisor parameters:")
243 1094acda Guido Trotter
  _PrintGroupedParams(result["hvparams"])
244 469f88e1 Iustin Pop
245 3a24c527 Iustin Pop
  ToStdout("Cluster parameters:")
246 4b7735f9 Iustin Pop
  ToStdout("  - candidate pool size: %s", result["candidate_pool_size"])
247 a8001106 Guido Trotter
  ToStdout("  - master netdev: %s", result["master_netdev"])
248 a8001106 Guido Trotter
  ToStdout("  - lvm volume group: %s", result["volume_group_name"])
249 a8001106 Guido Trotter
  ToStdout("  - file storage path: %s", result["file_storage_dir"])
250 4b7735f9 Iustin Pop
251 4b7735f9 Iustin Pop
  ToStdout("Default instance parameters:")
252 1094acda Guido Trotter
  _PrintGroupedParams(result["beparams"])
253 1094acda Guido Trotter
254 1094acda Guido Trotter
  ToStdout("Default nic parameters:")
255 1094acda Guido Trotter
  _PrintGroupedParams(result["nicparams"])
256 8a12ce45 Iustin Pop
257 a8083063 Iustin Pop
  return 0
258 a8083063 Iustin Pop
259 a8083063 Iustin Pop
260 a8083063 Iustin Pop
def ClusterCopyFile(opts, args):
261 a8083063 Iustin Pop
  """Copy a file from master to some nodes.
262 a8083063 Iustin Pop
263 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
264 469ee405 Iustin Pop
  @type args: list
265 469ee405 Iustin Pop
  @param args: should contain only one element, the path of
266 469ee405 Iustin Pop
      the file to be copied
267 469ee405 Iustin Pop
  @rtype: int
268 469ee405 Iustin Pop
  @return: the desired exit code
269 a8083063 Iustin Pop
270 a8083063 Iustin Pop
  """
271 b3989551 Iustin Pop
  filename = args[0]
272 b3989551 Iustin Pop
  if not os.path.exists(filename):
273 b3989551 Iustin Pop
    raise errors.OpPrereqError("No such filename '%s'" % filename)
274 b3989551 Iustin Pop
275 56bece1f Iustin Pop
  cl = GetClient()
276 56bece1f Iustin Pop
277 b3989551 Iustin Pop
  myname = utils.HostInfo().name
278 b3989551 Iustin Pop
279 56bece1f Iustin Pop
  cluster_name = cl.QueryConfigValues(["cluster_name"])[0]
280 56bece1f Iustin Pop
281 4040a784 Iustin Pop
  results = GetOnlineNodes(nodes=opts.nodes, cl=cl)
282 4040a784 Iustin Pop
  results = [name for name in results if name != myname]
283 e00ea635 Michael Hanselmann
284 56bece1f Iustin Pop
  srun = ssh.SshRunner(cluster_name=cluster_name)
285 b3989551 Iustin Pop
  for node in results:
286 b3989551 Iustin Pop
    if not srun.CopyFileToNode(node, filename):
287 3a24c527 Iustin Pop
      ToStderr("Copy of file %s to node %s failed", filename, node)
288 b3989551 Iustin Pop
289 a8083063 Iustin Pop
  return 0
290 a8083063 Iustin Pop
291 a8083063 Iustin Pop
292 a8083063 Iustin Pop
def RunClusterCommand(opts, args):
293 a8083063 Iustin Pop
  """Run a command on some nodes.
294 a8083063 Iustin Pop
295 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
296 469ee405 Iustin Pop
  @type args: list
297 469ee405 Iustin Pop
  @param args: should contain the command to be run and its arguments
298 469ee405 Iustin Pop
  @rtype: int
299 469ee405 Iustin Pop
  @return: the desired exit code
300 a8083063 Iustin Pop
301 a8083063 Iustin Pop
  """
302 56bece1f Iustin Pop
  cl = GetClient()
303 7688d0d3 Michael Hanselmann
304 a8083063 Iustin Pop
  command = " ".join(args)
305 4040a784 Iustin Pop
306 4040a784 Iustin Pop
  nodes = GetOnlineNodes(nodes=opts.nodes, cl=cl)
307 56bece1f Iustin Pop
308 56bece1f Iustin Pop
  cluster_name, master_node = cl.QueryConfigValues(["cluster_name",
309 56bece1f Iustin Pop
                                                    "master_node"])
310 b3989551 Iustin Pop
311 56bece1f Iustin Pop
  srun = ssh.SshRunner(cluster_name=cluster_name)
312 b3989551 Iustin Pop
313 7688d0d3 Michael Hanselmann
  # Make sure master node is at list end
314 b3989551 Iustin Pop
  if master_node in nodes:
315 b3989551 Iustin Pop
    nodes.remove(master_node)
316 b3989551 Iustin Pop
    nodes.append(master_node)
317 b3989551 Iustin Pop
318 b3989551 Iustin Pop
  for name in nodes:
319 b3989551 Iustin Pop
    result = srun.Run(name, "root", command)
320 3a24c527 Iustin Pop
    ToStdout("------------------------------------------------")
321 3a24c527 Iustin Pop
    ToStdout("node: %s", name)
322 3a24c527 Iustin Pop
    ToStdout("%s", result.output)
323 3a24c527 Iustin Pop
    ToStdout("return code = %s", result.exit_code)
324 b3989551 Iustin Pop
325 b3989551 Iustin Pop
  return 0
326 a8083063 Iustin Pop
327 a8083063 Iustin Pop
328 a8083063 Iustin Pop
def VerifyCluster(opts, args):
329 a8083063 Iustin Pop
  """Verify integrity of cluster, performing various test on nodes.
330 a8083063 Iustin Pop
331 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
332 469ee405 Iustin Pop
  @type args: list
333 469ee405 Iustin Pop
  @param args: should be an empty list
334 469ee405 Iustin Pop
  @rtype: int
335 469ee405 Iustin Pop
  @return: the desired exit code
336 a8083063 Iustin Pop
337 a8083063 Iustin Pop
  """
338 8d59409f Iustin Pop
  skip_checks = []
339 e54c4c5e Guido Trotter
  if opts.skip_nplusone_mem:
340 e54c4c5e Guido Trotter
    skip_checks.append(constants.VERIFY_NPLUSONE_MEM)
341 7c874ee1 Iustin Pop
  op = opcodes.OpVerifyCluster(skip_checks=skip_checks,
342 7c874ee1 Iustin Pop
                               verbose=opts.verbose,
343 a0c9776a Iustin Pop
                               error_codes=opts.error_codes,
344 a0c9776a Iustin Pop
                               debug_simulate_errors=opts.simulate_errors)
345 34290825 Michael Hanselmann
  if SubmitOpCode(op):
346 34290825 Michael Hanselmann
    return 0
347 34290825 Michael Hanselmann
  else:
348 34290825 Michael Hanselmann
    return 1
349 a8083063 Iustin Pop
350 a8083063 Iustin Pop
351 f4d4e184 Iustin Pop
def VerifyDisks(opts, args):
352 f4d4e184 Iustin Pop
  """Verify integrity of cluster disks.
353 f4d4e184 Iustin Pop
354 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
355 469ee405 Iustin Pop
  @type args: list
356 469ee405 Iustin Pop
  @param args: should be an empty list
357 469ee405 Iustin Pop
  @rtype: int
358 469ee405 Iustin Pop
  @return: the desired exit code
359 f4d4e184 Iustin Pop
360 f4d4e184 Iustin Pop
  """
361 f4d4e184 Iustin Pop
  op = opcodes.OpVerifyDisks()
362 f4d4e184 Iustin Pop
  result = SubmitOpCode(op)
363 29d376ec Iustin Pop
  if not isinstance(result, (list, tuple)) or len(result) != 3:
364 f4d4e184 Iustin Pop
    raise errors.ProgrammerError("Unknown result type for OpVerifyDisks")
365 f4d4e184 Iustin Pop
366 29d376ec Iustin Pop
  bad_nodes, instances, missing = result
367 b63ed789 Iustin Pop
368 f4d4e184 Iustin Pop
  retcode = constants.EXIT_SUCCESS
369 b63ed789 Iustin Pop
370 29d376ec Iustin Pop
  if bad_nodes:
371 29d376ec Iustin Pop
    for node, text in bad_nodes.items():
372 29d376ec Iustin Pop
      ToStdout("Error gathering data on node %s: %s",
373 26f15862 Iustin Pop
               node, utils.SafeEncode(text[-400:]))
374 b63ed789 Iustin Pop
      retcode |= 1
375 3a24c527 Iustin Pop
      ToStdout("You need to fix these nodes first before fixing instances")
376 b63ed789 Iustin Pop
377 f4d4e184 Iustin Pop
  if instances:
378 f4d4e184 Iustin Pop
    for iname in instances:
379 b63ed789 Iustin Pop
      if iname in missing:
380 b63ed789 Iustin Pop
        continue
381 f4d4e184 Iustin Pop
      op = opcodes.OpActivateInstanceDisks(instance_name=iname)
382 f4d4e184 Iustin Pop
      try:
383 3a24c527 Iustin Pop
        ToStdout("Activating disks for instance '%s'", iname)
384 f4d4e184 Iustin Pop
        SubmitOpCode(op)
385 f4d4e184 Iustin Pop
      except errors.GenericError, err:
386 f4d4e184 Iustin Pop
        nret, msg = FormatError(err)
387 f4d4e184 Iustin Pop
        retcode |= nret
388 3a24c527 Iustin Pop
        ToStderr("Error activating disks for instance %s: %s", iname, msg)
389 b63ed789 Iustin Pop
390 b63ed789 Iustin Pop
  if missing:
391 b63ed789 Iustin Pop
    for iname, ival in missing.iteritems():
392 29d376ec Iustin Pop
      all_missing = utils.all(ival, lambda x: x[0] in bad_nodes)
393 b63ed789 Iustin Pop
      if all_missing:
394 3a24c527 Iustin Pop
        ToStdout("Instance %s cannot be verified as it lives on"
395 3a24c527 Iustin Pop
                 " broken nodes", iname)
396 b63ed789 Iustin Pop
      else:
397 3a24c527 Iustin Pop
        ToStdout("Instance %s has missing logical volumes:", iname)
398 b63ed789 Iustin Pop
        ival.sort()
399 b63ed789 Iustin Pop
        for node, vol in ival:
400 29d376ec Iustin Pop
          if node in bad_nodes:
401 3a24c527 Iustin Pop
            ToStdout("\tbroken node %s /dev/xenvg/%s", node, vol)
402 b63ed789 Iustin Pop
          else:
403 3a24c527 Iustin Pop
            ToStdout("\t%s /dev/xenvg/%s", node, vol)
404 3a24c527 Iustin Pop
    ToStdout("You need to run replace_disks for all the above"
405 b63ed789 Iustin Pop
           " instances, if this message persist after fixing nodes.")
406 b63ed789 Iustin Pop
    retcode |= 1
407 f4d4e184 Iustin Pop
408 f4d4e184 Iustin Pop
  return retcode
409 f4d4e184 Iustin Pop
410 f4d4e184 Iustin Pop
411 60975797 Iustin Pop
def RepairDiskSizes(opts, args):
412 60975797 Iustin Pop
  """Verify sizes of cluster disks.
413 60975797 Iustin Pop
414 60975797 Iustin Pop
  @param opts: the command line options selected by the user
415 60975797 Iustin Pop
  @type args: list
416 60975797 Iustin Pop
  @param args: optional list of instances to restrict check to
417 60975797 Iustin Pop
  @rtype: int
418 60975797 Iustin Pop
  @return: the desired exit code
419 60975797 Iustin Pop
420 60975797 Iustin Pop
  """
421 60975797 Iustin Pop
  op = opcodes.OpRepairDiskSizes(instances=args)
422 60975797 Iustin Pop
  SubmitOpCode(op)
423 60975797 Iustin Pop
424 60975797 Iustin Pop
425 4331f6cd Michael Hanselmann
@UsesRPC
426 a8083063 Iustin Pop
def MasterFailover(opts, args):
427 a8083063 Iustin Pop
  """Failover the master node.
428 a8083063 Iustin Pop
429 a8083063 Iustin Pop
  This command, when run on a non-master node, will cause the current
430 a8083063 Iustin Pop
  master to cease being master, and the non-master to become new
431 a8083063 Iustin Pop
  master.
432 a8083063 Iustin Pop
433 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
434 469ee405 Iustin Pop
  @type args: list
435 469ee405 Iustin Pop
  @param args: should be an empty list
436 469ee405 Iustin Pop
  @rtype: int
437 469ee405 Iustin Pop
  @return: the desired exit code
438 469ee405 Iustin Pop
439 a8083063 Iustin Pop
  """
440 8e2524c3 Guido Trotter
  if opts.no_voting:
441 8e2524c3 Guido Trotter
    usertext = ("This will perform the failover even if most other nodes"
442 8e2524c3 Guido Trotter
                " are down, or if this node is outdated. This is dangerous"
443 8e2524c3 Guido Trotter
                " as it can lead to a non-consistent cluster. Check the"
444 8e2524c3 Guido Trotter
                " gnt-cluster(8) man page before proceeding. Continue?")
445 8e2524c3 Guido Trotter
    if not AskUser(usertext):
446 8e2524c3 Guido Trotter
      return 1
447 8e2524c3 Guido Trotter
448 8e2524c3 Guido Trotter
  return bootstrap.MasterFailover(no_voting=opts.no_voting)
449 a8083063 Iustin Pop
450 a8083063 Iustin Pop
451 73415719 Iustin Pop
def SearchTags(opts, args):
452 73415719 Iustin Pop
  """Searches the tags on all the cluster.
453 73415719 Iustin Pop
454 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
455 469ee405 Iustin Pop
  @type args: list
456 469ee405 Iustin Pop
  @param args: should contain only one element, the tag pattern
457 469ee405 Iustin Pop
  @rtype: int
458 469ee405 Iustin Pop
  @return: the desired exit code
459 469ee405 Iustin Pop
460 73415719 Iustin Pop
  """
461 73415719 Iustin Pop
  op = opcodes.OpSearchTags(pattern=args[0])
462 73415719 Iustin Pop
  result = SubmitOpCode(op)
463 73415719 Iustin Pop
  if not result:
464 73415719 Iustin Pop
    return 1
465 73415719 Iustin Pop
  result = list(result)
466 73415719 Iustin Pop
  result.sort()
467 73415719 Iustin Pop
  for path, tag in result:
468 3a24c527 Iustin Pop
    ToStdout("%s %s", path, tag)
469 73415719 Iustin Pop
470 73415719 Iustin Pop
471 90b6aa3a Manuel Franceschini
def SetClusterParams(opts, args):
472 90b6aa3a Manuel Franceschini
  """Modify the cluster.
473 90b6aa3a Manuel Franceschini
474 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
475 469ee405 Iustin Pop
  @type args: list
476 469ee405 Iustin Pop
  @param args: should be an empty list
477 469ee405 Iustin Pop
  @rtype: int
478 469ee405 Iustin Pop
  @return: the desired exit code
479 90b6aa3a Manuel Franceschini
480 90b6aa3a Manuel Franceschini
  """
481 779c15bb Iustin Pop
  if not (not opts.lvm_storage or opts.vg_name or
482 779c15bb Iustin Pop
          opts.enabled_hypervisors or opts.hvparams or
483 5af3da74 Guido Trotter
          opts.beparams or opts.nicparams or
484 5af3da74 Guido Trotter
          opts.candidate_pool_size is not None):
485 3a24c527 Iustin Pop
    ToStderr("Please give at least one of the parameters.")
486 90b6aa3a Manuel Franceschini
    return 1
487 90b6aa3a Manuel Franceschini
488 90b6aa3a Manuel Franceschini
  vg_name = opts.vg_name
489 90b6aa3a Manuel Franceschini
  if not opts.lvm_storage and opts.vg_name:
490 3a24c527 Iustin Pop
    ToStdout("Options --no-lvm-storage and --vg-name conflict.")
491 90b6aa3a Manuel Franceschini
    return 1
492 b8a8fbe1 Guido Trotter
  elif not opts.lvm_storage:
493 b8a8fbe1 Guido Trotter
    vg_name = ''
494 90b6aa3a Manuel Franceschini
495 779c15bb Iustin Pop
  hvlist = opts.enabled_hypervisors
496 779c15bb Iustin Pop
  if hvlist is not None:
497 779c15bb Iustin Pop
    hvlist = hvlist.split(",")
498 779c15bb Iustin Pop
499 f8e7ddca Guido Trotter
  # a list of (name, dict) we can pass directly to dict() (or [])
500 f8e7ddca Guido Trotter
  hvparams = dict(opts.hvparams)
501 a5728081 Guido Trotter
  for hv, hv_params in hvparams.iteritems():
502 a5728081 Guido Trotter
    utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
503 779c15bb Iustin Pop
504 779c15bb Iustin Pop
  beparams = opts.beparams
505 a5728081 Guido Trotter
  utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
506 779c15bb Iustin Pop
507 5af3da74 Guido Trotter
  nicparams = opts.nicparams
508 5af3da74 Guido Trotter
  utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
509 5af3da74 Guido Trotter
510 b8a8fbe1 Guido Trotter
  op = opcodes.OpSetClusterParams(vg_name=vg_name,
511 779c15bb Iustin Pop
                                  enabled_hypervisors=hvlist,
512 779c15bb Iustin Pop
                                  hvparams=hvparams,
513 4b7735f9 Iustin Pop
                                  beparams=beparams,
514 5af3da74 Guido Trotter
                                  nicparams=nicparams,
515 4b7735f9 Iustin Pop
                                  candidate_pool_size=opts.candidate_pool_size)
516 90b6aa3a Manuel Franceschini
  SubmitOpCode(op)
517 90b6aa3a Manuel Franceschini
  return 0
518 90b6aa3a Manuel Franceschini
519 90b6aa3a Manuel Franceschini
520 3ccafd0e Iustin Pop
def QueueOps(opts, args):
521 3ccafd0e Iustin Pop
  """Queue operations.
522 3ccafd0e Iustin Pop
523 469ee405 Iustin Pop
  @param opts: the command line options selected by the user
524 469ee405 Iustin Pop
  @type args: list
525 469ee405 Iustin Pop
  @param args: should contain only one element, the subcommand
526 469ee405 Iustin Pop
  @rtype: int
527 469ee405 Iustin Pop
  @return: the desired exit code
528 469ee405 Iustin Pop
529 3ccafd0e Iustin Pop
  """
530 3ccafd0e Iustin Pop
  command = args[0]
531 3ccafd0e Iustin Pop
  client = GetClient()
532 3ccafd0e Iustin Pop
  if command in ("drain", "undrain"):
533 3ccafd0e Iustin Pop
    drain_flag = command == "drain"
534 3ccafd0e Iustin Pop
    client.SetQueueDrainFlag(drain_flag)
535 3ccafd0e Iustin Pop
  elif command == "info":
536 3ccafd0e Iustin Pop
    result = client.QueryConfigValues(["drain_flag"])
537 3ccafd0e Iustin Pop
    if result[0]:
538 3a24c527 Iustin Pop
      val = "set"
539 3ccafd0e Iustin Pop
    else:
540 3a24c527 Iustin Pop
      val = "unset"
541 3a24c527 Iustin Pop
    ToStdout("The drain flag is %s" % val)
542 2e668b38 Guido Trotter
  else:
543 2e668b38 Guido Trotter
    raise errors.OpPrereqError("Command '%s' is not valid." % command)
544 2e668b38 Guido Trotter
545 3ccafd0e Iustin Pop
  return 0
546 3ccafd0e Iustin Pop
547 95b2e626 Michael Hanselmann
548 28b498cd Michael Hanselmann
def _ShowWatcherPause(until):
549 28b498cd Michael Hanselmann
  if until is None or until < time.time():
550 28b498cd Michael Hanselmann
    ToStdout("The watcher is not paused.")
551 28b498cd Michael Hanselmann
  else:
552 28b498cd Michael Hanselmann
    ToStdout("The watcher is paused until %s.", time.ctime(until))
553 28b498cd Michael Hanselmann
554 28b498cd Michael Hanselmann
555 95b2e626 Michael Hanselmann
def WatcherOps(opts, args):
556 95b2e626 Michael Hanselmann
  """Watcher operations.
557 95b2e626 Michael Hanselmann
558 95b2e626 Michael Hanselmann
  @param opts: the command line options selected by the user
559 95b2e626 Michael Hanselmann
  @type args: list
560 95b2e626 Michael Hanselmann
  @param args: should contain only one element, the subcommand
561 95b2e626 Michael Hanselmann
  @rtype: int
562 95b2e626 Michael Hanselmann
  @return: the desired exit code
563 95b2e626 Michael Hanselmann
564 95b2e626 Michael Hanselmann
  """
565 95b2e626 Michael Hanselmann
  command = args[0]
566 95b2e626 Michael Hanselmann
  client = GetClient()
567 95b2e626 Michael Hanselmann
568 95b2e626 Michael Hanselmann
  if command == "continue":
569 95b2e626 Michael Hanselmann
    client.SetWatcherPause(None)
570 28b498cd Michael Hanselmann
    ToStdout("The watcher is no longer paused.")
571 95b2e626 Michael Hanselmann
572 95b2e626 Michael Hanselmann
  elif command == "pause":
573 95b2e626 Michael Hanselmann
    if len(args) < 2:
574 95b2e626 Michael Hanselmann
      raise errors.OpPrereqError("Missing pause duration")
575 95b2e626 Michael Hanselmann
576 28b498cd Michael Hanselmann
    result = client.SetWatcherPause(time.time() + ParseTimespec(args[1]))
577 28b498cd Michael Hanselmann
    _ShowWatcherPause(result)
578 95b2e626 Michael Hanselmann
579 95b2e626 Michael Hanselmann
  elif command == "info":
580 95b2e626 Michael Hanselmann
    result = client.QueryConfigValues(["watcher_pause"])
581 28b498cd Michael Hanselmann
    _ShowWatcherPause(result)
582 95b2e626 Michael Hanselmann
583 95b2e626 Michael Hanselmann
  else:
584 95b2e626 Michael Hanselmann
    raise errors.OpPrereqError("Command '%s' is not valid." % command)
585 95b2e626 Michael Hanselmann
586 95b2e626 Michael Hanselmann
  return 0
587 95b2e626 Michael Hanselmann
588 95b2e626 Michael Hanselmann
589 a8083063 Iustin Pop
# this is an option common to more than one command, so we declare
590 a8083063 Iustin Pop
# it here and reuse it
591 c38c44ad Michael Hanselmann
node_option = cli_option("-n", "--node", action="append", dest="nodes",
592 c38c44ad Michael Hanselmann
                         help="Node to copy to (if not given, all nodes),"
593 c38c44ad Michael Hanselmann
                              " can be given multiple times",
594 c38c44ad Michael Hanselmann
                         metavar="<node>", default=[])
595 a8083063 Iustin Pop
596 a8083063 Iustin Pop
commands = {
597 83ec7961 Michael Hanselmann
  'init': (InitCluster, [ArgHost(min=1, max=1)],
598 a8083063 Iustin Pop
           [DEBUG_OPT,
599 c38c44ad Michael Hanselmann
            cli_option("-s", "--secondary-ip", dest="secondary_ip",
600 c38c44ad Michael Hanselmann
                       help="Specify the secondary ip for this node;"
601 c38c44ad Michael Hanselmann
                       " if given, the entire cluster must have secondary"
602 c38c44ad Michael Hanselmann
                       " addresses",
603 c38c44ad Michael Hanselmann
                       metavar="ADDRESS", default=None),
604 c38c44ad Michael Hanselmann
            cli_option("-m", "--mac-prefix", dest="mac_prefix",
605 c38c44ad Michael Hanselmann
                       help="Specify the mac prefix for the instance IP"
606 c38c44ad Michael Hanselmann
                       " addresses, in the format XX:XX:XX",
607 c38c44ad Michael Hanselmann
                       metavar="PREFIX",
608 c38c44ad Michael Hanselmann
                       default=constants.DEFAULT_MAC_PREFIX,),
609 c38c44ad Michael Hanselmann
            cli_option("-g", "--vg-name", dest="vg_name",
610 c38c44ad Michael Hanselmann
                       help="Specify the volume group name "
611 c38c44ad Michael Hanselmann
                       " (cluster-wide) for disk allocation [xenvg]",
612 c38c44ad Michael Hanselmann
                       metavar="VG",
613 c38c44ad Michael Hanselmann
                       default=None,),
614 c38c44ad Michael Hanselmann
            cli_option("--master-netdev", dest="master_netdev",
615 c38c44ad Michael Hanselmann
                       help="Specify the node interface (cluster-wide)"
616 c38c44ad Michael Hanselmann
                         " on which the master IP address will be added "
617 c38c44ad Michael Hanselmann
                         " [%s]" % constants.DEFAULT_BRIDGE,
618 c38c44ad Michael Hanselmann
                       metavar="NETDEV",
619 c38c44ad Michael Hanselmann
                       default=constants.DEFAULT_BRIDGE,),
620 c38c44ad Michael Hanselmann
            cli_option("--file-storage-dir", dest="file_storage_dir",
621 c38c44ad Michael Hanselmann
                       help="Specify the default directory (cluster-wide)"
622 c38c44ad Michael Hanselmann
                            " for storing the file-based disks [%s]" %
623 c38c44ad Michael Hanselmann
                            constants.DEFAULT_FILE_STORAGE_DIR,
624 c38c44ad Michael Hanselmann
                       metavar="DIR",
625 c38c44ad Michael Hanselmann
                       default=constants.DEFAULT_FILE_STORAGE_DIR,),
626 c38c44ad Michael Hanselmann
            cli_option("--no-lvm-storage", dest="lvm_storage",
627 c38c44ad Michael Hanselmann
                       help="No support for lvm based instances"
628 c38c44ad Michael Hanselmann
                            " (cluster-wide)",
629 c38c44ad Michael Hanselmann
                       action="store_false", default=True,),
630 c38c44ad Michael Hanselmann
            cli_option("--no-etc-hosts", dest="modify_etc_hosts",
631 c38c44ad Michael Hanselmann
                       help="Don't modify /etc/hosts"
632 c38c44ad Michael Hanselmann
                            " (cluster-wide)",
633 c38c44ad Michael Hanselmann
                       action="store_false", default=True,),
634 c38c44ad Michael Hanselmann
            cli_option("--enabled-hypervisors", dest="enabled_hypervisors",
635 c38c44ad Michael Hanselmann
                       help="Comma-separated list of hypervisors",
636 c38c44ad Michael Hanselmann
                       type="string",
637 c38c44ad Michael Hanselmann
                       default=constants.DEFAULT_ENABLED_HYPERVISOR),
638 552c8dff Michael Hanselmann
            cli_option("-H", "--hypervisor-parameters", dest="hvparams",
639 c38c44ad Michael Hanselmann
                       help="Hypervisor and hypervisor options, in the format"
640 c38c44ad Michael Hanselmann
                            " hypervisor:option=value,option=value,...",
641 ea3a925f Alexander Schreiber
                       default=[],
642 ea3a925f Alexander Schreiber
                       action="append",
643 ea3a925f Alexander Schreiber
                       type="identkeyval"),
644 087ed2ed Iustin Pop
            BACKEND_OPT,
645 552c8dff Michael Hanselmann
            cli_option("-N", "--nic-parameters", dest="nicparams",
646 552c8dff Michael Hanselmann
                       type="keyval", default={},
647 552c8dff Michael Hanselmann
                       help="NIC parameters"),
648 c38c44ad Michael Hanselmann
            cli_option("-C", "--candidate-pool-size",
649 c38c44ad Michael Hanselmann
                       default=constants.MASTER_POOL_SIZE_DEFAULT,
650 c38c44ad Michael Hanselmann
                       help="Set the candidate pool size",
651 c38c44ad Michael Hanselmann
                       dest="candidate_pool_size", type="int"),
652 a8083063 Iustin Pop
            ],
653 9a033156 Iustin Pop
           "[opts...] <cluster_name>",
654 a8083063 Iustin Pop
           "Initialises a new cluster configuration"),
655 4a265c08 Michael Hanselmann
  'destroy': (DestroyCluster, ARGS_NONE,
656 a8083063 Iustin Pop
              [DEBUG_OPT,
657 c38c44ad Michael Hanselmann
               cli_option("--yes-do-it", dest="yes_do_it",
658 c38c44ad Michael Hanselmann
                          help="Destroy cluster",
659 c38c44ad Michael Hanselmann
                          action="store_true"),
660 a8083063 Iustin Pop
              ],
661 9a033156 Iustin Pop
              "", "Destroy cluster"),
662 83ec7961 Michael Hanselmann
  'rename': (RenameCluster, [ArgHost(min=1, max=1)],
663 a8005e17 Michael Hanselmann
             [DEBUG_OPT, FORCE_OPT],
664 a8005e17 Michael Hanselmann
             "<new_name>",
665 a8005e17 Michael Hanselmann
             "Renames the cluster"),
666 4a265c08 Michael Hanselmann
  'redist-conf': (RedistributeConfig, ARGS_NONE, [DEBUG_OPT, SUBMIT_OPT],
667 afee0879 Iustin Pop
                  "",
668 afee0879 Iustin Pop
                  "Forces a push of the configuration file and ssconf files"
669 afee0879 Iustin Pop
                  " to the nodes in the cluster"),
670 7c874ee1 Iustin Pop
  'verify': (VerifyCluster, ARGS_NONE,
671 a0c9776a Iustin Pop
             [DEBUG_OPT, VERBOSE_OPT, DEBUG_SIMERR_OPT,
672 7c874ee1 Iustin Pop
              cli_option("--error-codes", dest="error_codes",
673 7c874ee1 Iustin Pop
                         help="Enable parseable error messages",
674 7c874ee1 Iustin Pop
                         action="store_true", default=False),
675 7c874ee1 Iustin Pop
              cli_option("--no-nplus1-mem", dest="skip_nplusone_mem",
676 7c874ee1 Iustin Pop
                         help="Skip N+1 memory redundancy tests",
677 7c874ee1 Iustin Pop
                         action="store_true", default=False),
678 7c874ee1 Iustin Pop
              ],
679 9a033156 Iustin Pop
             "", "Does a check on the cluster configuration"),
680 4a265c08 Michael Hanselmann
  'verify-disks': (VerifyDisks, ARGS_NONE, [DEBUG_OPT],
681 9a033156 Iustin Pop
                   "", "Does a check on the cluster disk status"),
682 4a265c08 Michael Hanselmann
  'repair-disk-sizes': (RepairDiskSizes, ARGS_MANY_INSTANCES, [DEBUG_OPT],
683 60975797 Iustin Pop
                   "", "Updates mismatches in recorded disk sizes"),
684 4a265c08 Michael Hanselmann
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT,
685 c38c44ad Michael Hanselmann
                     cli_option("--no-voting", dest="no_voting",
686 c38c44ad Michael Hanselmann
                                help="Skip node agreement check (dangerous)",
687 c38c44ad Michael Hanselmann
                                action="store_true",
688 c38c44ad Michael Hanselmann
                                default=False,),
689 8e2524c3 Guido Trotter
                     ],
690 9a033156 Iustin Pop
                     "", "Makes the current node the master"),
691 4a265c08 Michael Hanselmann
  'version': (ShowClusterVersion, ARGS_NONE, [DEBUG_OPT],
692 9a033156 Iustin Pop
              "", "Shows the cluster version"),
693 4a265c08 Michael Hanselmann
  'getmaster': (ShowClusterMaster, ARGS_NONE, [DEBUG_OPT],
694 9a033156 Iustin Pop
                "", "Shows the cluster master"),
695 a8005e17 Michael Hanselmann
  'copyfile': (ClusterCopyFile, [ArgFile(min=1, max=1)],
696 a8005e17 Michael Hanselmann
               [DEBUG_OPT, node_option],
697 9a033156 Iustin Pop
               "[-n node...] <filename>",
698 a8083063 Iustin Pop
               "Copies a file to all (or only some) nodes"),
699 a8005e17 Michael Hanselmann
  'command': (RunClusterCommand, [ArgCommand(min=1)], [DEBUG_OPT, node_option],
700 9a033156 Iustin Pop
              "[-n node...] <command>",
701 a8083063 Iustin Pop
              "Runs a command on all (or only some) nodes"),
702 4a265c08 Michael Hanselmann
  'info': (ShowClusterConfig, ARGS_NONE, [DEBUG_OPT],
703 a8005e17 Michael Hanselmann
           "", "Show cluster configuration"),
704 4a265c08 Michael Hanselmann
  'list-tags': (ListTags, ARGS_NONE,
705 9a033156 Iustin Pop
                [DEBUG_OPT], "", "List the tags of the cluster"),
706 a8005e17 Michael Hanselmann
  'add-tags': (AddTags, [ArgUnknown()], [DEBUG_OPT, TAG_SRC_OPT],
707 9a033156 Iustin Pop
               "tag...", "Add tags to the cluster"),
708 a8005e17 Michael Hanselmann
  'remove-tags': (RemoveTags, [ArgUnknown()], [DEBUG_OPT, TAG_SRC_OPT],
709 9a033156 Iustin Pop
                  "tag...", "Remove tags from the cluster"),
710 a8005e17 Michael Hanselmann
  'search-tags': (SearchTags, [ArgUnknown(min=1, max=1)],
711 9a033156 Iustin Pop
                  [DEBUG_OPT], "", "Searches the tags on all objects on"
712 73415719 Iustin Pop
                  " the cluster for a given pattern (regex)"),
713 a8005e17 Michael Hanselmann
  'queue': (QueueOps,
714 a8005e17 Michael Hanselmann
            [ArgChoice(min=1, max=1, choices=["drain", "undrain", "info"])],
715 a8005e17 Michael Hanselmann
            [DEBUG_OPT],
716 3ccafd0e Iustin Pop
            "drain|undrain|info", "Change queue properties"),
717 95b2e626 Michael Hanselmann
  'watcher': (WatcherOps,
718 95b2e626 Michael Hanselmann
              [ArgChoice(min=1, max=1,
719 95b2e626 Michael Hanselmann
                         choices=["pause", "continue", "info"]),
720 95b2e626 Michael Hanselmann
               ArgSuggest(min=0, max=1, choices=["30m", "1h", "4h"])],
721 95b2e626 Michael Hanselmann
              [DEBUG_OPT],
722 95b2e626 Michael Hanselmann
              "{pause <timespec>|continue|info}", "Change watcher properties"),
723 4a265c08 Michael Hanselmann
  'modify': (SetClusterParams, ARGS_NONE,
724 90b6aa3a Manuel Franceschini
             [DEBUG_OPT,
725 c38c44ad Michael Hanselmann
              cli_option("-g", "--vg-name", dest="vg_name",
726 c38c44ad Michael Hanselmann
                         help="Specify the volume group name "
727 c38c44ad Michael Hanselmann
                         " (cluster-wide) for disk allocation "
728 c38c44ad Michael Hanselmann
                         "and enable lvm based storage",
729 c38c44ad Michael Hanselmann
                         metavar="VG",),
730 c38c44ad Michael Hanselmann
              cli_option("--no-lvm-storage", dest="lvm_storage",
731 c38c44ad Michael Hanselmann
                         help="Disable support for lvm based instances"
732 c38c44ad Michael Hanselmann
                              " (cluster-wide)",
733 c38c44ad Michael Hanselmann
                         action="store_false", default=True,),
734 c38c44ad Michael Hanselmann
              cli_option("--enabled-hypervisors", dest="enabled_hypervisors",
735 c38c44ad Michael Hanselmann
                         help="Comma-separated list of hypervisors",
736 c38c44ad Michael Hanselmann
                         type="string", default=None),
737 552c8dff Michael Hanselmann
              cli_option("-H", "--hypervisor-parameters", dest="hvparams",
738 779c15bb Iustin Pop
                         help="Hypervisor and hypervisor options, in the"
739 779c15bb Iustin Pop
                         " format"
740 779c15bb Iustin Pop
                         " hypervisor:option=value,option=value,...",
741 779c15bb Iustin Pop
                         default=[],
742 779c15bb Iustin Pop
                         action="append",
743 779c15bb Iustin Pop
                         type="identkeyval"),
744 087ed2ed Iustin Pop
              BACKEND_OPT,
745 552c8dff Michael Hanselmann
              cli_option("-N", "--nic-parameters", dest="nicparams",
746 552c8dff Michael Hanselmann
                         type="keyval", default={},
747 552c8dff Michael Hanselmann
                         help="NIC parameters"),
748 c38c44ad Michael Hanselmann
              cli_option("-C", "--candidate-pool-size", default=None,
749 c38c44ad Michael Hanselmann
                         help="Set the candidate pool size",
750 c38c44ad Michael Hanselmann
                         dest="candidate_pool_size", type="int"),
751 90b6aa3a Manuel Franceschini
              ],
752 90b6aa3a Manuel Franceschini
             "[opts...]",
753 90b6aa3a Manuel Franceschini
             "Alters the parameters of the cluster"),
754 a8083063 Iustin Pop
  }
755 a8083063 Iustin Pop
756 a8083063 Iustin Pop
if __name__ == '__main__':
757 846baef9 Iustin Pop
  sys.exit(GenericMain(commands, override={"tag_type": constants.TAG_CLUSTER}))