#!/usr/bin/python # Check for user's folder on the /local/scratch # FIXME: ssh command is good if you're root from a server. User-side tool should use a telenet service to avoid 'Too many login' problems and password prompt if someone does not have keys # created: Andrea Silva (25-05-2017) # last edit: Andrea Silva (25-05-2017) from time import time import argparse import subprocess, sys, os, re from threading import Thread from re import sub sys.path.append("/home/150/scratch") from sshcmd2node import Node def print_progressbar(index, num) : sys.stderr.write('\r [' + '='*index + '>'*(1-int(index/num)) + ' '*(num-index-1) + ']') sys.stderr.flush() #################### # COMMAND DEFINITION #################### scratchpath="/local/scratch/" checkscratch="find /local/scratch/ -type d -name "+os.getenv("USER")+" -maxdepth 1 -exec du -haxd 1 {} \;" ## Main program desc="""Check if there's a folder with the same name as the user on the /local/scratch disk of the given node (defaul all) If the nodes aren't in the ~/.ssh/know_hosts, you will be asked to continue (e.g. it's the first time you run this command) Use the -s flag to run in serial and answer ssh prompts""" ## Argument Parser definition parser = argparse.ArgumentParser(description=desc) # optional arguments parser.add_argument( '-n', nargs='+', dest='node', default=[], help='select one or more nodes by hostname (at least one)' ) parser.add_argument( '-l', '--long', action='store_true', dest='long', help='be verbose: print subfolders and sizes' ) parser.add_argument( '-p', '--disable-progbar', action='store_false', dest='progbar', help='disable the progression bar.' ) parser.add_argument( '-s', '--serial', action='store_true', dest='serial', help="""Do the queries to nodes in serial rather than parallel (default). Hint: useful when connecting for the first time. Imply -p option.""" ) # End arg parser definition args = parser.parse_args() if args.serial : args.progbar=False ### HOST LIST ### # Only edit here to add/remove/change hostlist Hosts = [ ('abe', 'LCM1'), ('crash', 'LCM1'), ('duke', 'LCM1'), ('glados', 'LCM1'), ('lara', 'LCM1'), ('link', 'LCM1'), ('king', 'LCM1'), ('pang', 'LCM1'), ('pong', 'LCM1'), ('snake', 'LCM1'), ('sonic', 'LCM1'), ('spyro', 'LCM1'), ('yoshi', 'LCM1'), ('actarus', 'LCM2'), ('elwood', 'LCM2'), ('gex', 'LCM2'), ('gin', 'LCM2'), ('jake', 'LCM2'), ('kirk', 'LCM2'), ('martini', 'LCM2'), ('picard', 'LCM2'), ('q', 'LCM2'), ('raziel', 'LCM2'), ('sarek', 'LCM2'), ('spock', 'LCM2'), ('tron', 'LCM2'), ('worf', 'LCM2'), ('zombie', 'LCM2'), ] # Create nodes list according to options. ## All nodes nodes=[ Node(x[0],x[1], checkscratch) for x in Hosts ] ## Select given nodes if len(args.node) : nodes=[ x for x in nodes if x.hostname in args.node ] # Start time from here, when the threads are created start = time() # Start threads for i in nodes : i.start() if args.serial: i.join() # Get results: rejoin threads when their work is done num=len(nodes) index=0 print ' Querying ' + str(num) + ' hosts...' for i in nodes: i.join() index += 1 if args.progbar : print_progressbar(index, num) # New line after progress bar print '\n Done... (%(t).3f s)' % {'t': (time() - start)} for n in nodes : if not n.up : print "==>", n.hostname, "is not up" continue exitcode,output,error = n.cmdresult # Ugly but works: if it's your folder, you don't have permission to read: filter it # FIXME: there's an option in find to look for folders owned by a certain user? if exitcode == 0 or (exitcode==1 and re.search("Permission denied", error)) : if len(output)>1 : totsize, fldname=output[-1].split() print "==>", n.hostname,"size:", totsize # If long output is required, print all the matcher ps aux lines if args.long: for process in output: print '\t', process else : # Ssh "bug" can't log in twice on the same node. Should use Telnet instead if re.search("Too many logins", '\n'.join(output)) : print "==> Too many logins on", n.hostname else : print >> sys.stderr, "Query to host", n.hostname,"exited with", exitcode if args.long: print >> sys.stderr, "stderr:", error, '\n', \ "stdout", '\n'.join(output)