Package ClusterShell :: Package CLI :: Module Clubak
[hide private]
[frames] | no frames]

Source Code for Module ClusterShell.CLI.Clubak

  1  #!/usr/bin/env python 
  2  # 
  3  # Copyright (C) 2010-2012 CEA/DAM 
  4  # 
  5  # This file is part of ClusterShell. 
  6  # 
  7  # ClusterShell is free software; you can redistribute it and/or 
  8  # modify it under the terms of the GNU Lesser General Public 
  9  # License as published by the Free Software Foundation; either 
 10  # version 2.1 of the License, or (at your option) any later version. 
 11  # 
 12  # ClusterShell is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 15  # Lesser General Public License for more details. 
 16  # 
 17  # You should have received a copy of the GNU Lesser General Public 
 18  # License along with ClusterShell; if not, write to the Free Software 
 19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
 20   
 21  """ 
 22  format dsh/pdsh-like output for humans and more 
 23   
 24  For help, type:: 
 25      $ clubak --help 
 26  """ 
 27   
 28  from itertools import imap 
 29  import sys 
 30   
 31  from ClusterShell.MsgTree import MsgTree, MODE_DEFER, MODE_TRACE 
 32  from ClusterShell.NodeSet import NodeSetParseError, std_group_resolver 
 33   
 34  from ClusterShell.CLI.Display import Display, THREE_CHOICES 
 35  from ClusterShell.CLI.Error import GENERIC_ERRORS, handle_generic_error 
 36  from ClusterShell.CLI.OptionParser import OptionParser 
 37  from ClusterShell.CLI.Utils import NodeSet, nodeset_cmp 
 38   
 39   
40 -def display_tree(tree, disp, out):
41 """display sub-routine for clubak -T (msgtree trace mode)""" 42 togh = True 43 offset = 2 44 reldepth = -offset 45 reldepths = {} 46 line_mode = disp.line_mode 47 for msgline, keys, depth, nchildren in tree.walk_trace(): 48 if togh: 49 if depth in reldepths: 50 reldepth = reldepths[depth] 51 else: 52 reldepth = reldepths[depth] = reldepth + offset 53 if line_mode: 54 out.write("%s:\n" % NodeSet.fromlist(keys)) 55 else: 56 out.write("%s\n" % \ 57 (disp.format_header(NodeSet.fromlist(keys), reldepth))) 58 out.write("%s%s\n" % (" " * reldepth, msgline)) 59 togh = nchildren != 1
60
61 -def display(tree, disp, gather, trace_mode, enable_nodeset_key):
62 """nicely display MsgTree instance `tree' content according to 63 `disp' Display object and `gather' boolean flag""" 64 out = sys.stdout 65 try: 66 if trace_mode: 67 display_tree(tree, disp, out) 68 else: 69 if gather: 70 if enable_nodeset_key: 71 # lambda to create a NodeSet from keys returned by walk() 72 ns_getter = lambda x: NodeSet.fromlist(x[1]) 73 for nodeset in sorted(imap(ns_getter, tree.walk()), 74 cmp=nodeset_cmp): 75 disp.print_gather(nodeset, tree[nodeset[0]]) 76 else: 77 for msg, key in tree.walk(): 78 disp.print_gather_keys(key, msg) 79 else: 80 if enable_nodeset_key: 81 # nodes are automagically sorted by NodeSet 82 for node in NodeSet.fromlist(tree.keys()).nsiter(): 83 disp.print_gather(node, tree[str(node)]) 84 else: 85 for key in tree.keys(): 86 disp.print_gather_keys([ key ], tree[key]) 87 finally: 88 out.flush()
89
90 -def clubak():
91 """script subroutine""" 92 93 # Argument management 94 parser = OptionParser("%prog [options]") 95 parser.install_display_options(verbose_options=True, 96 separator_option=True, 97 dshbak_compat=True, 98 msgtree_mode=True) 99 options = parser.parse_args()[0] 100 101 if options.interpret_keys == THREE_CHOICES[-1]: # auto? 102 enable_nodeset_key = None # AUTO 103 else: 104 enable_nodeset_key = (options.interpret_keys == THREE_CHOICES[1]) 105 106 # Create new message tree 107 if options.trace_mode: 108 tree_mode = MODE_TRACE 109 else: 110 tree_mode = MODE_DEFER 111 tree = MsgTree(mode=tree_mode) 112 fast_mode = options.fast_mode 113 if fast_mode: 114 if tree_mode != MODE_DEFER or options.line_mode: 115 parser.error("incompatible tree options") 116 preload_msgs = {} 117 118 # Feed the tree from standard input lines 119 for line in sys.stdin: 120 try: 121 linestripped = line.rstrip('\r\n') 122 if options.verbose or options.debug: 123 print "INPUT %s" % linestripped 124 key, content = linestripped.split(options.separator, 1) 125 key = key.strip() 126 if not key: 127 raise ValueError("no node found") 128 if enable_nodeset_key is False: # interpret-keys=never? 129 keyset = [ key ] 130 else: 131 try: 132 keyset = NodeSet(key) 133 except NodeSetParseError: 134 if enable_nodeset_key: # interpret-keys=always? 135 raise 136 enable_nodeset_key = False # auto => switch off 137 keyset = [ key ] 138 if fast_mode: 139 for node in keyset: 140 preload_msgs.setdefault(node, []).append(content) 141 else: 142 for node in keyset: 143 tree.add(node, content) 144 except ValueError, ex: 145 raise ValueError("%s (\"%s\")" % (ex, linestripped)) 146 147 if fast_mode: 148 # Messages per node have been aggregated, now add to tree one 149 # full msg per node 150 for key, wholemsg in preload_msgs.iteritems(): 151 tree.add(key, '\n'.join(wholemsg)) 152 153 # Display results 154 try: 155 disp = Display(options) 156 if options.debug: 157 std_group_resolver().set_verbosity(1) 158 print >> sys.stderr, \ 159 "clubak: line_mode=%s gather=%s tree_depth=%d" % \ 160 (bool(options.line_mode), bool(disp.gather), tree._depth()) 161 display(tree, disp, disp.gather or disp.regroup, \ 162 options.trace_mode, enable_nodeset_key is not False) 163 except ValueError, exc: 164 parser.error("option mismatch (%s)" % exc)
165
166 -def main():
167 """main script function""" 168 try: 169 clubak() 170 except GENERIC_ERRORS, ex: 171 sys.exit(handle_generic_error(ex)) 172 except ValueError, ex: 173 print >> sys.stderr, "%s:" % sys.argv[0], ex 174 sys.exit(1) 175 176 sys.exit(0)
177 178 179 if __name__ == '__main__': 180 main() 181