diff --git a/htools/Ganeti/HTools/IAlloc.hs b/htools/Ganeti/HTools/IAlloc.hs index aa8a39c5b5323143d0f03bd20125dcae08935ff6..9ccc8ecb8a729502af11cbed1cdd0612d9b8fb60 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 cd80996bb9b7c079c90ad944ea99c532da7e1026..77d561472845ce6b4cbbdbe148e6081914ab5816 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 0f686c09b1272d1fc4a2240e4568be762cf59cd0..c117a6ae18c0f334638da04b5507e7b4aae64b23 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 b41f1db467add06537a22246c41d1601eedf5549..df1f5521e3d7bb87095df10aa4e28fb6728345fa 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 9eb5c0a99e6974fdffa290e5233445485f2de75a..e9f82a310147f957edef007ba1e547cd73f8fb5f 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 68755ea97ec640f87ab6150103305446f0eca4c2..9434e6fbf169ac9fada7ebdd5ce17aa620ab69c9 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 6aeb44a0204aef219bb9fdc598585598c883123a..c01376e590a8e1f224a3662244aadc5de3b5c7b8 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 ++ "'"