Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-instance @ 12c3449a

History | View | Annotate | Download (30.6 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
import os
24 312ac745 Iustin Pop
import itertools
25 a8083063 Iustin Pop
from optparse import make_option
26 a8083063 Iustin Pop
from cStringIO import StringIO
27 a8083063 Iustin Pop
28 a8083063 Iustin Pop
from ganeti.cli import *
29 a8083063 Iustin Pop
from ganeti import opcodes
30 a8083063 Iustin Pop
from ganeti import logger
31 a8083063 Iustin Pop
from ganeti import constants
32 a8083063 Iustin Pop
from ganeti import utils
33 312ac745 Iustin Pop
from ganeti import errors
34 312ac745 Iustin Pop
35 312ac745 Iustin Pop
36 312ac745 Iustin Pop
_SHUTDOWN_CLUSTER = "cluster"
37 312ac745 Iustin Pop
_SHUTDOWN_NODES_BOTH = "nodes"
38 312ac745 Iustin Pop
_SHUTDOWN_NODES_PRI = "nodes-pri"
39 312ac745 Iustin Pop
_SHUTDOWN_NODES_SEC = "nodes-sec"
40 312ac745 Iustin Pop
_SHUTDOWN_INSTANCES = "instances"
41 312ac745 Iustin Pop
42 312ac745 Iustin Pop
def _ExpandMultiNames(mode, names):
43 312ac745 Iustin Pop
  """Expand the given names using the passed mode.
44 312ac745 Iustin Pop
45 312ac745 Iustin Pop
  Args:
46 312ac745 Iustin Pop
    - mode, which can be one of _SHUTDOWN_CLUSTER, _SHUTDOWN_NODES_BOTH,
47 312ac745 Iustin Pop
      _SHUTDOWN_NODES_PRI, _SHUTDOWN_NODES_SEC or _SHUTDOWN_INSTANCES
48 312ac745 Iustin Pop
    - names, which is a list of names; for cluster, it must be empty,
49 312ac745 Iustin Pop
      and for node and instance it must be a list of valid item
50 312ac745 Iustin Pop
      names (short names are valid as usual, e.g. node1 instead of
51 312ac745 Iustin Pop
      node1.example.com)
52 312ac745 Iustin Pop
53 312ac745 Iustin Pop
  For _SHUTDOWN_CLUSTER, all instances will be returned. For
54 312ac745 Iustin Pop
  _SHUTDOWN_NODES_PRI/SEC, all instances having those nodes as
55 312ac745 Iustin Pop
  primary/secondary will be shutdown. For _SHUTDOWN_NODES_BOTH, all
56 312ac745 Iustin Pop
  instances having those nodes as either primary or secondary will be
57 312ac745 Iustin Pop
  returned. For _SHUTDOWN_INSTANCES, the given instances will be
58 312ac745 Iustin Pop
  returned.
59 312ac745 Iustin Pop
60 312ac745 Iustin Pop
  """
61 312ac745 Iustin Pop
  if mode == _SHUTDOWN_CLUSTER:
62 312ac745 Iustin Pop
    if names:
63 312ac745 Iustin Pop
      raise errors.OpPrereqError("Cluster filter mode takes no arguments")
64 312ac745 Iustin Pop
    op = opcodes.OpQueryInstances(output_fields=["name"], names=[])
65 312ac745 Iustin Pop
    idata = SubmitOpCode(op)
66 312ac745 Iustin Pop
    inames = [row[0] for row in idata]
67 312ac745 Iustin Pop
68 312ac745 Iustin Pop
  elif mode in (_SHUTDOWN_NODES_BOTH,
69 312ac745 Iustin Pop
                _SHUTDOWN_NODES_PRI,
70 312ac745 Iustin Pop
                _SHUTDOWN_NODES_SEC):
71 312ac745 Iustin Pop
    if not names:
72 312ac745 Iustin Pop
      raise errors.OpPrereqError("No node names passed")
73 312ac745 Iustin Pop
    op = opcodes.OpQueryNodes(output_fields=["name", "pinst_list",
74 312ac745 Iustin Pop
                                             "sinst_list"], names=names)
75 312ac745 Iustin Pop
    ndata = SubmitOpCode(op)
76 312ac745 Iustin Pop
    ipri = [row[1] for row in ndata]
77 312ac745 Iustin Pop
    pri_names = list(itertools.chain(*ipri))
78 312ac745 Iustin Pop
    isec = [row[2] for row in ndata]
79 312ac745 Iustin Pop
    sec_names = list(itertools.chain(*isec))
80 312ac745 Iustin Pop
    if mode == _SHUTDOWN_NODES_BOTH:
81 312ac745 Iustin Pop
      inames = pri_names + sec_names
82 312ac745 Iustin Pop
    elif mode == _SHUTDOWN_NODES_PRI:
83 312ac745 Iustin Pop
      inames = pri_names
84 312ac745 Iustin Pop
    elif mode == _SHUTDOWN_NODES_SEC:
85 312ac745 Iustin Pop
      inames = sec_names
86 312ac745 Iustin Pop
    else:
87 312ac745 Iustin Pop
      raise errors.ProgrammerError("Unhandled shutdown type")
88 312ac745 Iustin Pop
89 312ac745 Iustin Pop
  elif mode == _SHUTDOWN_INSTANCES:
90 312ac745 Iustin Pop
    if not names:
91 312ac745 Iustin Pop
      raise errors.OpPrereqError("No instance names passed")
92 312ac745 Iustin Pop
    op = opcodes.OpQueryInstances(output_fields=["name"], names=names)
93 312ac745 Iustin Pop
    idata = SubmitOpCode(op)
94 312ac745 Iustin Pop
    inames = [row[0] for row in idata]
95 312ac745 Iustin Pop
96 312ac745 Iustin Pop
  else:
97 312ac745 Iustin Pop
    raise errors.OpPrereqError("Unknown mode '%s'" % mode)
98 312ac745 Iustin Pop
99 312ac745 Iustin Pop
  return inames
100 a8083063 Iustin Pop
101 a8083063 Iustin Pop
102 804a1e8e Iustin Pop
def _ConfirmOperation(inames, text):
103 804a1e8e Iustin Pop
  """Ask the user to confirm an operation on a list of instances.
104 804a1e8e Iustin Pop
105 804a1e8e Iustin Pop
  This function is used to request confirmation for doing an operation
106 804a1e8e Iustin Pop
  on a given list of instances.
107 804a1e8e Iustin Pop
108 804a1e8e Iustin Pop
  The inames argument is what the selection algorithm computed, and
109 804a1e8e Iustin Pop
  the text argument is the operation we should tell the user to
110 804a1e8e Iustin Pop
  confirm (e.g. 'shutdown' or 'startup').
111 804a1e8e Iustin Pop
112 804a1e8e Iustin Pop
  Returns: boolean depending on user's confirmation.
113 804a1e8e Iustin Pop
114 804a1e8e Iustin Pop
  """
115 804a1e8e Iustin Pop
  count = len(inames)
116 804a1e8e Iustin Pop
  msg = ("The %s will operate on %d instances.\n"
117 804a1e8e Iustin Pop
         "Do you want to continue?" % (text, count))
118 804a1e8e Iustin Pop
  affected = ("\nAffected instances:\n" +
119 804a1e8e Iustin Pop
              "\n".join(["  %s" % name for name in inames]))
120 804a1e8e Iustin Pop
121 804a1e8e Iustin Pop
  choices = [('y', True, 'Yes, execute the %s' % text),
122 804a1e8e Iustin Pop
             ('n', False, 'No, abort the %s' % text)]
123 804a1e8e Iustin Pop
124 804a1e8e Iustin Pop
  if count > 20:
125 804a1e8e Iustin Pop
    choices.insert(1, ('v', 'v', 'View the list of affected instances'))
126 804a1e8e Iustin Pop
    ask = msg
127 804a1e8e Iustin Pop
  else:
128 804a1e8e Iustin Pop
    ask = msg + affected
129 804a1e8e Iustin Pop
130 804a1e8e Iustin Pop
  choice = AskUser(ask, choices)
131 804a1e8e Iustin Pop
  if choice == 'v':
132 804a1e8e Iustin Pop
    choices.pop(1)
133 804a1e8e Iustin Pop
    choice = AskUser(choices, msg + affected)
134 804a1e8e Iustin Pop
  return choice
135 804a1e8e Iustin Pop
136 804a1e8e Iustin Pop
137 a8083063 Iustin Pop
def ListInstances(opts, args):
138 f5abe9bd Oleksiy Mishchenko
  """List instances and their properties.
139 a8083063 Iustin Pop
140 a8083063 Iustin Pop
  """
141 a8083063 Iustin Pop
  if opts.output is None:
142 a8083063 Iustin Pop
    selected_fields = ["name", "os", "pnode", "admin_state",
143 a8083063 Iustin Pop
                       "oper_state", "oper_ram"]
144 a8083063 Iustin Pop
  else:
145 a8083063 Iustin Pop
    selected_fields = opts.output.split(",")
146 a8083063 Iustin Pop
147 069dcc86 Iustin Pop
  op = opcodes.OpQueryInstances(output_fields=selected_fields, names=[])
148 a8083063 Iustin Pop
  output = SubmitOpCode(op)
149 a8083063 Iustin Pop
150 a8083063 Iustin Pop
  if not opts.no_headers:
151 137161c9 Michael Hanselmann
    headers = {"name": "Instance", "os": "OS", "pnode": "Primary_node",
152 137161c9 Michael Hanselmann
               "snodes": "Secondary_Nodes", "admin_state": "Autostart",
153 137161c9 Michael Hanselmann
               "oper_state": "Status", "admin_ram": "Configured_memory",
154 137161c9 Michael Hanselmann
               "oper_ram": "Memory", "disk_template": "Disk_template",
155 137161c9 Michael Hanselmann
               "ip": "IP Address", "mac": "MAC Address",
156 644eeef9 Iustin Pop
               "bridge": "Bridge",
157 644eeef9 Iustin Pop
               "sda_size": "Disk/0", "sdb_size": "Disk/1"}
158 137161c9 Michael Hanselmann
  else:
159 137161c9 Michael Hanselmann
    headers = None
160 137161c9 Michael Hanselmann
161 137161c9 Michael Hanselmann
  if opts.human_readable:
162 644eeef9 Iustin Pop
    unitfields = ["admin_ram", "oper_ram", "sda_size", "sdb_size"]
163 137161c9 Michael Hanselmann
  else:
164 137161c9 Michael Hanselmann
    unitfields = None
165 137161c9 Michael Hanselmann
166 644eeef9 Iustin Pop
  numfields = ["admin_ram", "oper_ram", "sda_size", "sdb_size"]
167 137161c9 Michael Hanselmann
168 8a23d2d3 Iustin Pop
  # change raw values to nicer strings
169 8a23d2d3 Iustin Pop
  for row in output:
170 8a23d2d3 Iustin Pop
    for idx, field in enumerate(selected_fields):
171 8a23d2d3 Iustin Pop
      val = row[idx]
172 8a23d2d3 Iustin Pop
      if field == "snodes":
173 8a23d2d3 Iustin Pop
        val = ",".join(val) or "-"
174 8a23d2d3 Iustin Pop
      elif field == "admin_state":
175 8a23d2d3 Iustin Pop
        if val:
176 8a23d2d3 Iustin Pop
          val = "yes"
177 8a23d2d3 Iustin Pop
        else:
178 8a23d2d3 Iustin Pop
          val = "no"
179 8a23d2d3 Iustin Pop
      elif field == "oper_state":
180 8a23d2d3 Iustin Pop
        if val is None:
181 8a23d2d3 Iustin Pop
          val = "(node down)"
182 8a23d2d3 Iustin Pop
        elif val: # True
183 8a23d2d3 Iustin Pop
          val = "running"
184 8a23d2d3 Iustin Pop
        else:
185 8a23d2d3 Iustin Pop
          val = "stopped"
186 8a23d2d3 Iustin Pop
      elif field == "oper_ram":
187 8a23d2d3 Iustin Pop
        if val is None:
188 8a23d2d3 Iustin Pop
          val = "(node down)"
189 8a23d2d3 Iustin Pop
      elif field == "sda_size" or field == "sdb_size":
190 8a23d2d3 Iustin Pop
        if val is None:
191 8a23d2d3 Iustin Pop
          val = "N/A"
192 8a23d2d3 Iustin Pop
      row[idx] = str(val)
193 8a23d2d3 Iustin Pop
194 16be8703 Iustin Pop
  data = GenerateTable(separator=opts.separator, headers=headers,
195 16be8703 Iustin Pop
                       fields=selected_fields, unitfields=unitfields,
196 16be8703 Iustin Pop
                       numfields=numfields, data=output)
197 16be8703 Iustin Pop
198 16be8703 Iustin Pop
  for line in data:
199 16be8703 Iustin Pop
    logger.ToStdout(line)
200 a8083063 Iustin Pop
201 a8083063 Iustin Pop
  return 0
202 a8083063 Iustin Pop
203 a8083063 Iustin Pop
204 a8083063 Iustin Pop
def AddInstance(opts, args):
205 a8083063 Iustin Pop
  """Add an instance to the cluster.
206 a8083063 Iustin Pop
207 a8083063 Iustin Pop
  Args:
208 a8083063 Iustin Pop
    opts - class with options as members
209 a8083063 Iustin Pop
    args - list with a single element, the instance name
210 a8083063 Iustin Pop
  Opts used:
211 a8083063 Iustin Pop
    mem - amount of memory to allocate to instance (MiB)
212 a8083063 Iustin Pop
    size - amount of disk space to allocate to instance (MiB)
213 a8083063 Iustin Pop
    os - which OS to run on instance
214 a8083063 Iustin Pop
    node - node to run new instance on
215 a8083063 Iustin Pop
216 a8083063 Iustin Pop
  """
217 a8083063 Iustin Pop
  instance = args[0]
218 a8083063 Iustin Pop
219 60d49723 Michael Hanselmann
  (pnode, snode) = SplitNodeOption(opts.node)
220 60d49723 Michael Hanselmann
221 a8083063 Iustin Pop
  op = opcodes.OpCreateInstance(instance_name=instance, mem_size=opts.mem,
222 a8083063 Iustin Pop
                                disk_size=opts.size, swap_size=opts.swap,
223 a8083063 Iustin Pop
                                disk_template=opts.disk_template,
224 a8083063 Iustin Pop
                                mode=constants.INSTANCE_CREATE,
225 60d49723 Michael Hanselmann
                                os_type=opts.os, pnode=pnode,
226 60d49723 Michael Hanselmann
                                snode=snode, vcpus=opts.vcpus,
227 bdd55f71 Iustin Pop
                                ip=opts.ip, bridge=opts.bridge,
228 bdd55f71 Iustin Pop
                                start=opts.start, ip_check=opts.ip_check,
229 a8083063 Iustin Pop
                                wait_for_sync=opts.wait_for_sync)
230 a8083063 Iustin Pop
  SubmitOpCode(op)
231 a8083063 Iustin Pop
  return 0
232 a8083063 Iustin Pop
233 a8083063 Iustin Pop
234 fe7b0351 Michael Hanselmann
def ReinstallInstance(opts, args):
235 fe7b0351 Michael Hanselmann
  """Reinstall an instance.
236 fe7b0351 Michael Hanselmann
237 fe7b0351 Michael Hanselmann
  Args:
238 fe7b0351 Michael Hanselmann
    opts - class with options as members
239 fe7b0351 Michael Hanselmann
    args - list containing a single element, the instance name
240 fe7b0351 Michael Hanselmann
241 fe7b0351 Michael Hanselmann
  """
242 fe7b0351 Michael Hanselmann
  instance_name = args[0]
243 fe7b0351 Michael Hanselmann
244 fe7b0351 Michael Hanselmann
  if not opts.force:
245 fe7b0351 Michael Hanselmann
    usertext = ("This will reinstall the instance %s and remove "
246 fe7b0351 Michael Hanselmann
                "all data. Continue?") % instance_name
247 47988778 Iustin Pop
    if not AskUser(usertext):
248 fe7b0351 Michael Hanselmann
      return 1
249 fe7b0351 Michael Hanselmann
250 d0834de3 Michael Hanselmann
  op = opcodes.OpReinstallInstance(instance_name=instance_name,
251 d0834de3 Michael Hanselmann
                                   os_type=opts.os)
252 fe7b0351 Michael Hanselmann
  SubmitOpCode(op)
253 fe7b0351 Michael Hanselmann
254 fe7b0351 Michael Hanselmann
  return 0
255 fe7b0351 Michael Hanselmann
256 fe7b0351 Michael Hanselmann
257 a8083063 Iustin Pop
def RemoveInstance(opts, args):
258 a8083063 Iustin Pop
  """Remove an instance.
259 a8083063 Iustin Pop
260 a8083063 Iustin Pop
  Args:
261 a8083063 Iustin Pop
    opts - class with options as members
262 a8083063 Iustin Pop
    args - list containing a single element, the instance name
263 a8083063 Iustin Pop
264 a8083063 Iustin Pop
  """
265 a8083063 Iustin Pop
  instance_name = args[0]
266 a8083063 Iustin Pop
  force = opts.force
267 a8083063 Iustin Pop
268 a8083063 Iustin Pop
  if not force:
269 a8083063 Iustin Pop
    usertext = ("This will remove the volumes of the instance %s"
270 a8083063 Iustin Pop
                " (including mirrors), thus removing all the data"
271 a8083063 Iustin Pop
                " of the instance. Continue?") % instance_name
272 47988778 Iustin Pop
    if not AskUser(usertext):
273 a8083063 Iustin Pop
      return 1
274 a8083063 Iustin Pop
275 1d67656e Iustin Pop
  op = opcodes.OpRemoveInstance(instance_name=instance_name,
276 1d67656e Iustin Pop
                                ignore_failures=opts.ignore_failures)
277 a8083063 Iustin Pop
  SubmitOpCode(op)
278 a8083063 Iustin Pop
  return 0
279 a8083063 Iustin Pop
280 a8083063 Iustin Pop
281 decd5f45 Iustin Pop
def RenameInstance(opts, args):
282 4ab0b9e3 Guido Trotter
  """Rename an instance.
283 decd5f45 Iustin Pop
284 decd5f45 Iustin Pop
  Args:
285 decd5f45 Iustin Pop
    opts - class with options as members
286 decd5f45 Iustin Pop
    args - list containing two elements, the instance name and the new name
287 decd5f45 Iustin Pop
288 decd5f45 Iustin Pop
  """
289 decd5f45 Iustin Pop
  op = opcodes.OpRenameInstance(instance_name=args[0],
290 decd5f45 Iustin Pop
                                new_name=args[1],
291 decd5f45 Iustin Pop
                                ignore_ip=opts.ignore_ip)
292 decd5f45 Iustin Pop
  SubmitOpCode(op)
293 decd5f45 Iustin Pop
294 decd5f45 Iustin Pop
  return 0
295 decd5f45 Iustin Pop
296 decd5f45 Iustin Pop
297 a8083063 Iustin Pop
def ActivateDisks(opts, args):
298 a8083063 Iustin Pop
  """Activate an instance's disks.
299 a8083063 Iustin Pop
300 a8083063 Iustin Pop
  This serves two purposes:
301 a8083063 Iustin Pop
    - it allows one (as long as the instance is not running) to mount
302 a8083063 Iustin Pop
    the disks and modify them from the node
303 a8083063 Iustin Pop
    - it repairs inactive secondary drbds
304 a8083063 Iustin Pop
305 a8083063 Iustin Pop
  """
306 a8083063 Iustin Pop
  instance_name = args[0]
307 a8083063 Iustin Pop
  op = opcodes.OpActivateInstanceDisks(instance_name=instance_name)
308 a8083063 Iustin Pop
  disks_info = SubmitOpCode(op)
309 a8083063 Iustin Pop
  for host, iname, nname in disks_info:
310 a8083063 Iustin Pop
    print "%s:%s:%s" % (host, iname, nname)
311 a8083063 Iustin Pop
  return 0
312 a8083063 Iustin Pop
313 a8083063 Iustin Pop
314 a8083063 Iustin Pop
def DeactivateDisks(opts, args):
315 a8083063 Iustin Pop
  """Command-line interface for _ShutdownInstanceBlockDevices.
316 a8083063 Iustin Pop
317 a8083063 Iustin Pop
  This function takes the instance name, looks for its primary node
318 a8083063 Iustin Pop
  and the tries to shutdown its block devices on that node.
319 a8083063 Iustin Pop
320 a8083063 Iustin Pop
  """
321 a8083063 Iustin Pop
  instance_name = args[0]
322 a8083063 Iustin Pop
  op = opcodes.OpDeactivateInstanceDisks(instance_name=instance_name)
323 a8083063 Iustin Pop
  SubmitOpCode(op)
324 a8083063 Iustin Pop
  return 0
325 a8083063 Iustin Pop
326 a8083063 Iustin Pop
327 a8083063 Iustin Pop
def StartupInstance(opts, args):
328 decd5f45 Iustin Pop
  """Startup an instance.
329 a8083063 Iustin Pop
330 a8083063 Iustin Pop
  Args:
331 a8083063 Iustin Pop
    opts - class with options as members
332 a8083063 Iustin Pop
    args - list containing a single element, the instance name
333 a8083063 Iustin Pop
334 a8083063 Iustin Pop
  """
335 312ac745 Iustin Pop
  if opts.multi_mode is None:
336 312ac745 Iustin Pop
    opts.multi_mode = _SHUTDOWN_INSTANCES
337 312ac745 Iustin Pop
  inames = _ExpandMultiNames(opts.multi_mode, args)
338 bcee9cb4 Iustin Pop
  if not inames:
339 bcee9cb4 Iustin Pop
    raise errors.OpPrereqError("Selection filter does not match any instances")
340 804a1e8e Iustin Pop
  multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
341 804a1e8e Iustin Pop
  if not (opts.force_multi or not multi_on
342 804a1e8e Iustin Pop
          or _ConfirmOperation(inames, "startup")):
343 804a1e8e Iustin Pop
    return 1
344 312ac745 Iustin Pop
  for name in inames:
345 312ac745 Iustin Pop
    op = opcodes.OpStartupInstance(instance_name=name,
346 312ac745 Iustin Pop
                                   force=opts.force,
347 312ac745 Iustin Pop
                                   extra_args=opts.extra_args)
348 312ac745 Iustin Pop
    if multi_on:
349 312ac745 Iustin Pop
      logger.ToStdout("Starting up %s" % name)
350 312ac745 Iustin Pop
    SubmitOpCode(op)
351 a8083063 Iustin Pop
  return 0
352 a8083063 Iustin Pop
353 579d4337 Alexander Schreiber
def RebootInstance(opts, args):
354 579d4337 Alexander Schreiber
  """Reboot an instance
355 579d4337 Alexander Schreiber
356 579d4337 Alexander Schreiber
  Args:
357 579d4337 Alexander Schreiber
    opts - class with options as members
358 579d4337 Alexander Schreiber
    args - list containing a single element, the instance name
359 579d4337 Alexander Schreiber
360 579d4337 Alexander Schreiber
  """
361 579d4337 Alexander Schreiber
  if opts.multi_mode is None:
362 579d4337 Alexander Schreiber
    opts.multi_mode = _SHUTDOWN_INSTANCES
363 579d4337 Alexander Schreiber
  inames = _ExpandMultiNames(opts.multi_mode, args)
364 bcee9cb4 Iustin Pop
  if not inames:
365 bcee9cb4 Iustin Pop
    raise errors.OpPrereqError("Selection filter does not match any instances")
366 579d4337 Alexander Schreiber
  multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
367 579d4337 Alexander Schreiber
  if not (opts.force_multi or not multi_on
368 579d4337 Alexander Schreiber
          or _ConfirmOperation(inames, "reboot")):
369 579d4337 Alexander Schreiber
    return 1
370 579d4337 Alexander Schreiber
  for name in inames:
371 579d4337 Alexander Schreiber
    op = opcodes.OpRebootInstance(instance_name=name,
372 579d4337 Alexander Schreiber
                                  reboot_type=opts.reboot_type,
373 579d4337 Alexander Schreiber
                                  ignore_secondaries=opts.ignore_secondaries)
374 579d4337 Alexander Schreiber
375 579d4337 Alexander Schreiber
    SubmitOpCode(op)
376 579d4337 Alexander Schreiber
  return 0
377 a8083063 Iustin Pop
378 a8083063 Iustin Pop
def ShutdownInstance(opts, args):
379 a8083063 Iustin Pop
  """Shutdown an instance.
380 a8083063 Iustin Pop
381 a8083063 Iustin Pop
  Args:
382 a8083063 Iustin Pop
    opts - class with options as members
383 a8083063 Iustin Pop
    args - list containing a single element, the instance name
384 a8083063 Iustin Pop
385 a8083063 Iustin Pop
  """
386 312ac745 Iustin Pop
  if opts.multi_mode is None:
387 312ac745 Iustin Pop
    opts.multi_mode = _SHUTDOWN_INSTANCES
388 312ac745 Iustin Pop
  inames = _ExpandMultiNames(opts.multi_mode, args)
389 bcee9cb4 Iustin Pop
  if not inames:
390 bcee9cb4 Iustin Pop
    raise errors.OpPrereqError("Selection filter does not match any instances")
391 804a1e8e Iustin Pop
  multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
392 804a1e8e Iustin Pop
  if not (opts.force_multi or not multi_on
393 804a1e8e Iustin Pop
          or _ConfirmOperation(inames, "shutdown")):
394 804a1e8e Iustin Pop
    return 1
395 312ac745 Iustin Pop
  for name in inames:
396 312ac745 Iustin Pop
    op = opcodes.OpShutdownInstance(instance_name=name)
397 312ac745 Iustin Pop
    if multi_on:
398 312ac745 Iustin Pop
      logger.ToStdout("Shutting down %s" % name)
399 312ac745 Iustin Pop
    SubmitOpCode(op)
400 a8083063 Iustin Pop
  return 0
401 a8083063 Iustin Pop
402 a8083063 Iustin Pop
403 a8083063 Iustin Pop
def AddMDDRBDComponent(opts, args):
404 a8083063 Iustin Pop
  """Add a new component to a remote_raid1 disk.
405 a8083063 Iustin Pop
406 a8083063 Iustin Pop
  Args:
407 a8083063 Iustin Pop
    opts - class with options as members
408 a8083063 Iustin Pop
    args - list with a single element, the instance name
409 a8083063 Iustin Pop
410 a8083063 Iustin Pop
  """
411 a8083063 Iustin Pop
  op = opcodes.OpAddMDDRBDComponent(instance_name=args[0],
412 a8083063 Iustin Pop
                                    disk_name=opts.disk,
413 a8083063 Iustin Pop
                                    remote_node=opts.node)
414 a8083063 Iustin Pop
  SubmitOpCode(op)
415 a8083063 Iustin Pop
  return 0
416 a8083063 Iustin Pop
417 a8083063 Iustin Pop
418 a8083063 Iustin Pop
def RemoveMDDRBDComponent(opts, args):
419 bdb8c997 Guido Trotter
  """Remove a component from a remote_raid1 disk.
420 a8083063 Iustin Pop
421 a8083063 Iustin Pop
  Args:
422 a8083063 Iustin Pop
    opts - class with options as members
423 a8083063 Iustin Pop
    args - list with a single element, the instance name
424 a8083063 Iustin Pop
425 a8083063 Iustin Pop
  """
426 a8083063 Iustin Pop
  op = opcodes.OpRemoveMDDRBDComponent(instance_name=args[0],
427 a8083063 Iustin Pop
                                       disk_name=opts.disk,
428 a8083063 Iustin Pop
                                       disk_id=opts.port)
429 a8083063 Iustin Pop
  SubmitOpCode(op)
430 a8083063 Iustin Pop
  return 0
431 a8083063 Iustin Pop
432 a8083063 Iustin Pop
433 a8083063 Iustin Pop
def ReplaceDisks(opts, args):
434 a8083063 Iustin Pop
  """Replace the disks of an instance
435 a8083063 Iustin Pop
436 a8083063 Iustin Pop
  Args:
437 a8083063 Iustin Pop
    opts - class with options as members
438 a8083063 Iustin Pop
    args - list with a single element, the instance name
439 a8083063 Iustin Pop
440 a8083063 Iustin Pop
  """
441 a8083063 Iustin Pop
  instance_name = args[0]
442 a9e0c397 Iustin Pop
  new_2ndary = opts.new_secondary
443 a9e0c397 Iustin Pop
  if opts.disks is None:
444 a9e0c397 Iustin Pop
    disks = ["sda", "sdb"]
445 a9e0c397 Iustin Pop
  else:
446 a9e0c397 Iustin Pop
    disks = opts.disks.split(",")
447 a9e0c397 Iustin Pop
  if opts.on_primary == opts.on_secondary: # no -p or -s passed, or both passed
448 a9e0c397 Iustin Pop
    mode = constants.REPLACE_DISK_ALL
449 a9e0c397 Iustin Pop
  elif opts.on_primary: # only on primary:
450 a9e0c397 Iustin Pop
    mode = constants.REPLACE_DISK_PRI
451 a9e0c397 Iustin Pop
    if new_2ndary is not None:
452 a9e0c397 Iustin Pop
      raise errors.OpPrereqError("Can't change secondary node on primary disk"
453 a9e0c397 Iustin Pop
                                 " replacement")
454 a9e0c397 Iustin Pop
  elif opts.on_secondary is not None: # only on secondary
455 a9e0c397 Iustin Pop
    mode = constants.REPLACE_DISK_SEC
456 a9e0c397 Iustin Pop
457 a9e0c397 Iustin Pop
  op = opcodes.OpReplaceDisks(instance_name=args[0], disks=disks,
458 a9e0c397 Iustin Pop
                              remote_node=new_2ndary, mode=mode)
459 a8083063 Iustin Pop
  SubmitOpCode(op)
460 a8083063 Iustin Pop
  return 0
461 a8083063 Iustin Pop
462 a8083063 Iustin Pop
463 a8083063 Iustin Pop
def FailoverInstance(opts, args):
464 a8083063 Iustin Pop
  """Failover an instance.
465 a8083063 Iustin Pop
466 a8083063 Iustin Pop
  The failover is done by shutting it down on its present node and
467 a8083063 Iustin Pop
  starting it on the secondary.
468 a8083063 Iustin Pop
469 a8083063 Iustin Pop
  Args:
470 a8083063 Iustin Pop
    opts - class with options as members
471 a8083063 Iustin Pop
    args - list with a single element, the instance name
472 a8083063 Iustin Pop
  Opts used:
473 a8083063 Iustin Pop
    force - whether to failover without asking questions.
474 a8083063 Iustin Pop
475 a8083063 Iustin Pop
  """
476 80de0e3f Iustin Pop
  instance_name = args[0]
477 80de0e3f Iustin Pop
  force = opts.force
478 a8083063 Iustin Pop
479 80de0e3f Iustin Pop
  if not force:
480 80de0e3f Iustin Pop
    usertext = ("Failover will happen to image %s."
481 80de0e3f Iustin Pop
                " This requires a shutdown of the instance. Continue?" %
482 80de0e3f Iustin Pop
                (instance_name,))
483 80de0e3f Iustin Pop
    if not AskUser(usertext):
484 80de0e3f Iustin Pop
      return 1
485 a8083063 Iustin Pop
486 80de0e3f Iustin Pop
  op = opcodes.OpFailoverInstance(instance_name=instance_name,
487 80de0e3f Iustin Pop
                                  ignore_consistency=opts.ignore_consistency)
488 80de0e3f Iustin Pop
  SubmitOpCode(op)
489 80de0e3f Iustin Pop
  return 0
490 a8083063 Iustin Pop
491 a8083063 Iustin Pop
492 a8083063 Iustin Pop
def ConnectToInstanceConsole(opts, args):
493 a8083063 Iustin Pop
  """Connect to the console of an instance.
494 a8083063 Iustin Pop
495 a8083063 Iustin Pop
  Args:
496 a8083063 Iustin Pop
    opts - class with options as members
497 a8083063 Iustin Pop
    args - list with a single element, the instance name
498 a8083063 Iustin Pop
499 a8083063 Iustin Pop
  """
500 a8083063 Iustin Pop
  instance_name = args[0]
501 a8083063 Iustin Pop
502 a8083063 Iustin Pop
  op = opcodes.OpConnectConsole(instance_name=instance_name)
503 82122173 Iustin Pop
  cmd, argv = SubmitOpCode(op)
504 a8083063 Iustin Pop
  # drop lock and exec so other commands can run while we have console
505 a8083063 Iustin Pop
  utils.Unlock("cmd")
506 a8083063 Iustin Pop
  try:
507 82122173 Iustin Pop
    os.execvp(cmd, argv)
508 a8083063 Iustin Pop
  finally:
509 82122173 Iustin Pop
    sys.stderr.write("Can't run console command %s with arguments:\n'%s'" %
510 82122173 Iustin Pop
                     (cmd, " ".join(argv)))
511 a8083063 Iustin Pop
    os._exit(1)
512 a8083063 Iustin Pop
513 a8083063 Iustin Pop
514 a8083063 Iustin Pop
def _FormatBlockDevInfo(buf, dev, indent_level):
515 a8083063 Iustin Pop
  """Show block device information.
516 a8083063 Iustin Pop
517 a8083063 Iustin Pop
  This is only used by ShowInstanceConfig(), but it's too big to be
518 a8083063 Iustin Pop
  left for an inline definition.
519 a8083063 Iustin Pop
520 a8083063 Iustin Pop
  """
521 a8083063 Iustin Pop
  def helper(buf, dtype, status):
522 a8083063 Iustin Pop
    """Format one line for phsyical device status."""
523 a8083063 Iustin Pop
    if not status:
524 a8083063 Iustin Pop
      buf.write("not active\n")
525 a8083063 Iustin Pop
    else:
526 0834c866 Iustin Pop
      (path, major, minor, syncp, estt, degr, ldisk) = status
527 a8083063 Iustin Pop
      buf.write("%s (%d:%d)" % (path, major, minor))
528 a1f445d3 Iustin Pop
      if dtype in (constants.LD_MD_R1, constants.LD_DRBD7, constants.LD_DRBD8):
529 a8083063 Iustin Pop
        if syncp is not None:
530 a8083063 Iustin Pop
          sync_text = "*RECOVERING* %5.2f%%," % syncp
531 a8083063 Iustin Pop
          if estt:
532 a8083063 Iustin Pop
            sync_text += " ETA %ds" % estt
533 a8083063 Iustin Pop
          else:
534 a8083063 Iustin Pop
            sync_text += " ETA unknown"
535 a8083063 Iustin Pop
        else:
536 a8083063 Iustin Pop
          sync_text = "in sync"
537 a8083063 Iustin Pop
        if degr:
538 a8083063 Iustin Pop
          degr_text = "*DEGRADED*"
539 a8083063 Iustin Pop
        else:
540 a8083063 Iustin Pop
          degr_text = "ok"
541 0834c866 Iustin Pop
        if ldisk:
542 0834c866 Iustin Pop
          ldisk_text = " *MISSING DISK*"
543 0834c866 Iustin Pop
        else:
544 0834c866 Iustin Pop
          ldisk_text = ""
545 0834c866 Iustin Pop
        buf.write(" %s, status %s%s" % (sync_text, degr_text, ldisk_text))
546 9db6dbce Iustin Pop
      elif dtype == constants.LD_LV:
547 0834c866 Iustin Pop
        if ldisk:
548 0834c866 Iustin Pop
          ldisk_text = " *FAILED* (failed drive?)"
549 9db6dbce Iustin Pop
        else:
550 0834c866 Iustin Pop
          ldisk_text = ""
551 0834c866 Iustin Pop
        buf.write(ldisk_text)
552 a8083063 Iustin Pop
      buf.write("\n")
553 a8083063 Iustin Pop
554 a8083063 Iustin Pop
  if dev["iv_name"] is not None:
555 a8083063 Iustin Pop
    data = "  - %s, " % dev["iv_name"]
556 a8083063 Iustin Pop
  else:
557 a8083063 Iustin Pop
    data = "  - "
558 a8083063 Iustin Pop
  data += "type: %s" % dev["dev_type"]
559 a8083063 Iustin Pop
  if dev["logical_id"] is not None:
560 a8083063 Iustin Pop
    data += ", logical_id: %s" % (dev["logical_id"],)
561 a8083063 Iustin Pop
  elif dev["physical_id"] is not None:
562 a8083063 Iustin Pop
    data += ", physical_id: %s" % (dev["physical_id"],)
563 a8083063 Iustin Pop
  buf.write("%*s%s\n" % (2*indent_level, "", data))
564 a8083063 Iustin Pop
  buf.write("%*s    primary:   " % (2*indent_level, ""))
565 a8083063 Iustin Pop
  helper(buf, dev["dev_type"], dev["pstatus"])
566 a8083063 Iustin Pop
567 a8083063 Iustin Pop
  if dev["sstatus"]:
568 a8083063 Iustin Pop
    buf.write("%*s    secondary: " % (2*indent_level, ""))
569 a8083063 Iustin Pop
    helper(buf, dev["dev_type"], dev["sstatus"])
570 a8083063 Iustin Pop
571 a8083063 Iustin Pop
  if dev["children"]:
572 a8083063 Iustin Pop
    for child in dev["children"]:
573 a8083063 Iustin Pop
      _FormatBlockDevInfo(buf, child, indent_level+1)
574 a8083063 Iustin Pop
575 a8083063 Iustin Pop
576 a8083063 Iustin Pop
def ShowInstanceConfig(opts, args):
577 a8083063 Iustin Pop
  """Compute instance run-time status.
578 a8083063 Iustin Pop
579 a8083063 Iustin Pop
  """
580 a8083063 Iustin Pop
  retcode = 0
581 a8083063 Iustin Pop
  op = opcodes.OpQueryInstanceData(instances=args)
582 a8083063 Iustin Pop
  result = SubmitOpCode(op)
583 a8083063 Iustin Pop
584 a8083063 Iustin Pop
  if not result:
585 a8083063 Iustin Pop
    logger.ToStdout("No instances.")
586 a8083063 Iustin Pop
    return 1
587 a8083063 Iustin Pop
588 a8083063 Iustin Pop
  buf = StringIO()
589 a8083063 Iustin Pop
  retcode = 0
590 a8083063 Iustin Pop
  for instance_name in result:
591 a8083063 Iustin Pop
    instance = result[instance_name]
592 a8083063 Iustin Pop
    buf.write("Instance name: %s\n" % instance["name"])
593 a8083063 Iustin Pop
    buf.write("State: configured to be %s, actual state is %s\n" %
594 a8083063 Iustin Pop
              (instance["config_state"], instance["run_state"]))
595 a8083063 Iustin Pop
    buf.write("  Nodes:\n")
596 a8083063 Iustin Pop
    buf.write("    - primary: %s\n" % instance["pnode"])
597 a8083063 Iustin Pop
    buf.write("    - secondaries: %s\n" % ", ".join(instance["snodes"]))
598 a8083063 Iustin Pop
    buf.write("  Operating system: %s\n" % instance["os"])
599 a8083063 Iustin Pop
    buf.write("  Hardware:\n")
600 f55ff7ec Iustin Pop
    buf.write("    - VCPUs: %d\n" % instance["vcpus"])
601 a8083063 Iustin Pop
    buf.write("    - memory: %dMiB\n" % instance["memory"])
602 a8083063 Iustin Pop
    buf.write("    - NICs: %s\n" %
603 a8083063 Iustin Pop
        ", ".join(["{MAC: %s, IP: %s, bridge: %s}" %
604 a8083063 Iustin Pop
                   (mac, ip, bridge)
605 a8083063 Iustin Pop
                     for mac, ip, bridge in instance["nics"]]))
606 a8083063 Iustin Pop
    buf.write("  Block devices:\n")
607 a8083063 Iustin Pop
608 a8083063 Iustin Pop
    for device in instance["disks"]:
609 a8083063 Iustin Pop
      _FormatBlockDevInfo(buf, device, 1)
610 a8083063 Iustin Pop
611 a8083063 Iustin Pop
  logger.ToStdout(buf.getvalue().rstrip('\n'))
612 a8083063 Iustin Pop
  return retcode
613 a8083063 Iustin Pop
614 a8083063 Iustin Pop
615 a8083063 Iustin Pop
def SetInstanceParms(opts, args):
616 a8083063 Iustin Pop
  """Modifies an instance.
617 a8083063 Iustin Pop
618 a8083063 Iustin Pop
  All parameters take effect only at the next restart of the instance.
619 a8083063 Iustin Pop
620 a8083063 Iustin Pop
  Args:
621 a8083063 Iustin Pop
    opts - class with options as members
622 a8083063 Iustin Pop
    args - list with a single element, the instance name
623 a8083063 Iustin Pop
  Opts used:
624 a8083063 Iustin Pop
    memory - the new memory size
625 a8083063 Iustin Pop
    vcpus - the new number of cpus
626 a8083063 Iustin Pop
627 a8083063 Iustin Pop
  """
628 a8083063 Iustin Pop
  if not opts.mem and not opts.vcpus and not opts.ip and not opts.bridge:
629 a8083063 Iustin Pop
    logger.ToStdout("Please give at least one of the parameters.")
630 a8083063 Iustin Pop
    return 1
631 a8083063 Iustin Pop
632 a8083063 Iustin Pop
  op = opcodes.OpSetInstanceParms(instance_name=args[0], mem=opts.mem,
633 a8083063 Iustin Pop
                                  vcpus=opts.vcpus, ip=opts.ip,
634 a8083063 Iustin Pop
                                  bridge=opts.bridge)
635 a8083063 Iustin Pop
  result = SubmitOpCode(op)
636 a8083063 Iustin Pop
637 a8083063 Iustin Pop
  if result:
638 a8083063 Iustin Pop
    logger.ToStdout("Modified instance %s" % args[0])
639 a8083063 Iustin Pop
    for param, data in result:
640 a8083063 Iustin Pop
      logger.ToStdout(" - %-5s -> %s" % (param, data))
641 a8083063 Iustin Pop
    logger.ToStdout("Please don't forget that these parameters take effect"
642 a8083063 Iustin Pop
                    " only at the next start of the instance.")
643 a8083063 Iustin Pop
  return 0
644 a8083063 Iustin Pop
645 a8083063 Iustin Pop
646 a8083063 Iustin Pop
# options used in more than one cmd
647 a8083063 Iustin Pop
node_opt = make_option("-n", "--node", dest="node", help="Target node",
648 a8083063 Iustin Pop
                       metavar="<node>")
649 a8083063 Iustin Pop
650 d0834de3 Michael Hanselmann
os_opt = cli_option("-o", "--os-type", dest="os", help="What OS to run",
651 739ecd56 Michael Hanselmann
                    metavar="<os>")
652 d0834de3 Michael Hanselmann
653 312ac745 Iustin Pop
# multi-instance selection options
654 804a1e8e Iustin Pop
m_force_multi = make_option("--force-multiple", dest="force_multi",
655 804a1e8e Iustin Pop
                            help="Do not ask for confirmation when more than"
656 804a1e8e Iustin Pop
                            " one instance is affected",
657 804a1e8e Iustin Pop
                            action="store_true", default=False)
658 804a1e8e Iustin Pop
659 312ac745 Iustin Pop
m_pri_node_opt = make_option("--primary", dest="multi_mode",
660 312ac745 Iustin Pop
                             help="Filter by nodes (primary only)",
661 312ac745 Iustin Pop
                             const=_SHUTDOWN_NODES_PRI, action="store_const")
662 312ac745 Iustin Pop
663 312ac745 Iustin Pop
m_sec_node_opt = make_option("--secondary", dest="multi_mode",
664 312ac745 Iustin Pop
                             help="Filter by nodes (secondary only)",
665 312ac745 Iustin Pop
                             const=_SHUTDOWN_NODES_SEC, action="store_const")
666 312ac745 Iustin Pop
667 312ac745 Iustin Pop
m_node_opt = make_option("--node", dest="multi_mode",
668 312ac745 Iustin Pop
                         help="Filter by nodes (primary and secondary)",
669 312ac745 Iustin Pop
                         const=_SHUTDOWN_NODES_BOTH, action="store_const")
670 312ac745 Iustin Pop
671 312ac745 Iustin Pop
m_clust_opt = make_option("--all", dest="multi_mode",
672 312ac745 Iustin Pop
                          help="Select all instances in the cluster",
673 312ac745 Iustin Pop
                          const=_SHUTDOWN_CLUSTER, action="store_const")
674 312ac745 Iustin Pop
675 312ac745 Iustin Pop
m_inst_opt = make_option("--instance", dest="multi_mode",
676 312ac745 Iustin Pop
                         help="Filter by instance name [default]",
677 312ac745 Iustin Pop
                         const=_SHUTDOWN_INSTANCES, action="store_const")
678 312ac745 Iustin Pop
679 312ac745 Iustin Pop
680 a8083063 Iustin Pop
# this is defined separately due to readability only
681 a8083063 Iustin Pop
add_opts = [
682 a8083063 Iustin Pop
  DEBUG_OPT,
683 60d49723 Michael Hanselmann
  make_option("-n", "--node", dest="node",
684 60d49723 Michael Hanselmann
              help="Target node and optional secondary node",
685 60d49723 Michael Hanselmann
              metavar="<pnode>[:<snode>]"),
686 b9ac33e9 Iustin Pop
  cli_option("-s", "--os-size", dest="size", help="Disk size, in MiB unless"
687 b9ac33e9 Iustin Pop
             " a suffix is used",
688 a8083063 Iustin Pop
             default=20 * 1024, type="unit", metavar="<size>"),
689 b9ac33e9 Iustin Pop
  cli_option("--swap-size", dest="swap", help="Swap size, in MiB unless a"
690 b9ac33e9 Iustin Pop
             " suffix is used",
691 a8083063 Iustin Pop
             default=4 * 1024, type="unit", metavar="<size>"),
692 d0834de3 Michael Hanselmann
  os_opt,
693 b9ac33e9 Iustin Pop
  cli_option("-m", "--memory", dest="mem", help="Memory size (in MiB)",
694 a8083063 Iustin Pop
              default=128, type="unit", metavar="<mem>"),
695 a8083063 Iustin Pop
  make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs",
696 a8083063 Iustin Pop
              default=1, type="int", metavar="<PROC>"),
697 a8083063 Iustin Pop
  make_option("-t", "--disk-template", dest="disk_template",
698 a1f445d3 Iustin Pop
              help="Custom disk setup (diskless, plain, local_raid1,"
699 a1f445d3 Iustin Pop
              " remote_raid1 or drbd)", default=None, metavar="TEMPL"),
700 a8083063 Iustin Pop
  make_option("-i", "--ip", dest="ip",
701 a8083063 Iustin Pop
              help="IP address ('none' [default], 'auto', or specify address)",
702 a8083063 Iustin Pop
              default='none', type="string", metavar="<ADDRESS>"),
703 a8083063 Iustin Pop
  make_option("--no-wait-for-sync", dest="wait_for_sync", default=True,
704 a8083063 Iustin Pop
              action="store_false", help="Don't wait for sync (DANGEROUS!)"),
705 a8083063 Iustin Pop
  make_option("-b", "--bridge", dest="bridge",
706 a8083063 Iustin Pop
              help="Bridge to connect this instance to",
707 bdd55f71 Iustin Pop
              default=None, metavar="<bridge>"),
708 bdd55f71 Iustin Pop
  make_option("--no-start", dest="start", default=True,
709 bdd55f71 Iustin Pop
              action="store_false", help="Don't start the instance after"
710 bdd55f71 Iustin Pop
              " creation"),
711 bdd55f71 Iustin Pop
  make_option("--no-ip-check", dest="ip_check", default=True,
712 bdd55f71 Iustin Pop
              action="store_false", help="Don't check that the instance's IP"
713 bdd55f71 Iustin Pop
              " is alive (only valid with --no-start)"),
714 a8083063 Iustin Pop
  ]
