Add support for 'offline' nodes
[ganeti-local] / Ganeti / HTools / Node.hs
index 30e3362..8dffd58 100644 (file)
@@ -6,12 +6,17 @@
 
 module Ganeti.HTools.Node
     (
-      Node(failN1, idx, f_mem, f_dsk, p_mem, p_dsk, slist, plist, p_rem)
+      Node(failN1, idx, t_mem, n_mem, f_mem, t_dsk, f_dsk,
+           p_mem, p_dsk, p_rem,
+           plist, slist, offline)
     -- * Constructor
     , create
     -- ** Finalization after data loading
     , buildPeers
     , setIdx
+    , setOffline
+    , setXmem
+    , setFmem
     -- * Instance (re)location
     , removePri
     , removeSec
@@ -32,8 +37,10 @@ import qualified Ganeti.HTools.PeerMap as PeerMap
 
 import Ganeti.HTools.Utils
 
-data Node = Node { t_mem :: Double -- ^ total memory (Mib)
+data Node = Node { t_mem :: Double -- ^ total memory (MiB)
+                 , n_mem :: Int    -- ^ node memory (MiB)
                  , f_mem :: Int    -- ^ free memory (MiB)
+                 , x_mem :: Int    -- ^ unaccounted memory (MiB)
                  , t_dsk :: Double -- ^ total disk space (MiB)
                  , f_dsk :: Int    -- ^ free disk space (MiB)
                  , plist :: [Int]  -- ^ list of primary instance indices
@@ -46,6 +53,9 @@ data Node = Node { t_mem :: Double -- ^ total memory (Mib)
                  , p_mem :: Double -- ^ percent of free memory
                  , p_dsk :: Double -- ^ percent of free disk
                  , p_rem :: Double -- ^ percent of reserved memory
+                 , offline :: Bool -- ^ whether the node should not be used
+                                   -- for allocations and skipped from
+                                   -- score computations
   } deriving (Show)
 
 {- | Create a new node.
@@ -54,35 +64,50 @@ The index and the peers maps are empty, and will be need to be update
 later via the 'setIdx' and 'buildPeers' functions.
 
 -}
-create :: String -> String -> String -> String -> Node
-create mem_t_init mem_f_init dsk_t_init dsk_f_init =
-    let mem_t = read mem_t_init
-        mem_f = read mem_f_init
-        dsk_t = read dsk_t_init
-        dsk_f = read dsk_f_init
-    in
-      Node
-      {
-       t_mem = read mem_t_init,
-       f_mem = read mem_f_init,
-       t_dsk = read dsk_t_init,
-       f_dsk = read dsk_f_init,
-       plist = [],
-       slist = [],
-       failN1 = True,
-       idx = -1,
-       peers = PeerMap.empty,
-       r_mem = 0,
-       p_mem = (fromIntegral mem_f) / (fromIntegral mem_t),
-       p_dsk = (fromIntegral dsk_f) / (fromIntegral dsk_t),
-       p_rem = 0
-      }
+create :: Double -> Int -> Int -> Double -> Int -> Bool -> Node
+create mem_t_init mem_n_init mem_f_init dsk_t_init dsk_f_init
+       offline_init =
+    Node
+    {
+      t_mem = mem_t_init,
+      n_mem = mem_n_init,
+      f_mem = mem_f_init,
+      t_dsk = dsk_t_init,
+      f_dsk = dsk_f_init,
+      plist = [],
+      slist = [],
+      failN1 = True,
+      idx = -1,
+      peers = PeerMap.empty,
+      r_mem = 0,
+      p_mem = (fromIntegral mem_f_init) / mem_t_init,
+      p_dsk = (fromIntegral dsk_f_init) / dsk_t_init,
+      p_rem = 0,
+      offline = offline_init,
+      x_mem = 0
+    }
 
 -- | Changes the index.
 -- This is used only during the building of the data structures.
 setIdx :: Node -> Int -> Node
 setIdx t i = t {idx = i}
 
+-- | Sets the offline attribute
+setOffline :: Node -> Bool -> Node
+setOffline t val = t { offline = val }
+
+-- | Sets the unnaccounted memory
+setXmem :: Node -> Int -> Node
+setXmem t val = t { x_mem = val }
+
+-- | Sets the free memory
+setFmem :: Node -> Int -> Node
+setFmem t new_mem =
+    let new_n1 = computeFailN1 (r_mem t) new_mem (f_dsk t)
+        new_mp = (fromIntegral new_mem) / (t_mem t)
+    in
+      t { f_mem = new_mem, failN1 = new_n1, p_mem = new_mp }
+
 -- | Given the rmem, free memory and disk, computes the failn1 status.
 computeFailN1 :: Int -> Int -> Int -> Bool
 computeFailN1 new_rmem new_mem new_dsk =
@@ -193,15 +218,6 @@ setPri t idx = t { plist = idx:(plist t) }
 setSec :: Node -> Int -> Node
 setSec t idx = t { slist = idx:(slist t) }
 
--- | Simple converter to string.
-str :: Node -> String
-str t =
-    printf ("Node %d (mem=%5d MiB, disk=%5.2f GiB)\n  Primaries:" ++
-            " %s\nSecondaries: %s")
-      (idx t) (f_mem t) ((f_dsk t) `div` 1024)
-      (commaJoin (map show (plist t)))
-      (commaJoin (map show (slist t)))
-
 -- | String converter for the node list functionality.
 list :: Int -> String -> Node -> String
 list mname n t =
@@ -209,11 +225,17 @@ list mname n t =
         sl = slist t
         mp = p_mem t
         dp = p_dsk t
+        off = offline t
         fn = failN1 t
+        tmem = t_mem t
+        nmem = n_mem t
+        xmem = x_mem t
+        fmem = f_mem t
+        imem = (truncate tmem) - nmem - xmem - fmem
     in
-      printf " %c %-*s %5.0f %5d %5d %5.0f %5d %3d %3d %.5f %.5f"
-                 (if fn then '*' else ' ')
-                 mname n (t_mem t) (f_mem t) (r_mem t)
+      printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d %3d %3d %.5f %.5f"
+                 (if off then '-' else if fn then '*' else ' ')
+                 mname n tmem nmem imem xmem fmem (r_mem t)
                  ((t_dsk t) / 1024) ((f_dsk t) `div` 1024)
                  (length pl) (length sl)
                  mp dp