Revision 262a08a2 Ganeti/HTools/Cluster.hs

b/Ganeti/HTools/Cluster.hs
8 8
module Ganeti.HTools.Cluster
9 9
    (
10 10
     -- * Types
11
     NodeList
12
    , InstanceList
13
    , NameList
11
     NameList
14 12
    , Placement
15 13
    , Solution(..)
16 14
    , Table(..)
......
70 68
                      _ -> -1
71 69

  
72 70
-- | A removal set.
73
data Removal = Removal NodeList [Instance.Instance]
71
data Removal = Removal Node.List [Instance.Instance]
74 72

  
75 73
-- | An instance move definition
76 74
data IMove = Failover                -- ^ Failover the instance (f)
......
81 79
             deriving (Show)
82 80

  
83 81
-- | The complete state for the balancing solution
84
data Table = Table NodeList InstanceList Score [Placement]
82
data Table = Table Node.List Instance.List Score [Placement]
85 83
             deriving (Show)
86 84

  
87 85
-- General functions
......
103 101
verifyN1 nl = filter Node.failN1 nl
104 102

  
105 103
{-| Add an instance and return the new node and instance maps. -}
106
addInstance :: NodeList -> Instance.Instance ->
107
               Node.Node -> Node.Node -> Maybe NodeList
104
addInstance :: Node.List -> Instance.Instance ->
105
               Node.Node -> Node.Node -> Maybe Node.List
108 106
addInstance nl idata pri sec =
109 107
  let pdx = Node.idx pri
110 108
      sdx = Node.idx sec
......
116 114
      return new_nl
117 115

  
118 116
-- | Remove an instance and return the new node and instance maps.
119
removeInstance :: NodeList -> Instance.Instance -> NodeList
117
removeInstance :: Node.List -> Instance.Instance -> Node.List
120 118
removeInstance nl idata =
121 119
  let pnode = Instance.pnode idata
122 120
      snode = Instance.snode idata
......
128 126
  new_nl
129 127

  
130 128
-- | Remove an instance and return the new node map.
131
removeInstances :: NodeList -> [Instance.Instance] -> NodeList
129
removeInstances :: Node.List -> [Instance.Instance] -> Node.List
132 130
removeInstances = foldl' removeInstance
133 131

  
134 132
-- | Compute the total free disk and memory in the cluster.
......
148 146
their new nodes.
149 147

  
150 148
 -}
151
applySolution :: NodeList -> InstanceList -> [Placement] -> NodeList
149
applySolution :: Node.List -> Instance.List -> [Placement] -> Node.List
152 150
applySolution nl il sol =
153 151
    let odxes = map (\ (a, b, c, _) -> (Container.find a il,
154 152
                                        Node.idx (Container.find b nl),
......
200 198
those nodes.
201 199

  
202 200
-}
203
computeBadItems :: NodeList -> InstanceList ->
201
computeBadItems :: Node.List -> Instance.List ->
204 202
                   ([Node.Node], [Instance.Instance])
205 203
computeBadItems nl il =
206 204
  let bad_nodes = verifyN1 $ filter (not . Node.offline) $ Container.elems nl
......
218 216
placement can make this shortcut.
219 217

  
220 218
-}
221
checkRemoval :: NodeList -> [Instance.Instance] -> Maybe Removal
219
checkRemoval :: Node.List -> [Instance.Instance] -> Maybe Removal
222 220
checkRemoval nl victims =
223 221
  let nx = removeInstances nl victims
224 222
      failN1 = verifyN1Check (Container.elems nx)
......
230 228

  
231 229

  
232 230
-- | Computes the removals list for a given depth
233
computeRemovals :: NodeList
231
computeRemovals :: Node.List
234 232
                 -> [Instance.Instance]
235 233
                 -> Int
236 234
                 -> [Maybe Removal]
......
281 279
    solution by recursing until all target instances are placed.
282 280

  
283 281
-}
284
checkPlacement :: NodeList            -- ^ The current node list
282
checkPlacement :: Node.List            -- ^ The current node list
285 283
               -> [Instance.Instance] -- ^ List of instances still to place
286 284
               -> [Placement]         -- ^ Partial solution until now
287 285
               -> Int                 -- ^ The delta of the partial solution
......
334 332
    ) prev_sol nodes
335 333

  
336 334
-- | Apply a move
337
applyMove :: NodeList -> Instance.Instance
338
          -> IMove -> (Maybe NodeList, Instance.Instance, Int, Int)
335
applyMove :: Node.List -> Instance.Instance
336
          -> IMove -> (Maybe Node.List, Instance.Instance, Int, Int)
339 337
-- Failover (f)
340 338
applyMove nl inst Failover =
341 339
    let old_pdx = Instance.pnode inst
......
410 408
                 Container.addTwo old_sdx new_p old_pdx int_p nl
411 409
    in (new_nl, Instance.setBoth inst old_sdx new_sdx, old_sdx, new_sdx)
