Prevent silent failure in case of connection problems
[ganeti-local] / src / Ganeti / Query / Node.hs
index 77eef3e..36b5000 100644 (file)
@@ -36,12 +36,14 @@ import qualified Data.Map as Map
 import qualified Text.JSON as J
 
 import Ganeti.Config
+import Ganeti.Logging
 import Ganeti.Objects
 import Ganeti.JSON
 import Ganeti.Rpc
 import Ganeti.Query.Language
 import Ganeti.Query.Common
 import Ganeti.Query.Types
+import Ganeti.Utils (niceSort)
 
 -- | Runtime is the resulting type for NodeInfo call.
 type Runtime = Either RpcError RpcResultNodeInfo
@@ -182,11 +184,11 @@ nodeFields =
      QffNormal)
   , (FieldDefinition "pinst_list" "PriInstances" QFTOther
        "List of instances with this node as primary",
-     FieldConfig (\cfg -> rsNormal . map instName . fst .
+     FieldConfig (\cfg -> rsNormal . niceSort . map instName . fst .
                           getNodeInstances cfg . nodeName), QffNormal)
   , (FieldDefinition "sinst_list" "SecInstances" QFTOther
        "List of instances with this node as secondary",
-     FieldConfig (\cfg -> rsNormal . map instName . snd .
+     FieldConfig (\cfg -> rsNormal . niceSort . map instName . snd .
                           getNodeInstances cfg . nodeName), QffNormal)
   , (FieldDefinition "role" "Role" QFTText nodeRoleDoc,
      FieldConfig ((rsNormal .) . getNodeRole), QffNormal)
@@ -197,9 +199,9 @@ nodeFields =
   -- non-implemented node resource model; they are declared just for
   -- parity, but are not functional
   , (FieldDefinition "hv_state" "HypervisorState" QFTOther "Hypervisor state",
-     missingRuntime, QffNormal)
+     FieldSimple (const rsUnavail), QffNormal)
   , (FieldDefinition "disk_state" "DiskState" QFTOther "Disk state",
-     missingRuntime, QffNormal)
+     FieldSimple (const rsUnavail), QffNormal)
   ] ++
   map nodeLiveFieldBuilder nodeLiveFieldsDefs ++
   map buildNdParamField allNDParamFields ++
@@ -213,6 +215,15 @@ fieldsMap :: FieldMap Node Runtime
 fieldsMap =
   Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) nodeFields
 
+-- | Scan the list of results produced by executeRpcCall and log all the RPC
+-- errors.
+logRpcErrors :: [(Node, Runtime)] -> IO ()
+logRpcErrors allElems =
+  let logOneRpcErr (_, Right _) = return ()
+      logOneRpcErr (_, Left err) =
+        logError $ "Error in the RPC HTTP reply: " ++ show err
+  in mapM_ logOneRpcErr allElems
+
 -- | Collect live data from RPC query if enabled.
 --
 -- FIXME: Check which fields we actually need and possibly send empty
@@ -232,6 +243,7 @@ collectLiveData True cfg nodes = do
              Nothing -> (n : bn, gn, em)
       (bnodes, gnodes, emap) = foldr step ([], [], []) nodes
   rpcres <- executeRpcCall gnodes (RpcCallNodeInfo vgs hvs (Map.fromList emap))
+  logRpcErrors rpcres
   -- FIXME: The order of nodes in the result could be different from the input
   return $ zip bnodes (repeat $ Left (RpcResultError "Broken configuration"))
            ++ rpcres