labcalcoloctl 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #!/usr/bin/python
  2. ##Author: Elisa Aliverti
  3. ##Last edit: 22/02/2017 - Silva
  4. from time import time
  5. import argparse
  6. import textwrap
  7. import os
  8. import subprocess, sys
  9. from threading import Thread
  10. from getpass import getpass
  11. choices = ('status','start','stop', 'doctor')
  12. parser = argparse.ArgumentParser(usage='labcalcolo {'+','.join(choices)+'} [options]')
  13. ## positional arguments
  14. parser.add_argument( 'cmd', nargs="?", choices=choices, default='status',
  15. help='Specify command to execute, default is \'status\'' )
  16. ## optional arguments
  17. parser.add_argument( '-a', '--all', action='store_true', dest='lcm',
  18. help='All LCM nodes are considered' )
  19. parser.add_argument( '-n', nargs='+', dest='node',
  20. help='Select one or more nodes (at least one)' )
  21. parser.add_argument( '-1', '--lcm1', action='store_true', dest='lcm1',
  22. help='LCM1 nodes are considered' )
  23. parser.add_argument( '-2', '--lcm2', action='store_true', dest='lcm2',
  24. help='LCM2 nodes are considered' )
  25. parser.add_argument( '-v', '--version', action='version', version='%(prog)s 1.3',
  26. help='Print program version' )
  27. ##
  28. args = parser.parse_args()
  29. def print_progressbar(index, num) :
  30. sys.stdout.write('\r ['
  31. + '='*index
  32. + '>'*(1-int(index/num))
  33. + ' '*(num-index-1) + ']')
  34. sys.stdout.flush()
  35. ## main path (you don't say)
  36. main_path = "/var/etc/vmctl"
  37. class Host(Thread):
  38. # Constructor
  39. def __init__(self, name, location):
  40. # Fork the thread first thing
  41. Thread.__init__(self)
  42. # Variables initialization
  43. self.hostname = name
  44. self.location = location
  45. # Ping the host to see if it's up
  46. def isup(self):
  47. # Is the host up?
  48. ping = os.popen("ping -w1 -c1 " + self.hostname, "r")
  49. # print("pinging " self.hostname)
  50. if "0 received" in ping.read():
  51. return False
  52. else:
  53. return True
  54. def sshcommand(self, command):
  55. if self.isup():
  56. ssh = subprocess.Popen( ["ssh", "%s" % self.hostname, command],
  57. shell = False,
  58. stdout = subprocess.PIPE,
  59. stderr = subprocess.PIPE )
  60. return ssh
  61. else:
  62. print self.hostname + ' is not up.'
  63. return False
  64. def vmstart(self):
  65. if not self.vmstatus():
  66. startcmd = main_path + " 1"
  67. self.sshcommand(startcmd)
  68. print 'VM is now starting on ' + self.hostname
  69. else:
  70. print 'VM is already running on ' + self.hostname
  71. def vmstop(self):
  72. stopcmd = main_path + " 0"
  73. self.sshcommand(stopcmd)
  74. def vmstatus(self):
  75. statuscmd = "ps aux | grep qemu | grep -v grep"
  76. if self.isup():
  77. ssh = self.sshcommand(statuscmd)
  78. result = [ l for l in ssh.stdout.readlines() if 'qemu' in l ]
  79. if result == []:
  80. return False
  81. else:
  82. return True
  83. else:
  84. return -1
  85. def vmdoctor(self) :
  86. to_search=['qemu', 'spicec']
  87. # It's ugly, but it should not be necessary: passwords should not be visible from ps aux
  88. pw_remove=['s/,password=\w*$//', 's/-w \w*$//']
  89. # Build the status query with programs names and relative pw remove strings
  90. status_query="ps aux | grep -E '" + '|'.join(to_search) + "' | grep -v grep | sed '" + ';'.join(pw_remove)+ "'"
  91. if self.isup():
  92. ssh = self.sshcommand(status_query).stdout.readlines()
  93. qemu_status = [ l for l in ssh if 'qemu' in l ] # Filter for a single command
  94. if len(qemu_status) :
  95. print "Qemu command running on", self.hostname+":\n", qemu_status
  96. else :
  97. print "Qemu is not running on", self.hostname
  98. # Do we want to ask this? There's the start command to do this...
  99. #answer=raw_input("Do you want to start a VM now? [y/n] ")
  100. #if answer=="y" : self.vmstart()
  101. spicec_status = [ l for l in ssh if 'spicec' in l ]
  102. if not len(spicec_status) and len(qemu_status) :
  103. print "Spicec is not running on", self.hostname,
  104. if raw_input("Do you want to start it now? [y/n] ")=="y" :
  105. pw=getpass("Vm password: ")
  106. spiceccmd="export DISPLAY=:4 ; spicec -f -h 127.0.0.1 -p 5900 -w "+pw+" &"
  107. self.sshcommand(spiceccmd) # How to check if everything went as expected?
  108. # Check if everything works fine now
  109. spicec_status = [ l for l in self.sshcommand(status_query).stdout.readlines() if 'spicec' in l ]
  110. if len(spicec_status) :
  111. print "Spicec command running on", self.hostname+": ", spicec_status
  112. ### end class Host
  113. ## Host list
  114. Hosts = [
  115. Host('abe', 'LCM1'),
  116. Host('crash', 'LCM1'),
  117. Host('duke', 'LCM1'),
  118. Host('glados', 'LCM1'),
  119. Host('lara', 'LCM1'),
  120. Host('link', 'LCM1'),
  121. Host('king', 'LCM1'),
  122. Host('pang', 'LCM1'),
  123. Host('pong', 'LCM1'),
  124. Host('snake', 'LCM1'),
  125. Host('sonic', 'LCM1'),
  126. Host('spyro', 'LCM1'),
  127. Host('yoshi', 'LCM1'),
  128. Host('actarus', 'LCM2'),
  129. Host('elwood', 'LCM2'),
  130. Host('gex', 'LCM2'),
  131. Host('gin', 'LCM2'),
  132. Host('jake', 'LCM2'),
  133. Host('kirk', 'LCM2'),
  134. Host('martini', 'LCM2'),
  135. Host('picard', 'LCM2'),
  136. Host('q', 'LCM2'),
  137. Host('raziel', 'LCM2'),
  138. Host('sarek', 'LCM2'),
  139. Host('spock', 'LCM2'),
  140. Host('tron', 'LCM2'),
  141. Host('worf', 'LCM2'),
  142. Host('zombie', 'LCM2')
  143. ]
  144. nodes = []
  145. # Filter hostlist according to arguments
  146. if args.lcm:
  147. nodes = Hosts
  148. elif args.lcm1:
  149. nodes = [ host for host in Hosts if host.location == 'LCM1' ]
  150. elif args.lcm2:
  151. nodes = [ host for host in Hosts if host.location == 'LCM2' ]
  152. elif args.node:
  153. for i in args.node:
  154. for j in Hosts:
  155. if (i==j.hostname): nodes.append(j)
  156. # Run commands on nodes
  157. running=[]
  158. down=[]
  159. if args.cmd == 'status':
  160. start = time()
  161. num=len(nodes)
  162. index=0
  163. print ' Querying ' + str(num) + ' hosts...'
  164. for i in nodes:
  165. if i.vmstatus():
  166. running.append(i.hostname)
  167. if i.vmstatus()<0 :
  168. down.append(i.hostname)
  169. index += 1
  170. print_progressbar(index, num)
  171. # New line after progress bar
  172. print '\n Done... (%(t).3f s)' % {'t': (time() - start)}
  173. if len(running):
  174. print "VM(s) running on:"
  175. for i in running : print '\t',i
  176. else :
  177. print "No VMs are running"
  178. if len(down):
  179. print "Down nodes:"
  180. for i in down : print '\t',i
  181. elif args.cmd == 'start':
  182. for i in nodes: i.vmstart()
  183. elif args.cmd == 'stop':
  184. for i in nodes: i.vmstop()
  185. elif args.cmd == 'doctor' :
  186. for i in nodes : i.vmdoctor()