715 a8083063 Iustin Pop
716 a8083063 Iustin Pop
commands = {
717 a8083063 Iustin Pop
  'add': (AddInstance, ARGS_ONE, add_opts,
718 a8083063 Iustin Pop
          "[opts...] <name>",
719 a8083063 Iustin Pop
          "Creates and adds a new instance to the cluster"),
720 a8083063 Iustin Pop
  'add-mirror': (AddMDDRBDComponent, ARGS_ONE,
721 a8083063 Iustin Pop
                [DEBUG_OPT, node_opt,
722 a8083063 Iustin Pop
                 make_option("-b", "--disk", dest="disk", metavar="sdX",
723 a8083063 Iustin Pop
                             help=("The name of the instance disk for which to"
724 a8083063 Iustin Pop
                                   " add the mirror"))],
725 a8083063 Iustin Pop
                "-n node -b disk <instance>",
726 a8083063 Iustin Pop
                "Creates a new mirror for the instance"),
727 a8083063 Iustin Pop
  'console': (ConnectToInstanceConsole, ARGS_ONE, [DEBUG_OPT],
728 a8083063 Iustin Pop
              "<instance>",
729 a8083063 Iustin Pop
              "Opens a console on the specified instance"),
730 80de0e3f Iustin Pop
  'failover': (FailoverInstance, ARGS_ONE,
731 fe7b0351 Michael Hanselmann
               [DEBUG_OPT, FORCE_OPT,
732 a8083063 Iustin Pop
                make_option("--ignore-consistency", dest="ignore_consistency",
733 a8083063 Iustin Pop
                            action="store_true", default=False,
734 a8083063 Iustin Pop
                            help="Ignore the consistency of the disks on"
735 a8083063 Iustin Pop
                            " the secondary"),
736 a8083063 Iustin Pop
                ],
737 a8083063 Iustin Pop
               "[-f] <instance>",
738 a8083063 Iustin Pop
               "Stops the instance and starts it on the backup node, using"
739 a8083063 Iustin Pop
               " the remote mirror (only for instances of type remote_raid1)"),
740 a8083063 Iustin Pop
  'info': (ShowInstanceConfig, ARGS_ANY, [DEBUG_OPT], "[<instance>...]",
741 a8083063 Iustin Pop
           "Show information on the specified instance"),
742 a8083063 Iustin Pop
  'list': (ListInstances, ARGS_NONE,
743 dcb93971 Michael Hanselmann
           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
744 a8083063 Iustin Pop
           "", "Lists the instances and their status"),
745 d0834de3 Michael Hanselmann
  'reinstall': (ReinstallInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT, os_opt],
746 fe7b0351 Michael Hanselmann
                "[-f] <instance>", "Reinstall the instance"),
