Revision 0d0e9090 scripts/gnt-instance

b/scripts/gnt-instance
22 22
import sys
23 23
import os
24 24
import itertools
25
import simplejson
25 26
from optparse import make_option
26 27
from cStringIO import StringIO
27 28

  
28 29
from ganeti.cli import *
30
from ganeti import cli
29 31
from ganeti import opcodes
30 32
from ganeti import logger
31 33
from ganeti import constants
......
313 315
  return 0
314 316

  
315 317

  
318
def BatchCreate(opts, args):
319
  """Create instances on a batched base.
320

  
321
  This function reads a json with instances defined in the form:
322

  
323
  {"instance-name": {"disk_size": 25,
324
                     "swap_size": 1024,
325
                     "template": "drbd",
326
                     "backend": { "memory": 512,
327
                                  "vcpus": 1 },
328
                     "os": "etch-image",
329
                     "primary_node": "firstnode",
330
                     "secondary_node": "secondnode",
331
                     "iallocator": "dumb"}}
332

  
333
  primary_node and secondary_node has precedence over iallocator.
334

  
335
  Args:
336
    opts: The parsed command line options
337
    args: Argument passed to the command in our case the json file
338

  
339
  """
340
  _DEFAULT_SPECS = {"disk_size": 20 * 1024,
341
                    "swap_size": 4 * 1024,
342
                    "backend": {},
343
                    "iallocator": None,
344
                    "primary_node": None,
345
                    "secondary_node": None,
346
                    "ip": 'none',
347
                    "mac": 'auto',
348
                    "bridge": None,
349
                    "start": True,
350
                    "ip_check": True,
351
                    "hypervisor": None,
352
                    "file_storage_dir": None,
353
                    "file_driver": 'loop'}
354

  
355
  def _PopulateWithDefaults(spec):
356
    """Returns a new hash combined with default values."""
357
    dict = _DEFAULT_SPECS.copy()
358
    dict.update(spec)
359
    return dict
360

  
361
  def _Validate(spec):
362
    """Validate the instance specs."""
363
    # Validate fields required under any circumstances
364
    for required_field in ('os', 'template'):
365
      if required_field not in spec:
366
        raise errors.OpPrereqError('Required field "%s" is missing.' %
367
                                   required_field)
368
    # Validate special fields
369
    if spec['primary_node'] is not None:
370
      if (spec['template'] in constants.DTS_NET_MIRROR and
371
          spec['secondary_node'] is None):
372
        raise errors.OpPrereqError('Template requires secondary node, but'
373
                                   ' there was no secondary provided.')
374
    elif spec['iallocator'] is None:
375
      raise errors.OpPrereqError('You have to provide at least a primary_node'
376
                                 ' or an iallocator.')
377

  
378
    if (spec['hypervisor'] and
379
        not isinstance(spec['hypervisor'], dict)):
380
      raise errors.OpPrereqError('Hypervisor parameters must be a dict.')
381

  
382
  json_filename = args[0]
383
  fd = open(json_filename, 'r')
384
  try:
385
    instance_data = simplejson.load(fd)
386
  finally:
387
    fd.close()
388

  
389
  # Iterate over the instances and do:
390
  #  * Populate the specs with default value
391
  #  * Validate the instance specs
392
  for (name, specs) in instance_data.iteritems():
393
    specs = _PopulateWithDefaults(specs)
394
    _Validate(specs)
395

  
396
    hypervisor = None
397
    hvparams = {}
398
    if specs['hypervisor']:
399
      hypervisor, hvparams = specs['hypervisor'].iteritems()
400

  
401
    op = opcodes.OpCreateInstance(instance_name=name,
402
                                  disk_size=specs['disk_size'],
403
                                  swap_size=specs['swap_size'],
404
                                  disk_template=specs['template'],
405
                                  mode=constants.INSTANCE_CREATE,
406
                                  os_type=specs['os'],
407
                                  pnode=specs['primary_node'],
408
                                  snode=specs['secondary_node'],
409
                                  ip=specs['ip'], bridge=specs['bridge'],
410
                                  start=specs['start'],
411
                                  ip_check=specs['ip_check'],
412
                                  wait_for_sync=True,
413
                                  mac=specs['mac'],
414
                                  iallocator=specs['iallocator'],
415
                                  hypervisor=hypervisor,
416
                                  hvparams=hvparams,
417
                                  beparams=specs['backend'],
418
                                  file_storage_dir=specs['file_storage_dir'],
419
                                  file_driver=specs['file_driver'])
420

  
421
    print '%s: %s' % (name, cli.SendJob([op]))
422

  
423
  return 0
424

  
425

  
316 426
def ReinstallInstance(opts, args):
317 427
  """Reinstall an instance.
318 428

  
......
903 1013
  'add': (AddInstance, ARGS_ONE, add_opts,
904 1014
          "[...] -t disk-type -n node[:secondary-node] -o os-type <name>",
905 1015
          "Creates and adds a new instance to the cluster"),
1016
  'batch-create': (BatchCreate, ARGS_ONE,
1017
                   [DEBUG_OPT],
1018
                   "<instances_file.json>",
1019
                   "Create a bunch of instances based on specs in the file."),
906 1020
  'console': (ConnectToInstanceConsole, ARGS_ONE,
907 1021
              [DEBUG_OPT,
908 1022
               make_option("--show-cmd", dest="show_command",

Also available in: Unified diff