Revision 64c7b383 lib/cmdlib.py

b/lib/cmdlib.py
2542 2542

  
2543 2543
    return instdisk
2544 2544

  
2545
  @staticmethod
2546
  def _SshNodeSelector(group_uuid, all_nodes):
2547
    """Create endless iterators for all potential SSH check hosts.
2548

  
2549
    """
2550
    nodes = [node for node in all_nodes
2551
             if (node.group != group_uuid and
2552
                 not node.offline)]
2553
    keyfunc = operator.attrgetter("group")
2554

  
2555
    return map(itertools.cycle,
2556
               [sorted(map(operator.attrgetter("name"), names))
2557
                for _, names in itertools.groupby(sorted(nodes, key=keyfunc),
2558
                                                  keyfunc)])
2559

  
2560
  @classmethod
2561
  def _SelectSshCheckNodes(cls, group_nodes, group_uuid, all_nodes):
2562
    """Choose which nodes should talk to which other nodes.
2563

  
2564
    We will make nodes contact all nodes in their group, and one node from
2565
    every other group.
2566

  
2567
    @warning: This algorithm has a known issue if one node group is much
2568
      smaller than others (e.g. just one node). In such a case all other
2569
      nodes will talk to the single node.
2570

  
2571
    """
2572
    online_nodes = sorted(node.name for node in group_nodes if not node.offline)
2573
    sel = cls._SshNodeSelector(group_uuid, all_nodes)
2574

  
2575
    return (online_nodes,
2576
            dict((name, sorted([i.next() for i in sel]))
2577
                 for name in online_nodes))
2578

  
2545 2579
  def BuildHooksEnv(self):
2546 2580
    """Build hooks env.
2547 2581

  
......
2605 2639

  
2606 2640
    feedback_fn("* Gathering data (%d nodes)" % len(self.my_node_names))
2607 2641

  
2608
    # We will make nodes contact all nodes in their group, and one node from
2609
    # every other group.
2610
    # TODO: should it be a *random* node, different every time?
2611
    online_nodes = [node.name for node in node_data_list if not node.offline]
2612
    other_group_nodes = {}
2613

  
2614
    for name in sorted(self.all_node_info):
2615
      node = self.all_node_info[name]
2616
      if (node.group not in other_group_nodes
2617
          and node.group != self.group_uuid
2618
          and not node.offline):
2619
        other_group_nodes[node.group] = node.name
2620

  
2621 2642
    node_verify_param = {
2622 2643
      constants.NV_FILELIST:
2623 2644
        utils.UniqueSequence(filename
2624 2645
                             for files in filemap
2625 2646
                             for filename in files),
2626
      constants.NV_NODELIST: online_nodes + other_group_nodes.values(),
2647
      constants.NV_NODELIST:
2648
        self._SelectSshCheckNodes(node_data_list, self.group_uuid,
2649
                                  self.all_node_info.values()),
2627 2650
      constants.NV_HYPERVISOR: hypervisors,
2628 2651
      constants.NV_HVPARAMS:
2629 2652
        _GetAllHypervisorParameters(cluster, self.all_inst_info.values()),

Also available in: Unified diff