Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Loader.hs @ 497e30a1

History | View | Annotate | Download (3.5 kB)

1 040afc35 Iustin Pop
{-| Loading data from external sources
2 040afc35 Iustin Pop
3 040afc35 Iustin Pop
This module holds the common code for loading the cluster state from external sources.
4 040afc35 Iustin Pop
5 040afc35 Iustin Pop
-}
6 040afc35 Iustin Pop
7 040afc35 Iustin Pop
module Ganeti.HTools.Loader
8 040afc35 Iustin Pop
    where
9 040afc35 Iustin Pop
10 e4c5beaf Iustin Pop
import Data.List
11 e4c5beaf Iustin Pop
import Data.Maybe (isNothing, fromJust)
12 e4c5beaf Iustin Pop
13 e4c5beaf Iustin Pop
import qualified Ganeti.HTools.Container as Container
14 e4c5beaf Iustin Pop
import qualified Ganeti.HTools.Instance as Instance
15 e4c5beaf Iustin Pop
import qualified Ganeti.HTools.Node as Node
16 e4c5beaf Iustin Pop
17 e4c5beaf Iustin Pop
import Ganeti.HTools.Types
18 e4c5beaf Iustin Pop
19 e4c5beaf Iustin Pop
20 e4c5beaf Iustin Pop
-- | Swap a list of @(a, b)@ into @(b, a)@
21 e4c5beaf Iustin Pop
swapPairs :: [(a, b)] -> [(b, a)]
22 e4c5beaf Iustin Pop
swapPairs = map (\ (a, b) -> (b, a))
23 040afc35 Iustin Pop
24 040afc35 Iustin Pop
-- | Lookups a node into an assoc list
25 040afc35 Iustin Pop
lookupNode :: (Monad m) => NameAssoc -> String -> String -> m Int
26 040afc35 Iustin Pop
lookupNode ktn inst node =
27 040afc35 Iustin Pop
    case lookup node ktn of
28 040afc35 Iustin Pop
      Nothing -> fail $ "Unknown node '" ++ node ++ "' for instance " ++ inst
29 040afc35 Iustin Pop
      Just idx -> return idx
30 040afc35 Iustin Pop
31 497e30a1 Iustin Pop
assignIndices :: (Element a) =>
32 497e30a1 Iustin Pop
                 [(String, a)]
33 040afc35 Iustin Pop
              -> (NameAssoc, [(Int, a)])
34 497e30a1 Iustin Pop
assignIndices =
35 497e30a1 Iustin Pop
    unzip . map (\ (idx, (k, v)) -> ((k, idx), (idx, setIdx v idx)))
36 040afc35 Iustin Pop
          . zip [0..]
37 e4c5beaf Iustin Pop
38 e4c5beaf Iustin Pop
-- | For each instance, add its index to its primary and secondary nodes
39 e4c5beaf Iustin Pop
fixNodes :: [(Int, Node.Node)]
40 e4c5beaf Iustin Pop
         -> [(Int, Instance.Instance)]
41 e4c5beaf Iustin Pop
         -> [(Int, Node.Node)]
42 e4c5beaf Iustin Pop
fixNodes nl il =
43 e4c5beaf Iustin Pop
    foldl' (\accu (idx, inst) ->
44 e4c5beaf Iustin Pop
                let
45 e4c5beaf Iustin Pop
                    assocEqual = (\ (i, _) (j, _) -> i == j)
46 e4c5beaf Iustin Pop
                    pdx = Instance.pnode inst
47 e4c5beaf Iustin Pop
                    sdx = Instance.snode inst
48 e4c5beaf Iustin Pop
                    pold = fromJust $ lookup pdx accu
49 e4c5beaf Iustin Pop
                    pnew = Node.setPri pold idx
50 e4c5beaf Iustin Pop
                    ac1 = deleteBy assocEqual (pdx, pold) accu
51 e4c5beaf Iustin Pop
                    ac2 = (pdx, pnew):ac1
52 e4c5beaf Iustin Pop
                in
