From 8bc34c7b62c0eb5fbbad70e0e8f19b011b346db2 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 16 Feb 2012 12:52:54 +0100 Subject: [PATCH] htools: add spindle-related attribute to nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the spindleCount, hiSpindles and instSpindles attributes. The spindleCount is equivalent to spindle_count on the ganeti side (a node parameter). hiSpindles is the maximum instance-used spindles, and instSpindles will be used to track spindles as used by instances (in later patches). The patch also reads spindleCount from the live backends. The text and simu backends currently set it to 1, hard-coded. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: RenΓ© Nussbaumer <rn@google.com> --- htools/Ganeti/HTools/IAlloc.hs | 9 ++++++--- htools/Ganeti/HTools/Luxi.hs | 11 ++++++----- htools/Ganeti/HTools/Node.hs | 22 +++++++++++++++++++--- htools/Ganeti/HTools/QC.hs | 2 +- htools/Ganeti/HTools/Rapi.hs | 8 +++++--- htools/Ganeti/HTools/Simu.hs | 4 ++-- htools/Ganeti/HTools/Text.hs | 4 ++-- 7 files changed, 41 insertions(+), 19 deletions(-) diff --git a/htools/Ganeti/HTools/IAlloc.hs b/htools/Ganeti/HTools/IAlloc.hs index aa8a39c5b..9ccc8ecb8 100644 --- a/htools/Ganeti/HTools/IAlloc.hs +++ b/htools/Ganeti/HTools/IAlloc.hs @@ -4,7 +4,7 @@ {- -Copyright (C) 2009, 2010, 2011 Google Inc. +Copyright (C) 2009, 2010, 2011, 2012 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -105,7 +105,7 @@ parseNode ktg n a = do let vm_capable' = fromMaybe True vm_capable gidx <- lookupGroup ktg n guuid node <- if offline || drained || not vm_capable' - then return $ Node.create n 0 0 0 0 0 0 True gidx + then return $ Node.create n 0 0 0 0 0 0 True 0 gidx else do mtotal <- extract "total_memory" mnode <- extract "reserved_memory" @@ -113,8 +113,11 @@ parseNode ktg n a = do dtotal <- extract "total_disk" dfree <- extract "free_disk" ctotal <- extract "total_cpus" + ndparams <- extract "ndparams" >>= asJSObject + spindles <- tryFromObj desc (fromJSObject ndparams) + "spindle_count" return $ Node.create n mtotal mnode mfree - dtotal dfree ctotal False gidx + dtotal dfree ctotal False spindles gidx return (n, node) -- | Parses a group as found in the cluster group list. diff --git a/htools/Ganeti/HTools/Luxi.hs b/htools/Ganeti/HTools/Luxi.hs index cd80996bb..77d561472 100644 --- a/htools/Ganeti/HTools/Luxi.hs +++ b/htools/Ganeti/HTools/Luxi.hs @@ -4,7 +4,7 @@ {- -Copyright (C) 2009, 2010, 2011 Google Inc. +Copyright (C) 2009, 2010, 2011, 2012 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -99,7 +99,7 @@ queryNodesMsg :: L.LuxiOp queryNodesMsg = L.Query L.QRNode ["name", "mtotal", "mnode", "mfree", "dtotal", "dfree", "ctotal", "offline", "drained", "vm_capable", - "group.uuid"] () + "ndp/spindle_count", "group.uuid"] () -- | The input data for instance query. queryInstancesMsg :: L.LuxiOp @@ -175,16 +175,17 @@ getNodes ktg arr = extractArray arr >>= mapM (parseNode ktg) -- | Construct a node from a JSON object. parseNode :: NameAssoc -> [(JSValue, JSValue)] -> Result (String, Node.Node) parseNode ktg [ name, mtotal, mnode, mfree, dtotal, dfree - , ctotal, offline, drained, vm_capable, g_uuid ] + , ctotal, offline, drained, vm_capable, spindles, g_uuid ] = do xname <- annotateResult "Parsing new node" (fromJValWithStatus name) let convert a = genericConvert "Node" xname a xoffline <- convert "offline" offline xdrained <- convert "drained" drained xvm_capable <- convert "vm_capable" vm_capable + xspindles <- convert "spindles" spindles xgdx <- convert "group.uuid" g_uuid >>= lookupGroup ktg xname node <- if xoffline || xdrained || not xvm_capable - then return $ Node.create xname 0 0 0 0 0 0 True xgdx + then return $ Node.create xname 0 0 0 0 0 0 True xspindles xgdx else do xmtotal <- convert "mtotal" mtotal xmnode <- convert "mnode" mnode @@ -193,7 +194,7 @@ parseNode ktg [ name, mtotal, mnode, mfree, dtotal, dfree xdfree <- convert "dfree" dfree xctotal <- convert "ctotal" ctotal return $ Node.create xname xmtotal xmnode xmfree - xdtotal xdfree xctotal False xgdx + xdtotal xdfree xctotal False xspindles xgdx return (xname, node) parseNode _ v = fail ("Invalid node query result: " ++ show v) diff --git a/htools/Ganeti/HTools/Node.hs b/htools/Ganeti/HTools/Node.hs index 0f686c09b..c117a6ae1 100644 --- a/htools/Ganeti/HTools/Node.hs +++ b/htools/Ganeti/HTools/Node.hs @@ -101,6 +101,7 @@ data Node = Node , fDsk :: Int -- ^ Free disk space (MiB) , tCpu :: Double -- ^ Total CPU count , uCpu :: Int -- ^ Used VCPU count + , spindleCount :: Int -- ^ Node spindles (spindle_count node parameter) , pList :: [T.Idx] -- ^ List of primary instance indices , sList :: [T.Idx] -- ^ List of secondary instance indices , idx :: T.Ndx -- ^ Internal index for book-keeping @@ -117,6 +118,9 @@ data Node = Node -- threshold , hiCpu :: Int -- ^ Autocomputed from mCpu high cpu -- threshold + , hiSpindles :: Double -- ^ Auto-computed from policy spindle_ratio + -- and the node spindle count + , instSpindles :: Double -- ^ Spindles used by instances , offline :: Bool -- ^ Whether the node should not be used for -- allocations and skipped from score -- computations @@ -188,9 +192,10 @@ conflictingPrimaries (Node { pTags = t }) = Foldable.sum t - Map.size t -- 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 -> Double -> Bool -> T.Gdx -> Node + -> Int -> Double -> Bool -> Int -> T.Gdx -> Node create name_init mem_t_init mem_n_init mem_f_init - dsk_t_init dsk_f_init cpu_t_init offline_init group_init = + dsk_t_init dsk_f_init cpu_t_init offline_init spindles_init + group_init = Node { name = name_init , alias = name_init , tMem = mem_t_init @@ -199,6 +204,7 @@ create name_init mem_t_init mem_n_init mem_f_init , tDsk = dsk_t_init , fDsk = dsk_f_init , tCpu = cpu_t_init + , spindleCount = spindles_init , uCpu = 0 , pList = [] , sList = [] @@ -215,6 +221,9 @@ create name_init mem_t_init mem_n_init mem_f_init , mDsk = T.defReservedDiskRatio , loDsk = mDskToloDsk T.defReservedDiskRatio dsk_t_init , hiCpu = mCpuTohiCpu (T.iPolicyVcpuRatio T.defIPolicy) cpu_t_init + , hiSpindles = computeHiSpindles (T.iPolicySpindleRatio T.defIPolicy) + spindles_init + , instSpindles = 0 , utilPool = T.baseUtil , utilLoad = T.zeroUtil , pTags = Map.empty @@ -230,6 +239,10 @@ mDskToloDsk mval = floor . (mval *) mCpuTohiCpu :: Double -> Double -> Int mCpuTohiCpu mval = floor . (mval *) +-- | Conversiojn formula from spindles and spindle ratio to hiSpindles. +computeHiSpindles :: Double -> Int -> Double +computeHiSpindles spindle_ratio = (spindle_ratio *) . fromIntegral + -- | Changes the index. -- -- This is used only during the building of the data structures. @@ -265,7 +278,10 @@ setMcpu t val = setPolicy :: T.IPolicy -> Node -> Node setPolicy pol node = node { iPolicy = pol - , hiCpu = mCpuTohiCpu (T.iPolicyVcpuRatio pol) (tCpu node) } + , hiCpu = mCpuTohiCpu (T.iPolicyVcpuRatio pol) (tCpu node) + , hiSpindles = computeHiSpindles (T.iPolicySpindleRatio pol) + (spindleCount node) + } -- | Computes the maximum reserved memory for peers from a peer map. computeMaxRes :: P.PeerMap -> P.Elem diff --git a/htools/Ganeti/HTools/QC.hs b/htools/Ganeti/HTools/QC.hs index b41f1db46..df1f5521e 100644 --- a/htools/Ganeti/HTools/QC.hs +++ b/htools/Ganeti/HTools/QC.hs @@ -342,7 +342,7 @@ genNode min_multiplier max_multiplier = do cpu_t <- choose (base_cpu, top_cpu) offl <- arbitrary let n = Node.create name (fromIntegral mem_t) mem_n mem_f - (fromIntegral dsk_t) dsk_f (fromIntegral cpu_t) offl 0 + (fromIntegral dsk_t) dsk_f (fromIntegral cpu_t) offl 1 0 n' = Node.setPolicy nullIPolicy n return $ Node.buildPeers n' Container.empty diff --git a/htools/Ganeti/HTools/Rapi.hs b/htools/Ganeti/HTools/Rapi.hs index 9eb5c0a99..e9f82a310 100644 --- a/htools/Ganeti/HTools/Rapi.hs +++ b/htools/Ganeti/HTools/Rapi.hs @@ -4,7 +4,7 @@ {- -Copyright (C) 2009, 2010, 2011 Google Inc. +Copyright (C) 2009, 2010, 2011, 2012 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -137,10 +137,12 @@ parseNode ktg a = do drained <- extract "drained" vm_cap <- annotateResult desc $ maybeFromObj a "vm_capable" let vm_cap' = fromMaybe True vm_cap + ndparams <- extract "ndparams" >>= asJSObject + spindles <- tryFromObj desc (fromJSObject ndparams) "spindle_count" guuid <- annotateResult desc $ maybeFromObj a "group.uuid" guuid' <- lookupGroup ktg name (fromMaybe defaultGroupID guuid) node <- if offline || drained || not vm_cap' - then return $ Node.create name 0 0 0 0 0 0 True guuid' + then return $ Node.create name 0 0 0 0 0 0 True 0 guuid' else do mtotal <- extract "mtotal" mnode <- extract "mnode" @@ -149,7 +151,7 @@ parseNode ktg a = do dfree <- extract "dfree" ctotal <- extract "ctotal" return $ Node.create name mtotal mnode mfree - dtotal dfree ctotal False guuid' + dtotal dfree ctotal False spindles guuid' return (name, node) -- | Construct a group from a JSON object. diff --git a/htools/Ganeti/HTools/Simu.hs b/htools/Ganeti/HTools/Simu.hs index 68755ea97..9434e6fbf 100644 --- a/htools/Ganeti/HTools/Simu.hs +++ b/htools/Ganeti/HTools/Simu.hs @@ -6,7 +6,7 @@ This module holds the code for parsing a cluster description. {- -Copyright (C) 2009, 2010, 2011 Google Inc. +Copyright (C) 2009, 2010, 2011, 2012 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -74,7 +74,7 @@ createGroup grpIndex spec = do Node.create (printf "node-%02d-%03d" grpIndex idx) (fromIntegral mem) 0 mem (fromIntegral disk) disk - (fromIntegral cpu) False grpIndex + (fromIntegral cpu) False 1 grpIndex ) [1..ncount] grp = Group.create (printf "group-%02d" grpIndex) (printf "fake-uuid-%02d" grpIndex) apol defIPolicy diff --git a/htools/Ganeti/HTools/Text.hs b/htools/Ganeti/HTools/Text.hs index 6aeb44a02..c01376e59 100644 --- a/htools/Ganeti/HTools/Text.hs +++ b/htools/Ganeti/HTools/Text.hs @@ -181,7 +181,7 @@ loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu] = do gdx <- lookupGroup ktg name gu new_node <- if any (== "?") [tm,nm,fm,td,fd,tc] || fo == "Y" then - return $ Node.create name 0 0 0 0 0 0 True gdx + return $ Node.create name 0 0 0 0 0 0 True 0 gdx else do vtm <- tryRead name tm vnm <- tryRead name nm @@ -189,7 +189,7 @@ loadNode ktg [name, tm, nm, fm, td, fd, tc, fo, gu] = do vtd <- tryRead name td vfd <- tryRead name fd vtc <- tryRead name tc - return $ Node.create name vtm vnm vfm vtd vfd vtc False gdx + return $ Node.create name vtm vnm vfm vtd vfd vtc False 1 gdx return (name, new_node) loadNode _ s = fail $ "Invalid/incomplete node data: '" ++ show s ++ "'" -- GitLab