From 313fdabc5bd7b32e6e57e1d0a0cd57f8005607b5 Mon Sep 17 00:00:00 2001 From: Klaus Aehlig <aehlig@google.com> Date: Thu, 2 May 2013 15:12:00 +0200 Subject: [PATCH] Add option to hroller to select nodes based on tags Add option --node-tags to tell hroller to consider only nodes with these tags. A use case would be a tag tracking on which nodes the maintenance has not yet been carried out, e.g., if rolling reboots are interleaved with other cluster operations. Signed-off-by: Klaus Aehlig <aehlig@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- man/hroller.rst | 5 +++++ src/Ganeti/HTools/CLI.hs | 10 ++++++++++ src/Ganeti/HTools/Program/Hroller.hs | 12 ++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/man/hroller.rst b/man/hroller.rst index 25ffa34b3..b96508b36 100644 --- a/man/hroller.rst +++ b/man/hroller.rst @@ -27,6 +27,8 @@ Algorithm options: **[ -O *name...* ]** +**[ --node-tags** *tag,..* **]** + Reporting options: **[ -v... | -q ]** @@ -59,6 +61,9 @@ OPTIONS For a description of the standard options check **htools**\(7) and **hbal**\(1). +\--node-tags *tag,...* + Restrict to nodes having at least one of the given tags. + \--force Do not fail, even if the master node cannot be determined. diff --git a/src/Ganeti/HTools/CLI.hs b/src/Ganeti/HTools/CLI.hs index 8f55f6fb4..80fa89f64 100644 --- a/src/Ganeti/HTools/CLI.hs +++ b/src/Ganeti/HTools/CLI.hs @@ -69,6 +69,7 @@ module Ganeti.HTools.CLI , oNoHeaders , oNoSimulation , oNodeSim + , oNodeTags , oOfflineNode , oOutputDir , oPrintCommands @@ -135,6 +136,7 @@ data Options = Options , optNoHeaders :: Bool -- ^ Do not show a header line , optNoSimulation :: Bool -- ^ Skip the rebalancing dry-run , optNodeSim :: [String] -- ^ Cluster simulation mode + , optNodeTags :: Maybe [String] -- ^ List of node tags to restrict to , optOffline :: [String] -- ^ Names of offline nodes , optOutPath :: FilePath -- ^ Path to the output directory , optSaveCluster :: Maybe FilePath -- ^ Save cluster state to this file @@ -182,6 +184,7 @@ defaultOptions = Options , optNoHeaders = False , optNoSimulation = False , optNodeSim = [] + , optNodeTags = Nothing , optOffline = [] , optOutPath = "." , optSaveCluster = Nothing @@ -452,6 +455,13 @@ oNodeSim = \ 'alloc_policy,num_nodes,disk,ram,cpu'", OptComplString) +oNodeTags :: OptType +oNodeTags = + (Option "" ["node-tags"] + (ReqArg (\ f opts -> Ok opts { optNodeTags = Just $ sepSplit ',' f }) + "TAG,...") "Restrict to nodes with the given tags", + OptComplString) + oOfflineNode :: OptType oOfflineNode = (Option "O" ["offline"] diff --git a/src/Ganeti/HTools/Program/Hroller.hs b/src/Ganeti/HTools/Program/Hroller.hs index 98aa30f13..356cea5b8 100644 --- a/src/Ganeti/HTools/Program/Hroller.hs +++ b/src/Ganeti/HTools/Program/Hroller.hs @@ -60,6 +60,7 @@ options = do , oVerbose , oQuiet , oNoHeaders + , oNodeTags , oSaveCluster , oGroup , oForce @@ -92,6 +93,11 @@ hasGroup :: Maybe Group.Group -> Node.Node -> Bool hasGroup Nothing _ = True hasGroup (Just grp) node = Node.group node == Group.idx grp +-- | Predicate of having at least one tag in a given set. +hasTag :: Maybe [String] -> Node.Node -> Bool +hasTag Nothing _ = True +hasTag (Just tags) node = not . null $ Node.nTags node `intersect` tags + -- | Put the master node last. -- Reorder a list of lists of nodes such that the master node (if present) -- is the last node of the last group. @@ -130,8 +136,10 @@ main opts args = do Nothing -> exitErr "Cannot find target group." Just grp -> return (Just grp) - let nodes = IntMap.filter - (liftA2 (&&) (not . Node.offline) (hasGroup wantedGroup)) + let nodes = IntMap.filter (foldl (liftA2 (&&)) (const True) + [ (not . Node.offline) + , (hasTag $ optNodeTags opts) + , hasGroup wantedGroup ]) nlf -- TODO: fail if instances are running (with option to warn only) -- GitLab