747 1d67656e Iustin Pop
  'remove': (RemoveInstance, ARGS_ONE,
748 1d67656e Iustin Pop
             [DEBUG_OPT, FORCE_OPT,
749 1d67656e Iustin Pop
              make_option("--ignore-failures", dest="ignore_failures",
750 1d67656e Iustin Pop
                          action="store_true", default=False,
751 1d67656e Iustin Pop
                          help=("Remove the instance from the cluster even"
752 1d67656e Iustin Pop
                                " if there are failures during the removal"
753 1d67656e Iustin Pop
                                " process (shutdown, disk removal, etc.)")),
754 1d67656e Iustin Pop
              ],
755 a8083063 Iustin Pop
             "[-f] <instance>", "Shuts down the instance and removes it"),
756 a8083063 Iustin Pop
  'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE,
757 a8083063 Iustin Pop
                   [DEBUG_OPT, node_opt,
758 a8083063 Iustin Pop
                    make_option("-b", "--disk", dest="disk", metavar="sdX",
759 a8083063 Iustin Pop
                                help=("The name of the instance disk"
760 a8083063 Iustin Pop
                                      " for which to add the mirror")),
761 a8083063 Iustin Pop
                    make_option("-p", "--port", dest="port", metavar="PORT",
762 a8083063 Iustin Pop
                                help=("The port of the drbd device"
763 a8083063 Iustin Pop
                                      " which to remove from the mirror"),
764 a8083063 Iustin Pop
                                type="int"),
765 a8083063 Iustin Pop
                    ],
766 a8083063 Iustin Pop
                   "-b disk -p port <instance>",
767 a8083063 Iustin Pop
                   "Removes a mirror from the instance"),
768 decd5f45 Iustin Pop
  'rename': (RenameInstance, ARGS_FIXED(2),
769 decd5f45 Iustin Pop
             [DEBUG_OPT,
770 decd5f45 Iustin Pop
              make_option("--no-ip-check", dest="ignore_ip",
771 decd5f45 Iustin Pop
                          help="Do not check that the IP of the new name"
772 decd5f45 Iustin Pop
                          " is alive",
773 decd5f45 Iustin Pop
                          default=False, action="store_true"),
774 decd5f45 Iustin Pop
              ],
775 decd5f45 Iustin Pop
             "<instance> <new_name>", "Rename the instance"),
776 a8083063 Iustin Pop
  'replace-disks': (ReplaceDisks, ARGS_ONE,
777 a8083063 Iustin Pop
                    [DEBUG_OPT,
778 a8083063 Iustin Pop
                     make_option("-n", "--new-secondary", dest="new_secondary",
779 a9e0c397 Iustin Pop
                                 help=("New secondary node (for secondary"
780 a9e0c397 Iustin Pop
                                       " node change)"), metavar="NODE"),
781 a9e0c397 Iustin Pop
                     make_option("-p", "--on-primary", dest="on_primary",
782 a9e0c397 Iustin Pop
                                 default=False, action="store_true",
783 a9e0c397 Iustin Pop
                                 help=("Replace the disk(s) on the primary"
784 12c3449a Michael Hanselmann
                                       " node (only for the drbd template)")),
785 a9e0c397 Iustin Pop
                     make_option("-s", "--on-secondary", dest="on_secondary",
786 a9e0c397 Iustin Pop
                                 default=False, action="store_true",
787 a9e0c397 Iustin Pop
                                 help=("Replace the disk(s) on the secondary"
788 12c3449a Michael Hanselmann
                                       " node (only for the drbd template)")),
789 a9e0c397 Iustin Pop
                     make_option("--disks", dest="disks", default=None,
790 a9e0c397 Iustin Pop
                                 help=("Comma-separated list of disks"
791 a9e0c397 Iustin Pop
                                       " to replace (e.g. sda) (optional,"
792 a9e0c397 Iustin Pop
                                       " defaults to all disks")),
793 a9e0c397 Iustin Pop
                     ],
794 a8083063 Iustin Pop
                    "[-n NODE] <instance>",
795 a8083063 Iustin Pop
                    "Replaces all disks for the instance"),
