Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-cluster @ 02715459

History | View | Annotate | Download (8 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2006, 2007 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
import sys
23
from optparse import make_option
24
import pprint
25

    
26
from ganeti.cli import *
27
from ganeti import opcodes
28
from ganeti import constants
29

    
30

    
31
def InitCluster(opts, args):
32
  """Initialize the cluster.
33

    
34
  Args:
35
    opts - class with options as members
36
    args - list of arguments, expected to be [clustername]
37

    
38
  """
39
  op = opcodes.OpInitCluster(cluster_name=args[0],
40
                             secondary_ip=opts.secondary_ip,
41
                             hypervisor_type=opts.hypervisor_type,
42
                             vg_name=opts.vg_name,
43
                             mac_prefix=opts.mac_prefix,
44
                             def_bridge=opts.def_bridge,
45
                             master_netdev=opts.master_netdev)
46
  SubmitOpCode(op)
47
  return 0
48

    
49

    
50
def DestroyCluster(opts, args):
51
  """Destroy the cluster.
52

    
53
  Args:
54
    opts - class with options as members
55

    
56
  """
57
  if not opts.yes_do_it:
58
    print ("Destroying a cluster is irreversibly. If you really want destroy"
59
           " this cluster, supply the --yes-do-it option.")
60
    return 1
61

    
62
  op = opcodes.OpDestroyCluster()
63
  SubmitOpCode(op)
64
  return 0
65

    
66

    
67
def ShowClusterVersion(opts, args):
68
  """Write version of ganeti software to the standard output.
69

    
70
  Args:
71
    opts - class with options as members
72

    
73
  """
74
  op = opcodes.OpQueryClusterInfo()
75
  result = SubmitOpCode(op)
76
  print ("Software version: %s" % result["software_version"])
77
  print ("Internode protocol: %s" % result["protocol_version"])
78
  print ("Configuration format: %s" % result["config_version"])
79
  print ("OS api version: %s" % result["os_api_version"])
80
  print ("Export interface: %s" % result["export_version"])
81
  return 0
82

    
83

    
84
def ShowClusterMaster(opts, args):
85
  """Write name of master node to the standard output.
86

    
87
  Args:
88
    opts - class with options as members
89

    
90
  """
91
  op = opcodes.OpQueryClusterInfo()
92
  result = SubmitOpCode(op)
93
  print (result["master"])
94
  return 0
95

    
96

    
97
def ShowClusterConfig(opts, args):
98
  """Shows cluster information.
99

    
100
  """
101
  op = opcodes.OpQueryClusterInfo()
102
  result = SubmitOpCode(op)
103

    
104
  print ("Cluster name: %s" % result["name"])
105

    
106
  print ("Master node: %s" % result["master"])
107

    
108
  print ("Architecture (this node): %s (%s)" %
109
         (result["architecture"][0], result["architecture"][1]))
110

    
111
  return 0
112

    
113

    
114
def ClusterCopyFile(opts, args):
115
  """Copy a file from master to some nodes.
116

    
117
  Args:
118
    opts - class with options as members
119
    args - list containing a single element, the file name
120
  Opts used:
121
    nodes - list containing the name of target nodes; if empty, all nodes
122

    
123
  """
124
  op = opcodes.OpClusterCopyFile(filename=args[0], nodes=opts.nodes)
125
  SubmitOpCode(op)
126
  return 0
127

    
128

    
129
def RunClusterCommand(opts, args):
130
  """Run a command on some nodes.
131

    
132
  Args:
133
    opts - class with options as members
134
    args - the command list as a list
135
  Opts used:
136
    nodes: list containing the name of target nodes; if empty, all nodes
137

    
138
  """
139
  command = " ".join(args)
140
  nodes = opts.nodes
141
  op = opcodes.OpRunClusterCommand(command=command, nodes=nodes)
142
  result = SubmitOpCode(op)
143
  for node, output, exit_code in result:
144
    print ("------------------------------------------------")
145
    print ("node: %s" % node)
146
    print ("%s" % output)
147
    print ("return code = %s" % exit_code)
148

    
149

    
150
def VerifyCluster(opts, args):
151
  """Verify integrity of cluster, performing various test on nodes.
152

    
153
  Args:
154
    opts - class with options as members
155

    
156
  """
157
  op = opcodes.OpVerifyCluster()
158
  result = SubmitOpCode(op)
159
  return result
160

    
161

    
162
def MasterFailover(opts, args):
163
  """Failover the master node.
164

    
165
  This command, when run on a non-master node, will cause the current
166
  master to cease being master, and the non-master to become new
167
  master.
168

    
169
  """
170
  op = opcodes.OpMasterFailover()
171
  SubmitOpCode(op)
172

    
173

    
174
# this is an option common to more than one command, so we declare
175
# it here and reuse it
176
node_option = make_option("-n", "--node", action="append", dest="nodes",
177
                          help="Node to copy to (if not given, all nodes)"
178
                          ", can be given multiple times", metavar="<node>",
179
                          default=[])
180

    
181
commands = {
182
  'init': (InitCluster, ARGS_ONE,
183
           [DEBUG_OPT,
184
            make_option("-s", "--secondary-ip", dest="secondary_ip",
185
                        help="Specify the secondary ip for this node;"
186
                        " if given, the entire cluster must have secondary"
187
                        " addresses",
188
                        metavar="ADDRESS", default=None),
189
            make_option("-t", "--hypervisor-type", dest="hypervisor_type",
190
                        help="Specify the hypervisor type (xen-3.0, fake)",
191
                        metavar="TYPE", choices=["xen-3.0", "fake"],
192
                        default="xen-3.0",),
193
            make_option("-m", "--mac-prefix", dest="mac_prefix",
194
                        help="Specify the mac prefix for the instance IP"
195
                        " addresses, in the format XX:XX:XX",
196
                        metavar="PREFIX",
197
                        default="aa:00:00",),
198
            make_option("-g", "--vg-name", dest="vg_name",
199
                        help="Specify the volume group name "
200
                        " (cluster-wide) for disk allocation [xenvg]",
201
                        metavar="VG",
202
                        default="xenvg",),
203
            make_option("-b", "--bridge", dest="def_bridge",
204
                        help="Specify the default bridge name (cluster-wide)"
205
                          " to connect the instances to [%s]" %
206
                          constants.DEFAULT_BRIDGE,
207
                        metavar="BRIDGE",
208
                        default=constants.DEFAULT_BRIDGE,),
209
            make_option("--master-netdev", dest="master_netdev",
210
                        help="Specify the node interface (cluster-wide)"
211
                          " on which the master IP address will be added "
212
                          " [%s]" % constants.DEFAULT_BRIDGE,
213
                        metavar="NETDEV",
214
                        default=constants.DEFAULT_BRIDGE,),
215
            ],
216
           "[opts...] <cluster_name>",
217
           "Initialises a new cluster configuration"),
218
  'destroy': (DestroyCluster, ARGS_NONE,
219
              [DEBUG_OPT,
220
               make_option("--yes-do-it", dest="yes_do_it",
221
                           help="Destroy cluster",
222
                           action="store_true"),
223
              ],
224
              "", "Destroy cluster"),
225
  'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT],
226
             "", "Does a check on the cluster configuration"),
227
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT],
228
                     "", "Makes the current node the master"),
229
  'version': (ShowClusterVersion, ARGS_NONE, [DEBUG_OPT],
230
              "", "Shows the cluster version"),
231
  'getmaster': (ShowClusterMaster, ARGS_NONE, [DEBUG_OPT],
232
                "", "Shows the cluster master"),
233
  'copyfile': (ClusterCopyFile, ARGS_ONE, [DEBUG_OPT, node_option],
234
               "[-n node...] <filename>",
235
               "Copies a file to all (or only some) nodes"),
236
  'command': (RunClusterCommand, ARGS_ATLEAST(1), [DEBUG_OPT, node_option],
237
              "[-n node...] <command>",
238
              "Runs a command on all (or only some) nodes"),
239
  'info': (ShowClusterConfig, ARGS_NONE, [DEBUG_OPT],
240
                 "", "Show cluster configuration"),
241
  }
242

    
243
if __name__ == '__main__':
244
  sys.exit(GenericMain(commands))