53 e4c5beaf Iustin Pop
                  if sdx /= Node.noSecondary then
54 e4c5beaf Iustin Pop
                      let
55 e4c5beaf Iustin Pop
                          sold = fromJust $ lookup sdx accu
56 e4c5beaf Iustin Pop
                          snew = Node.setSec sold idx
57 e4c5beaf Iustin Pop
                          ac3 = deleteBy assocEqual (sdx, sold) ac2
58 e4c5beaf Iustin Pop
                          ac4 = (sdx, snew):ac3
59 e4c5beaf Iustin Pop
                      in ac4
60 e4c5beaf Iustin Pop
                  else
61 e4c5beaf Iustin Pop
                      ac2
62 e4c5beaf Iustin Pop
           ) nl il
63 e4c5beaf Iustin Pop
64 e4c5beaf Iustin Pop
-- | Compute the longest common suffix of a NameList list that
65 e4c5beaf Iustin Pop
-- | starts with a dot
66 e4c5beaf Iustin Pop
longestDomain :: NameList -> String
67 e4c5beaf Iustin Pop
longestDomain [] = ""
68 e4c5beaf Iustin Pop
longestDomain ((_,x):xs) =
69 e4c5beaf Iustin Pop
    let
70 e4c5beaf Iustin Pop
        onlyStrings = snd $ unzip xs
71 e4c5beaf Iustin Pop
    in
72 e4c5beaf Iustin Pop
      foldr (\ suffix accu -> if all (isSuffixOf suffix) onlyStrings
73 e4c5beaf Iustin Pop
                              then suffix
74 e4c5beaf Iustin Pop
                              else accu)
75 e4c5beaf Iustin Pop
      "" $ filter (isPrefixOf ".") (tails x)
76 e4c5beaf Iustin Pop
77 e4c5beaf Iustin Pop
-- | Remove tails from the (Int, String) lists
78 e4c5beaf Iustin Pop
stripSuffix :: String -> NameList -> NameList
79 e4c5beaf Iustin Pop
stripSuffix suffix lst =
80 e4c5beaf Iustin Pop
    let sflen = length suffix in
81 e4c5beaf Iustin Pop
    map (\ (key, name) -> (key, take ((length name) - sflen) name)) lst
82 e4c5beaf Iustin Pop
83 e4c5beaf Iustin Pop
{-| Initializer function that loads the data from a node and list file
84 e4c5beaf Iustin Pop
    and massages it into the correct format. -}
85 e4c5beaf Iustin Pop
mergeData :: ([(String, Int)], Node.AssocList,
86 e4c5beaf Iustin Pop
              [(String, Int)], Instance.AssocList) -- ^ Data from either
87 e4c5beaf Iustin Pop
                                                   -- Text.loadData
88 e4c5beaf Iustin Pop
                                                   -- or Rapi.loadData
89 e4c5beaf Iustin Pop
          -> Result (NodeList, InstanceList, String, NameList, NameList)
90 e4c5beaf Iustin Pop
mergeData (ktn, nl, kti, il) = do
91 e4c5beaf Iustin Pop
  let
92 e4c5beaf Iustin Pop
      nl2 = fixNodes nl il
93 e4c5beaf Iustin Pop
      il3 = Container.fromAssocList il
94 e4c5beaf Iustin Pop
      nl3 = Container.fromAssocList
95 e4c5beaf Iustin Pop
            (map (\ (k, v) -> (k, Node.buildPeers v il3 (length nl2))) nl2)
96 e4c5beaf Iustin Pop
      xtn = swapPairs ktn
97 e4c5beaf Iustin Pop
      xti = swapPairs kti
98 e4c5beaf Iustin Pop
      common_suffix = longestDomain (xti ++ xtn)
99 e4c5beaf Iustin Pop
      stn = stripSuffix common_suffix xtn
100 e4c5beaf Iustin Pop
      sti = stripSuffix common_suffix xti
101 e4c5beaf Iustin Pop
  return (nl3, il3, common_suffix, stn, sti)