Browse Source

Merge branch 'andreatsh'

Conflicts:
	whoall

 It looks like you may be committing a merge.
 If this is not correct, please remove the file
	.git/MERGE_HEAD
 and try again.

 Please enter the commit message for your changes. Lines starting
 with '#' will be ignored, and an empty message aborts the commit.
 On branch master
 Your branch is up-to-date with 'origin/master'.

 All conflicts fixed but you are still merging.

 Changes to be committed:
	modified:   whoall

 Untracked files:
	whoall.orig
Stefano Mandelli 8 years ago
parent
commit
d23b43642c
1 changed files with 283 additions and 326 deletions
  1. 283 326
      whoall

+ 283 - 326
whoall

@@ -1,375 +1,332 @@
-#!/usr/bin/env python2.7
-#python whoall
-#parallel, multi-threaded version
-#jacopogh - nov 2006
-#updated by various lcm admins & 150ers up to Nov 2015
-#requires python version 2.7 or above
-#please read the wiki before editing this file
-
-#take the starting time
-from time import time
+#!/usr/bin/python
+#
+# Python whoall: parallel, multi-threaded version
+# First author: jacopogh - nov 2006
+# Modified and updated by admins & 150 over time
+#
+# Requires python version 2.7 or above
+# Please read the wiki before editing this file
 
+from time import time
 start = time()
 
-#import needed modules
-import telnetlib
-from sys import argv,exit,stdout
-import getopt
+# Import needed modules
+import argparse
+import collections
 import os
+import telnetlib
+import textwrap
 from threading import Thread
 from socket import error
-import collections
-
-#important variables: gods, hosts and term colors
-gods = ['root','andreatsh','andreamalerba','lorenzouboldi','stefanobalzan','eugeniothieme']
-#former admins: bother them at your own risk
-chucknorris = [ 'agalli', 'ikki', 'buddino', 'alex', 'ema', 'ktf', 'davideg', 'jacopogh', 'lampo', 'gian', 'rbondesan', 'scolari', 'emanueleb', 'giani_matteo','gabryv','fran','alqahirah','giorgio_ruffa','palazzi','algebrato','blanc','blue','silviacotroneo'] 
+from sys import argv,exit,stdout
 
-#riordinati in ordine alfabetico - jp
+# Some array definitions
 lcm1 = ['abe','crash','duke','glados','lara','link','king','pang','pong','snake','sonic','spyro','yoshi']
 lcm2 = ['actarus','elwood','gex','gin','jake','kirk','martini','picard','q','raziel','sarek','spock','tron','worf','zombie']
 laur = ['eskimo','orion','tilde']
 
-cuda = ['jacobi','yukawa','tesla']
-math5 = ['abe','glados','link','king','pang','pong','snake','spyro','yoshi']
 math4 = ['sonic','crash','duke','raziel','actarus','gin','kirk','martini','picard','sarek','tron','worf','zombie','q','elwood','jake']
