Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ 2a6469d5

History | View | Annotate | Download (10.8 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
import sys
23 a8083063 Iustin Pop
from optparse import make_option
24 a8083063 Iustin Pop
import pprint
25 a8083063 Iustin Pop
26 a8083063 Iustin Pop
from ganeti.cli import *
27 a8083063 Iustin Pop
from ganeti import opcodes
28 c2a62a33 Michael Hanselmann
from ganeti import constants
29 f4d4e184 Iustin Pop
from ganeti import errors
30 a8083063 Iustin Pop
31 a8083063 Iustin Pop
32 a8083063 Iustin Pop
def InitCluster(opts, args):
33 a8083063 Iustin Pop
  """Initialize the cluster.
34 a8083063 Iustin Pop
35 a8083063 Iustin Pop
  Args:
36 a8083063 Iustin Pop
    opts - class with options as members
37 a8083063 Iustin Pop
    args - list of arguments, expected to be [clustername]
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
  """
40 a8083063 Iustin Pop
  op = opcodes.OpInitCluster(cluster_name=args[0],
41 a8083063 Iustin Pop
                             secondary_ip=opts.secondary_ip,
42 a8083063 Iustin Pop
                             hypervisor_type=opts.hypervisor_type,
43 a8083063 Iustin Pop
                             vg_name=opts.vg_name,
44 a8083063 Iustin Pop
                             mac_prefix=opts.mac_prefix,
45 880478f8 Iustin Pop
                             def_bridge=opts.def_bridge,
46 880478f8 Iustin Pop
                             master_netdev=opts.master_netdev)
47 a8083063 Iustin Pop
  SubmitOpCode(op)
48 a8083063 Iustin Pop
  return 0
49 a8083063 Iustin Pop
50 a8083063 Iustin Pop
51 a8083063 Iustin Pop
def DestroyCluster(opts, args):
52 a8083063 Iustin Pop
  """Destroy the cluster.
53 a8083063 Iustin Pop
54 a8083063 Iustin Pop
  Args:
55 a8083063 Iustin Pop
    opts - class with options as members
56 098c0958 Michael Hanselmann
57 a8083063 Iustin Pop
  """
58 a8083063 Iustin Pop
  if not opts.yes_do_it:
59 a8083063 Iustin Pop
    print ("Destroying a cluster is irreversibly. If you really want destroy"
60 79f7be7b Iustin Pop
           " this cluster, supply the --yes-do-it option.")
61 a8083063 Iustin Pop
    return 1
62 a8083063 Iustin Pop
63 a8083063 Iustin Pop
  op = opcodes.OpDestroyCluster()
64 a8083063 Iustin Pop
  SubmitOpCode(op)
65 a8083063 Iustin Pop
  return 0
66 a8083063 Iustin Pop
67 a8083063 Iustin Pop
68 07bd8a51 Iustin Pop
def RenameCluster(opts, args):
69 07bd8a51 Iustin Pop
  """Rename the cluster.
70 07bd8a51 Iustin Pop
71 07bd8a51 Iustin Pop
  Args:
72 07bd8a51 Iustin Pop
    opts - class with options as members, we use force only
73 07bd8a51 Iustin Pop
    args - list of arguments, expected to be [new_name]
74 07bd8a51 Iustin Pop
75 07bd8a51 Iustin Pop
  """
76 07bd8a51 Iustin Pop
  name = args[0]
77 07bd8a51 Iustin Pop
  if not opts.force:
78 07bd8a51 Iustin Pop
    usertext = ("This will rename the cluster to '%s'. If you are connected"
79 07bd8a51 Iustin Pop
                " over the network to the cluster name, the operation is very"
80 07bd8a51 Iustin Pop
                " dangerous as the IP address will be removed from the node"
81 07bd8a51 Iustin Pop
                " and the change may not go through. Continue?") % name
82 47988778 Iustin Pop
    if not AskUser(usertext):
83 07bd8a51 Iustin Pop
      return 1
84 07bd8a51 Iustin Pop
85 07bd8a51 Iustin Pop
  op = opcodes.OpRenameCluster(name=name)
86 07bd8a51 Iustin Pop
  SubmitOpCode(op)
87 07bd8a51 Iustin Pop
  return 0
88 07bd8a51 Iustin Pop
89 07bd8a51 Iustin Pop
90 a8083063 Iustin Pop
def ShowClusterVersion(opts, args):
91 a8083063 Iustin Pop
  """Write version of ganeti software to the standard output.
92 a8083063 Iustin Pop
93 a8083063 Iustin Pop
  Args:
94 a8083063 Iustin Pop
    opts - class with options as members
95 a8083063 Iustin Pop
96 a8083063 Iustin Pop
  """
97 a8083063 Iustin Pop
  op = opcodes.OpQueryClusterInfo()
98 a8083063 Iustin Pop
  result = SubmitOpCode(op)
99 a8083063 Iustin Pop
  print ("Software version: %s" % result["software_version"])
100 a8083063 Iustin Pop
  print ("Internode protocol: %s" % result["protocol_version"])
101 a8083063 Iustin Pop
  print ("Configuration format: %s" % result["config_version"])
102 a8083063 Iustin Pop
  print ("OS api version: %s" % result["os_api_version"])
103 a8083063 Iustin Pop
  print ("Export interface: %s" % result["export_version"])
104 a8083063 Iustin Pop
  return 0
105 a8083063 Iustin Pop
106 a8083063 Iustin Pop
107 a8083063 Iustin Pop
def ShowClusterMaster(opts, args):
108 a8083063 Iustin Pop
  """Write name of master node to the standard output.
109 a8083063 Iustin Pop
110 a8083063 Iustin Pop
  Args:
111 a8083063 Iustin Pop
    opts - class with options as members
112 a8083063 Iustin Pop
113 a8083063 Iustin Pop
  """
114 a8083063 Iustin Pop
  op = opcodes.OpQueryClusterInfo()
115 a8083063 Iustin Pop
  result = SubmitOpCode(op)
116 a8083063 Iustin Pop
  print (result["master"])
117 a8083063 Iustin Pop
  return 0
118 a8083063 Iustin Pop
119 a8083063 Iustin Pop
120 a8083063 Iustin Pop
def ShowClusterConfig(opts, args):
121 a8083063 Iustin Pop
  """Shows cluster information.
122 a8083063 Iustin Pop
123 a8083063 Iustin Pop
  """
124 a8083063 Iustin Pop
  op = opcodes.OpQueryClusterInfo()
125 a8083063 Iustin Pop
  result = SubmitOpCode(op)
126 a8083063 Iustin Pop
127 a8083063 Iustin Pop
  print ("Cluster name: %s" % result["name"])
128 a8083063 Iustin Pop
129 a8083063 Iustin Pop
  print ("Master node: %s" % result["master"])
130 a8083063 Iustin Pop
131 59322403 Iustin Pop
  print ("Architecture (this node): %s (%s)" %
132 59322403 Iustin Pop
         (result["architecture"][0], result["architecture"][1]))
133 a8083063 Iustin Pop
134 a8083063 Iustin Pop
  return 0
135 a8083063 Iustin Pop
136 a8083063 Iustin Pop
137 a8083063 Iustin Pop
def ClusterCopyFile(opts, args):
138 a8083063 Iustin Pop
  """Copy a file from master to some nodes.
139 a8083063 Iustin Pop
140 a8083063 Iustin Pop
  Args:
141 a8083063 Iustin Pop
    opts - class with options as members
142 a8083063 Iustin Pop
    args - list containing a single element, the file name
143 a8083063 Iustin Pop
  Opts used:
144 a8083063 Iustin Pop
    nodes - list containing the name of target nodes; if empty, all nodes
145 a8083063 Iustin Pop
146 a8083063 Iustin Pop
  """
147 a8083063 Iustin Pop
  op = opcodes.OpClusterCopyFile(filename=args[0], nodes=opts.nodes)
148 a8083063 Iustin Pop
  SubmitOpCode(op)
149 a8083063 Iustin Pop
  return 0
150 a8083063 Iustin Pop
151 a8083063 Iustin Pop
152 a8083063 Iustin Pop
def RunClusterCommand(opts, args):
153 a8083063 Iustin Pop
  """Run a command on some nodes.
154 a8083063 Iustin Pop
155 a8083063 Iustin Pop
  Args:
156 a8083063 Iustin Pop
    opts - class with options as members
157 a8083063 Iustin Pop
    args - the command list as a list
158 a8083063 Iustin Pop
  Opts used:
159 a8083063 Iustin Pop
    nodes: list containing the name of target nodes; if empty, all nodes
160 a8083063 Iustin Pop
161 a8083063 Iustin Pop
  """
162 a8083063 Iustin Pop
  command = " ".join(args)
163 a8083063 Iustin Pop
  nodes = opts.nodes
164 a8083063 Iustin Pop
  op = opcodes.OpRunClusterCommand(command=command, nodes=nodes)
165 a8083063 Iustin Pop
  result = SubmitOpCode(op)
166 02715459 Iustin Pop
  for node, output, exit_code in result:
167 a8083063 Iustin Pop
    print ("------------------------------------------------")
168 a8083063 Iustin Pop
    print ("node: %s" % node)
169 a8083063 Iustin Pop
    print ("%s" % output)
170 a8083063 Iustin Pop
    print ("return code = %s" % exit_code)
171 a8083063 Iustin Pop
172 a8083063 Iustin Pop
173 a8083063 Iustin Pop
def VerifyCluster(opts, args):
174 a8083063 Iustin Pop
  """Verify integrity of cluster, performing various test on nodes.
175 a8083063 Iustin Pop
176 a8083063 Iustin Pop
  Args:
177 a8083063 Iustin Pop
    opts - class with options as members
178 a8083063 Iustin Pop
179 a8083063 Iustin Pop
  """
180 a8083063 Iustin Pop
  op = opcodes.OpVerifyCluster()
181 a8083063 Iustin Pop
  result = SubmitOpCode(op)
182 a8083063 Iustin Pop
  return result
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
185 f4d4e184 Iustin Pop
def VerifyDisks(opts, args):
186 f4d4e184 Iustin Pop
  """Verify integrity of cluster disks.
187 f4d4e184 Iustin Pop
188 f4d4e184 Iustin Pop
  Args:
189 f4d4e184 Iustin Pop
    opts - class with options as members
190 f4d4e184 Iustin Pop
191 f4d4e184 Iustin Pop
  """
192 f4d4e184 Iustin Pop
  op = opcodes.OpVerifyDisks()
193 f4d4e184 Iustin Pop
  result = SubmitOpCode(op)
194 f4d4e184 Iustin Pop
  if not isinstance(result, tuple) or len(result) != 2:
195 f4d4e184 Iustin Pop
    raise errors.ProgrammerError("Unknown result type for OpVerifyDisks")
196 f4d4e184 Iustin Pop
197 f4d4e184 Iustin Pop
  nodes, instances = result
198 f4d4e184 Iustin Pop
  if nodes:
199 f4d4e184 Iustin Pop
    print "Nodes unreachable or with bad data:"
200 f4d4e184 Iustin Pop
    for name in nodes:
201 f4d4e184 Iustin Pop
      print "\t%s" % name
202 f4d4e184 Iustin Pop
  retcode = constants.EXIT_SUCCESS
203 f4d4e184 Iustin Pop
  if instances:
204 f4d4e184 Iustin Pop
    for iname in instances:
205 f4d4e184 Iustin Pop
      op = opcodes.OpActivateInstanceDisks(instance_name=iname)
206 f4d4e184 Iustin Pop
      try:
207 f4d4e184 Iustin Pop
        print "Activating disks for instance '%s'" % iname
208 f4d4e184 Iustin Pop
        SubmitOpCode(op)
209 f4d4e184 Iustin Pop
      except errors.GenericError, err:
210 f4d4e184 Iustin Pop
        nret, msg = FormatError(err)
211 f4d4e184 Iustin Pop
        retcode |= nret
212 f4d4e184 Iustin Pop
        print >>sys.stderr, ("Error activating disks for instance %s: %s" %
213 f4d4e184 Iustin Pop
                             (iname, msg))
214 f4d4e184 Iustin Pop
215 f4d4e184 Iustin Pop
  return retcode
216 f4d4e184 Iustin Pop
217 f4d4e184 Iustin Pop
218 a8083063 Iustin Pop
def MasterFailover(opts, args):
219 a8083063 Iustin Pop
  """Failover the master node.
220 a8083063 Iustin Pop
221 a8083063 Iustin Pop
  This command, when run on a non-master node, will cause the current
222 a8083063 Iustin Pop
  master to cease being master, and the non-master to become new
223 a8083063 Iustin Pop
  master.
224 a8083063 Iustin Pop
225 a8083063 Iustin Pop
  """
226 a8083063 Iustin Pop
  op = opcodes.OpMasterFailover()
227 a8083063 Iustin Pop
  SubmitOpCode(op)
228 a8083063 Iustin Pop
229 a8083063 Iustin Pop
230 73415719 Iustin Pop
def SearchTags(opts, args):
231 73415719 Iustin Pop
  """Searches the tags on all the cluster.
232 73415719 Iustin Pop
233 73415719 Iustin Pop
  """
234 73415719 Iustin Pop
  op = opcodes.OpSearchTags(pattern=args[0])
235 73415719 Iustin Pop
  result = SubmitOpCode(op)
236 73415719 Iustin Pop
  if not result:
237 73415719 Iustin Pop
    return 1
238 73415719 Iustin Pop
  result = list(result)
239 73415719 Iustin Pop
  result.sort()
240 73415719 Iustin Pop
  for path, tag in result:
241 73415719 Iustin Pop
    print "%s %s" % (path, tag)
242 73415719 Iustin Pop
243 73415719 Iustin Pop
244 a8083063 Iustin Pop
# this is an option common to more than one command, so we declare
245 a8083063 Iustin Pop
# it here and reuse it
246 a8083063 Iustin Pop
node_option = make_option("-n", "--node", action="append", dest="nodes",
247 f4bc1f2c Michael Hanselmann
                          help="Node to copy to (if not given, all nodes),"
248 f4bc1f2c Michael Hanselmann
                               " can be given multiple times",
249 f4bc1f2c Michael Hanselmann
                          metavar="<node>", default=[])
250 a8083063 Iustin Pop
251 a8083063 Iustin Pop
commands = {
252 a8083063 Iustin Pop
  'init': (InitCluster, ARGS_ONE,
253 a8083063 Iustin Pop
           [DEBUG_OPT,
254 a8083063 Iustin Pop
            make_option("-s", "--secondary-ip", dest="secondary_ip",
255 a8083063 Iustin Pop
                        help="Specify the secondary ip for this node;"
256 a8083063 Iustin Pop
                        " if given, the entire cluster must have secondary"
257 a8083063 Iustin Pop
                        " addresses",
258 a8083063 Iustin Pop
                        metavar="ADDRESS", default=None),
259 a8083063 Iustin Pop
            make_option("-t", "--hypervisor-type", dest="hypervisor_type",
260 2a6469d5 Alexander Schreiber
                        help="Specify the hypervisor type "
261 2a6469d5 Alexander Schreiber
                        "(xen-3.0, fake, xen-hvm-3.1)",
262 2a6469d5 Alexander Schreiber
                        metavar="TYPE", choices=["xen-3.0",
263 2a6469d5 Alexander Schreiber
                                                 "fake",
264 2a6469d5 Alexander Schreiber
                                                 "xen-hvm-3.1"],
265 a8083063 Iustin Pop
                        default="xen-3.0",),
266 a8083063 Iustin Pop
            make_option("-m", "--mac-prefix", dest="mac_prefix",
267 a8083063 Iustin Pop
                        help="Specify the mac prefix for the instance IP"
268 a8083063 Iustin Pop
                        " addresses, in the format XX:XX:XX",
269 a8083063 Iustin Pop
                        metavar="PREFIX",
270 a8083063 Iustin Pop
                        default="aa:00:00",),
271 a8083063 Iustin Pop
            make_option("-g", "--vg-name", dest="vg_name",
272 a8083063 Iustin Pop
                        help="Specify the volume group name "
273 a8083063 Iustin Pop
                        " (cluster-wide) for disk allocation [xenvg]",
274 a8083063 Iustin Pop
                        metavar="VG",
275 a8083063 Iustin Pop
                        default="xenvg",),
276 a8083063 Iustin Pop
            make_option("-b", "--bridge", dest="def_bridge",
277 a8083063 Iustin Pop
                        help="Specify the default bridge name (cluster-wide)"
278 cf62a272 Michael Hanselmann
                          " to connect the instances to [%s]" %
279 cf62a272 Michael Hanselmann
                          constants.DEFAULT_BRIDGE,
280 a8083063 Iustin Pop
                        metavar="BRIDGE",
281 cf62a272 Michael Hanselmann
                        default=constants.DEFAULT_BRIDGE,),
282 880478f8 Iustin Pop
            make_option("--master-netdev", dest="master_netdev",
283 880478f8 Iustin Pop
                        help="Specify the node interface (cluster-wide)"
284 cf62a272 Michael Hanselmann
                          " on which the master IP address will be added "
285 cf62a272 Michael Hanselmann
                          " [%s]" % constants.DEFAULT_BRIDGE,
286 880478f8 Iustin Pop
                        metavar="NETDEV",
287 cf62a272 Michael Hanselmann
                        default=constants.DEFAULT_BRIDGE,),
288 a8083063 Iustin Pop
            ],
289 a8083063 Iustin Pop
           "[opts...] <cluster_name>",
290 a8083063 Iustin Pop
           "Initialises a new cluster configuration"),
291 a8083063 Iustin Pop
  'destroy': (DestroyCluster, ARGS_NONE,
292 a8083063 Iustin Pop
              [DEBUG_OPT,
293 a8083063 Iustin Pop
               make_option("--yes-do-it", dest="yes_do_it",
294 a8083063 Iustin Pop
                           help="Destroy cluster",
295 a8083063 Iustin Pop
                           action="store_true"),
296 a8083063 Iustin Pop
              ],
297 a8083063 Iustin Pop
              "", "Destroy cluster"),
298 07bd8a51 Iustin Pop
  'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
299 07bd8a51 Iustin Pop
               "<new_name>",
300 07bd8a51 Iustin Pop
               "Renames the cluster"),
301 a8083063 Iustin Pop
  'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT],
302 a8083063 Iustin Pop
             "", "Does a check on the cluster configuration"),
303 f4d4e184 Iustin Pop
  'verify-disks': (VerifyDisks, ARGS_NONE, [DEBUG_OPT],
304 f4d4e184 Iustin Pop
                   "", "Does a check on the cluster disk status"),
305 a8083063 Iustin Pop
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT],
306 a8083063 Iustin Pop
                     "", "Makes the current node the master"),
307 a8083063 Iustin Pop
  'version': (ShowClusterVersion, ARGS_NONE, [DEBUG_OPT],
308 a8083063 Iustin Pop
              "", "Shows the cluster version"),
309 a8083063 Iustin Pop
  'getmaster': (ShowClusterMaster, ARGS_NONE, [DEBUG_OPT],
310 a8083063 Iustin Pop
                "", "Shows the cluster master"),
311 a8083063 Iustin Pop
  'copyfile': (ClusterCopyFile, ARGS_ONE, [DEBUG_OPT, node_option],
312 a8083063 Iustin Pop
               "[-n node...] <filename>",
313 a8083063 Iustin Pop
               "Copies a file to all (or only some) nodes"),
314 a8083063 Iustin Pop
  'command': (RunClusterCommand, ARGS_ATLEAST(1), [DEBUG_OPT, node_option],
315 a8083063 Iustin Pop
              "[-n node...] <command>",
316 a8083063 Iustin Pop
              "Runs a command on all (or only some) nodes"),