412 410

  
413
allocateOnSingle :: NodeList -> Instance.Instance -> Node.Node
414
                 -> (Maybe NodeList, Instance.Instance)
411
allocateOnSingle :: Node.List -> Instance.Instance -> Node.Node
412
                 -> (Maybe Node.List, Instance.Instance)
415 413
allocateOnSingle nl inst p =
416 414
    let new_pdx = Node.idx p
417 415
        new_nl = Node.addPri p inst >>= \new_p ->
418 416
                 return $ Container.add new_pdx new_p nl
419 417
    in (new_nl, Instance.setBoth inst new_pdx Node.noSecondary)
420 418

  
421
allocateOnPair :: NodeList -> Instance.Instance -> Node.Node -> Node.Node
422
               -> (Maybe NodeList, Instance.Instance)
419
allocateOnPair :: Node.List -> Instance.Instance -> Node.Node -> Node.Node
420
               -> (Maybe Node.List, Instance.Instance)
423 421
allocateOnPair nl inst tgt_p tgt_s =
424 422
    let new_pdx = Node.idx tgt_p
425 423
        new_sdx = Node.idx tgt_s
......
543 541
solutionFromRemovals. In case we have no solution, we return Nothing.
544 542

  
545 543
-}
546
computeSolution :: NodeList        -- ^ The original node data
544
computeSolution :: Node.List        -- ^ The original node data
547 545
                -> [Instance.Instance] -- ^ The list of /bad/ instances
548 546
                -> Int             -- ^ The /depth/ of removals
549 547
                -> Int             -- ^ Maximum number of removals to process
......
604 602
                      printf "replace-disks -n %s %s" d i])
605 603

  
606 604
{-| Converts a placement to string format -}
607
printSolutionLine :: NodeList
608
                  -> InstanceList
605
printSolutionLine :: Node.List
606
                  -> Instance.List
609 607
                  -> Int
610 608
                  -> Int
611 609
                  -> Placement
......
617 615
        (i, p, s, c) = plc
618 616
        inst = Container.find i il
619 617
        inam = Instance.name inst
620
        npri = cNameOf nl p
621
        nsec = cNameOf nl s
622
        opri = cNameOf nl $ Instance.pnode inst
623
        osec = cNameOf nl $ Instance.snode inst
618
        npri = Container.nameOf nl p
619
        nsec = Container.nameOf nl s
620
        opri = Container.nameOf nl $ Instance.pnode inst
621
        osec = Container.nameOf nl $ Instance.snode inst
624 622
        (moves, cmds) =  computeMoves inam opri osec npri nsec
625 623
        ostr = (printf "%s:%s" opri osec)::String
626 624
        nstr = (printf "%s:%s" npri nsec)::String
......
640 638
        zip [1..] cmd_strs
641 639

  
642 640
{-| Converts a solution to string format -}
643
printSolution :: NodeList
644
              -> InstanceList
641
printSolution :: Node.List
642
              -> Instance.List
645 643
              -> [Placement]
646 644
              -> ([String], [[String]])
647 645
printSolution nl il sol =
648 646
    let
649
        nmlen = cMaxNamelen nl
650
        imlen = cMaxNamelen il
647
        nmlen = Container.maxNameLen nl
648
        imlen = Container.maxNameLen il
651 649
    in
652 650
      unzip $ map (uncurry $ printSolutionLine nl il nmlen imlen) $
653 651
            zip sol [1..]
654 652

  
655 653
-- | Print the node list.
656
printNodes :: NodeList -> String
654
printNodes :: Node.List -> String
657 655
printNodes nl =
658 656
    let snl = sortBy (compare `on` Node.idx) (Container.elems nl)
659 657
        m_name = maximum . map (length . Node.name) $ snl
......
667 665
    in unlines $ (header:map helper snl)
668 666

  
669 667
-- | Compute the mem and disk covariance.
670
compDetailedCV :: NodeList -> (Double, Double, Double, Double, Double)
668
compDetailedCV :: Node.List -> (Double, Double, Double, Double, Double)
671 669
compDetailedCV nl =
672 670
    let
673 671
        all_nodes = Container.elems nl
......
689 687
    in (mem_cv, dsk_cv, n1_score, res_cv, off_score)
690 688

  
691 689
-- | Compute the 'total' variance.
692
compCV :: NodeList -> Double
690
compCV :: Node.List -> Double
693 691
compCV nl =
694 692
    let (mem_cv, dsk_cv, n1_score, res_cv, off_score) = compDetailedCV nl
695 693
    in mem_cv + dsk_cv + n1_score + res_cv + off_score
696 694

  
697
printStats :: NodeList -> String
695
printStats :: Node.List -> String
698 696
printStats nl =
699 697
    let (mem_cv, dsk_cv, n1_score, res_cv, off_score) = compDetailedCV nl
700 698
    in printf "f_mem=%.8f, r_mem=%.8f, f_dsk=%.8f, n1=%.3f, uf=%.3f"

Also available in: Unified diff