Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-instance @ d8052456

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