796 a8083063 Iustin Pop
  'modify': (SetInstanceParms, ARGS_ONE,
797 fe7b0351 Michael Hanselmann
             [DEBUG_OPT, FORCE_OPT,
798 a8083063 Iustin Pop
              cli_option("-m", "--memory", dest="mem",
799 a8083063 Iustin Pop
                         help="Memory size",
800 a8083063 Iustin Pop
                         default=None, type="unit", metavar="<mem>"),
801 a8083063 Iustin Pop
              make_option("-p", "--cpu", dest="vcpus",
802 a8083063 Iustin Pop
                          help="Number of virtual CPUs",
803 a8083063 Iustin Pop
                          default=None, type="int", metavar="<PROC>"),
804 a8083063 Iustin Pop
              make_option("-i", "--ip", dest="ip",
805 a8083063 Iustin Pop
                          help="IP address ('none' or numeric IP)",
806 a8083063 Iustin Pop
                          default=None, type="string", metavar="<ADDRESS>"),
807 a8083063 Iustin Pop
              make_option("-b", "--bridge", dest="bridge",
808 a8083063 Iustin Pop
                          help="Bridge to connect this instance to",
809 decd5f45 Iustin Pop
                          default=None, type="string", metavar="<bridge>"),
810 a8083063 Iustin Pop
              ],
811 a8083063 Iustin Pop
             "<instance>", "Alters the parameters of an instance"),
