On Wed, Feb 25, 2015 at 01:58:46PM +0100, 'Klaus Aehlig' via ganeti-devel wrote:
Querying collectors might fail and for some collectors
the information might be incomplete. In this case, it might
be useful to continue with he information available, but this
is not necessarily the case. Therefore, provide the information
if the dynamic data collection was successful.
Signed-off-by: Klaus Aehlig <[email protected]>
---
src/Ganeti/HTools/Backend/MonD.hs | 24 +++++++++++++++---------
src/Ganeti/HTools/ExtLoader.hs | 6 +++---
src/Ganeti/HTools/Program/Hail.hs | 5 +++--
3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/src/Ganeti/HTools/Backend/MonD.hs
b/src/Ganeti/HTools/Backend/MonD.hs
index bc85ff4..fb684ee 100644
--- a/src/Ganeti/HTools/Backend/MonD.hs
+++ b/src/Ganeti/HTools/Backend/MonD.hs
@@ -265,9 +265,10 @@ queryAMonD m dc node =
Nothing -> fromCurl dc node
Just m' -> return $ fromFile dc node m'
--- | Query all MonDs for a single Data Collector.
+-- | Query all MonDs for a single Data Collector. Return the updated
+-- cluster, as well as a bit inidicating wether the collector succeeded.
queryAllMonDs :: Maybe MapMonDData -> (Node.List, Instance.List)
- -> DataCollector -> IO (Node.List, Instance.List)
+ -> DataCollector -> IO ((Node.List, Instance.List), Bool)
queryAllMonDs m (nl, il) dc = do
elems <- mapM (queryAMonD m dc) (Container.elems nl)
let elems' = catMaybes elems
@@ -275,17 +276,19 @@ queryAllMonDs m (nl, il) dc = do
then
let results = zip (Container.elems nl) elems'
in case dUse dc results (nl, il) of
- Ok (nl', il') -> return (nl', il')
+ Ok (nl', il') -> return ((nl', il'), True)
Bad s -> do
logWarning s
- return (nl, il)
+ return ((nl, il), False)
else do
logWarning $ "Didn't receive an answer by all MonDs, " ++ dName dc
++ "'s data will be ignored."
- return (nl,il)
+ return ((nl,il), False)
--- | Query all MonDs for all Data Collector.
-queryAllMonDDCs :: ClusterData -> Options -> IO ClusterData
+-- | Query all MonDs for all Data Collector. Return the cluster enriched
+-- by dynamic data, as well as a bit indicating wether all collectors
+-- could be queried successfully.
+queryAllMonDDCs :: ClusterData -> Options -> IO (ClusterData, Bool)
queryAllMonDDCs cdata opts = do
map_mDD <-
case optMonDFile opts of
@@ -295,6 +298,9 @@ queryAllMonDDCs cdata opts = do
monDData <- exitIfBad "can't parse MonD data"
. pMonDData $ monDData_contents
return . Just $ Map.fromList monDData
+ let query (cluster, ok) collector = do
+ (cluster', ok') <- queryAllMonDs map_mDD cluster collector
+ return (cluster', ok && ok')
let (ClusterData _ nl il _ _) = cdata
- (nl', il') <- foldM (queryAllMonDs map_mDD) (nl, il) (collectors opts)
- return $ cdata {cdNodes = nl', cdInstances = il'}
+ ((nl', il'), ok) <- foldM query ((nl, il), True) (collectors opts)
+ return (cdata {cdNodes = nl', cdInstances = il'}, ok)
diff --git a/src/Ganeti/HTools/ExtLoader.hs b/src/Ganeti/HTools/ExtLoader.hs
index cdc81eb..18b1563 100644
--- a/src/Ganeti/HTools/ExtLoader.hs
+++ b/src/Ganeti/HTools/ExtLoader.hs
@@ -124,9 +124,9 @@ loadExternalData opts = do
ldresult = input_data >>= (if ignoreDynU then clearDynU else return)
>>= mergeData eff_u exTags selInsts exInsts now
cdata <- exitIfBad "failed to load data, aborting" ldresult
- cdata' <- if optMonD opts
- then MonD.queryAllMonDDCs cdata opts
- else return cdata
+ (cdata', _) <- if optMonD opts
+ then MonD.queryAllMonDDCs cdata opts
+ else return (cdata, True)
let (fix_msgs, nl) = checkData (cdNodes cdata') (cdInstances cdata')
unless (optVerbose opts == 0) $ maybeShowWarnings fix_msgs
diff --git a/src/Ganeti/HTools/Program/Hail.hs
b/src/Ganeti/HTools/Program/Hail.hs
index 2a398ad..1d57f17 100644
--- a/src/Ganeti/HTools/Program/Hail.hs
+++ b/src/Ganeti/HTools/Program/Hail.hs
@@ -87,8 +87,9 @@ wrapReadRequest opts args = do
return $ Request rqt cdata
else do
let Request rqt cdata = r1
- cdata' <-
- if optMonD opts then MonD.queryAllMonDDCs cdata opts else return cdata
+ (cdata', _) <- if optMonD opts
+ then MonD.queryAllMonDDCs cdata opts
+ else return (cdata, True)
return $ Request rqt cdata'
-- | Main function.
--
2.2.0.rc0.207.ga3a616c
LGTM
A suggestion for discussion: Adding the 'Bool' parameters obscures a bit the
code, as it needs to be dealt with at various places. What about using
WriterT All IO a
(perhaps as a type alias for easier refactoring, if needed) instead of
IO (a, Bool)
? Reporting a failure is then just calling `tell (All False)` and a lot of
the existing code (foldM etc) would remain unchanged, without needing to
explicitly process the boolean part, making the && implicit. On the other
hand, it requires adding liftIO at a few places and also at the place where
the whole query is run.