from ganeti.cmdlib.backup import LUBackupQuery, LUBackupPrepare, \
LUBackupExport, LUBackupRemove
from ganeti.cmdlib.query import LUQuery, LUQueryFields
+from ganeti.cmdlib.operating_system import LUOsDiagnose
from ganeti.cmdlib.tags import LUTagsGet, LUTagsSearch, LUTagsSet, LUTagsDel
from ganeti.cmdlib.network import LUNetworkAdd, LUNetworkRemove, \
LUNetworkSetParams, LUNetworkQuery, LUNetworkConnect, LUNetworkDisconnect
utils.CommaJoin(errs))
-class _OsQuery(_QueryBase):
- FIELDS = query.OS_FIELDS
-
- def ExpandNames(self, lu):
- # Lock all nodes in shared mode
- # Temporary removal of locks, should be reverted later
- # TODO: reintroduce locks when they are lighter-weight
- lu.needed_locks = {}
- #self.share_locks[locking.LEVEL_NODE] = 1
- #self.needed_locks[locking.LEVEL_NODE] = locking.ALL_SET
-
- # The following variables interact with _QueryBase._GetNames
- if self.names:
- self.wanted = self.names
- else:
- self.wanted = locking.ALL_SET
-
- self.do_locking = self.use_locking
-
- def DeclareLocks(self, lu, level):
- pass
-
- @staticmethod
- def _DiagnoseByOS(rlist):
- """Remaps a per-node return list into an a per-os per-node dictionary
-
- @param rlist: a map with node names as keys and OS objects as values
-
- @rtype: dict
- @return: a dictionary with osnames as keys and as value another
- map, with nodes as keys and tuples of (path, status, diagnose,
- variants, parameters, api_versions) as values, eg::
-
- {"debian-etch": {"node1": [(/usr/lib/..., True, "", [], []),
- (/srv/..., False, "invalid api")],
- "node2": [(/srv/..., True, "", [], [])]}
- }
-
- """
- all_os = {}
- # we build here the list of nodes that didn't fail the RPC (at RPC
- # level), so that nodes with a non-responding node daemon don't
- # make all OSes invalid
- good_nodes = [node_name for node_name in rlist
- if not rlist[node_name].fail_msg]
- for node_name, nr in rlist.items():
- if nr.fail_msg or not nr.payload:
- continue
- for (name, path, status, diagnose, variants,
- params, api_versions) in nr.payload:
- if name not in all_os:
- # build a list of nodes for this os containing empty lists
- # for each node in node_list
- all_os[name] = {}
- for nname in good_nodes:
- all_os[name][nname] = []
- # convert params from [name, help] to (name, help)
- params = [tuple(v) for v in params]
- all_os[name][node_name].append((path, status, diagnose,
- variants, params, api_versions))
- return all_os
-
- def _GetQueryData(self, lu):
- """Computes the list of nodes and their attributes.
-
- """
- # Locking is not used
- assert not (compat.any(lu.glm.is_owned(level)
- for level in locking.LEVELS
- if level != locking.LEVEL_CLUSTER) or
- self.do_locking or self.use_locking)
-
- valid_nodes = [node.name
- for node in lu.cfg.GetAllNodesInfo().values()
- if not node.offline and node.vm_capable]
- pol = self._DiagnoseByOS(lu.rpc.call_os_diagnose(valid_nodes))
- cluster = lu.cfg.GetClusterInfo()
-
- data = {}
-
- for (os_name, os_data) in pol.items():
- info = query.OsInfo(name=os_name, valid=True, node_status=os_data,
- hidden=(os_name in cluster.hidden_os),
- blacklisted=(os_name in cluster.blacklisted_os))
-
- variants = set()
- parameters = set()
- api_versions = set()
-
- for idx, osl in enumerate(os_data.values()):
- info.valid = bool(info.valid and osl and osl[0][1])
- if not info.valid:
- break
-
- (node_variants, node_params, node_api) = osl[0][3:6]
- if idx == 0:
- # First entry
- variants.update(node_variants)
- parameters.update(node_params)
- api_versions.update(node_api)
- else:
- # Filter out inconsistent values
- variants.intersection_update(node_variants)
- parameters.intersection_update(node_params)
- api_versions.intersection_update(node_api)
-
- info.variants = list(variants)
- info.parameters = list(parameters)
- info.api_versions = list(api_versions)
-
- data[os_name] = info
-
- # Prepare data in requested order
- return [data[name] for name in self._GetNames(lu, pol.keys(), None)
- if name in data]
-
-
-class LUOsDiagnose(NoHooksLU):
- """Logical unit for OS diagnose/query.
-
- """
- REQ_BGL = False
-
- @staticmethod
- def _BuildFilter(fields, names):
- """Builds a filter for querying OSes.
-
- """
- name_filter = qlang.MakeSimpleFilter("name", names)
-
- # Legacy behaviour: Hide hidden, blacklisted or invalid OSes if the
- # respective field is not requested
- status_filter = [[qlang.OP_NOT, [qlang.OP_TRUE, fname]]
- for fname in ["hidden", "blacklisted"]
- if fname not in fields]
- if "valid" not in fields:
- status_filter.append([qlang.OP_TRUE, "valid"])
-
- if status_filter:
- status_filter.insert(0, qlang.OP_AND)
- else:
- status_filter = None
-
- if name_filter and status_filter:
- return [qlang.OP_AND, name_filter, status_filter]
- elif name_filter:
- return name_filter
- else:
- return status_filter
-
- def CheckArguments(self):
- self.oq = _OsQuery(self._BuildFilter(self.op.output_fields, self.op.names),
- self.op.output_fields, False)
-
- def ExpandNames(self):
- self.oq.ExpandNames(self)
-
- def Exec(self, feedback_fn):
- return self.oq.OldStyleQuery(self)
-
-
class _ExtStorageQuery(_QueryBase):
FIELDS = query.EXTSTORAGE_FIELDS