"ctotal",
])
- _CheckOutputFields(static=["name", "pinst_cnt", "sinst_cnt",
- "pinst_list", "sinst_list",
- "pip", "sip", "tags"],
+ self.static_fields = frozenset([
+ "name", "pinst_cnt", "sinst_cnt",
+ "pinst_list", "sinst_list",
+ "pip", "sip", "tags",
+ ])
+
+ _CheckOutputFields(static=self.static_fields,
dynamic=self.dynamic_fields,
selected=self.op.output_fields)
self.needed_locks = {}
self.share_locks[locking.LEVEL_NODE] = 1
- # TODO: we could lock nodes only if the user asked for dynamic fields. For
- # that we need atomic ways to get info for a group of nodes from the
- # config, though.
- if not self.op.names:
- self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
+
+ if self.op.names:
+ self.wanted = _GetWantedNodes(self, self.op.names)
else:
- self.needed_locks[locking.LEVEL_NODE] = \
- _GetWantedNodes(self, self.op.names)
+ self.wanted = locking.ALL_SET
+
+ self.do_locking = not self.static_fields.issuperset(self.op.output_fields)
+ if self.do_locking:
+ # if we don't request only static fields, we need to lock the nodes
+ self.needed_locks[locking.LEVEL_NODE] = self.wanted
+
def CheckPrereq(self):
"""Check prerequisites.
"""
- # This of course is valid only if we locked the nodes
- self.wanted = self.acquired_locks[locking.LEVEL_NODE]
+ # The validation of the node list is done in the _GetWantedNodes,
+ # if non empty, and if empty, there's no validation to do
+ pass
def Exec(self, feedback_fn):
"""Computes the list of nodes and their attributes.
"""
- nodenames = self.wanted
- nodelist = [self.cfg.GetNodeInfo(name) for name in nodenames]
+ all_info = self.cfg.GetAllNodesInfo()
+ if self.do_locking:
+ nodenames = self.acquired_locks[locking.LEVEL_NODE]
+ else:
+ nodenames = all_info.keys()
+ nodelist = [all_info[name] for name in nodenames]
# begin data gathering
def ExpandNames(self):
self.dynamic_fields = frozenset(["oper_state", "oper_ram", "status"])
- _CheckOutputFields(static=["name", "os", "pnode", "snodes",
- "admin_state", "admin_ram",
- "disk_template", "ip", "mac", "bridge",
- "sda_size", "sdb_size", "vcpus", "tags",
- "auto_balance",
- "network_port", "kernel_path", "initrd_path",
- "hvm_boot_order", "hvm_acpi", "hvm_pae",
- "hvm_cdrom_image_path", "hvm_nic_type",
- "hvm_disk_type", "vnc_bind_address"],
+ self.static_fields = frozenset([
+ "name", "os", "pnode", "snodes",
+ "admin_state", "admin_ram",
+ "disk_template", "ip", "mac", "bridge",
+ "sda_size", "sdb_size", "vcpus", "tags",
+ "auto_balance",
+ "network_port", "kernel_path", "initrd_path",
+ "hvm_boot_order", "hvm_acpi", "hvm_pae",
+ "hvm_cdrom_image_path", "hvm_nic_type",
+ "hvm_disk_type", "vnc_bind_address",
+ ])
+ _CheckOutputFields(static=self.static_fields,
dynamic=self.dynamic_fields,
selected=self.op.output_fields)
self.share_locks[locking.LEVEL_INSTANCE] = 1
self.share_locks[locking.LEVEL_NODE] = 1
- # TODO: we could lock instances (and nodes) only if the user asked for
- # dynamic fields. For that we need atomic ways to get info for a group of
- # instances from the config, though.
- if not self.op.names:
- self.needed_locks[locking.LEVEL_INSTANCE] = locking.ALL_SET
+ if self.op.names:
+ self.wanted = _GetWantedInstances(self, self.op.names)
else:
- self.needed_locks[locking.LEVEL_INSTANCE] = \
- _GetWantedInstances(self, self.op.names)
+ self.wanted = locking.ALL_SET
- self.needed_locks[locking.LEVEL_NODE] = []
- self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
+ self.do_locking = not self.static_fields.issuperset(self.op.output_fields)
+ if self.do_locking:
+ self.needed_locks[locking.LEVEL_INSTANCE] = self.wanted
+ self.needed_locks[locking.LEVEL_NODE] = []
+ self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
def DeclareLocks(self, level):
- # TODO: locking of nodes could be avoided when not querying them
- if level == locking.LEVEL_NODE:
+ if level == locking.LEVEL_NODE and self.do_locking:
self._LockInstancesNodes()
def CheckPrereq(self):
"""Check prerequisites.
"""
- # This of course is valid only if we locked the instances
- self.wanted = self.acquired_locks[locking.LEVEL_INSTANCE]
+ pass
def Exec(self, feedback_fn):
"""Computes the list of nodes and their attributes.
"""
- instance_names = self.wanted
- instance_list = [self.cfg.GetInstanceInfo(iname) for iname
- in instance_names]
+ all_info = self.cfg.GetAllInstancesInfo()
+ if self.do_locking:
+ instance_names = self.acquired_locks[locking.LEVEL_INSTANCE]
+ else:
+ instance_names = all_info.keys()
+ instance_list = [all_info[iname] for iname in instance_names]
# begin data gathering
"""
_OP_REQP = ["instances"]
+ REQ_BGL = False
+ def ExpandNames(self):
+ self.needed_locks = {}
+ self.share_locks = dict(((i, 1) for i in locking.LEVELS))
+
+ if not isinstance(self.op.instances, list):
+ raise errors.OpPrereqError("Invalid argument type 'instances'")
+
+ if self.op.instances:
+ self.wanted_names = []
+ for name in self.op.instances:
+ full_name = self.cfg.ExpandInstanceName(name)
+ if full_name is None:
+ raise errors.OpPrereqError("Instance '%s' not known" %
+ self.op.instance_name)
+ self.wanted_names.append(full_name)
+ self.needed_locks[locking.LEVEL_INSTANCE] = self.wanted_names
+ else:
+ self.wanted_names = None
+ self.needed_locks[locking.LEVEL_INSTANCE] = locking.ALL_SET
+
+ self.needed_locks[locking.LEVEL_NODE] = []
+ self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
+
+ def DeclareLocks(self, level):
+ if level == locking.LEVEL_NODE:
+ self._LockInstancesNodes()
def CheckPrereq(self):
"""Check prerequisites.
This only checks the optional instance list against the existing names.
"""
- if not isinstance(self.op.instances, list):
- raise errors.OpPrereqError("Invalid argument type 'instances'")
- if self.op.instances:
- self.wanted_instances = []
- names = self.op.instances
- for name in names:
- instance = self.cfg.GetInstanceInfo(self.cfg.ExpandInstanceName(name))
- if instance is None:
- raise errors.OpPrereqError("No such instance name '%s'" % name)
- self.wanted_instances.append(instance)
- else:
- self.wanted_instances = [self.cfg.GetInstanceInfo(name) for name
- in self.cfg.GetInstanceList()]
- return
+ if self.wanted_names is None:
+ self.wanted_names = self.acquired_locks[locking.LEVEL_INSTANCE]
+ self.wanted_instances = [self.cfg.GetInstanceInfo(name) for name
+ in self.wanted_names]
+ return
def _ComputeDiskStatus(self, instance, snode, dev):
"""Compute block device status.