Revision e69d05fd lib/backend.py

b/lib/backend.py
231 231
  raise errors.QuitGanetiException(False, 'Shutdown scheduled')
232 232

  
233 233

  
234
def GetNodeInfo(vgname):
234
def GetNodeInfo(vgname, hypervisor_type):
235 235
  """Gives back a hash with different informations about the node.
236 236

  
237
  Returns:
238
    { 'vg_size' : xxx,  'vg_free' : xxx, 'memory_domain0': xxx,
239
      'memory_free' : xxx, 'memory_total' : xxx }
240
    where
241
    vg_size is the size of the configured volume group in MiB
242
    vg_free is the free size of the volume group in MiB
243
    memory_dom0 is the memory allocated for domain0 in MiB
244
    memory_free is the currently available (free) ram in MiB
245
    memory_total is the total number of ram in MiB
237
  @type vgname: C{string}
238
  @param vgname: the name of the volume group to ask for disk space information
239
  @type hypervisor_type: C{str}
240
  @param hypervisor_type: the name of the hypervisor to ask for
241
      memory information
242
  @rtype: C{dict}
243
  @return: dictionary with the following keys:
244
      - vg_size is the size of the configured volume group in MiB
245
      - vg_free is the free size of the volume group in MiB
246
      - memory_dom0 is the memory allocated for domain0 in MiB
247
      - memory_free is the currently available (free) ram in MiB
248
      - memory_total is the total number of ram in MiB
246 249

  
247 250
  """
248 251
  outputarray = {}
......
250 253
  outputarray['vg_size'] = vginfo['vg_size']
251 254
  outputarray['vg_free'] = vginfo['vg_free']
252 255

  
253
  hyper = hypervisor.GetHypervisor(_GetConfig())
256
  hyper = hypervisor.GetHypervisor(hypervisor_type)
254 257
  hyp_info = hyper.GetNodeInfo()
255 258
  if hyp_info is not None:
256 259
    outputarray.update(hyp_info)
......
267 270
def VerifyNode(what, cluster_name):
268 271
  """Verify the status of the local node.
269 272

  
270
  Args:
271
    what - a dictionary of things to check:
272
      'filelist' : list of files for which to compute checksums
273
      'nodelist' : list of nodes we should check communication with
274
      'hypervisor': run the hypervisor-specific verify
273
  Based on the input L{what} parameter, various checks are done on the
274
  local node.
275

  
276
  If the I{filelist} key is present, this list of
277
  files is checksummed and the file/checksum pairs are returned.
278

  
279
  If the I{nodelist} key is present, we check that we have
280
  connectivity via ssh with the target nodes (and check the hostname
281
  report).
275 282

  
276
  Requested files on local node are checksummed and the result returned.
283
  If the I{node-net-test} key is present, we check that we have
284
  connectivity to the given nodes via both primary IP and, if
285
  applicable, secondary IPs.
286

  
287
  @type what: C{dict}
288
  @param what: a dictionary of things to check:
289
      - filelist: list of files for which to compute checksums
290
      - nodelist: list of nodes we should check ssh communication with
291
      - node-net-test: list of nodes we should check node daemon port
292
        connectivity with
293
      - hypervisor: list with hypervisors to run the verify for
277 294

  
278
  The nodelist is traversed, with the following checks being made
279
  for each node:
280
  - known_hosts key correct
281
  - correct resolving of node name (target node returns its own hostname
282
    by ssh-execution of 'hostname', result compared against name in list.
283 295

  
284 296
  """
285 297
  result = {}
286 298

  
287 299
  if 'hypervisor' in what:
288
    result['hypervisor'] = hypervisor.GetHypervisor(_GetConfig()).Verify()
300
    result['hypervisor'] = my_dict = {}
301
    for hv_name in what['hypervisor']:
302
      my_dict[hv_name] = hypervisor.GetHypervisor(hv_name).Verify()
289 303

  
290 304
  if 'filelist' in what:
291 305
    result['filelist'] = utils.FingerprintFiles(what['filelist'])
......
415 429
  return True
416 430

  
417 431

  
418
def GetInstanceList():
432
def GetInstanceList(hypervisor_list):
419 433
  """Provides a list of instances.
420 434

  
421
  Returns:
422
    A list of all running instances on the current node
423
    - instance1.example.com
424
    - instance2.example.com
435
  @type hypervisor_list: list
436
  @param hypervisor_list: the list of hypervisors to query information
437

  
438
  @rtype: list
439
  @return: a list of all running instances on the current node
440
             - instance1.example.com
441
             - instance2.example.com
425 442

  
426 443
  """
427
  try:
428
    names = hypervisor.GetHypervisor(_GetConfig()).ListInstances()
429
  except errors.HypervisorError, err:
430
    logging.exception("Error enumerating instances")
431
    raise
444
  results = []
445
  for hname in hypervisor_list:
446
    try:
447
      names = hypervisor.GetHypervisor(hname).ListInstances()
448
      results.extend(names)
449
    except errors.HypervisorError, err:
450
      logging.exception("Error enumerating instances for hypevisor %s", hname)
451
      # FIXME: should we somehow not propagate this to the master?
452
      raise
432 453

  
433
  return names
454
  return results
434 455

  
435 456

  
436
def GetInstanceInfo(instance):
457
def GetInstanceInfo(instance, hname):
437 458
  """Gives back the informations about an instance as a dictionary.
438 459

  
439
  Args:
440
    instance: name of the instance (ex. instance1.example.com)
460
  @type instance: string
461
  @param instance: the instance name
462
  @type hname: string
463
  @param hname: the hypervisor type of the instance
441 464

  
442
  Returns:
443
    { 'memory' : 511, 'state' : '-b---', 'time' : 3188.8, }
444
    where
445
    memory: memory size of instance (int)
446
    state: xen state of instance (string)
447
    time: cpu time of instance (float)
465
  @rtype: dict
466
  @return: dictionary with the following keys:
467
      - memory: memory size of instance (int)
468
      - state: xen state of instance (string)
469
      - time: cpu time of instance (float)
448 470

  
449 471
  """
450 472
  output = {}
451 473

  
452
  iinfo = hypervisor.GetHypervisor(_GetConfig()).GetInstanceInfo(instance)
474
  iinfo = hypervisor.GetHypervisor(hname).GetInstanceInfo(instance)
453 475
  if iinfo is not None:
454 476
    output['memory'] = iinfo[2]
455 477
    output['state'] = iinfo[4]
......
458 480
  return output
459 481

  
460 482

  
461
def GetAllInstancesInfo():
483
def GetAllInstancesInfo(hypervisor_list):
462 484
  """Gather data about all instances.
463 485

  
464 486
  This is the equivalent of `GetInstanceInfo()`, except that it
465 487
  computes data for all instances at once, thus being faster if one
466 488
  needs data about more than one instance.
467 489

  
468
  Returns: a dictionary of dictionaries, keys being the instance name,
469
    and with values:
470
    { 'memory' : 511, 'state' : '-b---', 'time' : 3188.8, }
471
    where
472
    memory: memory size of instance (int)
473
    state: xen state of instance (string)
474
    time: cpu time of instance (float)
475
    vcpus: the number of cpus
490
  @type hypervisor_list: list
491
  @param hypervisor_list: list of hypervisors to query for instance data
492

  
493
  @rtype: dict of dicts
494
  @return: dictionary of instance: data, with data having the following keys:
495
      - memory: memory size of instance (int)
496
      - state: xen state of instance (string)
497
      - time: cpu time of instance (float)
498
      - vcpuus: the number of vcpus
476 499

  
477 500
  """
478 501
  output = {}
479 502

  
480
  iinfo = hypervisor.GetHypervisor(_GetConfig()).GetAllInstancesInfo()
481
  if iinfo:
482
    for name, inst_id, memory, vcpus, state, times in iinfo:
483
      output[name] = {
484
        'memory': memory,
485
        'vcpus': vcpus,
486
        'state': state,
487
        'time': times,
488
        }
503
  for hname in hypervisor_list:
504
    iinfo = hypervisor.GetHypervisor(hname).GetAllInstancesInfo()
505
    if iinfo:
506
      for name, inst_id, memory, vcpus, state, times in iinfo:
507
        if name in output:
508
          raise errors.HypervisorError("Instance %s running duplicate" % name)
509
        output[name] = {
510
          'memory': memory,
511
          'vcpus': vcpus,
512
          'state': state,
513
          'time': times,
514
          }
489 515

  
490 516
  return output
491 517

  
......
499 525
    swap_disk: the instance-visible name of the swap device
