From 00b157522469058680f231f51880e720ee48d12c Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Tue, 19 May 2009 22:45:31 +0100 Subject: [PATCH] Add support for 'offline' nodes This patch drops compatiblity with Ganeti 1.2 and adds support for offline nodes in the cluster. When reading from RAPI, the drained nodes are considered offline so that we don't allocate on them too. --- Ganeti/HTools/Cluster.hs | 10 +++++++--- Ganeti/HTools/Node.hs | 7 ++++--- Ganeti/HTools/Rapi.hs | 21 ++++++++++++++++----- Ganeti/HTools/Utils.hs | 4 ++++ README | 5 +++-- hbal.1 | 3 +++ hscan.hs | 6 ++++-- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs index 966362d..e3753cc 100644 --- a/Ganeti/HTools/Cluster.hs +++ b/Ganeti/HTools/Cluster.hs @@ -753,10 +753,14 @@ loadData ndata idata = let {- node file: name t_mem n_mem f_mem t_disk f_disk -} (ktn, nl) = loadTabular ndata - (\ (name:tm:nm:fm:td:fd:[]) -> + (\ (name:tm:nm:fm:td:fd:fo:[]) -> (name, - Node.create (read tm) (read nm) - (read fm) (read td) (read fd))) + if any (== "?") [tm,nm,fm,td,fd] || fo == "Y" then + Node.create 0 0 0 0 0 True + else + Node.create (read tm) (read nm) (read fm) + (read td) (read fd) False + )) Node.setIdx {- instance file: name mem disk status pnode snode -} (kti, il) = loadTabular idata diff --git a/Ganeti/HTools/Node.hs b/Ganeti/HTools/Node.hs index 1156ee2..8dffd58 100644 --- a/Ganeti/HTools/Node.hs +++ b/Ganeti/HTools/Node.hs @@ -64,8 +64,9 @@ The index and the peers maps are empty, and will be need to be update later via the 'setIdx' and 'buildPeers' functions. -} -create :: Double -> Int -> Int -> Double -> Int -> Node -create mem_t_init mem_n_init mem_f_init dsk_t_init dsk_f_init = +create :: Double -> Int -> Int -> Double -> Int -> Bool -> Node +create mem_t_init mem_n_init mem_f_init dsk_t_init dsk_f_init + offline_init = Node { t_mem = mem_t_init, @@ -82,7 +83,7 @@ create mem_t_init mem_n_init mem_f_init dsk_t_init dsk_f_init = p_mem = (fromIntegral mem_f_init) / mem_t_init, p_dsk = (fromIntegral dsk_f_init) / dsk_t_init, p_rem = 0, - offline = False, + offline = offline_init, x_mem = 0 } diff --git a/Ganeti/HTools/Rapi.hs b/Ganeti/HTools/Rapi.hs index c6db593..bfba589 100644 --- a/Ganeti/HTools/Rapi.hs +++ b/Ganeti/HTools/Rapi.hs @@ -90,17 +90,28 @@ parseInstance a = concatEitherElems running $ concatEitherElems pnode snode +boolToYN :: Bool -> Either String String +boolToYN True = Right "Y" +boolToYN _ = Right "N" + parseNode :: JSObject JSValue -> Either String String parseNode a = let name = getStringElement "name" a + offline = getBoolElement "offline" a + drained = getBoolElement "drained" a mtotal = getIntElement "mtotal" a mnode = getIntElement "mnode" a mfree = getIntElement "mfree" a dtotal = getIntElement "dtotal" a dfree = getIntElement "dfree" a in concatEitherElems name $ - concatEitherElems (show `applyEither1` mtotal) $ - concatEitherElems (show `applyEither1` mnode) $ - concatEitherElems (show `applyEither1` mfree) $ - concatEitherElems (show `applyEither1` dtotal) - (show `applyEither1` dfree) + (case offline of + Right True -> Right "0|0|0|0|0|Y" + _ -> + concatEitherElems (show `applyEither1` mtotal) $ + concatEitherElems (show `applyEither1` mnode) $ + concatEitherElems (show `applyEither1` mfree) $ + concatEitherElems (show `applyEither1` dtotal) $ + concatEitherElems (show `applyEither1` dfree) + ((applyEither2 (||) offline drained) `combineEithers` boolToYN) + ) diff --git a/Ganeti/HTools/Utils.hs b/Ganeti/HTools/Utils.hs index fde9616..c231a6f 100644 --- a/Ganeti/HTools/Utils.hs +++ b/Ganeti/HTools/Utils.hs @@ -20,6 +20,7 @@ module Ganeti.HTools.Utils , fromObj , getStringElement , getIntElement + , getBoolElement , getListElement , getObjectElement , asJSObject @@ -165,6 +166,9 @@ getStringElement = fromObj getIntElement :: String -> JSObject JSValue -> Either String Int getIntElement = fromObj +getBoolElement :: String -> JSObject JSValue -> Either String Bool +getBoolElement = fromObj + getListElement :: String -> JSObject JSValue -> Either String [JSValue] getListElement = fromObj diff --git a/README b/README index 6949fbb..ff5936e 100644 --- a/README +++ b/README @@ -2,7 +2,8 @@ Ganeti Cluster tools (htools) ============================= These are some simple cluster tools for fixing common problems. Right -now N+1 and rebalancing are included. +now N+1 and rebalancing are included. Starting with version 0.1.0, +only Ganeti 2.0 is supported. Cluster N+1 solver @@ -37,7 +38,7 @@ gathering if RAPI is available, which is better since it can extract more precise information. In case RAPI is not usable for whatever reason, the following two commands should be run:: - gnt-node list -oname,mtotal,mnode,mfree,dtotal,dfree \ + gnt-node list -oname,mtotal,mnode,mfree,dtotal,dfree,offline \ --separator '|' --no-headers > nodes gnt-instance list -oname,admin_ram,sda_size,status,pnode,snodes \ --separator '|' --no-head > instances diff --git a/hbal.1 b/hbal.1 index 09c4bf1..cfa401c 100644 --- a/hbal.1 +++ b/hbal.1 @@ -247,6 +247,9 @@ node is offline, since this move requires a failover. these nodes will not be included in the score calculation (except for the percentage of instances on offline nodes) .RE +Note that hbal will also mark as offline any nodes which are reported +by RAPI as such, or that have "?" in file-based input in any numeric +fields. .RE .TP diff --git a/hscan.hs b/hscan.hs index e9c2981..e859c9a 100644 --- a/hscan.hs +++ b/hscan.hs @@ -79,9 +79,11 @@ serializeNodes nl csf ktn = t_mem = (truncate $ Node.t_mem node)::Int t_dsk = (truncate $ Node.t_dsk node)::Int in - printf "%s|%d|%d|%d|%d|%d" name + printf "%s|%d|%d|%d|%d|%d|%c" name t_mem (Node.n_mem node) (Node.f_mem node) - t_dsk (Node.f_dsk node)) + t_dsk (Node.f_dsk node) + (if Node.offline node then 'Y' else 'N') + ) nodes in unlines nlines -- 1.7.10.4