Revision 313fdabc

b/man/hroller.rst
27 27

  
28 28
**[ -O *name...* ]**
29 29

  
30
**[ --node-tags** *tag,..* **]**
31

  
30 32
Reporting options:
31 33

  
32 34
**[ -v... | -q ]**
......
59 61
For a description of the standard options check **htools**\(7) and
60 62
**hbal**\(1).
61 63

  
64
\--node-tags *tag,...*
65
  Restrict to nodes having at least one of the given tags.
66

  
62 67
\--force
63 68
  Do not fail, even if the master node cannot be determined.
64 69

  
b/src/Ganeti/HTools/CLI.hs
69 69
  , oNoHeaders
70 70
  , oNoSimulation
71 71
  , oNodeSim
72
  , oNodeTags
72 73
  , oOfflineNode
73 74
  , oOutputDir
74 75
  , oPrintCommands
......
135 136
  , optNoHeaders   :: Bool           -- ^ Do not show a header line
136 137
  , optNoSimulation :: Bool          -- ^ Skip the rebalancing dry-run
137 138
  , optNodeSim     :: [String]       -- ^ Cluster simulation mode
139
  , optNodeTags    :: Maybe [String] -- ^ List of node tags to restrict to 
138 140
  , optOffline     :: [String]       -- ^ Names of offline nodes
139 141
  , optOutPath     :: FilePath       -- ^ Path to the output directory
140 142
  , optSaveCluster :: Maybe FilePath -- ^ Save cluster state to this file
......
182 184
  , optNoHeaders   = False
183 185
  , optNoSimulation = False
184 186
  , optNodeSim     = []
187
  , optNodeTags    = Nothing
185 188
  , optOffline     = []
186 189
  , optOutPath     = "."
187 190
  , optSaveCluster = Nothing
......
452 455
   \ 'alloc_policy,num_nodes,disk,ram,cpu'",
453 456
   OptComplString)
454 457

  
458
oNodeTags :: OptType
459
oNodeTags =
460
  (Option "" ["node-tags"]
461
   (ReqArg (\ f opts -> Ok opts { optNodeTags = Just $ sepSplit ',' f })
462
    "TAG,...") "Restrict to nodes with the given tags",
463
   OptComplString)
464
     
455 465
oOfflineNode :: OptType
456 466
oOfflineNode =
457 467
  (Option "O" ["offline"]
b/src/Ganeti/HTools/Program/Hroller.hs
60 60
    , oVerbose
61 61
    , oQuiet
62 62
    , oNoHeaders
63
    , oNodeTags
63 64
    , oSaveCluster
64 65
    , oGroup
65 66
    , oForce
......
92 93
hasGroup Nothing _ = True
93 94
hasGroup (Just grp) node = Node.group node == Group.idx grp 
94 95

  
96
-- | Predicate of having at least one tag in a given set.
97
hasTag :: Maybe [String] -> Node.Node -> Bool
98
hasTag Nothing _ = True
99
hasTag (Just tags) node = not . null $ Node.nTags node `intersect` tags
100

  
95 101
-- | Put the master node last.
96 102
-- Reorder a list of lists of nodes such that the master node (if present)
97 103
-- is the last node of the last group.
......
130 136
      Nothing -> exitErr "Cannot find target group."
131 137
      Just grp -> return (Just grp)
132 138

  
133
  let nodes = IntMap.filter
134
              (liftA2 (&&) (not . Node.offline) (hasGroup wantedGroup))
139
  let nodes = IntMap.filter (foldl (liftA2 (&&)) (const True)
140
                             [ (not . Node.offline) 
141
                             , (hasTag $ optNodeTags opts)
142
                             , hasGroup wantedGroup ])
135 143
              nlf
136 144

  
137 145
  -- TODO: fail if instances are running (with option to warn only)

Also available in: Unified diff