500 526

  
501 527
  """
502
  cfg = _GetConfig()
503 528
  inst_os = OSFromDisk(instance.os)
504 529

  
505 530
  create_script = inst_os.create_script
......
535 560
                                inst_os.path, create_script, instance.name,
536 561
                                real_os_dev.dev_path, real_swap_dev.dev_path,
537 562
                                logfile)
538
  env = {'HYPERVISOR': cfg.GetHypervisorType()}
563
  env = {'HYPERVISOR': instance.hypervisor}
539 564

  
540 565
  result = utils.RunCmd(command, env=env)
541 566
  if result.failed:
......
666 691
def StartInstance(instance, extra_args):
667 692
  """Start an instance.
668 693

  
669
  Args:
670
    instance - name of instance to start.
694
  @type instance: instance object
695
  @param instance: the instance object
696
  @rtype: boolean
697
  @return: whether the startup was successful or not
671 698

  
672 699
  """
673
  running_instances = GetInstanceList()
700
  running_instances = GetInstanceList([instance.hypervisor])
674 701

  
675 702
  if instance.name in running_instances:
676 703
    return True
677 704

  
678 705
  block_devices = _GatherBlockDevs(instance)
679
  hyper = hypervisor.GetHypervisor(_GetConfig())
706
  hyper = hypervisor.GetHypervisor(instance.hypervisor)
680 707

  
681 708
  try:
682 709
    hyper.StartInstance(instance, block_devices, extra_args)
......
690 717
def ShutdownInstance(instance):
691 718
  """Shut an instance down.
692 719

  
693
  Args:
694
    instance - name of instance to shutdown.
720
  @type instance: instance object
721
  @param instance: the instance object
722
  @rtype: boolean
723
  @return: whether the startup was successful or not
695 724

  
696 725
  """
697
  running_instances = GetInstanceList()
726
  hv_name = instance.hypervisor
727
  running_instances = GetInstanceList([hv_name])
698 728

  
699 729
  if instance.name not in running_instances:
700 730
    return True
701 731

  
702
  hyper = hypervisor.GetHypervisor(_GetConfig())
732
  hyper = hypervisor.GetHypervisor(hv_name)
703 733
  try:
704 734
    hyper.StopInstance(instance)
705 735
  except errors.HypervisorError, err:
......
711 741

  
712 742
  time.sleep(1)
713 743
  for dummy in range(11):
714
    if instance.name not in GetInstanceList():
744
    if instance.name not in GetInstanceList([hv_name]):
715 745
      break
716 746
    time.sleep(10)
717 747
  else:
......
725 755
      return False
726 756

  
727 757
    time.sleep(1)
728
    if instance.name in GetInstanceList():
758
    if instance.name in GetInstanceList([hv_name]):
729 759
      logging.error("could not shutdown instance '%s' even by destroy",
730 760
                    instance.name)
731 761
      return False
......
741 771
    reboot_type - how to reboot [soft,hard,full]
742 772

  
743 773
  """
744
  running_instances = GetInstanceList()
774
  running_instances = GetInstanceList([instance.hypervisor])
745 775

  
746 776
  if instance.name not in running_instances:
747 777
    logging.error("Cannot reboot instance that is not running")
748 778
    return False
749 779

  
750
  hyper = hypervisor.GetHypervisor(_GetConfig())
780
  hyper = hypervisor.GetHypervisor(instance.hypervisor)
751 781
  if reboot_type == constants.INSTANCE_REBOOT_SOFT:
752 782
    try:
753 783
      hyper.RebootInstance(instance)
......
764 794
  else:
765 795
    raise errors.ParameterError("reboot_type invalid")
766 796

  
767

  
768 797
  return True
769 798

  
770 799

  
......
784 813
      - msg is a string with details in case of failure
785 814

  
786 815
  """
787
  hyper = hypervisor.GetHypervisor(_GetConfig())
816
  hyper = hypervisor.GetHypervisor(instance.hypervisor_name)
788 817

  
789 818
  try:
790 819
    hyper.MigrateInstance(instance.name, target, live)
......
1464 1493
    False in case of error, True otherwise.
1465 1494

  
1466 1495
  """
1467
  cfg = _GetConfig()
1468 1496
  inst_os = OSFromDisk(instance.os)
1469 1497
  import_script = inst_os.import_script
1470 1498

  
......
1507 1535
                               logfile)
1508 1536

  
1509 1537
  command = '|'.join([utils.ShellQuoteArgs(remotecmd), comprcmd, impcmd])
1510
  env = {'HYPERVISOR': cfg.GetHypervisorType()}
1538
  env = {'HYPERVISOR': instance.hypervisor}
1511 1539

  
1512 1540
  result = utils.RunCmd(command, env=env)
1513 1541

  

Also available in: Unified diff