812 312ac745 Iustin Pop
  'shutdown': (ShutdownInstance, ARGS_ANY,
813 312ac745 Iustin Pop
               [DEBUG_OPT, m_node_opt, m_pri_node_opt, m_sec_node_opt,
814 804a1e8e Iustin Pop
                m_clust_opt, m_inst_opt, m_force_multi],
815 a8083063 Iustin Pop
               "<instance>", "Stops an instance"),
816 312ac745 Iustin Pop
  'startup': (StartupInstance, ARGS_ANY,
817 804a1e8e Iustin Pop
              [DEBUG_OPT, FORCE_OPT, m_force_multi,
818 a8083063 Iustin Pop
               make_option("-e", "--extra", dest="extra_args",
819 a8083063 Iustin Pop
                           help="Extra arguments for the instance's kernel",
820 a8083063 Iustin Pop
                           default=None, type="string", metavar="<PARAMS>"),
821 312ac745 Iustin Pop
               m_node_opt, m_pri_node_opt, m_sec_node_opt,
822 312ac745 Iustin Pop
               m_clust_opt, m_inst_opt,
823 a8083063 Iustin Pop
               ],
824 a8083063 Iustin Pop
            "<instance>", "Starts an instance"),
825 579d4337 Alexander Schreiber
826 579d4337 Alexander Schreiber
  'reboot': (RebootInstance, ARGS_ANY,
827 579d4337 Alexander Schreiber
              [DEBUG_OPT, m_force_multi,
828 579d4337 Alexander Schreiber
               make_option("-e", "--extra", dest="extra_args",
829 579d4337 Alexander Schreiber
                           help="Extra arguments for the instance's kernel",
830 579d4337 Alexander Schreiber
                           default=None, type="string", metavar="<PARAMS>"),
831 579d4337 Alexander Schreiber
               make_option("-t", "--type", dest="reboot_type",
832 579d4337 Alexander Schreiber
                           help="Type of reboot: soft/hard/full",
833 579d4337 Alexander Schreiber
                           default=constants.INSTANCE_REBOOT_SOFT,
834 579d4337 Alexander Schreiber
                           type="string", metavar="<REBOOT>"),
835 579d4337 Alexander Schreiber
               make_option("--ignore-secondaries", dest="ignore_secondaries",
836 579d4337 Alexander Schreiber
                           default=False, action="store_true",
837 579d4337 Alexander Schreiber
                           help="Ignore errors from secondaries"),
838 579d4337 Alexander Schreiber
               m_node_opt, m_pri_node_opt, m_sec_node_opt,
839 579d4337 Alexander Schreiber
               m_clust_opt, m_inst_opt,
840 579d4337 Alexander Schreiber
               ],
841 579d4337 Alexander Schreiber
            "<instance>", "Reboots an instance"),
