Add loading and processing of utilisation data
[ganeti-local] / Ganeti / HTools / Loader.hs
index 85fb5bf..87f11f0 100644 (file)
@@ -1,6 +1,7 @@
-{-| Loading data from external sources
+{-| Generic data loader
 
-This module holds the common code for loading the cluster state from external sources.
+This module holds the common code for parsing the input data after it
+has been loaded from external sources.
 
 -}
 
@@ -36,6 +37,7 @@ module Ganeti.HTools.Loader
     , Request(..)
     ) where
 
+import Control.Monad (foldM)
 import Data.Function (on)
 import Data.List
 import Data.Maybe (fromJust)
@@ -95,21 +97,20 @@ assocEqual = (==) `on` fst
 
 -- | For each instance, add its index to its primary and secondary nodes.
 fixNodes :: [(Ndx, Node.Node)]
-         -> (Idx, Instance.Instance)
+         -> Instance.Instance
          -> [(Ndx, Node.Node)]
-fixNodes accu (idx, inst) =
+fixNodes accu inst =
     let
-        pdx = Instance.pnode inst
-        sdx = Instance.snode inst
+        pdx = Instance.pNode inst
+        sdx = Instance.sNode inst
         pold = fromJust $ lookup pdx accu
-        pnew = Node.setPri pold idx
-        pnew' = Node.addCpus pnew (Instance.vcpus inst)
+        pnew = Node.setPri pold inst
         ac1 = deleteBy assocEqual (pdx, pold) accu
-        ac2 = (pdx, pnew'):ac1
+        ac2 = (pdx, pnew):ac1
     in
       if sdx /= Node.noSecondary
       then let sold = fromJust $ lookup sdx accu
-               snew = Node.setSec sold idx
+               snew = Node.setSec sold inst
                ac3 = deleteBy assocEqual (sdx, sold) ac2
            in (sdx, snew):ac3
       else ac2
@@ -130,15 +131,21 @@ stripSuffix sflen name = take (length name - sflen) name
 
 -- | Initializer function that loads the data from a node and instance
 -- list and massages it into the correct format.
-mergeData :: (Node.AssocList,
+mergeData :: [(String, DynUtil)]  -- ^ Instance utilisation data
+          -> (Node.AssocList,
               Instance.AssocList) -- ^ Data from either Text.loadData
                                   -- or Rapi.loadData
           -> Result (Node.List, Instance.List, String)
-mergeData (nl, il) = do
-  let
-      nl2 = foldl' fixNodes nl il
-      il3 = Container.fromAssocList il
-      nl3 = Container.fromAssocList
+mergeData um (nl, il) = do
+  let il2 = Container.fromAssocList il
+  il3 <- foldM (\im (name, n_util) -> do
+                  idx <- Container.findByName im name
+                  let inst = Container.find idx im
+                      new_i = inst { Instance.util = n_util }
+                  return $ Container.add idx new_i im
+               ) il2 um
+  let nl2 = foldl' fixNodes nl (Container.elems il3)
+  let nl3 = Container.fromAssocList
             (map (\ (k, v) -> (k, Node.buildPeers v il3)) nl2)
       node_names = map Node.name $ Container.elems nl3
       inst_names = map Instance.name $ Container.elems il3
@@ -155,19 +162,19 @@ checkData nl il =
     Container.mapAccum
         (\ msgs node ->
              let nname = Node.name node
-                 nilst = map (flip Container.find il) (Node.plist node)
+                 nilst = map (flip Container.find il) (Node.pList node)
                  dilst = filter (not . Instance.running) nilst
                  adj_mem = sum . map Instance.mem $ dilst
-                 delta_mem = truncate (Node.t_mem node)
-                             - Node.n_mem node
-                             - Node.f_mem node
+                 delta_mem = truncate (Node.tMem node)
+                             - Node.nMem node
+                             - Node.fMem node
                              - nodeImem node il
                              + adj_mem
-                 delta_dsk = truncate (Node.t_dsk node)
-                             - Node.f_dsk node
+                 delta_dsk = truncate (Node.tDsk node)
+                             - Node.fDsk node
                              - nodeIdsk node il
                  newn = Node.setFmem (Node.setXmem node delta_mem)
-                        (Node.f_mem node - adj_mem)
+                        (Node.fMem node - adj_mem)
                  umsg1 = [printf "node %s is missing %d MB ram \
                                  \and %d GB disk"
                                  nname delta_mem (delta_dsk `div` 1024) |
@@ -180,7 +187,7 @@ nodeImem :: Node.Node -> Instance.List -> Int
 nodeImem node il =
     let rfind = flip Container.find il
     in sum . map (Instance.mem . rfind)
-           $ Node.plist node
+           $ Node.pList node
 
 -- | Compute the amount of disk used by instances on a node (either primary
 -- or secondary).
@@ -188,4 +195,4 @@ nodeIdsk :: Node.Node -> Instance.List -> Int
 nodeIdsk node il =
     let rfind = flip Container.find il
     in sum . map (Instance.dsk . rfind)
-           $ Node.plist node ++ Node.slist node
+           $ Node.pList node ++ Node.sList node