Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-instance @ 7c0d6283

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