-math = math5 + math4
-condor = lcm1 + lcm2
-masterizzatori = ['crash','duke','spyro']
+math5 = ['abe','glados','link','king','pang','pong','snake','spyro','yoshi']
+math = math4 + math5
+
+cuda = ['jacobi','yukawa','tesla']
+
+
+# Important variables: gods, hosts and term colors
+gods = ['root','andreatsh','andreamalerba','lorenzouboldi','stefanobalzan','eugeniothieme']
+# Former admins: bother them at your own risk
+chucknorris = [ 'agalli', 'ikki', 'buddino', 'alex', 'ema', 'ktf', 'davideg', 'jacopogh', 'lampo', 'gian', 'rbondesan', 'scolari', 'emanueleb', 'giani_matteo','gabryv','fran','alqahirah','giorgio_ruffa','palazzi','algebrato','blanc','blue','silviacotroneo'] 
+
+
+parser = argparse.ArgumentParser( epilog='Please, report bugs or unwanted behavior to: working@lcm.mi.infn.it' )
+
+## Optional arguments
+parser.add_argument( '-1', '--lcm1', action='store_true', default=False, dest='lcm1', help='LCM1 hosts ' )
+parser.add_argument( '-2', '--lcm2', action='store_true', default=False, dest='lcm2', help='LCM2 hosts ' )
+parser.add_argument( '-l', '--laur', action='store_true', default=False, dest='laur', help='only LAUR hosts ' )
+parser.add_argument( '-c', '--condor', action='store_true', default=False, dest='condor', help='condor nodes '  )
+parser.add_argument( '-C', '--cuda', action='store_true', default=False, dest='cuda', help='only CUDA hosts ' )
+parser.add_argument( '-f', '--full', action='store_true', default=False, dest='full', help='empty, unreachable and unavailable info' )
+parser.add_argument( '-m', '--math', action='store_true', default=False, dest='math', help='only Mathematica hosts ' )
+parser.add_argument( '-n', action='store_true', default=False, dest='n', help='not display the progressbar and colors' )
+parser.add_argument( '-N', action='store_true', default=False, dest='N', help='also display number of logs' )
+parser.add_argument( '-v', '--version', action='version', version='%(prog)s 2.0', help='Print program version' )	   
+####
+
+args = parser.parse_args()
+
+hosts=[]
+
+if (( args.lcm1 and args.lcm2 ) or args.condor ) : hosts = lcm1 + lcm2 
+elif args.lcm1: hosts += lcm1
+elif args.lcm2: hosts += lcm2
+elif args.laur: hosts += laur
+elif args.cuda: hosts += cuda
+elif args.math: hosts += math
+else: hosts = lcm1 + lcm2 + laur + cuda
+
+if args.n:
+   splitters = [('jake','LCM1'),('gin','LCM2'),('jacobi','CUDA'),('orion','LAUR')]
+   progressbar = 0
+else: 
+   splitters = [('abe','\033[1;36mLCM1\033[0m'),('actarus','\033[1;32mLCM2\033[0m'),('jacobi','\033[1;35mCUDA\033[0m'),('eskimo','\033[1;33mLAUR\033[0m')]
+   progressbar = 1
+    
+# Define port
+port = 79 
 
 
 #############################################
-#Node class
-#the bulk of the program is done here
+# Node class
+# The bulk of the program is done here
 #############################################
 
 class Node(Thread):
-	#constructor
-	def __init__(self,nome,port):
-		#fork the thread first thing
-		Thread.__init__(self)
-		#variable initialization
-		self.hostname = nome
-		self.local = []
-		self.remote = []
-		self.lgod = []
-		self.rgod = []
-		#former admins
-		self.chuck = []
-		#node status
-		self.up = True
-		self.aval = True
-		self.port = port
-		self.timeout = False
-
-	#ping the host to see if it's up
-	def isup(self):
-		#is the host up?
-		ping = os.popen("ping -w1 -c1 "+self.hostname,"r")
-        	if "0 received" in ping.read():
-			self.up = False
-			return False
-		else:
-			return True
-	
-	#open telnet connection
-	def connect(self):
-		#try to connect first
-		try: 
-			self.conn = telnetlib.Telnet(self.hostname,self.port)
-		#inetd is down!
-		except error, msg:
-			self.aval = False
-			return False
-		return True
-	
-	#read lcm_w ouput and fill accordingly the users-gods lists
-	def read(self):	
-		#read data
-		lista=''
-		reachable=0
-		try: lista = self.conn.read_until("EOF",1)
-		except EOFError: reachable=1
-		del self.conn
-		
-		if lista=='':
-			if reachable == 0:
-				self.timeout=True	
-
-		#split lines and fields
-		righe = lista.splitlines()
-		#needed later for isempty
-		self.users = len(righe)
-
-		#local-remote-god user check
-		for x in righe:
-			fields = x.split()
-
-			if "tty" in fields[1]:
-				if fields[0] in gods:
-					self.lgod.append(fields[0].lower())
-				else:
-					if fields[0] not in chucknorris:
-						self.local.append(fields[0].lower())
-			else:
-				if fields[0] in gods:
-					if fields[0] not in self.lgod:
-						self.rgod.append(fields[0].lower())
-				else:
-					if fields[0] not in self.local:
-						if fields[0] not in chucknorris:
-							self.remote.append(fields[0].lower())
-				#former admins
-			if fields[0] in chucknorris:
-				self.chuck.append(fields[0].lower())
-	#run method
-	#this is the part that every thread executes in parallel
-	#if host is up -> open connection -> if connection -> read data
-	def run(self):
-		if self.isup(): 
-			if self.connect():
-				self.read()
-	
-	#is the host empty?
-	def isempty(self):
-		if (self.users > 0): 
-			return False
-		else:
-			return True
-
-	#print output giorgio-style, host based (after threads have finished)
-	def printlist(self):
-		#uniq equivalent and string conversion
-		strlocal = ""
-		strremote = ""
-		strlgod = ""
-		strrgod = ""
-		strchuck = ""
-		
-	
-		if "-N" not in str(params[0]):
-                        #a set cannot have duplicate entries: uniq equivalent
-                        for item in set(self.local):
-                                strlocal += str(item) + ' '
-                        for item in set(self.remote):
-                                strremote += str(item) +' '
-                        for item in set(self.lgod):
-                                strlgod += str(item) +' '
-                        for item in set(self.rgod):
-                                strrgod += str(item) +' '
-                        for item in set(self.chuck):
-                                strchuck += str(item) +' '
+    # Constructor
+    def __init__(self,nome,port):
+        # Fork the thread first thing
+        Thread.__init__(self)
+        # Variables initialization
+        self.hostname = nome
+        self.local = []
+        self.remote = []
+        self.lgod = []
+        self.rgod = []
+        # Former admins
+        self.chuck = []
+        # Node status
+        self.up = True
+        self.aval = True
+        self.port = port
+        self.timeout = False
+
+    # Ping the host to see if it's up
+    def isup(self):
+        # Is the host up?
+        ping = os.popen("ping -w1 -c1 "+self.hostname,"r")
+        if "0 received" in ping.read():
+            self.up = False
+            return False
+        else:
+            return True
+    
+    # Open telnet connection
+    def connect(self):
+        # Try to connect first
+        try: 
+            self.conn = telnetlib.Telnet(self.hostname,self.port)
+        # Inetd is down!
+        except error, msg:
+            self.aval = False
+            return False
+        return True
+    
+    # Read lcm_w ouput and fill accordingly the users-gods lists
+    def read(self):    
+        # Read data
+        lista=''
+        reachable=0
+        try: lista = self.conn.read_until("EOF",1)
+        except EOFError: reachable=1
+        del self.conn
+        
+        if lista=='':
+            if reachable == 0:
+                self.timeout=True    
+
+        # Split lines and fields
+        righe = lista.splitlines()
+        # Needed later for isempty
+        self.users = len(righe)
+
+        # Local-remote-god user check
+        for x in righe:
+            fields = x.split()
+
+            if "tty" in fields[1]:
+                if fields[0] in gods:
+                    self.lgod.append(fields[0].lower())
+                else:
+                    if fields[0] not in chucknorris:
+                        self.local.append(fields[0].lower())
+            else:
+                if fields[0] in gods:
+                    if fields[0] not in self.lgod:
+                        self.rgod.append(fields[0].lower())
                 else:
-                        #print also how many times users are logged (added by jp)
-                        for item in set(self.local):
-                                strlocal += str(item) + '('+str(collections.Counter(self.local).values()[collections.Counter(self.local).keys().index(item)])+') '
-                        for item in set(self.remote):
-                                strremote += str(item) +'('+str(collections.Counter(self.remote).values()[collections.Counter(self.remote).keys().index(item)])+') '
-                        for item in set(self.lgod):
-                                strlgod += str(item) +'('+str(collections.Counter(self.lgod).values()[collections.Counter(self.lgod).keys().index(item)])+') '
-                        for item in set(self.rgod):
-                                strrgod += str(item) +'('+str(collections.Counter(self.rgod).values()[collections.Counter(self.rgod).keys().index(item)])+') '
-                        for item in set(self.chuck):
-                                strchuck += str(item) +'('+str(collections.Counter(self.chuck).values()[collections.Counter(self.chuck).keys().index(item)])+') '
-
-		#routine that prints 64-bit nodes' names in yellow
-	#	if self.hostname in newcluster:
-	#		print ' ' + "\033[1;33m" + self.hostname + ' '*(15-len(self.hostname))+ red + strlgod + normal + pink + strrgod + normal + green + strlocal + normal + blue + strremote + normal+ turquoise+strchuck+normal
-	#	else:
-	
-		#print a tag [C] aside CUDA hosts (jp)
-		if self.hostname in cuda:
-			self.hostname = self.hostname + ' '*(5-len(self.hostname))+'[C]'
-
-		print ' ' + self.hostname + ' '*(15-len(self.hostname))+ red + strlgod + normal + pink + strrgod + normal + green + strlocal + normal + blue + strremote + normal+ turquoise+strchuck+normal
-		
+                    if fields[0] not in self.local:
+                        if fields[0] not in chucknorris:
+                            self.remote.append(fields[0].lower())
+            # Former admins
+            if fields[0] in chucknorris:
+                self.chuck.append(fields[0].lower())
+    # Run method
+    # This is the part that every thread executes in parallel
+    # If host is up -> open connection -> if connection -> read data
+    def run(self):
+        if self.isup(): 
+            if self.connect():
+                self.read()
+    
+    # Is the host empty?
+    def isempty(self):
+        if (self.users > 0): 
+            return False
+        else:
+            return True
+
+    # Print output giorgio-style, host based (after threads have finished)
+    def printlist(self):
+        # Uniq equivalent and string conversion
+        strlocal = ""
+        strremote = ""
+        strlgod = ""
+        strrgod = ""
+        strchuck = ""
+        
+    
+        if not args.N:
+            # A set cannot have duplicate entries: uniq equivalent
+            for item in set(self.local):
+                strlocal += str(item) + ' '
+            for item in set(self.remote):
+                strremote += str(item) +' '
+            for item in set(self.lgod):
+                strlgod += str(item) +' '
+            for item in set(self.rgod):
+                strrgod += str(item) +' '
+            for item in set(self.chuck):
+                strchuck += str(item) +' '
+        else:
+            # Print also how many times users are logged (added by jp)
+            for item in set(self.local):
+                strlocal += str(item) + '('+str(collections.Counter(self.local).values()[collections.Counter(self.local).keys().index(item)])+') '
+            for item in set(self.remote):
+                strremote += str(item) +'('+str(collections.Counter(self.remote).values()[collections.Counter(self.remote).keys().index(item)])+') '
+            for item in set(self.lgod):
+                strlgod += str(item) +'('+str(collections.Counter(self.lgod).values()[collections.Counter(self.lgod).keys().index(item)])+') '
+            for item in set(self.rgod):
+                strrgod += str(item) +'('+str(collections.Counter(self.rgod).values()[collections.Counter(self.rgod).keys().index(item)])+') '
+            for item in set(self.chuck):
+                strchuck += str(item) +'('+str(collections.Counter(self.chuck).values()[collections.Counter(self.chuck).keys().index(item)])+') '
+
+        # Print a tag [C] aside CUDA hosts (jp)
+        if self.hostname in cuda:
+            self.hostname = self.hostname + ' '*(5-len(self.hostname))+'[C]'
+
+        print ' ' + self.hostname + ' '*(15-len(self.hostname))+ red + strlgod + normal + pink + strrgod + normal + green + strlocal + normal + blue + strremote + normal+ turquoise+strchuck+normal
+
+
 ###################################################
-#main part
+# Main 
 ###################################################
 
 
-#get user groups
+# Get user groups
 groups = os.popen("groups").readlines()[0].split()
 
-#print usage info
-def Usage():
-	print 'Usage: '+argv[0]+' [flags]'
-	print ' -h\tthis help'
-	print ' -f\tempty, unreachable and unavailable info'
-	print ' -1\tonly LCM1 hosts'
-	print ' -2\tonly LCM2 hosts'
-	print ' -l\tonly LAUR hosts'
-	print ' -C\tonly CUDA hosts'
-	print ' -m\tonly mathematica hosts'
-	print ' -c\tonly condor hosts'
-	print ' -w\tonly hosts with cd burner'
-	print ' -n\tnot display the progressbar and colors'
-	print ' -N\talso display number of logs'
-	exit(1)
-
-#getopt
-try: params = getopt.getopt(argv[1:],'12lcCmfhkFnwN')
-except getopt.GetoptError:
-	print 'Wrong parameter'
-	Usage()
-
-#help mode (-h)
-if "-h" in str(params[0]): Usage()
-
-#kurt mode
-port = 79
-if "-k" in str(params[0]): port = 799
-
-#default (no options given)
-splitters = [('abe','\033[1;36mLCM1\033[0m'),('actarus','\033[1;32mLCM2\033[0m'),('jacobi','\033[1;35mCUDA\033[0m'),('eskimo','\033[1;33mLAUR\033[0m')]
-progressbar = 1
-
-hosts = []
-#boring: define the various cases
-if "-1" in str(params[0]): 
-	hosts += lcm1
-
-if "-2" in str(params[0]): 
-	hosts += lcm2
-
-if "-l" in str(params[0]): 
-	hosts += laur
-
-if "-C" in str(params[0]): 
-	hosts += cuda
-
-if "-m" in str(params[0]): 
-	hosts += math
-	#splitters = [('jake','LCM1'),('tilde','LCM2'),('wolfgang','LAUR')]
-	
-if "-c" in str(params[0]): 
-	hosts = condor
-	#splitters = [('jake','LCM1'),('gin','LCM2')]
-
-if "-w" in str(params[0]): 
-	hosts = masterizzatori
-	#splitters = [('actarus','LCM1'),('z','LCM2')]
-
-if "-n" in str(params[0]):
-	splitters = [('jake','LCM1'),('gin','LCM2'),('jacobi','CUDA'),('orion','LAUR')]
-	progressbar = 0
-
-#commented lines: CUDA hosts are printed only once under section 'CUDA', not also under 'LCM1/2'
-#for i in cuda:
-#	if i in lcm1:
-#		lcm1=lcm1[:lcm1.index(i)]+lcm1[lcm1.index(i)+1:]
-#	elif i in lcm2:
-#		lcm2=lcm2[:lcm2.index(i)]+lcm2[lcm2.index(i)+1:]
-#	elif i in laur:
-#		laur=laur[:laur.index(i)]+laur[laur.index(i)+1:]
-
-#default behaviour (no options given)
-if (hosts == []):
-	hosts = lcm1 + lcm2 + laur + cuda
-
-#setting colors
+# Setting colors
 if progressbar > 0:
-	red = "\033[1;31m"
-	normal = "\033[0m"
-	blue = "\033[1;34m"
-	pink = "\033[1;35m"
-	green = "\033[1;32m"
-	turquoise ="\033[1;36m"
+    red = "\033[1;31m"
+    normal = "\033[0m"
+    blue = "\033[1;34m"
+    pink = "\033[1;35m"
+    green = "\033[1;32m"
+    turquoise ="\033[1;36m"
 else:
-	red = ""
-	normal = ""
-	blue = ""
-	pink = ""
-	green = ""
-	turquoise =""
+    red = ""
+    normal = ""
+    blue = ""
+    pink = ""
+    green = ""
+    turquoise =""
 
 
-#initialization of the four lists
+# Initialization of the four lists
 downlist = ""
 emptylist = ""
 unavlist = ""
 timeoutlist = ""
 
-#initialize the threadlist
+# Initialize the threadlist
 threadlist = []
-	
-#number of hosts (for progressbar)
+
+# Number of hosts (for progressbar)
 num = len(hosts)
 
-#start the threads
+# Start the threads
 for item in hosts:
-	m=Node(item,port)
-	threadlist.append(m)
-	m.start()
+    m=Node(item,port)
+    threadlist.append(m)
+    m.start()
 
-#used for progressbar
+# Used for progressbar
 index = 0
 print ' Querying '+str(num)+' hosts...'
 
-#rejoin them when their work is done
+# Rejoin them when their work is done
 for thread in threadlist:
-	thread.join()
-	if progressbar > 0:
-		#progessbar
-		index += 1
-		stdout.write('\r ['+'='*index+'>'*(1-int(index/num))+' '*(num-index-1)+']')	
-		stdout.flush()
+    thread.join()
+    if progressbar > 0:
+        # Progessbar
+        index += 1
+        stdout.write('\r ['+'='*index+'>'*(1-int(index/num))+' '*(num-index-1)+']')    
+        stdout.flush()
 
 if progressbar > 0:
