Revision 73415719

b/lib/cmdlib.py
4141 4141
    return self.target.GetTags()
4142 4142

  
4143 4143

  
4144
class LUSearchTags(NoHooksLU):
4145
  """Searches the tags for a given pattern.
4146

  
4147
  """
4148
  _OP_REQP = ["pattern"]
4149

  
4150
  def CheckPrereq(self):
4151
    """Check prerequisites.
4152

  
4153
    This checks the pattern passed for validity by compiling it.
4154

  
4155
    """
4156
    try:
4157
      self.re = re.compile(self.op.pattern)
4158
    except re.error, err:
4159
      raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
4160
                                 (self.op.pattern, err))
4161

  
4162
  def Exec(self, feedback_fn):
4163
    """Returns the tag list.
4164

  
4165
    """
4166
    cfg = self.cfg
4167
    tgts = [("/cluster", cfg.GetClusterInfo())]
4168
    ilist = [cfg.GetInstanceInfo(name) for name in cfg.GetInstanceList()]
4169
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
4170
    nlist = [cfg.GetNodeInfo(name) for name in cfg.GetNodeList()]
4171
    tgts.extend([("/nodes/%s" % n.name, n) for n in nlist])
4172
    results = []
4173
    for path, target in tgts:
4174
      for tag in target.GetTags():
4175
        if self.re.search(tag):
4176
          results.append((path, tag))
4177
    return results
4178

  
4179

  
4144 4180
class LUAddTags(TagsLU):
4145 4181
  """Sets a tag on a given object.
4146 4182

  
b/lib/mcpu.py
80 80
    opcodes.OpExportInstance: cmdlib.LUExportInstance,
81 81
    # tags lu
82 82
    opcodes.OpGetTags: cmdlib.LUGetTags,
83
    opcodes.OpSearchTags: cmdlib.LUSearchTags,
83 84
    opcodes.OpAddTags: cmdlib.LUAddTags,
84 85
    opcodes.OpDelTags: cmdlib.LUDelTags,
85 86
    }
b/lib/opcodes.py
263 263
  __slots__ = ["kind", "name"]
264 264

  
265 265

  
266
class OpSearchTags(OpCode):
267
  """Searches the tags in the cluster for a given pattern."""
268
  OP_ID = "OP_TAGS_SEARCH"
269
  __slots__ = ["pattern"]
270

  
271

  
266 272
class OpAddTags(OpCode):
267 273
  """Add a list of tags on a given object."""
268 274
  OP_ID = "OP_TAGS_SET"
b/man/gnt-cluster.sgml
302 302
    </refsect2>
303 303

  
304 304
    <refsect2>
305
      <title>SEARCH-TAGS</title>
306

  
307
      <cmdsynopsis>
308
        <command>search-tags</command>
309
        <arg choice="req"><replaceable>pattern</replaceable></arg>
310
      </cmdsynopsis>
311

  
312
      <para>
313
        Searches the tags on all objects in the cluster (the cluster
314
        itself, the nodes and the instances) for a given pattern. The
315
        pattern is interpreted as a regular expression and a search
316
        will be done on it (i.e. the given pattern is not anchored to
317
        the beggining of the string; if you want that, prefix the
318
        pattern with <literal>^</literal>).
319
      </para>
320

  
321
      <para>
322
        If no tags are matching the pattern, the exit code of the
323
        command will be one. If there is at least one match, the exit
324
        code will be zero. Each match is listed on one line, the
325
        object and the tag separated by a space. The cluster will be
326
        listed as <filename>/cluster</filename>, a node will be listed
327
        as
328
        <filename>/nodes/<replaceable>name</replaceable></filename>,
329
        and an instance as
330
        <filename>/instances/<replaceable>name</replaceable></filename>.
331
        Example:
332
      </para>
333
<screen>
334
# gnt-cluster search time
335
/cluster ctime:2007-09-01
336
/nodes/node1.example.com mtime:2007-10-04
337
</screen>
338
    </refsect2>
339

  
340
    <refsect2>
305 341
      <title>VERIFY</title>
306 342

  
307 343
      <cmdsynopsis>
b/scripts/gnt-cluster
193 193
  SubmitOpCode(op)
194 194

  
195 195

  
196
def SearchTags(opts, args):
197
  """Searches the tags on all the cluster.
198

  
199
  """
200
  op = opcodes.OpSearchTags(pattern=args[0])
201
  result = SubmitOpCode(op)
202
  if not result:
203
    return 1
204
  result = list(result)
205
  result.sort()
206
  for path, tag in result:
207
    print "%s %s" % (path, tag)
208

  
209

  
196 210
# this is an option common to more than one command, so we declare
197 211
# it here and reuse it
198 212
node_option = make_option("-n", "--node", action="append", dest="nodes",
......
269 283
               "tag...", "Add tags to the cluster"),
270 284
  'remove-tags': (RemoveTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
271 285
                  "tag...", "Remove tags from the cluster"),
286
  'search-tags': (SearchTags, ARGS_ONE,
287
                  [DEBUG_OPT], "", "Searches the tags on all objects on"
288
                  " the cluster for a given pattern (regex)"),
272 289
  }
273 290

  
274 291
if __name__ == '__main__':

Also available in: Unified diff