Revision 72a84c96

b/lib/cmdlib.py
3422 3422
      _RedistributeAncillaryFiles(self)
3423 3423

  
3424 3424

  
3425
class LUQueryNodes(NoHooksLU):
3426
  """Logical unit for querying nodes.
3427

  
3428
  """
3429
  # pylint: disable-msg=W0142
3430
  _OP_PARAMS = [
3431
    _POutputFields,
3432
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
3433
    ("use_locking", False, ht.TBool),
3434
    ]
3435
  REQ_BGL = False
3436

  
3437
  _SIMPLE_FIELDS = ["name", "serial_no", "ctime", "mtime", "uuid",
3438
                    "master_candidate", "offline", "drained",
3439
                    "master_capable", "vm_capable"]
3440

  
3441
  _FIELDS_DYNAMIC = utils.FieldSet(
3442
    "dtotal", "dfree",
3443
    "mtotal", "mnode", "mfree",
3444
    "bootid",
3445
    "ctotal", "cnodes", "csockets",
3446
    )
3447

  
3448
  _FIELDS_STATIC = utils.FieldSet(*[
3449
    "pinst_cnt", "sinst_cnt",
3450
    "pinst_list", "sinst_list",
3451
    "pip", "sip", "tags",
3452
    "master", "role",
3453
    "group.uuid", "group",
3454
    ] + _SIMPLE_FIELDS
3455
    )
3456

  
3457
  def CheckArguments(self):
3458
    _CheckOutputFields(static=self._FIELDS_STATIC,
3459
                       dynamic=self._FIELDS_DYNAMIC,
3460
                       selected=self.op.output_fields)
3425
class _NodeQuery(_QueryBase):
3426
  FIELDS = query.NODE_FIELDS
3461 3427

  
3462
  def ExpandNames(self):
3463
    self.needed_locks = {}
3464
    self.share_locks[locking.LEVEL_NODE] = 1
3428
  def ExpandNames(self, lu):
3429
    lu.needed_locks = {}
3430
    lu.share_locks[locking.LEVEL_NODE] = 1
3465 3431

  
3466
    if self.op.names:
3467
      self.wanted = _GetWantedNodes(self, self.op.names)
3432
    if self.names:
3433
      self.wanted = _GetWantedNodes(lu, self.names)
3468 3434
    else:
3469 3435
      self.wanted = locking.ALL_SET
3470 3436

  
3471
    self.do_node_query = self._FIELDS_STATIC.NonMatching(self.op.output_fields)
3472
    self.do_locking = self.do_node_query and self.op.use_locking
3437
    self.do_locking = (self.use_locking and
3438
                       query.NQ_LIVE in self.requested_data)
3439

  
3473 3440
    if self.do_locking:
3474 3441
      # if we don't request only static fields, we need to lock the nodes
3475
      self.needed_locks[locking.LEVEL_NODE] = self.wanted
3442
      lu.needed_locks[locking.LEVEL_NODE] = self.wanted
3476 3443

  
3477
  def Exec(self, feedback_fn):
3444
  def DeclareLocks(self, _):
3445
    pass
3446

  
3447
  def _GetQueryData(self, lu):
3478 3448
    """Computes the list of nodes and their attributes.
3479 3449

  
3480 3450
    """
3481
    all_info = self.cfg.GetAllNodesInfo()
3451
    all_info = lu.cfg.GetAllNodesInfo()
3452

  
3482 3453
    if self.do_locking:
3483
      nodenames = self.acquired_locks[locking.LEVEL_NODE]
3454
      nodenames = lu.acquired_locks[locking.LEVEL_NODE]
3484 3455
    elif self.wanted != locking.ALL_SET:
3485 3456
      nodenames = self.wanted
3486 3457
      missing = set(nodenames).difference(all_info.keys())
3487 3458
      if missing:
3488
        raise errors.OpExecError(
3489
          "Some nodes were removed before retrieving their data: %s" % missing)
3459
        raise errors.OpExecError("Some nodes were removed before retrieving"
3460
                                 " their data: %s" % missing)
3490 3461
    else:
3491 3462
      nodenames = all_info.keys()
3492 3463

  
3493 3464
    nodenames = utils.NiceSort(nodenames)
3494
    nodelist = [all_info[name] for name in nodenames]
3495

  
3496
    if "group" in self.op.output_fields:
3497
      groups = self.cfg.GetAllNodeGroupsInfo()
3498
    else:
3499
      groups = {}
3500

  
3501
    # begin data gathering
3502 3465

  
3503
    if self.do_node_query:
3504
      live_data = {}
3505
      node_data = self.rpc.call_node_info(nodenames, self.cfg.GetVGName(),
3506
                                          self.cfg.GetHypervisorType())
3507
      for name in nodenames:
3508
        nodeinfo = node_data[name]
3509
        if not nodeinfo.fail_msg and nodeinfo.payload:
3510
          nodeinfo = nodeinfo.payload
3511
          fn = utils.TryConvert
3512
          live_data[name] = {
3513
            "mtotal": fn(int, nodeinfo.get('memory_total', None)),
3514
            "mnode": fn(int, nodeinfo.get('memory_dom0', None)),
3515
            "mfree": fn(int, nodeinfo.get('memory_free', None)),
3516
            "dtotal": fn(int, nodeinfo.get('vg_size', None)),
3517
            "dfree": fn(int, nodeinfo.get('vg_free', None)),
3518
            "ctotal": fn(int, nodeinfo.get('cpu_total', None)),
3519
            "bootid": nodeinfo.get('bootid', None),
3520
            "cnodes": fn(int, nodeinfo.get('cpu_nodes', None)),
3521
            "csockets": fn(int, nodeinfo.get('cpu_sockets', None)),
3522
            }
3523
        else:
3524
          live_data[name] = {}
3466
    # Gather data as requested
3467
    if query.NQ_LIVE in self.requested_data:
3468
      node_data = lu.rpc.call_node_info(nodenames, lu.cfg.GetVGName(),
3469
                                        lu.cfg.GetHypervisorType())
3470
      live_data = dict((name, nresult.payload)
3471
                       for (name, nresult) in node_data.items()
3472
                       if not nresult.fail_msg and nresult.payload)
3525 3473
    else:
3526
      live_data = dict.fromkeys(nodenames, {})
3474
      live_data = None
3527 3475

  
3528
    node_to_primary = dict([(name, set()) for name in nodenames])
3529
    node_to_secondary = dict([(name, set()) for name in nodenames])
3476
    if query.NQ_INST in self.requested_data:
3477
      node_to_primary = dict([(name, set()) for name in nodenames])
3478
      node_to_secondary = dict([(name, set()) for name in nodenames])
3530 3479

  
3531
    inst_fields = frozenset(("pinst_cnt", "pinst_list",
3532
                             "sinst_cnt", "sinst_list"))
3533
    if inst_fields & frozenset(self.op.output_fields):
3534
      inst_data = self.cfg.GetAllInstancesInfo()
3480
      inst_data = lu.cfg.GetAllInstancesInfo()
3535 3481

  
3536 3482
      for inst in inst_data.values():
3537 3483
        if inst.primary_node in node_to_primary:
......
3539 3485
        for secnode in inst.secondary_nodes:
3540 3486
          if secnode in node_to_secondary:
3541 3487
            node_to_secondary[secnode].add(inst.name)
3488
    else:
3489
      node_to_primary = None
3490
      node_to_secondary = None
3542 3491

  
3543
    master_node = self.cfg.GetMasterNode()
3492
    if query.NQ_GROUP in self.requested_data:
3493
      groups = lu.cfg.GetAllNodeGroupsInfo()
3494
    else:
3495
      groups = {}
3544 3496

  
3545
    # end data gathering
3497
    return query.NodeQueryData([all_info[name] for name in nodenames],
3498
                               live_data, lu.cfg.GetMasterNode(),
3499
                               node_to_primary, node_to_secondary, groups)
3546 3500

  
3547
    output = []
3548
    for node in nodelist:
3549
      node_output = []
3550
      for field in self.op.output_fields:
3551
        if field in self._SIMPLE_FIELDS:
3552
          val = getattr(node, field)
3553
        elif field == "pinst_list":
3554
          val = list(node_to_primary[node.name])
3555
        elif field == "sinst_list":
3556
          val = list(node_to_secondary[node.name])
3557
        elif field == "pinst_cnt":
3558
          val = len(node_to_primary[node.name])
3559
        elif field == "sinst_cnt":
3560
          val = len(node_to_secondary[node.name])
3561
        elif field == "pip":
3562
          val = node.primary_ip
3563
        elif field == "sip":
3564
          val = node.secondary_ip
3565
        elif field == "tags":
3566
          val = list(node.GetTags())
3567
        elif field == "master":
3568
          val = node.name == master_node
3569
        elif self._FIELDS_DYNAMIC.Matches(field):
3570
          val = live_data[node.name].get(field, None)
3571
        elif field == "role":
3572
          if node.name == master_node:
3573
            val = "M"
3574
          elif node.master_candidate:
3575
            val = "C"
3576
          elif node.drained:
3577
            val = "D"
3578
          elif node.offline:
3579
            val = "O"
3580
          else:
3581
            val = "R"
3582
        elif field == "group.uuid":
3583
          val = node.group
3584
        elif field == "group":
3585
          ng = groups.get(node.group, None)
3586
          if ng is None:
3587
            val = "<unknown>"
3588
          else:
3589
            val = ng.name
3590
        else:
3591
          raise errors.ParameterError(field)
3592
        node_output.append(val)
3593
      output.append(node_output)
3594 3501

  
3595
    return output
3502
class LUQueryNodes(NoHooksLU):
3503
  """Logical unit for querying nodes.
3504

  
3505
  """
3506
  # pylint: disable-msg=W0142
3507
  _OP_PARAMS = [
3508
    _POutputFields,
3509
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
3510
    ("use_locking", False, ht.TBool),
3511
    ]
3512
  REQ_BGL = False
3513

  
3514
  def CheckArguments(self):
3515
    self.nq = _NodeQuery(self.op.names, self.op.output_fields,
3516
                         self.op.use_locking)
3517

  
3518
  def ExpandNames(self):
3519
    self.nq.ExpandNames(self)
3520

  
3521
  def Exec(self, feedback_fn):
3522
    return self.nq.OldStyleQuery(self)
3596 3523

  
3597 3524

  
3598 3525
class LUQueryNodeVolumes(NoHooksLU):

Also available in: Unified diff