Anonymous avatar Anonymous committed 6b10db2

Change .. to : in job result uniquefier + munge non-printables + other fixes

Comments (0)

Files changed (1)

 #!/usr/bin/env python
-__author__   = '''James T. Dennis answrguy@gmail.com'''
-__version__  = '''0.01'''
-__homepage__ = '''http://
+##############################################################################
+'''Provide an easy way to concurrently run ssh jobs on a large number of 
+   targets, gather output, error messages and results from each and handle 
+   timeouts.
+'''
+
+__author__='''Jim Dennis <answrguy@gmail.com>'''
+__url__   ='''http://bitbucket.org/jimd/classh/'''
+__license___='''BSD'''
+
 
 from subprocess import Popen, PIPE
 from time import sleep, time
-import sys, os, signal
+import sys, os, string, signal
 ## from signal import alarm
 
 
         '''
         '''
         self.started = False
-        self.poolsize = 100
+        self.poolsize = 50
         self.pool = dict()         # for maintain host/process data
         self.results = dict()  
         self.jobtimeout = 300
            calling the gather method to save their results.  The key
            is used to keep track of each job even if multiple jobs
            go to the same target.  (If there are duplicate targets than
-           the additional keys will be of the form: hostname..XX)
+           the additional keys will be of the form: hostname:XX)
         '''
 
         while self.targets and len(self.pool.keys()) < self.poolsize:
             host  = key
             if key in self.results:
                 x = 0 
-                while key + '..' + str(x) in self.results:  # Unique-ify a key
+                while key + ':' + str(x) in self.results:  # Unique-ify a key
                     x += 1
-                key = key + '..' + str(x) 
+                key = key + ':' + str(x) 
             self.results[key] = {   # Placeholder  + start time
               'Job:': host,
               'Start': time() }
         '''Kill a subprocess which has exceeded its timeout
            called by poll()
         '''
-        ## TODO: import signal and do this using signal.SIGKILL
         debug('Killing %s' % proc.pid)
         try:
-            os.kill(proc.pid, 9)
+            os.kill(proc.pid, signal.SIGTERM)
         except OSError:
-            debug('Ignoring os.kill OSError')
+            debug('Trying SIGKILL!')
+            try:
+                os.kill(proc.pid, signal.SIGKILL)
+            except OSError:
+                debug('Ignoring os.kill OSError')
 
     def done(self):
         '''We're done when we have been started and
         return self.started and not len(self.pool.keys())
 
 
+# Use in print results to munge non-printable chars
+filter = string.maketrans(
+           string.translate(string.maketrans('',''),
+           string.maketrans('',''),string.printable[:-5]),
+           '.'*len(string.translate(string.maketrans('',''),
+           string.maketrans('',''),string.printable[:-5])))
+
+
 def print_results(key, res):
     errs = ' '.join(res['Err'].split('\n'))
     outs = ' '.join(res['Out'].split('\n')) 
-    errs = errs[:60]
-    outs = outs[:60]
+    errs = errs[:60].translate(filter)
+    outs = outs[:60].translate(filter)
 
-    pfix = ''.join(["%-40s" % key, "%-5s" % res['Ret'], 
-        "(%5.2d)" % (res['End'] - res['Start'])])
+    pfix = ''.join(["%-48s" % key, "%-5s" % res['Ret'], 
+        "(%s)" % ("%0.2f" % (res['End'] - res['Start']))])
     if res['Ret']:
-        print pfix, "\tErrors: ", errs
-    print pfix, "\tOutput: ", outs
+        print pfix, "\tErrors: ", errs[:40]
+    print pfix, "\tOutput: ", outs[:40]
             
 def summarize_results(res):
     success = 0
        Dispatch jobs to hosts and incrementally print
        results
     '''
+    start = time()
     if len(sys.argv[1:]) < 2:
         print >> sys.stderr, "Must specify a command and a list of hosts"
         sys.exit(1)
     while not job.done():
         completed = job.poll()
         sleep(0.2)
-
-	if completed:
+        if completed:
             for each in completed:
                 print_results(each, job.results[each])
         
     summarize_results(job.results)
+    print "Completed in %s seconds" % (time() - start)
        
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.