RAPI client: fix epydoc formatting
[ganeti-local] / lib / cmdlib.py
index b967979..fa8716e 100644 (file)
@@ -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: