Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-instance @ 644eeef9

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