Revision 9d3fada5 Ganeti/HTools/Cluster.hs

b/Ganeti/HTools/Cluster.hs
40 40
import Data.Maybe (isNothing, fromJust)
41 41
import Text.Printf (printf)
42 42
import Data.Function
43
import Control.Monad
43 44

  
44 45
import qualified Ganeti.HTools.Container as Container
45 46
import qualified Ganeti.HTools.Instance as Instance
......
694 695
supplied conversion function.
695 696

  
696 697
-}
697
loadTabular :: String -> ([String] -> (String, a))
698
            -> (a -> Int -> a) -> ([(String, Int)], [(Int, a)])
699
loadTabular text_data convert_fn set_fn =
700
    let lines_data = lines text_data
701
        rows = map (sepSplit '|') lines_data
702
        kerows = (map convert_fn rows)
703
        idxrows = map (\ (idx, (k, v)) -> ((k, idx), (idx, set_fn v idx)))
704
                  (zip [0..] kerows)
705
    in unzip idxrows
698
loadTabular :: (Monad m) => String -> ([String] -> m (String, a))
699
            -> (a -> Int -> a) -> m ([(String, Int)], [(Int, a)])
700
loadTabular text_data convert_fn set_fn = do
701
  let lines_data = lines text_data
702
      rows = map (sepSplit '|') lines_data
703
  kerows <- mapM convert_fn rows
704
  let idxrows = map (\ (idx, (k, v)) -> ((k, idx), (idx, set_fn v idx)))
705
                (zip [0..] kerows)
706
  return $ unzip idxrows
706 707

  
707 708
-- | For each instance, add its index to its primary and secondary nodes
708 709
fixNodes :: [(Int, Node.Node)]
......
742 743
    let sflen = length suffix in
743 744
    map (\ (key, name) -> (key, take ((length name) - sflen) name)) lst
744 745

  
746
-- | Lookups a node into an assoc list
747
lookupNode :: (Monad m) => String -> String -> [(String, Int)] -> m Int
748
lookupNode node inst ktn =
749
    case lookup node ktn of
750
      Nothing -> fail $ "Unknown node " ++ node ++ " for instance " ++ inst
751
      Just idx -> return idx
752

  
745 753
{-| Initializer function that loads the data from a node and list file
746 754
    and massages it into the correct format. -}
747 755
loadData :: String -- ^ Node data in text format
......
749 757
         -> Result (Container.Container Node.Node,
750 758
                    Container.Container Instance.Instance,
751 759
                    String, NameList, NameList)
752
loadData ndata idata =
753
    let
754
    {- node file: name t_mem n_mem f_mem t_disk f_disk -}
755
        (ktn, nl) = loadTabular ndata
756
                    (\ (name:tm:nm:fm:td:fd:fo:[]) ->
757
                         (name,
758
                          if any (== "?") [tm,nm,fm,td,fd] || fo == "Y" then
759
                              Node.create 0 0 0 0 0 True
760
                          else
761
                              Node.create (read tm) (read nm) (read fm)
762
                                      (read td) (read fd) False
763
                         ))
764
                    Node.setIdx
765
    {- instance file: name mem disk status pnode snode -}
766
        (kti, il) = loadTabular idata
767
                    (\ (name:mem:dsk:status:pnode:snode:[]) ->
768
                         (name,
769
                          Instance.create (read mem) (read dsk)
770
                              status
771
                              (fromJust $ lookup pnode ktn)
772
                              (fromJust $ lookup snode ktn)))
773
                    Instance.setIdx
774
        nl2 = fixNodes nl il
775
        il3 = Container.fromAssocList il
776
        nl3 = Container.fromAssocList
777
             (map (\ (k, v) -> (k, Node.buildPeers v il3 (length nl2))) nl2)
778
        xtn = swapPairs ktn
779
        xti = swapPairs kti
780
        common_suffix = longestDomain (xti ++ xtn)
781
        stn = stripSuffix common_suffix xtn
782
        sti = stripSuffix common_suffix xti
783
    in
784
      Ok (nl3, il3, common_suffix, stn, sti)
760
loadData ndata idata = do
761
  {- node file: name t_mem n_mem f_mem t_disk f_disk -}
762
  (ktn, nl) <- loadTabular ndata
763
               (\ (name:tm:nm:fm:td:fd:fo:[]) ->
764
                    return (name,
765
                            if any (== "?") [tm,nm,fm,td,fd] || fo == "Y" then
766
                                Node.create 0 0 0 0 0 True
767
                            else
768
                                Node.create (read tm) (read nm) (read fm)
769
                                        (read td) (read fd) False
770
                           ))
771
               Node.setIdx
772
      {- instance file: name mem disk status pnode snode -}
773
  (kti, il) <- loadTabular idata
774
                  (\ (name:mem:dsk:status:pnode:snode:[]) -> do
775
                     pidx <- lookupNode pnode name ktn
776
                     sidx <- lookupNode snode name ktn
777
                     let newinst = Instance.create (read mem) (read dsk)
778
                                   status pidx sidx
779
                     return (name, newinst)
780
                  )
781
                  Instance.setIdx
782
  let
783
      nl2 = fixNodes nl il
784
      il3 = Container.fromAssocList il
785
      nl3 = Container.fromAssocList
786
            (map (\ (k, v) -> (k, Node.buildPeers v il3 (length nl2))) nl2)
787
      xtn = swapPairs ktn
788
      xti = swapPairs kti
789
      common_suffix = longestDomain (xti ++ xtn)
790
      stn = stripSuffix common_suffix xtn
791
      sti = stripSuffix common_suffix xti
792
  return (nl3, il3, common_suffix, stn, sti)
785 793

  
786 794
-- | Compute the amount of memory used by primary instances on a node.
787 795
nodeImem :: Node.Node -> InstanceList -> Int

Also available in: Unified diff