Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-instance @ 79f7be7b

History | View | Annotate | Download (18.8 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
import sys
23 a8083063 Iustin Pop
import os
24 a8083063 Iustin Pop
from optparse import make_option
25 a8083063 Iustin Pop
import textwrap
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 a8083063 Iustin Pop
34 a8083063 Iustin Pop
35 a8083063 Iustin Pop
def ListInstances(opts, args):
36 a8083063 Iustin Pop
  """List nodes and their properties.
37 a8083063 Iustin Pop
38 a8083063 Iustin Pop
  """
39 a8083063 Iustin Pop
  if opts.output is None:
40 a8083063 Iustin Pop
    selected_fields = ["name", "os", "pnode", "admin_state",
41 a8083063 Iustin Pop
                       "oper_state", "oper_ram"]
42 a8083063 Iustin Pop
  else:
43 a8083063 Iustin Pop
    selected_fields = opts.output.split(",")
44 a8083063 Iustin Pop
45 a8083063 Iustin Pop
  op = opcodes.OpQueryInstances(output_fields=selected_fields)
46 a8083063 Iustin Pop
  output = SubmitOpCode(op)
47 a8083063 Iustin Pop
48 a8083063 Iustin Pop
  mlens = [0 for name in selected_fields]
49 a8083063 Iustin Pop
50 a8083063 Iustin Pop
  format_fields = []
51 a8083063 Iustin Pop
  unitformat_fields = ("admin_ram", "oper_ram")
52 a8083063 Iustin Pop
  for field in selected_fields:
53 a8083063 Iustin Pop
    if field in ("admin_ram", "oper_ram"):
54 a8083063 Iustin Pop
      format_fields.append("%*s")
55 a8083063 Iustin Pop
    else:
56 a8083063 Iustin Pop
      format_fields.append("%-*s")
57 a8083063 Iustin Pop
  separator = opts.separator
58 a8083063 Iustin Pop
  if "%" in separator:
59 a8083063 Iustin Pop
    separator = separator.replace("%", "%%")
60 a8083063 Iustin Pop
  format = separator.join(format_fields)
61 a8083063 Iustin Pop
62 a8083063 Iustin Pop
  for row in output:
63 a8083063 Iustin Pop
    for idx, val in enumerate(row):
64 a8083063 Iustin Pop
      if opts.human_readable and selected_fields[idx] in unitformat_fields:
65 a8083063 Iustin Pop
        try:
66 a8083063 Iustin Pop
          val = int(val)
67 a8083063 Iustin Pop
        except ValueError:
68 a8083063 Iustin Pop
          pass
69 a8083063 Iustin Pop
        else:
70 a8083063 Iustin Pop
          val = row[idx] = utils.FormatUnit(val)
71 a8083063 Iustin Pop
      mlens[idx] = max(mlens[idx], len(val))
72 a8083063 Iustin Pop
73 a8083063 Iustin Pop
  if not opts.no_headers:
74 a8083063 Iustin Pop
    header_list = {"name": "Instance", "os": "OS", "pnode": "Primary_node",
75 a8083063 Iustin Pop
                   "snodes": "Secondary_Nodes", "admin_state": "Autostart",
76 a8083063 Iustin Pop
                   "oper_state": "Status", "admin_ram": "Configured_memory",
77 a8083063 Iustin Pop
                   "oper_ram": "Memory", "disk_template": "Disk_template",
78 a8083063 Iustin Pop
                   "ip": "IP Address", "mac": "MAC Address",
79 a8083063 Iustin Pop
                   "bridge": "Bridge"}
80 a8083063 Iustin Pop
    args = []
81 a8083063 Iustin Pop
    for idx, name in enumerate(selected_fields):
82 a8083063 Iustin Pop
      hdr = header_list[name]
83 a8083063 Iustin Pop
      mlens[idx] = max(mlens[idx], len(hdr))
84 a8083063 Iustin Pop
      args.append(mlens[idx])
85 a8083063 Iustin Pop
      args.append(hdr)
86 a8083063 Iustin Pop
    logger.ToStdout(format % tuple(args))
87 a8083063 Iustin Pop
88 a8083063 Iustin Pop
  for line in output:
89 a8083063 Iustin Pop
    args = []
90 a8083063 Iustin Pop
    for idx in range(len(selected_fields)):
91 a8083063 Iustin Pop
      args.append(mlens[idx])
92 a8083063 Iustin Pop
      args.append(line[idx])
93 a8083063 Iustin Pop
    logger.ToStdout(format % tuple(args))
94 a8083063 Iustin Pop
95 a8083063 Iustin Pop
  return 0
96 a8083063 Iustin Pop
97 a8083063 Iustin Pop
98 a8083063 Iustin Pop
def AddInstance(opts, args):
99 a8083063 Iustin Pop
  """Add an instance to the cluster.
100 a8083063 Iustin Pop
101 a8083063 Iustin Pop
  Args:
102 a8083063 Iustin Pop
    opts - class with options as members
103 a8083063 Iustin Pop
    args - list with a single element, the instance name
104 a8083063 Iustin Pop
  Opts used:
105 a8083063 Iustin Pop
    mem - amount of memory to allocate to instance (MiB)
106 a8083063 Iustin Pop
    size - amount of disk space to allocate to instance (MiB)
107 a8083063 Iustin Pop
    os - which OS to run on instance
108 a8083063 Iustin Pop
    node - node to run new instance on
109 a8083063 Iustin Pop
110 a8083063 Iustin Pop
  """
111 a8083063 Iustin Pop
112 a8083063 Iustin Pop
  instance = args[0]
113 a8083063 Iustin Pop
114 a8083063 Iustin Pop
  op = opcodes.OpCreateInstance(instance_name=instance, mem_size=opts.mem,
115 a8083063 Iustin Pop
                                disk_size=opts.size, swap_size=opts.swap,
116 a8083063 Iustin Pop
                                disk_template=opts.disk_template,
117 a8083063 Iustin Pop
                                mode=constants.INSTANCE_CREATE,
118 a8083063 Iustin Pop
                                os_type=opts.os, pnode=opts.node,
119 a8083063 Iustin Pop
                                snode=opts.snode, vcpus=opts.vcpus,
120 a8083063 Iustin Pop
                                ip=opts.ip, bridge=opts.bridge, start=True,
121 a8083063 Iustin Pop
                                wait_for_sync=opts.wait_for_sync)
122 a8083063 Iustin Pop
  SubmitOpCode(op)
123 a8083063 Iustin Pop
  return 0
124 a8083063 Iustin Pop
125 a8083063 Iustin Pop
126 a8083063 Iustin Pop
def RemoveInstance(opts, args):
127 a8083063 Iustin Pop
  """Remove an instance.
128 a8083063 Iustin Pop
129 a8083063 Iustin Pop
  Args:
130 a8083063 Iustin Pop
    opts - class with options as members
131 a8083063 Iustin Pop
    args - list containing a single element, the instance name
132 a8083063 Iustin Pop
133 a8083063 Iustin Pop
  """
134 a8083063 Iustin Pop
  instance_name = args[0]
135 a8083063 Iustin Pop
  force = opts.force
136 a8083063 Iustin Pop
137 a8083063 Iustin Pop
  if not force:
138 a8083063 Iustin Pop
    usertext = ("This will remove the volumes of the instance %s"
139 a8083063 Iustin Pop
                " (including mirrors), thus removing all the data"
140 a8083063 Iustin Pop
                " of the instance. Continue?") % instance_name
141 a8083063 Iustin Pop
    if not opts._ask_user(usertext):
142 a8083063 Iustin Pop
      return 1
143 a8083063 Iustin Pop
144 a8083063 Iustin Pop
  op = opcodes.OpRemoveInstance(instance_name=instance_name)
145 a8083063 Iustin Pop
  SubmitOpCode(op)
146 a8083063 Iustin Pop
  return 0
147 a8083063 Iustin Pop
148 a8083063 Iustin Pop
149 a8083063 Iustin Pop
def ActivateDisks(opts, args):
150 a8083063 Iustin Pop
  """Activate an instance's disks.
151 a8083063 Iustin Pop
152 a8083063 Iustin Pop
  This serves two purposes:
153 a8083063 Iustin Pop
    - it allows one (as long as the instance is not running) to mount
154 a8083063 Iustin Pop
    the disks and modify them from the node
155 a8083063 Iustin Pop
    - it repairs inactive secondary drbds
156 a8083063 Iustin Pop
157 a8083063 Iustin Pop
  """
158 a8083063 Iustin Pop
  instance_name = args[0]
159 a8083063 Iustin Pop
  op = opcodes.OpActivateInstanceDisks(instance_name=instance_name)
160 a8083063 Iustin Pop
  disks_info = SubmitOpCode(op)
161 a8083063 Iustin Pop
  for host, iname, nname in disks_info:
162 a8083063 Iustin Pop
    print "%s:%s:%s" % (host, iname, nname)
163 a8083063 Iustin Pop
  return 0
164 a8083063 Iustin Pop
165 a8083063 Iustin Pop
166 a8083063 Iustin Pop
def DeactivateDisks(opts, args):
167 a8083063 Iustin Pop
  """Command-line interface for _ShutdownInstanceBlockDevices.
168 a8083063 Iustin Pop
169 a8083063 Iustin Pop
  This function takes the instance name, looks for its primary node
170 a8083063 Iustin Pop
  and the tries to shutdown its block devices on that node.
171 a8083063 Iustin Pop
172 a8083063 Iustin Pop
  """
173 a8083063 Iustin Pop
  instance_name = args[0]
174 a8083063 Iustin Pop
  op = opcodes.OpDeactivateInstanceDisks(instance_name=instance_name)
175 a8083063 Iustin Pop
  SubmitOpCode(op)
176 a8083063 Iustin Pop
  return 0
177 a8083063 Iustin Pop
178 a8083063 Iustin Pop
179 a8083063 Iustin Pop
def StartupInstance(opts, args):
180 a8083063 Iustin Pop
  """Shutdown an instance.
181 a8083063 Iustin Pop
182 a8083063 Iustin Pop
  Args:
183 a8083063 Iustin Pop
    opts - class with options as members
184 a8083063 Iustin Pop
    args - list containing a single element, the instance name
185 a8083063 Iustin Pop
186 a8083063 Iustin Pop
  """
187 a8083063 Iustin Pop
  instance_name = args[0]
188 a8083063 Iustin Pop
  op = opcodes.OpStartupInstance(instance_name=instance_name, force=opts.force,
189 a8083063 Iustin Pop
                                 extra_args=opts.extra_args)
190 a8083063 Iustin Pop
  SubmitOpCode(op)
191 a8083063 Iustin Pop
  return 0
192 a8083063 Iustin Pop
193 a8083063 Iustin Pop
194 a8083063 Iustin Pop
def ShutdownInstance(opts, args):
195 a8083063 Iustin Pop
  """Shutdown an instance.
196 a8083063 Iustin Pop
197 a8083063 Iustin Pop
  Args:
198 a8083063 Iustin Pop
    opts - class with options as members
199 a8083063 Iustin Pop
    args - list containing a single element, the instance name
200 a8083063 Iustin Pop
201 a8083063 Iustin Pop
  """
202 a8083063 Iustin Pop
  instance_name = args[0]
203 a8083063 Iustin Pop
  op = opcodes.OpShutdownInstance(instance_name=instance_name)
204 a8083063 Iustin Pop
  SubmitOpCode(op)
205 a8083063 Iustin Pop
  return 0
206 a8083063 Iustin Pop
207 a8083063 Iustin Pop
208 a8083063 Iustin Pop
def AddMDDRBDComponent(opts, args):
209 a8083063 Iustin Pop
  """Add a new component to a remote_raid1 disk.
210 a8083063 Iustin Pop
211 a8083063 Iustin Pop
  Args:
212 a8083063 Iustin Pop
    opts - class with options as members
213 a8083063 Iustin Pop
    args - list with a single element, the instance name
214 a8083063 Iustin Pop
215 a8083063 Iustin Pop
  """
216 a8083063 Iustin Pop
  op = opcodes.OpAddMDDRBDComponent(instance_name=args[0],
217 a8083063 Iustin Pop
                                    disk_name=opts.disk,
218 a8083063 Iustin Pop
                                    remote_node=opts.node)
219 a8083063 Iustin Pop
  SubmitOpCode(op)
220 a8083063 Iustin Pop
  return 0
221 a8083063 Iustin Pop
222 a8083063 Iustin Pop
223 a8083063 Iustin Pop
def RemoveMDDRBDComponent(opts, args):
224 a8083063 Iustin Pop
  """Connect to the console of an instance
225 a8083063 Iustin Pop
226 a8083063 Iustin Pop
  Args:
227 a8083063 Iustin Pop
    opts - class with options as members
228 a8083063 Iustin Pop
    args - list with a single element, the instance name
229 a8083063 Iustin Pop
230 a8083063 Iustin Pop
  """
231 a8083063 Iustin Pop
  op = opcodes.OpRemoveMDDRBDComponent(instance_name=args[0],
232 a8083063 Iustin Pop
                                       disk_name=opts.disk,
233 a8083063 Iustin Pop
                                       disk_id=opts.port)
234 a8083063 Iustin Pop
  SubmitOpCode(op)
235 a8083063 Iustin Pop
  return 0
236 a8083063 Iustin Pop
237 a8083063 Iustin Pop
238 a8083063 Iustin Pop
def ReplaceDisks(opts, args):
239 a8083063 Iustin Pop
  """Replace the disks of an instance
240 a8083063 Iustin Pop
241 a8083063 Iustin Pop
  Args:
242 a8083063 Iustin Pop
    opts - class with options as members
243 a8083063 Iustin Pop
    args - list with a single element, the instance name
244 a8083063 Iustin Pop
245 a8083063 Iustin Pop
  """
246 a8083063 Iustin Pop
  instance_name = args[0]
247 a8083063 Iustin Pop
  new_secondary = opts.new_secondary
248 a8083063 Iustin Pop
  op = opcodes.OpReplaceDisks(instance_name=args[0],
249 a8083063 Iustin Pop
                              remote_node=opts.new_secondary)
250 a8083063 Iustin Pop
  SubmitOpCode(op)
251 a8083063 Iustin Pop
  return 0
252 a8083063 Iustin Pop
253 a8083063 Iustin Pop
254 a8083063 Iustin Pop
def FailoverInstance(opts, args):
255 a8083063 Iustin Pop
  """Failover an instance.
256 a8083063 Iustin Pop
257 a8083063 Iustin Pop
  The failover is done by shutting it down on its present node and
258 a8083063 Iustin Pop
  starting it on the secondary.
259 a8083063 Iustin Pop
260 a8083063 Iustin Pop
  Args:
261 a8083063 Iustin Pop
    opts - class with options as members
262 a8083063 Iustin Pop
    args - list with a single element, the instance name
263 a8083063 Iustin Pop
  Opts used:
264 a8083063 Iustin Pop
    force - whether to failover without asking questions.
265 a8083063 Iustin Pop
266 a8083063 Iustin Pop
  """
267 a8083063 Iustin Pop
  instance_name = args[0]
268 a8083063 Iustin Pop
  force = opts.force
269 a8083063 Iustin Pop
270 a8083063 Iustin Pop
  if not force:
271 a8083063 Iustin Pop
    usertext = ("Failover will happen to image %s."
272 a8083063 Iustin Pop
                " This requires a shutdown of the instance. Continue?" %
273 a8083063 Iustin Pop
                (instance_name,))
274 a8083063 Iustin Pop
    usertext = textwrap.fill(usertext)
275 a8083063 Iustin Pop
    if not opts._ask_user(usertext):
276 a8083063 Iustin Pop
      return 1
277 a8083063 Iustin Pop
278 a8083063 Iustin Pop
  op = opcodes.OpFailoverInstance(instance_name=instance_name,
279 a8083063 Iustin Pop
                                  ignore_consistency=opts.ignore_consistency)
280 a8083063 Iustin Pop
  SubmitOpCode(op)
281 a8083063 Iustin Pop
  return 0
282 a8083063 Iustin Pop
283 a8083063 Iustin Pop
284 a8083063 Iustin Pop
def ConnectToInstanceConsole(opts, args):
285 a8083063 Iustin Pop
  """Connect to the console of an instance.
286 a8083063 Iustin Pop
287 a8083063 Iustin Pop
  Args:
288 a8083063 Iustin Pop
    opts - class with options as members
289 a8083063 Iustin Pop
    args - list with a single element, the instance name
290 a8083063 Iustin Pop
291 a8083063 Iustin Pop
  """
292 a8083063 Iustin Pop
  instance_name = args[0]
293 a8083063 Iustin Pop
294 a8083063 Iustin Pop
  op = opcodes.OpConnectConsole(instance_name=instance_name)
295 a8083063 Iustin Pop
  node, console_cmd = SubmitOpCode(op)
296 a8083063 Iustin Pop
  # drop lock and exec so other commands can run while we have console
297 a8083063 Iustin Pop
  utils.Unlock("cmd")
298 a8083063 Iustin Pop
  try:
299 a8083063 Iustin Pop
    os.execv("/usr/bin/ssh", ["ssh", "-qt", node, console_cmd])
300 a8083063 Iustin Pop
  finally:
301 a8083063 Iustin Pop
    sys.stderr.write("Can't run console command %s on node %s" %
302 a8083063 Iustin Pop
                     (console_cmd, node))
303 a8083063 Iustin Pop
    os._exit(1)
304 a8083063 Iustin Pop
305 a8083063 Iustin Pop
306 a8083063 Iustin Pop
def _FormatBlockDevInfo(buf, dev, indent_level):
307 a8083063 Iustin Pop
  """Show block device information.
308 a8083063 Iustin Pop
309 a8083063 Iustin Pop
  This is only used by ShowInstanceConfig(), but it's too big to be
310 a8083063 Iustin Pop
  left for an inline definition.
311 a8083063 Iustin Pop
312 a8083063 Iustin Pop
  """
313 a8083063 Iustin Pop
  def helper(buf, dtype, status):
314 a8083063 Iustin Pop
    """Format one line for phsyical device status."""
315 a8083063 Iustin Pop
    if not status:
316 a8083063 Iustin Pop
      buf.write("not active\n")
317 a8083063 Iustin Pop
    else:
318 a8083063 Iustin Pop
      (path, major, minor, syncp, estt, degr) = status
319 a8083063 Iustin Pop
      buf.write("%s (%d:%d)" % (path, major, minor))
320 a8083063 Iustin Pop
      if dtype in ("md_raid1", "drbd"):
321 a8083063 Iustin Pop
        if syncp is not None:
322 a8083063 Iustin Pop
          sync_text = "*RECOVERING* %5.2f%%," % syncp
323 a8083063 Iustin Pop
          if estt:
324 a8083063 Iustin Pop
            sync_text += " ETA %ds" % estt
325 a8083063 Iustin Pop
          else:
326 a8083063 Iustin Pop
            sync_text += " ETA unknown"
327 a8083063 Iustin Pop
        else:
328 a8083063 Iustin Pop
          sync_text = "in sync"
329 a8083063 Iustin Pop
        if degr:
330 a8083063 Iustin Pop
          degr_text = "*DEGRADED*"
331 a8083063 Iustin Pop
        else:
332 a8083063 Iustin Pop
          degr_text = "ok"
333 a8083063 Iustin Pop
        buf.write(" %s, status %s" % (sync_text, degr_text))
334 a8083063 Iustin Pop
      buf.write("\n")
335 a8083063 Iustin Pop
336 a8083063 Iustin Pop
  if dev["iv_name"] is not None:
337 a8083063 Iustin Pop
    data = "  - %s, " % dev["iv_name"]
338 a8083063 Iustin Pop
  else:
339 a8083063 Iustin Pop
    data = "  - "
340 a8083063 Iustin Pop
  data += "type: %s" % dev["dev_type"]
341 a8083063 Iustin Pop
  if dev["logical_id"] is not None:
342 a8083063 Iustin Pop
    data += ", logical_id: %s" % (dev["logical_id"],)
343 a8083063 Iustin Pop
  elif dev["physical_id"] is not None:
344 a8083063 Iustin Pop
    data += ", physical_id: %s" % (dev["physical_id"],)
345 a8083063 Iustin Pop
  buf.write("%*s%s\n" % (2*indent_level, "", data))
346 a8083063 Iustin Pop
  buf.write("%*s    primary:   " % (2*indent_level, ""))
347 a8083063 Iustin Pop
  helper(buf, dev["dev_type"], dev["pstatus"])
348 a8083063 Iustin Pop
349 a8083063 Iustin Pop
  if dev["sstatus"]:
350 a8083063 Iustin Pop
    buf.write("%*s    secondary: " % (2*indent_level, ""))
351 a8083063 Iustin Pop
    helper(buf, dev["dev_type"], dev["sstatus"])
352 a8083063 Iustin Pop
353 a8083063 Iustin Pop
  if dev["children"]:
354 a8083063 Iustin Pop
    for child in dev["children"]:
355 a8083063 Iustin Pop
      _FormatBlockDevInfo(buf, child, indent_level+1)
356 a8083063 Iustin Pop
357 a8083063 Iustin Pop
358 a8083063 Iustin Pop
def ShowInstanceConfig(opts, args):
359 a8083063 Iustin Pop
  """Compute instance run-time status.
360 a8083063 Iustin Pop
361 a8083063 Iustin Pop
  """
362 a8083063 Iustin Pop
363 a8083063 Iustin Pop
  retcode = 0
364 a8083063 Iustin Pop
  op = opcodes.OpQueryInstanceData(instances=args)
365 a8083063 Iustin Pop
  result = SubmitOpCode(op)
366 a8083063 Iustin Pop
367 a8083063 Iustin Pop
  if not result:
368 a8083063 Iustin Pop
    logger.ToStdout("No instances.")
369 a8083063 Iustin Pop
    return 1
370 a8083063 Iustin Pop
371 a8083063 Iustin Pop
  buf = StringIO()
372 a8083063 Iustin Pop
  retcode = 0
373 a8083063 Iustin Pop
  for instance_name in result:
374 a8083063 Iustin Pop
    instance = result[instance_name]
375 a8083063 Iustin Pop
    buf.write("Instance name: %s\n" % instance["name"])
376 a8083063 Iustin Pop
    buf.write("State: configured to be %s, actual state is %s\n" %
377 a8083063 Iustin Pop
              (instance["config_state"], instance["run_state"]))
378 a8083063 Iustin Pop
    buf.write("  Nodes:\n")
379 a8083063 Iustin Pop
    buf.write("    - primary: %s\n" % instance["pnode"])
380 a8083063 Iustin Pop
    buf.write("    - secondaries: %s\n" % ", ".join(instance["snodes"]))
381 a8083063 Iustin Pop
    buf.write("  Operating system: %s\n" % instance["os"])
382 a8083063 Iustin Pop
    buf.write("  Hardware:\n")
383 a8083063 Iustin Pop
    buf.write("    - memory: %dMiB\n" % instance["memory"])
384 a8083063 Iustin Pop
    buf.write("    - NICs: %s\n" %
385 a8083063 Iustin Pop
        ", ".join(["{MAC: %s, IP: %s, bridge: %s}" %
386 a8083063 Iustin Pop
                   (mac, ip, bridge)
387 a8083063 Iustin Pop
                     for mac, ip, bridge in instance["nics"]]))
388 a8083063 Iustin Pop
    buf.write("  Block devices:\n")
389 a8083063 Iustin Pop
390 a8083063 Iustin Pop
    for device in instance["disks"]:
391 a8083063 Iustin Pop
      _FormatBlockDevInfo(buf, device, 1)
392 a8083063 Iustin Pop
393 a8083063 Iustin Pop
  logger.ToStdout(buf.getvalue().rstrip('\n'))
394 a8083063 Iustin Pop
  return retcode
395 a8083063 Iustin Pop
396 a8083063 Iustin Pop
397 a8083063 Iustin Pop
def SetInstanceParms(opts, args):
398 a8083063 Iustin Pop
  """Modifies an instance.
399 a8083063 Iustin Pop
400 a8083063 Iustin Pop
  All parameters take effect only at the next restart of the instance.
401 a8083063 Iustin Pop
402 a8083063 Iustin Pop
  Args:
403 a8083063 Iustin Pop
    opts - class with options as members
404 a8083063 Iustin Pop
    args - list with a single element, the instance name
405 a8083063 Iustin Pop
  Opts used:
406 a8083063 Iustin Pop
    memory - the new memory size
407 a8083063 Iustin Pop
    vcpus - the new number of cpus
408 a8083063 Iustin Pop
409 a8083063 Iustin Pop
  """
410 a8083063 Iustin Pop
  if not opts.mem and not opts.vcpus and not opts.ip and not opts.bridge:
411 a8083063 Iustin Pop
    logger.ToStdout("Please give at least one of the parameters.")
412 a8083063 Iustin Pop
    return 1
413 a8083063 Iustin Pop
414 a8083063 Iustin Pop
  op = opcodes.OpSetInstanceParms(instance_name=args[0], mem=opts.mem,
415 a8083063 Iustin Pop
                                  vcpus=opts.vcpus, ip=opts.ip,
416 a8083063 Iustin Pop
                                  bridge=opts.bridge)
417 a8083063 Iustin Pop
  result = SubmitOpCode(op)
418 a8083063 Iustin Pop
419 a8083063 Iustin Pop
  if result:
420 a8083063 Iustin Pop
    logger.ToStdout("Modified instance %s" % args[0])
421 a8083063 Iustin Pop
    for param, data in result:
422 a8083063 Iustin Pop
      logger.ToStdout(" - %-5s -> %s" % (param, data))
423 a8083063 Iustin Pop
    logger.ToStdout("Please don't forget that these parameters take effect"
424 a8083063 Iustin Pop
                    " only at the next start of the instance.")
425 a8083063 Iustin Pop
  return 0
426 a8083063 Iustin Pop
427 a8083063 Iustin Pop
428 a8083063 Iustin Pop
# options used in more than one cmd
429 a8083063 Iustin Pop
node_opt = make_option("-n", "--node", dest="node", help="Target node",
430 a8083063 Iustin Pop
                       metavar="<node>")
431 a8083063 Iustin Pop
force_opt = make_option("-f", "--force", dest="force", action="store_true",
432 a8083063 Iustin Pop
                        default=False, help="Force the operation")
433 a8083063 Iustin Pop
434 a8083063 Iustin Pop
# this is defined separately due to readability only
435 a8083063 Iustin Pop
add_opts = [
436 a8083063 Iustin Pop
  DEBUG_OPT,
437 a8083063 Iustin Pop
  node_opt,
438 a8083063 Iustin Pop
  cli_option("-s", "--os-size", dest="size", help="Disk size",
439 a8083063 Iustin Pop
             default=20 * 1024, type="unit", metavar="<size>"),
440 a8083063 Iustin Pop
  cli_option("--swap-size", dest="swap", help="Swap size",
441 a8083063 Iustin Pop
             default=4 * 1024, type="unit", metavar="<size>"),
442 a8083063 Iustin Pop
  cli_option("-o", "--os-type", dest="os", help="What OS to run",
443 a8083063 Iustin Pop
             metavar="<os>"),
444 a8083063 Iustin Pop
  cli_option("-m", "--memory", dest="mem", help="Memory size",
445 a8083063 Iustin Pop
              default=128, type="unit", metavar="<mem>"),
446 a8083063 Iustin Pop
  make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs",
447 a8083063 Iustin Pop
              default=1, type="int", metavar="<PROC>"),
448 a8083063 Iustin Pop
  make_option("-t", "--disk-template", dest="disk_template",
449 a8083063 Iustin Pop
              help="Custom disk setup (diskless, plain, local_raid1 or"
450 a8083063 Iustin Pop
              " remote_raid1)", default=None, metavar="TEMPL"),
451 a8083063 Iustin Pop
  make_option("-i", "--ip", dest="ip",
452 a8083063 Iustin Pop
              help="IP address ('none' [default], 'auto', or specify address)",
453 a8083063 Iustin Pop
              default='none', type="string", metavar="<ADDRESS>"),
454 a8083063 Iustin Pop
  make_option("--no-wait-for-sync", dest="wait_for_sync", default=True,
455 a8083063 Iustin Pop
              action="store_false", help="Don't wait for sync (DANGEROUS!)"),
456 a8083063 Iustin Pop
  make_option("--secondary-node", dest="snode",
457 a8083063 Iustin Pop
              help="Secondary node for remote_raid1 disk layout",
458 a8083063 Iustin Pop
              metavar="<node>"),
459 a8083063 Iustin Pop
  make_option("-b", "--bridge", dest="bridge",
460 a8083063 Iustin Pop
              help="Bridge to connect this instance to",
461 a8083063 Iustin Pop
              default=None, metavar="<bridge>")
462 a8083063 Iustin Pop
  ]