842 a8083063 Iustin Pop
  'activate-disks': (ActivateDisks, ARGS_ONE, [DEBUG_OPT],
843 a8083063 Iustin Pop
                     "<instance>",
844 a8083063 Iustin Pop
                     "Activate an instance's disks"),
845 a8083063 Iustin Pop
  'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT],
846 a8083063 Iustin Pop
                       "<instance>",
847 a8083063 Iustin Pop
                       "Deactivate an instance's disks"),
848 846baef9 Iustin Pop
  'list-tags': (ListTags, ARGS_ONE, [DEBUG_OPT],
849 846baef9 Iustin Pop
                "<node_name>", "List the tags of the given instance"),
850 810c50b7 Iustin Pop
  'add-tags': (AddTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
851 846baef9 Iustin Pop
               "<node_name> tag...", "Add tags to the given instance"),
852 810c50b7 Iustin Pop
  'remove-tags': (RemoveTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
853 846baef9 Iustin Pop
                  "<node_name> tag...", "Remove tags from given instance"),
854 a8083063 Iustin Pop
  }
855 a8083063 Iustin Pop
856 a8083063 Iustin Pop
if __name__ == '__main__':
857 846baef9 Iustin Pop
  sys.exit(GenericMain(commands,
858 846baef9 Iustin Pop
                       override={"tag_type": constants.TAG_INSTANCE}))