X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/be3a4b145fbb80d50df7d9e743a301dd735daa60..cfda0e48eb3238187dbb74bb56d54ca87747684c:/lib/cmdlib.py diff --git a/lib/cmdlib.py b/lib/cmdlib.py index b967979..fa8716e 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -496,15 +496,6 @@ class _QueryBase: # Return expanded names return self.wanted - @classmethod - def FieldsQuery(cls, fields): - """Returns list of available fields. - - @return: List of L{objects.QueryFieldDefinition} - - """ - return query.QueryFields(cls.FIELDS, fields) - def ExpandNames(self, lu): """Expand names for this query. @@ -615,6 +606,18 @@ def _GetUpdatedParams(old_params, update_dict, return params_copy +def _RunPostHook(lu, node_name): + """Runs the post-hook for an opcode on a single node. + + """ + hm = lu.proc.hmclass(lu.rpc.call_hooks_runner, lu) + try: + hm.RunPhase(constants.HOOKS_PHASE_POST, nodes=[node_name]) + except: + # pylint: disable-msg=W0702 + lu.LogWarning("Errors occurred running hooks on %s" % node_name) + + def _CheckOutputFields(static, dynamic, selected): """Checks whether all selected fields are valid. @@ -1159,12 +1162,7 @@ class LUClusterDestroy(LogicalUnit): master = self.cfg.GetMasterNode() # Run post hooks on master node before it's removed - hm = self.proc.hmclass(self.rpc.call_hooks_runner, self) - try: - hm.RunPhase(constants.HOOKS_PHASE_POST, [master]) - except: - # pylint: disable-msg=W0702 - self.LogWarning("Errors occurred running hooks on %s" % master) + _RunPostHook(self, master) result = self.rpc.call_node_stop_master(master, False) result.Raise("Could not disable the master role") @@ -3479,20 +3477,12 @@ class _OsQuery(_QueryBase): # Locking is not used assert not (lu.acquired_locks or self.do_locking or self.use_locking) - # Used further down - assert "valid" in self.FIELDS - assert "hidden" in self.FIELDS - assert "blacklisted" in self.FIELDS - 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() - # Build list of used field names - fields = [fdef.name for fdef in self.query.GetFields()] - data = {} for (os_name, os_data) in pol.items(): @@ -3525,12 +3515,6 @@ class _OsQuery(_QueryBase): info.parameters = list(parameters) info.api_versions = list(api_versions) - # TODO: Move this to filters provided by the client - if (("hidden" not in fields and info.hidden) or - ("blacklisted" not in fields and info.blacklisted) or - ("valid" not in fields and not info.valid)): - continue - data[os_name] = info # Prepare data in requested order @@ -3544,8 +3528,35 @@ class LUOsDiagnose(NoHooksLU): """ 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(qlang.MakeSimpleFilter("name", self.op.names), + self.oq = _OsQuery(self._BuildFilter(self.op.output_fields, self.op.names), self.op.output_fields, False) def ExpandNames(self): @@ -3628,12 +3639,7 @@ class LUNodeRemove(LogicalUnit): self.context.RemoveNode(node.name) # Run post hooks on the node before it's removed - hm = self.proc.hmclass(self.rpc.call_hooks_runner, self) - try: - hm.RunPhase(constants.HOOKS_PHASE_POST, [node.name]) - except: - # pylint: disable-msg=W0702 - self.LogWarning("Errors occurred running hooks on %s" % node.name) + _RunPostHook(self, node.name) result = self.rpc.call_node_leave_cluster(node.name, modify_ssh_setup) msg = result.fail_msg @@ -4031,7 +4037,7 @@ class LUQueryFields(NoHooksLU): self.needed_locks = {} def Exec(self, feedback_fn): - return self.qcls.FieldsQuery(self.op.fields) + return query.QueryFields(self.qcls.FIELDS, self.op.fields) class LUNodeModifyStorage(NoHooksLU): @@ -4108,9 +4114,12 @@ class LUNodeAdd(LogicalUnit): "MASTER_CAPABLE": str(self.op.master_capable), "VM_CAPABLE": str(self.op.vm_capable), } - nodes_0 = self.cfg.GetNodeList() - nodes_1 = nodes_0 + [self.op.node_name, ] - return env, nodes_0, nodes_1 + + # Exclude added node + pre_nodes = list(set(self.cfg.GetNodeList()) - set([self.op.node_name])) + post_nodes = pre_nodes + [self.op.node_name, ] + + return (env, pre_nodes, post_nodes) def CheckPrereq(self): """Check prerequisites. @@ -8345,6 +8354,30 @@ class TLReplaceDisks(Tasklet): return _FindFaultyInstanceDisks(self.cfg, self.rpc, self.instance, node_name, True) + def _CheckDisksActivated(self, instance): + """Checks if the instance disks are activated. + + @param instance: The instance to check disks + @return: True if they are activated, False otherwise + + """ + nodes = instance.all_nodes + + for idx, dev in enumerate(instance.disks): + for node in nodes: + self.lu.LogInfo("Checking disk/%d on %s", idx, node) + self.cfg.SetDiskID(dev, node) + + result = self.rpc.call_blockdev_find(node, dev) + + if result.offline: + continue + elif result.fail_msg or not result.payload: + return False + + return True + + def CheckPrereq(self): """Check prerequisites. @@ -8408,6 +8441,10 @@ class TLReplaceDisks(Tasklet): errors.ECODE_INVAL) if self.mode == constants.REPLACE_DISK_AUTO: + if not self._CheckDisksActivated(instance): + raise errors.OpPrereqError("Please run activate-disks on instance %s" + " first" % self.instance_name, + errors.ECODE_STATE) faulty_primary = self._FindFaultyDisks(instance.primary_node) faulty_secondary = self._FindFaultyDisks(secondary_node) @@ -11653,13 +11690,13 @@ _QUERY_IMPL = { constants.QR_OS: _OsQuery, } -assert set(_QUERY_IMPL.keys()) == constants.QR_OP_QUERY +assert set(_QUERY_IMPL.keys()) == constants.QR_VIA_OP def _GetQueryImplementation(name): """Returns the implemtnation for a query type. - @param name: Query type, must be one of L{constants.QR_OP_QUERY} + @param name: Query type, must be one of L{constants.QR_VIA_OP} """ try: