scratchall 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/python
  2. # Check for user's folder on the /local/scratch
  3. # 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
  4. # created: Andrea Silva (25-05-2017)
  5. # last edit: Andrea Silva (25-05-2017)
  6. from time import time
  7. import argparse
  8. import subprocess, sys, os, re
  9. from threading import Thread
  10. from re import sub
  11. sys.path.append("/home/150/scratch")
  12. from sshcmd2node import Node
  13. def print_progressbar(index, num) :
  14. sys.stderr.write('\r ['
  15. + '='*index
  16. + '>'*(1-int(index/num))
  17. + ' '*(num-index-1) + ']')
  18. sys.stderr.flush()
  19. ####################
  20. # COMMAND DEFINITION
  21. ####################
  22. scratchpath="/local/scratch/"
  23. checkscratch="find /local/scratch/ -type d -name "+os.getenv("USER")+" -maxdepth 1 -exec du -haxd 1 {} \;"
  24. ## Main program
  25. 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)
  26. If the nodes aren't in the ~/.ssh/know_hosts, you will be asked to continue
  27. (e.g. it's the first time you run this command)
  28. Use the -s flag to run in serial and answer ssh prompts"""
  29. ## Argument Parser definition
  30. parser = argparse.ArgumentParser(description=desc)
  31. # optional arguments
  32. parser.add_argument( '-n', nargs='+', dest='node', default=[],
  33. help='select one or more nodes by hostname (at least one)' )
  34. parser.add_argument( '-l', '--long', action='store_true', dest='long',
  35. help='be verbose: print subfolders and sizes' )
  36. parser.add_argument( '-p', '--disable-progbar', action='store_false', dest='progbar',
  37. help='disable the progression bar.' )
  38. parser.add_argument( '-s', '--serial', action='store_true', dest='serial',
  39. help="""Do the queries to nodes in serial rather than parallel (default).
  40. Hint: useful when connecting for the first time.
  41. Imply -p option.""" )
  42. # End arg parser definition
  43. args = parser.parse_args()
  44. if args.serial : args.progbar=False
  45. ### HOST LIST ###
  46. # Only edit here to add/remove/change hostlist
  47. Hosts = [
  48. ('abe', 'LCM1'),
  49. ('crash', 'LCM1'),
  50. ('duke', 'LCM1'),
  51. ('glados', 'LCM1'),
  52. ('lara', 'LCM1'),
  53. ('link', 'LCM1'),
  54. ('king', 'LCM1'),
  55. ('pang', 'LCM1'),
  56. ('pong', 'LCM1'),
  57. ('snake', 'LCM1'),
  58. ('sonic', 'LCM1'),
  59. ('spyro', 'LCM1'),
  60. ('yoshi', 'LCM1'),
  61. ('actarus', 'LCM2'),
  62. ('elwood', 'LCM2'),
  63. ('gex', 'LCM2'),
  64. ('gin', 'LCM2'),
  65. ('jake', 'LCM2'),
  66. ('kirk', 'LCM2'),
  67. ('martini', 'LCM2'),
  68. ('picard', 'LCM2'),
  69. ('q', 'LCM2'),
  70. ('raziel', 'LCM2'),
  71. ('sarek', 'LCM2'),
  72. ('spock', 'LCM2'),
  73. ('tron', 'LCM2'),
  74. ('worf', 'LCM2'),
  75. ('zombie', 'LCM2'),
  76. ]
  77. # Create nodes list according to options.
  78. ## All nodes
  79. nodes=[ Node(x[0],x[1], checkscratch) for x in Hosts ]
  80. ## Select given nodes
  81. if len(args.node) :
  82. nodes=[ x for x in nodes if x.hostname in args.node ]
  83. # Start time from here, when the threads are created
  84. start = time()
  85. # Start threads
  86. for i in nodes :
  87. i.start()
  88. if args.serial: i.join()
  89. # Get results: rejoin threads when their work is done
  90. num=len(nodes)
  91. index=0
  92. print ' Querying ' + str(num) + ' hosts...'
  93. for i in nodes:
  94. i.join()
  95. index += 1
  96. if args.progbar : print_progressbar(index, num)
  97. # New line after progress bar
  98. print '\n Done... (%(t).3f s)' % {'t': (time() - start)}
  99. for n in nodes :
  100. if not n.up :
  101. print "==>", n.hostname, "is not up"
  102. continue
  103. exitcode,output,error = n.cmdresult
  104. # Ugly but works: if it's your folder, you don't have permission to read: filter it
  105. # FIXME: there's an option in find to look for folders owned by a certain user?
  106. if exitcode == 0 or (exitcode==1 and re.search("Permission denied", error)) :
  107. if len(output)>1 :
  108. totsize, fldname=output[-1].split()
  109. print "==>", n.hostname,"size:", totsize
  110. # If long output is required, print all the matcher ps aux lines
  111. if args.long:
  112. for process in output:
  113. print '\t', process
  114. else :
  115. # Ssh "bug" can't log in twice on the same node. Should use Telnet instead
  116. if re.search("Too many logins", '\n'.join(output)) :
  117. print "==> Too many logins on", n.hostname
  118. else :
  119. print >> sys.stderr, "Query to host", n.hostname,"exited with", exitcode
  120. if args.long:
  121. print >> sys.stderr, "stderr:", error, '\n', \
  122. "stdout", '\n'.join(output)