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