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