[Pkg-ganeti-devel] [ganeti] 54/165: Sort MonD backend into logical order
Apollon Oikonomopoulos
apoikos at moszumanska.debian.org
Tue Aug 11 13:53:12 UTC 2015
This is an automated email from the git hooks/post-receive script.
apoikos pushed a commit to branch master
in repository ganeti.
commit 43056bf77fd56a66f6ffd6a70c243f1eb990ab8b
Author: Klaus Aehlig <aehlig at google.com>
Date: Fri Feb 20 14:42:47 2015 +0100
Sort MonD backend into logical order
As in this patch series every line of code is moved
anyway (when the htools MonD backend was added), we
have the unique chance of moving code around without
creating additional conflicts. Use this opportunity
to sort functions into logical order, i.e., introduce
each function before its first use.
Signed-off-by: Klaus Aehlig <aehlig at google.com>
Reviewed-by: Petr Pudlak <pudlak at google.com>
---
src/Ganeti/HTools/Backend/MonD.hs | 224 ++++++++++++++++++++------------------
1 file changed, 116 insertions(+), 108 deletions(-)
diff --git a/src/Ganeti/HTools/Backend/MonD.hs b/src/Ganeti/HTools/Backend/MonD.hs
index 13197b5..d7f4d4c 100644
--- a/src/Ganeti/HTools/Backend/MonD.hs
+++ b/src/Ganeti/HTools/Backend/MonD.hs
@@ -67,6 +67,11 @@ import Ganeti.JSON
import Ganeti.Logging (logWarning)
import Ganeti.Utils (exitIfBad)
+-- * General definitions
+
+-- | The actual data types for MonD's Data Collectors.
+data Report = CPUavgloadReport CPUavgload
+
-- | Type describing a data collector basic information.
data DataCollector = DataCollector
{ dName :: String -- ^ Name of the data collector
@@ -79,6 +84,50 @@ data DataCollector = DataCollector
-- data into a cluster
}
+-- * Node-total CPU load average data collector
+
+-- | Parse a DCReport for the node-total CPU collector.
+mkCpuReport :: DCReport -> Maybe Report
+mkCpuReport dcr =
+ case fromJVal (dcReportData dcr) :: Result CPUavgload of
+ Ok cav -> Just $ CPUavgloadReport cav
+ Bad _ -> Nothing
+
+-- | Take reports of node CPU values and update a node accordingly.
+updateNodeCpuFromReport :: (Node.Node, Report) -> Node.Node
+updateNodeCpuFromReport (node, CPUavgloadReport cav) =
+ let ct = cavCpuTotal cav
+ du = Node.utilLoad node
+ du' = du {cpuWeight = ct}
+ in node { Node.utilLoad = du' }
+
+-- | Update the instance CPU-utilization data, asuming that each virtual
+-- CPU contributes equally to the node CPU load.
+updateCpuUtilDataFromNode :: Instance.List -> Node.Node -> Instance.List
+updateCpuUtilDataFromNode il node =
+ let ct = cpuWeight (Node.utilLoad node)
+ n_uCpu = Node.uCpu node
+ upd inst =
+ if Node.idx node == Instance.pNode inst
+ then
+ let i_vcpus = Instance.vcpus inst
+ i_util = ct / fromIntegral n_uCpu * fromIntegral i_vcpus
+ i_du = Instance.util inst
+ i_du' = i_du {cpuWeight = i_util}
+ in inst {Instance.util = i_du'}
+ else inst
+ in Container.map upd il
+
+-- | Update cluster data from node CPU load reports.
+useNodeTotalCPU :: [(Node.Node, Report)]
+ -> (Node.List, Instance.List)
+ -> Result (Node.List, Instance.List)
+useNodeTotalCPU reports (nl, il) =
+ let newnodes = map updateNodeCpuFromReport reports
+ il' = foldl updateCpuUtilDataFromNode il newnodes
+ nl' = zip (Container.keys nl) newnodes
+ in return (Container.fromList nl', il')
+
-- | The node-total CPU collector.
totalCPUCollector :: DataCollector
totalCPUCollector = DataCollector { dName = CPUload.dcName
@@ -87,8 +136,7 @@ totalCPUCollector = DataCollector { dName = CPUload.dcName
, dUse = useNodeTotalCPU
}
--- | The actual data types for MonD's Data Collectors.
-data Report = CPUavgloadReport CPUavgload
+-- * Collector choice
-- | The list of Data Collectors used by hail and hbal.
collectors :: Options -> [DataCollector]
@@ -97,6 +145,13 @@ collectors opts =
then []
else [ totalCPUCollector ]
+-- * Querying infrastructure
+
+-- | Return the data from correct combination of a Data Collector
+-- and a DCReport.
+mkReport :: DataCollector -> Maybe DCReport -> Maybe Report
+mkReport dc = (>>= dMkReport dc)
+
-- | MonDs Data parsed by a mock file. Representing (node name, list of reports
-- produced by MonDs Data Collectors).
type MonDData = (String, [DCReport])
@@ -104,11 +159,39 @@ type MonDData = (String, [DCReport])
-- | A map storing MonDs data.
type MapMonDData = Map.Map String [DCReport]
--- | Parse MonD data file contents.
-pMonDData :: String -> Result [MonDData]
-pMonDData input =
- loadJSArray "Parsing MonD's answer" input >>=
- mapM (pMonDN . J.fromJSObject)
+-- | Get data report for the specified Data Collector and Node from the map.
+fromFile :: DataCollector -> Node.Node -> MapMonDData -> Maybe DCReport
+fromFile dc node m =
+ let matchDCName dcr = dName dc == dcReportName dcr
+ in maybe Nothing (L.find matchDCName) $ Map.lookup (Node.name node) m
+
+-- | Get Category Name.
+getDCCName :: Maybe DCCategory -> String
+getDCCName dcc =
+ case dcc of
+ Nothing -> "default"
+ Just c -> getCategoryName c
+
+-- | Prepare url to query a single collector.
+prepareUrl :: DataCollector -> Node.Node -> URLString
+prepareUrl dc node =
+ Node.name node ++ ":" ++ show C.defaultMondPort ++ "/"
+ ++ show C.mondLatestApiVersion ++ "/report/" ++
+ getDCCName (dCategory dc) ++ "/" ++ dName dc
+
+-- | Query a specified MonD for a Data Collector.
+fromCurl :: DataCollector -> Node.Node -> IO (Maybe DCReport)
+fromCurl dc node = do
+ (code, !body) <- curlGetString (prepareUrl dc node) []
+ case code of
+ CurlOK ->
+ case J.decodeStrict body :: J.Result DCReport of
+ J.Ok r -> return $ Just r
+ J.Error _ -> return Nothing
+ _ -> do
+ logWarning $ "Failed to contact node's " ++ Node.name node
+ ++ " MonD for DC " ++ dName dc
+ return Nothing
-- | Parse a node's JSON record.
pMonDN :: JSRecord -> Result MonDData
@@ -117,38 +200,19 @@ pMonDN a = do
reports <- tryFromObj "Parsing node's reports" a "reports"
return (node, reports)
--- | Query all MonDs for all Data Collector.
-queryAllMonDDCs :: ClusterData -> Options -> IO ClusterData
-queryAllMonDDCs cdata opts = do
- map_mDD <-
- case optMonDFile opts of
- Nothing -> return Nothing
- Just fp -> do
- monDData_contents <- readFile fp
- monDData <- exitIfBad "can't parse MonD data"
- . pMonDData $ monDData_contents
- return . Just $ Map.fromList monDData
- let (ClusterData _ nl il _ _) = cdata
- (nl', il') <- foldM (queryAllMonDs map_mDD) (nl, il) (collectors opts)
- return $ cdata {cdNodes = nl', cdInstances = il'}
-
--- | Take reports of node CPU values and update a node accordingly.
-updateNodeCpuFromReport :: (Node.Node, Report) -> Node.Node
-updateNodeCpuFromReport (node, CPUavgloadReport cav) =
- let ct = cavCpuTotal cav
- du = Node.utilLoad node
- du' = du {cpuWeight = ct}
- in node { Node.utilLoad = du' }
+-- | Parse MonD data file contents.
+pMonDData :: String -> Result [MonDData]
+pMonDData input =
+ loadJSArray "Parsing MonD's answer" input >>=
+ mapM (pMonDN . J.fromJSObject)
--- | Update cluster data from node CPU load reports.
-useNodeTotalCPU :: [(Node.Node, Report)]
- -> (Node.List, Instance.List)
- -> Result (Node.List, Instance.List)
-useNodeTotalCPU reports (nl, il) =
- let newnodes = map updateNodeCpuFromReport reports
- il' = foldl updateCpuUtilDataFromNode il newnodes
- nl' = zip (Container.keys nl) newnodes
- in return (Container.fromList nl', il')
+-- | Query a single MonD for a single Data Collector.
+queryAMonD :: Maybe MapMonDData -> DataCollector -> Node.Node
+ -> IO (Maybe Report)
+queryAMonD m dc node =
+ liftM (mkReport dc) $ case m of
+ Nothing -> fromCurl dc node
+ Just m' -> return $ fromFile dc node m'
-- | Query all MonDs for a single Data Collector.
queryAllMonDs :: Maybe MapMonDData -> (Node.List, Instance.List)
@@ -169,73 +233,17 @@ queryAllMonDs m (nl, il) dc = do
++ "'s data will be ignored."
return (nl,il)
--- | Query a specified MonD for a Data Collector.
-fromCurl :: DataCollector -> Node.Node -> IO (Maybe DCReport)
-fromCurl dc node = do
- (code, !body) <- curlGetString (prepareUrl dc node) []
- case code of
- CurlOK ->
- case J.decodeStrict body :: J.Result DCReport of
- J.Ok r -> return $ Just r
- J.Error _ -> return Nothing
- _ -> do
- logWarning $ "Failed to contact node's " ++ Node.name node
- ++ " MonD for DC " ++ dName dc
- return Nothing
-
--- | Return the data from correct combination of a Data Collector
--- and a DCReport.
-mkReport :: DataCollector -> Maybe DCReport -> Maybe Report
-mkReport dc = (>>= dMkReport dc)
-
--- | Parse a DCReport for the node-total CPU collector.
-mkCpuReport :: DCReport -> Maybe Report
-mkCpuReport dcr =
- case fromJVal (dcReportData dcr) :: Result CPUavgload of
- Ok cav -> Just $ CPUavgloadReport cav
- Bad _ -> Nothing
-
--- | Get data report for the specified Data Collector and Node from the map.
-fromFile :: DataCollector -> Node.Node -> MapMonDData -> Maybe DCReport
-fromFile dc node m =
- let matchDCName dcr = dName dc == dcReportName dcr
- in maybe Nothing (L.find matchDCName) $ Map.lookup (Node.name node) m
-
--- | Query a single MonD for a single Data Collector.
-queryAMonD :: Maybe MapMonDData -> DataCollector -> Node.Node
- -> IO (Maybe Report)
-queryAMonD m dc node =
- liftM (mkReport dc) $ case m of
- Nothing -> fromCurl dc node
- Just m' -> return $ fromFile dc node m'
-
--- | Update the instance CPU-utilization data, asuming that each virtual
--- CPU contributes equally to the node CPU load.
-updateCpuUtilDataFromNode :: Instance.List -> Node.Node -> Instance.List
-updateCpuUtilDataFromNode il node =
- let ct = cpuWeight (Node.utilLoad node)
- n_uCpu = Node.uCpu node
- upd inst =
- if Node.idx node == Instance.pNode inst
- then
- let i_vcpus = Instance.vcpus inst
- i_util = ct / fromIntegral n_uCpu * fromIntegral i_vcpus
- i_du = Instance.util inst
- i_du' = i_du {cpuWeight = i_util}
- in inst {Instance.util = i_du'}
- else inst
- in Container.map upd il
-
--- | Prepare url to query a single collector.
-prepareUrl :: DataCollector -> Node.Node -> URLString
-prepareUrl dc node =
- Node.name node ++ ":" ++ show C.defaultMondPort ++ "/"
- ++ show C.mondLatestApiVersion ++ "/report/" ++
- getDCCName (dCategory dc) ++ "/" ++ dName dc
-
--- | Get Category Name.
-getDCCName :: Maybe DCCategory -> String
-getDCCName dcc =
- case dcc of
- Nothing -> "default"
- Just c -> getCategoryName c
+-- | Query all MonDs for all Data Collector.
+queryAllMonDDCs :: ClusterData -> Options -> IO ClusterData
+queryAllMonDDCs cdata opts = do
+ map_mDD <-
+ case optMonDFile opts of
+ Nothing -> return Nothing
+ Just fp -> do
+ monDData_contents <- readFile fp
+ monDData <- exitIfBad "can't parse MonD data"
+ . pMonDData $ monDData_contents
+ return . Just $ Map.fromList monDData
+ let (ClusterData _ nl il _ _) = cdata
+ (nl', il') <- foldM (queryAllMonDs map_mDD) (nl, il) (collectors opts)
+ return $ cdata {cdNodes = nl', cdInstances = il'}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ganeti/ganeti.git
More information about the Pkg-ganeti-devel
mailing list