463 a8083063 Iustin Pop
464 a8083063 Iustin Pop
465 a8083063 Iustin Pop
commands = {
466 a8083063 Iustin Pop
  'add': (AddInstance, ARGS_ONE, add_opts,
467 a8083063 Iustin Pop
          "[opts...] <name>",
468 a8083063 Iustin Pop
          "Creates and adds a new instance to the cluster"),
469 a8083063 Iustin Pop
  'add-mirror': (AddMDDRBDComponent, ARGS_ONE,
470 a8083063 Iustin Pop
                [DEBUG_OPT, node_opt,
471 a8083063 Iustin Pop
                 make_option("-b", "--disk", dest="disk", metavar="sdX",
472 a8083063 Iustin Pop
                             help=("The name of the instance disk for which to"
473 a8083063 Iustin Pop
                                   " add the mirror"))],
474 a8083063 Iustin Pop
                "-n node -b disk <instance>",
475 a8083063 Iustin Pop
                "Creates a new mirror for the instance"),
476 a8083063 Iustin Pop
  'console': (ConnectToInstanceConsole, ARGS_ONE, [DEBUG_OPT],
477 a8083063 Iustin Pop
              "<instance>",
478 a8083063 Iustin Pop
              "Opens a console on the specified instance"),
479 a8083063 Iustin Pop
  'failover': (FailoverInstance, ARGS_ONE,
480 a8083063 Iustin Pop
               [DEBUG_OPT, force_opt,
481 a8083063 Iustin Pop
                make_option("--ignore-consistency", dest="ignore_consistency",
482 a8083063 Iustin Pop
                            action="store_true", default=False,
483 a8083063 Iustin Pop
                            help="Ignore the consistency of the disks on"
484 a8083063 Iustin Pop
                            " the secondary"),
485 a8083063 Iustin Pop
                ],
486 a8083063 Iustin Pop
               "[-f] <instance>",
487 a8083063 Iustin Pop
               "Stops the instance and starts it on the backup node, using"
488 a8083063 Iustin Pop
               " the remote mirror (only for instances of type remote_raid1)"),
489 a8083063 Iustin Pop
  'info': (ShowInstanceConfig, ARGS_ANY, [DEBUG_OPT], "[<instance>...]",
490 a8083063 Iustin Pop
           "Show information on the specified instance"),
491 a8083063 Iustin Pop
  'list': (ListInstances, ARGS_NONE,
492 a8083063 Iustin Pop
           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT,
493 a8083063 Iustin Pop
            make_option("-o", "--output", dest="output", action="store",
494 a8083063 Iustin Pop
                        type="string", help="Select output fields",
495 a8083063 Iustin Pop
                        metavar="FIELDS")
496 a8083063 Iustin Pop
            ],
497 a8083063 Iustin Pop
           "", "Lists the instances and their status"),
