Add a separate function for looking up instances
[ganeti-local] / Ganeti / HTools / Loader.hs
index 4f6359c..0aac79a 100644 (file)
@@ -9,7 +9,8 @@ module Ganeti.HTools.Loader
     , checkData
     , assignIndices
     , lookupNode
-    , swapPairs
+    , lookupInstance
+    , stripSuffix
     ) where
 
 import Data.List
@@ -22,18 +23,21 @@ import qualified Ganeti.HTools.Node as Node
 
 import Ganeti.HTools.Types
 
-
--- | Swap a list of @(a, b)@ into @(b, a)@
-swapPairs :: [(a, b)] -> [(b, a)]
-swapPairs = map (\ (a, b) -> (b, a))
-
 -- | Lookups a node into an assoc list
-lookupNode :: (Monad m) => NameAssoc -> String -> String -> m Int
+lookupNode :: (Monad m) => [(String, Ndx)] -> String -> String -> m Ndx
 lookupNode ktn inst node =
     case lookup node ktn of
       Nothing -> fail $ "Unknown node '" ++ node ++ "' for instance " ++ inst
       Just idx -> return idx
 
+-- | Lookups an instance into an assoc list
+lookupInstance :: (Monad m) => [(String, Idx)] -> String -> m Idx
+lookupInstance kti inst =
+    case lookup inst kti of
+      Nothing -> fail $ "Unknown instance '" ++ inst ++ "'"
+      Just idx -> return idx
+
+-- | Given a list of elements (and their names), assign indices to them
 assignIndices :: (Element a) =>
                  [(String, a)]
               -> (NameAssoc, [(Int, a)])
@@ -42,9 +46,9 @@ assignIndices =
           . zip [0..]
 
 -- | For each instance, add its index to its primary and secondary nodes
-fixNodes :: [(Int, Node.Node)]
-         -> [(Int, Instance.Instance)]
-         -> [(Int, Node.Node)]
+fixNodes :: [(Ndx, Node.Node)]
+         -> [(Idx, Instance.Instance)]
+         -> [(Ndx, Node.Node)]
 fixNodes nl il =
     foldl' (\accu (idx, inst) ->
                 let
@@ -69,50 +73,45 @@ fixNodes nl il =
 
 -- | Compute the longest common suffix of a NameList list that
 -- | starts with a dot
-longestDomain :: NameList -> String
+longestDomain :: [String] -> String
 longestDomain [] = ""
-longestDomain ((_,x):xs) =
-    let
-        onlyStrings = snd $ unzip xs
-    in
-      foldr (\ suffix accu -> if all (isSuffixOf suffix) onlyStrings
+longestDomain (x:xs) =
+      foldr (\ suffix accu -> if all (isSuffixOf suffix) xs
                               then suffix
                               else accu)
       "" $ filter (isPrefixOf ".") (tails x)
 
--- | Remove tails from the (Int, String) lists
-stripSuffix :: String -> NameList -> NameList
-stripSuffix suffix lst =
-    let sflen = length suffix in
-    map (\ (key, name) -> (key, take ((length name) - sflen) name)) lst
+-- | Remove tail suffix from a string
+stripSuffix :: Int -> String -> String
+stripSuffix sflen name = take ((length name) - sflen) name
 
 {-| Initializer function that loads the data from a node and list file
     and massages it into the correct format. -}
-mergeData :: ([(String, Int)], Node.AssocList,
-              [(String, Int)], Instance.AssocList) -- ^ Data from either
-                                                   -- Text.loadData
-                                                   -- or Rapi.loadData
-          -> Result (NodeList, InstanceList, String, NameList, NameList)
-mergeData (ktn, nl, kti, il) = do
+mergeData :: (Node.AssocList,
+              Instance.AssocList) -- ^ Data from either Text.loadData
+                                  -- or Rapi.loadData
+          -> Result (Node.List, Instance.List, String)
+mergeData (nl, il) = do
   let
       nl2 = fixNodes nl il
       il3 = Container.fromAssocList il
       nl3 = Container.fromAssocList
             (map (\ (k, v) -> (k, Node.buildPeers v il3 (length nl2))) nl2)
-      xtn = swapPairs ktn
-      xti = swapPairs kti
-      common_suffix = longestDomain (xti ++ xtn)
-      stn = stripSuffix common_suffix xtn
-      sti = stripSuffix common_suffix xti
-  return (nl3, il3, common_suffix, stn, sti)
+      node_names = map Node.name $ Container.elems nl3
+      inst_names = map Instance.name $ Container.elems il3
+      common_suffix = longestDomain (node_names ++ inst_names)
+      csl = length common_suffix
+      snl = Container.map (\n -> setName n (stripSuffix csl $ nameOf n)) nl3
+      sil = Container.map (\i -> setName i (stripSuffix csl $ nameOf i)) il3
+  return (snl, sil, common_suffix)
 
 -- | Check cluster data for consistency
-checkData :: NodeList -> InstanceList -> NameList -> NameList
-          -> ([String], NodeList)
-checkData nl il ktn _ =
+checkData :: Node.List -> Instance.List
+          -> ([String], Node.List)
+checkData nl il =
     Container.mapAccum
         (\ msgs node ->
-             let nname = fromJust $ lookup (Node.idx node) ktn
+             let nname = Node.name node
                  nilst = map (flip Container.find $ il) (Node.plist node)
                  dilst = filter (not . Instance.running) nilst
                  adj_mem = sum . map Instance.mem $ dilst
@@ -135,7 +134,7 @@ checkData nl il ktn _ =
         ) [] nl
 
 -- | Compute the amount of memory used by primary instances on a node.
-nodeImem :: Node.Node -> InstanceList -> Int
+nodeImem :: Node.Node -> Instance.List -> Int
 nodeImem node il =
     let rfind = flip Container.find $ il
     in sum . map Instance.mem .
@@ -143,7 +142,7 @@ nodeImem node il =
 
 -- | Compute the amount of disk used by instances on a node (either primary
 -- or secondary).
-nodeIdsk :: Node.Node -> InstanceList -> Int
+nodeIdsk :: Node.Node -> Instance.List -> Int
 nodeIdsk node il =
     let rfind = flip Container.find $ il
     in sum . map Instance.dsk .