Revision 25361b9a lib/cmdlib.py

b/lib/cmdlib.py
570 570
    }
571 571
    self.share_locks = dict(((i, 1) for i in locking.LEVELS))
572 572

  
573
  def _VerifyNode(self, nodeinfo, file_list, local_cksum, vglist, node_result,
574
                  remote_version, feedback_fn, master_files):
573
  def _VerifyNode(self, nodeinfo, file_list, local_cksum,
574
                  node_result, feedback_fn, master_files):
575 575
    """Run multiple tests against a node.
576 576

  
577 577
    Test list:
......
585 585
    @param nodeinfo: the node to check
586 586
    @param file_list: required list of files
587 587
    @param local_cksum: dictionary of local files and their checksums
588
    @type vglist: dict
589
    @param vglist: dictionary of volume group names and their size
590 588
    @param node_result: the results from the node
591
    @param remote_version: the RPC version from the remote node
592 589
    @param feedback_fn: function used to accumulate results
593 590
    @param master_files: list of files that only masters should have
594 591

  
595 592
    """
596 593
    node = nodeinfo.name
594

  
595
    # main result, node_result should be a non-empty dict
596
    if not node_result or not isinstance(node_result, dict):
597
      feedback_fn("  - ERROR: unable to verify node %s." % (node,))
598
      return True
599

  
597 600
    # compares ganeti version
598 601
    local_version = constants.PROTOCOL_VERSION
602
    remote_version = node_result.get('version', None)
599 603
    if not remote_version:
600 604
      feedback_fn("  - ERROR: connection to %s failed" % (node))
601 605
      return True
......
608 612
    # checks vg existance and size > 20G
609 613

  
610 614
    bad = False
615
    vglist = node_result.get(constants.NV_VGLIST, None)
611 616
    if not vglist:
612 617
      feedback_fn("  - ERROR: unable to check volume groups on node %s." %
613 618
                      (node,))
......
619 624
        feedback_fn("  - ERROR: %s on node %s" % (vgstatus, node))
620 625
        bad = True
621 626

  
622
    if not node_result:
623
      feedback_fn("  - ERROR: unable to verify node %s." % (node,))
624
      return True
625

  
626 627
    # checks config file checksum
627
    # checks ssh to any
628 628

  
629
    if 'filelist' not in node_result:
629
    remote_cksum = node_result.get(constants.NV_FILELIST, None)
630
    if not isinstance(remote_cksum, dict):
630 631
      bad = True
631 632
      feedback_fn("  - ERROR: node hasn't returned file checksum data")
632 633
    else:
633
      remote_cksum = node_result['filelist']
634 634
      for file_name in file_list:
635 635
        node_is_mc = nodeinfo.master_candidate
636 636
        must_have_file = file_name not in master_files
......
653 653
            feedback_fn("  - ERROR: file '%s' should not exist on non master"
654 654
                        " candidates" % file_name)
655 655

  
656
    if 'nodelist' not in node_result:
656
    # checks ssh to any
657

  
658
    if constants.NV_NODELIST not in node_result:
657 659
      bad = True
658 660
      feedback_fn("  - ERROR: node hasn't returned node ssh connectivity data")
659 661
    else:
660
      if node_result['nodelist']:
662
      if node_result[constants.NV_NODELIST]:
661 663
        bad = True
662
        for node in node_result['nodelist']:
664
        for node in node_result[constants.NV_NODELIST]:
663 665
          feedback_fn("  - ERROR: ssh communication with node '%s': %s" %
664
                          (node, node_result['nodelist'][node]))
665
    if 'node-net-test' not in node_result:
666
                          (node, node_result[constants.NV_NODELIST][node]))
667

  
668
    if constants.NV_NODENETTEST not in node_result:
666 669
      bad = True
667 670
      feedback_fn("  - ERROR: node hasn't returned node tcp connectivity data")
668 671
    else:
669
      if node_result['node-net-test']:
672
      if node_result[constants.NV_NODENETTEST]:
670 673
        bad = True
671
        nlist = utils.NiceSort(node_result['node-net-test'].keys())
674
        nlist = utils.NiceSort(node_result[constants.NV_NODENETTEST].keys())
672 675
        for node in nlist:
673 676
          feedback_fn("  - ERROR: tcp communication with node '%s': %s" %
674
                          (node, node_result['node-net-test'][node]))
677
                          (node, node_result[constants.NV_NODENETTEST][node]))
675 678

  
676
    hyp_result = node_result.get('hypervisor', None)
679
    hyp_result = node_result.get(constants.NV_HYPERVISOR, None)
677 680
    if isinstance(hyp_result, dict):
678 681
      for hv_name, hv_result in hyp_result.iteritems():
679 682
        if hv_result is not None:
......
836 839
    local_checksums = utils.FingerprintFiles(file_names)
837 840

  
838 841
    feedback_fn("* Gathering data (%d nodes)" % len(nodelist))
839
    all_volumeinfo = self.rpc.call_volume_list(nodelist, vg_name)
840
    all_instanceinfo = self.rpc.call_instance_list(nodelist, hypervisors)
841
    all_vglist = self.rpc.call_vg_list(nodelist)