498 a8083063 Iustin Pop
  'remove': (RemoveInstance, ARGS_ONE, [DEBUG_OPT, force_opt],
499 a8083063 Iustin Pop
             "[-f] <instance>", "Shuts down the instance and removes it"),
500 a8083063 Iustin Pop
  'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE,
501 a8083063 Iustin Pop
                   [DEBUG_OPT, node_opt,
502 a8083063 Iustin Pop
                    make_option("-b", "--disk", dest="disk", metavar="sdX",
503 a8083063 Iustin Pop
                                help=("The name of the instance disk"
504 a8083063 Iustin Pop
                                      " for which to add the mirror")),
505 a8083063 Iustin Pop
                    make_option("-p", "--port", dest="port", metavar="PORT",
506 a8083063 Iustin Pop
                                help=("The port of the drbd device"
507 a8083063 Iustin Pop
                                      " which to remove from the mirror"),
508 a8083063 Iustin Pop
                                type="int"),
509 a8083063 Iustin Pop
                    ],
510 a8083063 Iustin Pop
                   "-b disk -p port <instance>",
511 a8083063 Iustin Pop
                   "Removes a mirror from the instance"),
512 a8083063 Iustin Pop
  'replace-disks': (ReplaceDisks, ARGS_ONE,
513 a8083063 Iustin Pop
                    [DEBUG_OPT,
514 a8083063 Iustin Pop
                     make_option("-n", "--new-secondary", dest="new_secondary",
515 a8083063 Iustin Pop
                                 metavar="NODE",
516 a8083063 Iustin Pop
                                 help=("New secondary node (if you want to"
517 a8083063 Iustin Pop
                                       " change the secondary)"))],
518 a8083063 Iustin Pop
                    "[-n NODE] <instance>",
519 a8083063 Iustin Pop
                    "Replaces all disks for the instance"),