317 a8083063 Iustin Pop
  'info': (ShowClusterConfig, ARGS_NONE, [DEBUG_OPT],
318 a8083063 Iustin Pop
                 "", "Show cluster configuration"),
319 846baef9 Iustin Pop
  'list-tags': (ListTags, ARGS_NONE,
320 846baef9 Iustin Pop
                [DEBUG_OPT], "", "List the tags of the cluster"),
321 810c50b7 Iustin Pop
  'add-tags': (AddTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
322 846baef9 Iustin Pop
               "tag...", "Add tags to the cluster"),
323 810c50b7 Iustin Pop
  'remove-tags': (RemoveTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
324 846baef9 Iustin Pop
                  "tag...", "Remove tags from the cluster"),
325 73415719 Iustin Pop
  'search-tags': (SearchTags, ARGS_ONE,
326 73415719 Iustin Pop
                  [DEBUG_OPT], "", "Searches the tags on all objects on"
327 73415719 Iustin Pop
                  " the cluster for a given pattern (regex)"),
328 a8083063 Iustin Pop
  }
329 a8083063 Iustin Pop
330 a8083063 Iustin Pop
if __name__ == '__main__':
331 846baef9 Iustin Pop
  sys.exit(GenericMain(commands, override={"tag_type": constants.TAG_CLUSTER}))