Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ 9ebe9556

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