842 842
    node_verify_param = {
843
      'filelist': file_names,
844
      'nodelist': nodelist,
845
      'hypervisor': hypervisors,
846
      'node-net-test': [(node.name, node.primary_ip, node.secondary_ip)
847
                        for node in nodeinfo]
843
      constants.NV_FILELIST: file_names,
844
      constants.NV_NODELIST: nodelist,
845
      constants.NV_HYPERVISOR: hypervisors,
846
      constants.NV_NODENETTEST: [(node.name, node.primary_ip,
847
                                  node.secondary_ip) for node in nodeinfo],
848
      constants.NV_LVLIST: vg_name,
849
      constants.NV_INSTANCELIST: hypervisors,
850
      constants.NV_VGLIST: None,
851
      constants.NV_VERSION: None,
852
      constants.NV_HVINFO: self.cfg.GetHypervisorType(),
848 853
      }
849 854
    all_nvinfo = self.rpc.call_node_verify(nodelist, node_verify_param,
850 855
                                           self.cfg.GetClusterName())
851
    all_rversion = self.rpc.call_version(nodelist)
852
    all_ninfo = self.rpc.call_node_info(nodelist, self.cfg.GetVGName(),
853
                                        self.cfg.GetHypervisorType())
854 856

  
855 857
    cluster = self.cfg.GetClusterInfo()
856 858
    master_node = self.cfg.GetMasterNode()
857 859
    for node_i in nodeinfo:
858 860
      node = node_i.name
861
      nresult = all_nvinfo[node].data
862

  
859 863
      if node == master_node:
860
        ntype="master"
864
        ntype = "master"
861 865
      elif node_i.master_candidate:
862
        ntype="master candidate"
866
        ntype = "master candidate"
863 867
      else:
864
        ntype="regular"
868
        ntype = "regular"
865 869
      feedback_fn("* Verifying node %s (%s)" % (node, ntype))
870

  
871
      if all_nvinfo[node].failed or not isinstance(nresult, dict):
872
        feedback_fn("  - ERROR: connection to %s failed" % (node,))
873
        bad = True
874
        continue
875

  
866 876
      result = self._VerifyNode(node_i, file_names, local_checksums,
867
                                all_vglist[node], all_nvinfo[node],
868
                                all_rversion[node], feedback_fn, master_files)
877
                                nresult, feedback_fn, master_files)
869 878
      bad = bad or result
870 879

  
871
      # node_volume
872
      volumeinfo = all_volumeinfo[node]
873

  
874
      if isinstance(volumeinfo, basestring):
880
      lvdata = nresult.get(constants.NV_LVLIST, "Missing LV data")
881
      if isinstance(lvdata, basestring):
875 882
        feedback_fn("  - ERROR: LVM problem on node %s: %s" %
876
                    (node, volumeinfo[-400:].encode('string_escape')))
883
                    (node, lvdata.encode('string_escape')))
877 884
        bad = True
878 885
        node_volume[node] = {}
879
      elif not isinstance(volumeinfo, dict):
880
        feedback_fn("  - ERROR: connection to %s failed" % (node,))
886
      elif not isinstance(lvdata, dict):
887
        feedback_fn("  - ERROR: connection to %s failed (lvlist)" % (node,))
881 888
        bad = True
882 889
        continue
883 890
      else:
884
        node_volume[node] = volumeinfo
891
        node_volume[node] = lvdata
885 892

  
886 893
      # node_instance
887
      nodeinstance = all_instanceinfo[node]
888
      if type(nodeinstance) != list:
889
        feedback_fn("  - ERROR: connection to %s failed" % (node,))
894
      idata = nresult.get(constants.NV_INSTANCELIST, None)
895
      if not isinstance(idata, list):
896
        feedback_fn("  - ERROR: connection to %s failed (instancelist)" %
897
                    (node,))
890 898
        bad = True
891 899
        continue
892 900

  
893
      node_instance[node] = nodeinstance
901
      node_instance[node] = idata
894 902

  
895 903
      # node_info
896
      nodeinfo = all_ninfo[node]
904
      nodeinfo = nresult.get(constants.NV_HVINFO, None)
897 905
      if not isinstance(nodeinfo, dict):
898
        feedback_fn("  - ERROR: connection to %s failed" % (node,))
906
        feedback_fn("  - ERROR: connection to %s failed (hvinfo)" % (node,))
899 907
        bad = True
900 908
        continue
901 909

  
902 910
      try:
903 911
        node_info[node] = {
904 912
          "mfree": int(nodeinfo['memory_free']),
905
          "dfree": int(nodeinfo['vg_free']),
913
          "dfree": int(nresult[constants.NV_VGLIST][vg_name]),
906 914
          "pinst": [],
907 915
          "sinst": [],
908 916
          # dictionary holding all instances this node is secondary for,
......
1017 1025
        for node_name in hooks_results:
1018 1026
          show_node_header = True
1019 1027
          res = hooks_results[node_name]
1020
          if res is False or not isinstance(res, list):
1021
            feedback_fn("    Communication failure")
1028
          if res.failed or res.data is False or not isinstance(res.data, list):
1029
            feedback_fn("    Communication failure in hooks execution")
1022 1030
            lu_result = 1
1023 1031
            continue
1024
          for script, hkr, output in res:
1032
          for script, hkr, output in res.data:
1025 1033
            if hkr == constants.HKR_FAIL:
1026 1034
              # The node header is only shown once, if there are
1027 1035
              # failing hooks on that node
......
5500 5508
    found = False
5501 5509
    for node in exportlist:
5502 5510
      if exportlist[node].failed:
5503
        self.Warning("Failed to query node %s, continuing" % node)
5511
        self.LogWarning("Failed to query node %s, continuing" % node)
5504 5512
        continue
5505 5513
      if instance_name in exportlist[node].data:
5506 5514
        found = True

Also available in: Unified diff