520 a8083063 Iustin Pop
521 a8083063 Iustin Pop
  'modify': (SetInstanceParms, ARGS_ONE,
522 a8083063 Iustin Pop
             [DEBUG_OPT, force_opt,
523 a8083063 Iustin Pop
              cli_option("-m", "--memory", dest="mem",
524 a8083063 Iustin Pop
                         help="Memory size",
525 a8083063 Iustin Pop
                         default=None, type="unit", metavar="<mem>"),
526 a8083063 Iustin Pop
              make_option("-p", "--cpu", dest="vcpus",
527 a8083063 Iustin Pop
                          help="Number of virtual CPUs",
528 a8083063 Iustin Pop
                          default=None, type="int", metavar="<PROC>"),
529 a8083063 Iustin Pop
              make_option("-i", "--ip", dest="ip",
530 a8083063 Iustin Pop
                          help="IP address ('none' or numeric IP)",
531 a8083063 Iustin Pop
                          default=None, type="string", metavar="<ADDRESS>"),
532 a8083063 Iustin Pop
              make_option("-b", "--bridge", dest="bridge",
533 a8083063 Iustin Pop
                          help="Bridge to connect this instance to",
534 a8083063 Iustin Pop
                          default=None, type="string", metavar="<bridge>")
535 a8083063 Iustin Pop
              ],
536 a8083063 Iustin Pop
             "<instance>", "Alters the parameters of an instance"),
