m_name = maximum . map (length . Node.name) $ snl
helper = Node.list m_name
header = printf
- "%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %3s %3s %7s %7s"
+ "%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %3s %3s %7s %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"
+ "pri" "sec" "p_fmem" "p_fdsk" "r_cpu"
in unlines $ (header:map helper snl)
-- | Shows statistics for a given node list.
offline <- fromObj "offline" a
drained <- fromObj "drained" a
node <- (case offline of
- True -> return $ Node.create name 0 0 0 0 0 True
+ True -> return $ Node.create name 0 0 0 0 0 0 True
_ -> do
mtotal <- fromObj "total_memory" a
- mnode <- fromObj "reserved_memory" a
- mfree <- fromObj "free_memory" a
- dtotal <- fromObj "total_disk" a
- dfree <- fromObj "free_disk" a
+ mnode <- fromObj "reserved_memory" a
+ mfree <- fromObj "free_memory" a
+ dtotal <- fromObj "total_disk" a
+ dfree <- fromObj "free_disk" a
+ ctotal <- fromObj "total_cpus" a
return $ Node.create n mtotal mnode mfree
- dtotal dfree (offline || drained))
+ dtotal dfree ctotal (offline || drained))
return (name, node)
-- | Top-level parser.
sdx = Instance.snode inst
pold = fromJust $ lookup pdx accu
pnew = Node.setPri pold idx
+ pnew' = Node.addCpus pnew (Instance.vcpus inst)
ac1 = deleteBy assocEqual (pdx, pold) accu
- ac2 = (pdx, pnew):ac1
+ ac2 = (pdx, pnew'):ac1
in
if sdx /= Node.noSecondary then
let
-}
module Ganeti.HTools.Node
- ( Node(failN1, name, idx, t_mem, n_mem, f_mem, r_mem, t_dsk, f_dsk,
- p_mem, p_dsk, p_rem,
+ ( Node(failN1, name, idx, t_mem, n_mem, f_mem, r_mem,
+ t_dsk, f_dsk,
+ t_cpu, u_cpu,
+ p_mem, p_dsk, p_rem, p_cpu,
plist, slist, offline)
, List
-- * Constructor
, setFmem
, setPri
, setSec
+ , addCpus
-- * Instance (re)location
, removePri
, removeSec
, x_mem :: Int -- ^ Unaccounted memory (MiB)
, t_dsk :: Double -- ^ Total disk space (MiB)
, f_dsk :: Int -- ^ Free disk space (MiB)
+ , t_cpu :: Double -- ^ Total CPU count
+ , u_cpu :: Int -- ^ Used VCPU count
, plist :: [T.Idx]-- ^ List of primary instance indices
, slist :: [T.Idx]-- ^ List of secondary instance indices
, idx :: T.Ndx -- ^ Internal index for book-keeping
, p_mem :: Double -- ^ Percent of free memory
, p_dsk :: Double -- ^ Percent of free disk
, p_rem :: Double -- ^ Percent of reserved memory
+ , p_cpu :: Double -- ^ Ratio of virtual to physical CPUs
, offline :: Bool -- ^ Whether the node should not be used
-- for allocations and skipped from
-- score computations
--
-- The index and the peers maps are empty, and will be need to be
-- update later via the 'setIdx' and 'buildPeers' functions.
-create :: String -> Double -> Int -> Int -> Double -> Int -> Bool -> Node
+create :: String -> Double -> Int -> Int -> Double
+ -> Int -> Double -> Bool -> Node
create name_init mem_t_init mem_n_init mem_f_init
- dsk_t_init dsk_f_init offline_init =
+ dsk_t_init dsk_f_init cpu_t_init offline_init =
Node
{
name = name_init,
f_mem = mem_f_init,
t_dsk = dsk_t_init,
f_dsk = dsk_f_init,
+ t_cpu = cpu_t_init,
+ u_cpu = 0,
plist = [],
slist = [],
failN1 = True,
p_mem = (fromIntegral mem_f_init) / mem_t_init,
p_dsk = (fromIntegral dsk_f_init) / dsk_t_init,
p_rem = 0,
+ p_cpu = 0,
offline = offline_init,
x_mem = 0
}
setSec :: Node -> T.Idx -> Node
setSec t idx = t { slist = idx:(slist t) }
+-- | Add primary cpus to a node
+addCpus :: Node -> Int -> Node
+addCpus t count =
+ let new_count = (u_cpu t) + count
+ in t { u_cpu = new_count, p_cpu = (fromIntegral new_count) / (t_cpu t) }
+
-- * Update functions
-- | Sets the free memory.
sl = slist t
mp = p_mem t
dp = p_dsk t
+ cp = p_cpu t
off = offline t
fn = failN1 t
tmem = t_mem t
fmem = f_mem t
imem = (truncate tmem) - nmem - xmem - fmem
in
- printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d %3d %3d %.5f %.5f"
+ printf " %c %-*s %5.0f %5d %5d %5d %5d %5d %5.0f %5d %3d %3d\
+ \ %.5f %.5f %.5f"
(if off then '-' else if fn then '*' else ' ')
mname (name t) tmem nmem imem xmem fmem (r_mem t)
((t_dsk t) / 1024) ((f_dsk t) `div` 1024)
(length pl) (length sl)
- mp dp
+ mp dp cp
name <- fromObj "name" a
offline <- fromObj "offline" a
node <- (case offline of
- True -> return $ Node.create name 0 0 0 0 0 True
+ True -> return $ Node.create name 0 0 0 0 0 0 True
_ -> do
drained <- fromObj "drained" a
- mtotal <- fromObj "mtotal" a
- mnode <- fromObj "mnode" a
- mfree <- fromObj "mfree" a
- dtotal <- fromObj "dtotal" a
- dfree <- fromObj "dfree" a
+ mtotal <- fromObj "mtotal" a
+ mnode <- fromObj "mnode" a
+ mfree <- fromObj "mfree" a
+ dtotal <- fromObj "dtotal" a
+ dfree <- fromObj "dfree" a
+ ctotal <- fromObj "ctotal" a
return $ Node.create name mtotal mnode mfree
- dtotal dfree (offline || drained))
+ dtotal dfree ctotal (offline || drained))
return (name, node)
-- | Builds the cluster data from an URL.
-- | Load a node from a field list.
loadNode :: (Monad m) => [String] -> m (String, Node.Node)
-loadNode (name:tm:nm:fm:td:fd:fo:[]) = do
+loadNode (name:tm:nm:fm:td:fd:tc:fo:[]) = do
new_node <-
- if any (== "?") [tm,nm,fm,td,fd] || fo == "Y" then
- return $ Node.create name 0 0 0 0 0 True
+ if any (== "?") [tm,nm,fm,td,fd,tc] || fo == "Y" then
+ return $ Node.create name 0 0 0 0 0 0 True
else do
vtm <- tryRead name tm
vnm <- tryRead name nm
vfm <- tryRead name fm
vtd <- tryRead name td
vfd <- tryRead name fd
- return $ Node.create name vtm vnm vfm vtd vfd False
+ vtc <- tryRead name tc
+ return $ Node.create name vtm vnm vfm vtd vfd vtc False
return (name, new_node)
loadNode s = fail $ "Invalid/incomplete node data: '" ++ (show s) ++ "'"