-	#newline
-	print '\n Done... ( %(t).3f s)' % {'t': (time() - start)}
+    # Newline
+    print '\n Done... ( %(t).3f s)' % {'t': (time() - start)}
 
-#and now print!
+# And now print!
 for thread in threadlist:
-	#lcm1-lcm2-laur splitters
-	for pair in splitters:
-		if thread.hostname in pair[0]: print '-' + pair[1] + normal +'----'
-	
-	#see what they are up to
-	#and print accordingly
-	
-	if thread.hostname in cuda:
-		thread.hostname +='[C]'
-	if "-m" in str(params[0]):
-		if thread.hostname in math4:
-			thread.hostname +='[M4]'
-		if thread.hostname in math5:
-	        	thread.hostname +='[M5]'
-	if not thread.up:
-		#host down
-		downlist += thread.hostname + ' '
-	else:
-		if not thread.aval:
-			#host unavailable
-			unavlist += thread.hostname + ' '
-			continue
-		if thread.timeout:
-			#thread has timed out
-			timeoutlist += thread.hostname + ' '
-			continue
-		if thread.isempty():
-			#host is empty
-			emptylist += thread.hostname + ' '
-		else:
-			thread.printlist()
-	
-#some final output
+    # lcm1-lcm2-laur splitters
+    for pair in splitters:
+        if thread.hostname in pair[0]: print '-' + pair[1] + normal +'----'
+    
+    # See what they are up to and print accordingly
+    if thread.hostname in cuda:
+        thread.hostname +='[C]'
+    if args.math :
+        if thread.hostname in math4:
+            thread.hostname +='[M4]'
+        if thread.hostname in math5:
+                thread.hostname +='[M5]'
+    if not thread.up:
+        # Host down
+        downlist += thread.hostname + ' '
+    else:
+        if not thread.aval:
+            # Host unavailable
+            unavlist += thread.hostname + ' '
+            continue
+        if thread.timeout:
+            # Thread has timed out
+            timeoutlist += thread.hostname + ' '
+            continue
+        if thread.isempty():
+            # Host is empty
+            emptylist += thread.hostname + ' '
+        else:
+            thread.printlist()
+    
+# Some final output
 if progressbar > 0:
-	print
-	print 'Legenda: '+green + 'utente locale '+normal+blue+'utente remoto '+normal+red+'admin locale '+normal+pink+'admin remoto '+normal+turquoise+'nirvana'+normal
-	print "         I nodi contrassegnati con [C] sono i nodi CUDA."
-	if "-m" in str(params[0]):
-		print "         I nodi contrassegnati con [M4] hanno Mathematica 4.0"
-		print "         I nodi contrassegnati con [M5] hanno Mathematica 5.2"
-#	print "         I nodi colorati in " + "\033[1;33mgiallo " + normal + "appartengono al cluster a 64bit"
-	print
-
-#only in full mode 
-if ("-f" in str(params[0])) or ("-F" in str(params[0])) or ("-m" in str(params[0])) or ("-C" in str(params[0])):
-	print red+'Empty: '+normal+emptylist
-	print red+'Timeout: '+normal+timeoutlist
-	print red+'Unreachable: '+normal+downlist
-	print red+'Unavailable: '+normal+unavlist
-
-#exit gracefully
+    print
+    print 'Legenda: '+green + 'utente locale '+normal+blue+'utente remoto '+normal+red+'admin locale '+normal+pink+'admin remoto '+normal+turquoise+'nirvana'+normal
+    print "         I nodi contrassegnati con [C] sono i nodi CUDA."
+    if args.math:
+        print "         I nodi contrassegnati con [M4] hanno Mathematica 4.0"
+        print "         I nodi contrassegnati con [M5] hanno Mathematica 5.2"
+    print
+
+# Only in full mode 
+#if ("-f" in str(params[0])) or ("-F" in str(params[0])) or ("-m" in str(params[0])) or ("-C" in str(params[0])):
+if args.full or args.math or args.cuda: 
+    print red+'Empty: '+normal+emptylist
+    print red+'Timeout: '+normal+timeoutlist
+    print red+'Unreachable: '+normal+downlist
+    print red+'Unavailable: '+normal+unavlist
+
+# Exit gracefully
 exit(0)
+