537 a8083063 Iustin Pop
  'shutdown': (ShutdownInstance, ARGS_ONE, [DEBUG_OPT],
538 a8083063 Iustin Pop
               "<instance>", "Stops an instance"),
539 a8083063 Iustin Pop
  'startup': (StartupInstance, ARGS_ONE,
540 a8083063 Iustin Pop
              [DEBUG_OPT, force_opt,
541 a8083063 Iustin Pop
               make_option("-e", "--extra", dest="extra_args",
542 a8083063 Iustin Pop
                           help="Extra arguments for the instance's kernel",
543 a8083063 Iustin Pop
                           default=None, type="string", metavar="<PARAMS>"),
544 a8083063 Iustin Pop
               ],
545 a8083063 Iustin Pop
            "<instance>", "Starts an instance"),
546 a8083063 Iustin Pop
  'activate-disks': (ActivateDisks, ARGS_ONE, [DEBUG_OPT],
547 a8083063 Iustin Pop
                     "<instance>",
548 a8083063 Iustin Pop
                     "Activate an instance's disks"),
549 a8083063 Iustin Pop
  'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT],
550 a8083063 Iustin Pop
                       "<instance>",
551 a8083063 Iustin Pop
                       "Deactivate an instance's disks"),
552 a8083063 Iustin Pop
  }
553 a8083063 Iustin Pop
554 a8083063 Iustin Pop
if __name__ == '__main__':
555 a8083063 Iustin Pop
  retcode = GenericMain(commands)
556 a8083063 Iustin Pop
  sys.exit(retcode)