Implement writing the command list to a script
[ganeti-local] / Ganeti / HTools / Cluster.hs
index 6877f6c..4153af6 100644 (file)
@@ -563,27 +563,27 @@ computeMoves i a b c d =
     else
         if c == b then {- Failover and ... -}
             if d == a then {- that's all -}
-                ("f", [printf "migrate %s" i])
+                ("f", [printf "migrate -f %s" i])
             else
                 (printf "f r:%s" d,
-                 [printf "migrate %s" i,
+                 [printf "migrate -f %s" i,
                   printf "replace-disks -n %s %s" d i])
         else
             if d == a then {- ... and keep primary as secondary -}
                 (printf "r:%s f" c,
                  [printf "replace-disks -n %s %s" c i,
-                  printf "migrate %s" i])
+                  printf "migrate -f %s" i])
             else
                 if d == b then {- ... keep same secondary -}
                     (printf "f r:%s f" c,
-                     [printf "migrate %s" i,
+                     [printf "migrate -f %s" i,
                       printf "replace-disks -n %s %s" c i,
-                      printf "migrate %s" i])
+                      printf "migrate -f %s" i])
 
                 else {- Nothing in common -}
                     (printf "r:%s f r:%s" c d,
                      [printf "replace-disks -n %s %s" c i,
-                      printf "migrate %s" i,
+                      printf "migrate -f %s" i,
                       printf "replace-disks -n %s %s" d i])
 
 {-| Converts a placement to string format -}
@@ -616,9 +616,11 @@ printSolutionLine il ktn kti nmlen imlen plc pos =
 
 formatCmds :: [[String]] -> String
 formatCmds cmd_strs =
-    unlines $ map ("  echo " ++) $
+    unlines $
     concat $ map (\(a, b) ->
-        (printf "step %d" (a::Int)):(map ("gnt-instance " ++) b)) $
+        (printf "echo step %d" (a::Int)):
+        (printf "check"):
+        (map ("gnt-instance " ++) b)) $
         zip [1..] cmd_strs
 
 {-| Converts a solution to string format -}
@@ -643,8 +645,10 @@ printNodes ktn nl =
         snl' = map (\ n -> ((fromJust $ lookup (Node.idx n) ktn), n)) snl
         m_name = maximum . (map length) . fst . unzip $ snl'
         helper = Node.list m_name
-        header = printf "%2s %-*s %5s %5s %5s %5s %5s %5s %3s %3s %7s %7s"
-                 " F" m_name "Name" "t_mem" "n_mem" "f_mem" "r_mem"
+        header = printf
+                 "%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %3s %3s %7s %7s"
+                 " F" m_name "Name"
+                 "t_mem" "n_mem" "i_mem" "x_mem" "f_mem" "r_mem"
                  "t_dsk" "f_dsk"
                  "pri" "sec" "p_fmem" "p_fdsk"
     in unlines $ (header:map (uncurry helper) snl')
@@ -758,11 +762,12 @@ loadData ndata idata =
                           Node.create (read tm) (read nm)
                                   (read fm) (read td) (read fd)))
                     Node.setIdx
-    {- instance file: name mem disk pnode snode -}
+    {- instance file: name mem disk status pnode snode -}
         (kti, il) = loadTabular idata
-                    (\ (name:mem:dsk:pnode:snode:[]) ->
+                    (\ (name:mem:dsk:status:pnode:snode:[]) ->
                          (name,
                           Instance.create (read mem) (read dsk)
+                              status
                               (fromJust $ lookup pnode ktn)
                               (fromJust $ lookup snode ktn)))
                     Instance.setIdx
@@ -785,23 +790,39 @@ nodeImem node il =
     in sum . map Instance.mem .
        map rfind $ Node.plist node
 
+-- | Compute the amount of disk used by instances on a node (either primary
+-- or secondary).
+nodeIdsk :: Node.Node -> InstanceList -> Int
+nodeIdsk node il =
+    let rfind = flip Container.find $ il
+    in sum . map Instance.dsk .
+       map rfind $ (Node.plist node) ++ (Node.slist node)
+
 
 -- | Check cluster data for consistency
 checkData :: NodeList -> InstanceList -> NameList -> NameList
           -> ([String], NodeList)
-checkData nl il ktn kti =
+checkData nl il ktn _ =
     Container.mapAccum
         (\ msgs node ->
              let nname = fromJust $ lookup (Node.idx node) ktn
-                 delta_mem = (truncate $ Node.t_mem node) -
-                             (Node.n_mem node) -
-                             (Node.f_mem node) -
-                             (nodeImem node il)
-                 newn = Node.setXmem node delta_mem
-                 umsg = if delta_mem > 16
-                        then (printf "node %s has %6d MB of unaccounted \
-                                     \memory "
-                                     nname delta_mem):msgs
-                        else msgs
-             in (umsg, newn)
+                 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)
+                             - (nodeImem node il)
+                             + adj_mem
+                 delta_dsk = (truncate $ Node.t_dsk node)
+                             - (Node.f_dsk node)
+                             - (nodeIdsk node il)
+                 newn = Node.setFmem (Node.setXmem node delta_mem)
+                        (Node.f_mem node - adj_mem)
+                 umsg1 = if delta_mem > 16 || delta_dsk > 1024
+                         then [printf "node %s is missing %d MB ram \
+                                     \and %d GB disk"
+                                     nname delta_mem (delta_dsk `div` 1024)]
+                         else []
+             in (msgs ++ umsg1, newn)
         ) [] nl