Browse Source

- Correct a couple of typos in the output.
- Changed the sshcommand function of Host class so that it returns the output of the ssh command instead of a boolean.
- Modified Host.vmstatus(): it now uses the sshcommand method instead of calling subprocess explicitly.
- Created a vmdoctor function: check out if qemu and spicec are running on the Host with ps aux.
It's not uncommon that qemu is working fine but spicec process is missing and the display is not exported.
If that's the case, Doctor suggest starting it. VM passwor is asked.
- Updated README to include this last feature

Andrea Silva 7 years ago
parent
commit
83b44a0f2a
2 changed files with 49 additions and 15 deletions
  1. 6 2
      README.md
  2. 43 13
      labcalcoloctl

+ 6 - 2
README.md

@@ -1,10 +1,14 @@
 # labcalcoloctl
 Simple tool to handle LabCalcolo's VMs.
 
-usage: labcalcolo [{status,start,stop}] [options]
+usage: labcalcolo [{status,start,stop,doctor}] [options]
 
 positional arguments:
-  {status,start,stop}  Specify command to execute, default is 'status'
+  {status,start,stop, doctor}  Specify command to execute, default is 'status'
+
+    status             check whether there are VMs running on the considered nodes
+    start, stop        start and stop VMs
+    doctor             check if qemu and spicec are running. If qemu is running, but spicec is not, ask if the want to start it
 
 optional arguments:
   -h, --help           show this help message and exit

+ 43 - 13
labcalcoloctl

@@ -1,7 +1,7 @@
 #!/usr/bin/python
 
 ##Author: Elisa Aliverti
-##Last edit: 14/02/2017 - Silva
+##Last edit: 22/02/2017 - Silva
 
 from time import time
 import argparse
@@ -9,11 +9,13 @@ import textwrap
 import os
 import subprocess, sys
 from threading import Thread
+from getpass import getpass
 
-parser = argparse.ArgumentParser(usage='labcalcolo [{status,start,stop}] [options]')
+choices = ('status','start','stop', 'doctor') 
+parser = argparse.ArgumentParser(usage='labcalcolo {'+','.join(choices)+'} [options]')
 
 ## positional arguments
-parser.add_argument( 'cmd', nargs="?", choices=('status','start','stop'), default='status', 
+parser.add_argument( 'cmd', nargs="?", choices=choices, default='status', 
                      help='Specify command to execute, default is \'status\'' )
 
 ## optional arguments
@@ -30,7 +32,7 @@ parser.add_argument( '-v', '--version', action='version', version='%(prog)s 1.3'
 ## 
 args = parser.parse_args()
 
-def progress_bar(index, num) :
+def print_progressbar(index, num) :
     sys.stdout.write('\r ['
                         + '='*index
                         + '>'*(1-int(index/num))
@@ -66,8 +68,10 @@ class Host(Thread):
        	         		 shell = False, 
                                  stdout = subprocess.PIPE,
                                  stderr = subprocess.PIPE )
+         return ssh
       else:
          print self.hostname + ' is not up.'
+         return False
 
    def vmstart(self):
       if not self.vmstatus():
@@ -84,10 +88,7 @@ class Host(Thread):
    def vmstatus(self):
       statuscmd = "ps aux | grep qemu | grep -v grep"
       if self.isup():
-         ssh = subprocess.Popen( ["ssh", "%s" % self.hostname, statuscmd],
-       	         		 shell = False,
-				 stdout = subprocess.PIPE,
-				 stderr = subprocess.PIPE )
+         ssh = self.sshcommand(statuscmd)
          result = [ l for l in ssh.stdout.readlines() if 'qemu' in l ]
          if result == []:
               return False
@@ -95,6 +96,36 @@ class Host(Thread):
               return True
       else:
           return -1
+    
+   def vmdoctor(self) :
+      to_search=['qemu', 'spicec']
+      # It's ugly, but it should not be necessary: passwords should not be visible from ps aux
+      pw_remove=['s/,password=\w*$//', 's/-w \w*$//']
+      # Build the status query with programs names and relative pw remove strings
+      status_query="ps aux | grep -E '" + '|'.join(to_search) + "' | grep -v grep | sed '" + ';'.join(pw_remove)+ "'"
+      if self.isup():
+        ssh = self.sshcommand(status_query).stdout.readlines()
+        qemu_status = [ l for l in ssh if 'qemu' in l ] # Filter for a single command
+        if len(qemu_status) :
+            print "Qemu command running on", self.hostname+":\n", qemu_status 
+        else :
+            print "Qemu is not running on", self.hostname
+            # Do we want to ask this? There's the start command to do this...
+            #answer=raw_input("Do you want to start a VM now? [y/n] ")
+            #if answer=="y" : self.vmstart()
+
+        spicec_status = [ l for l in ssh if 'spicec' in l ]
+        if not len(spicec_status) and len(qemu_status) :
+            print "Spicec is not running on", self.hostname, 
+            if raw_input("Do you want to start it now? [y/n] ")=="y" :
+                pw=getpass("Vm password: ")
+                spiceccmd="export DISPLAY=:4 ; spicec -f -h 127.0.0.1 -p 5900 -w "+pw+" &"
+                self.sshcommand(spiceccmd) # How to check if everything went as expected?
+                # Check if everything works fine now
+                spicec_status = [ l for l in self.sshcommand(status_query).stdout.readlines() if 'spicec' in l ]
+        if len(spicec_status) :
+            print "Spicec command running on", self.hostname+": ", spicec_status
+
 ### end class Host
 
 ## Host list
@@ -158,14 +189,12 @@ if args.cmd == 'status':
         if i.vmstatus()<0 :
           down.append(i.hostname)
         index += 1
-        progress_bar(index, num)
+        print_progressbar(index, num)
     # New line after progress bar     
     print '\n Done... (%(t).3f s)' % {'t': (time() - start)}
 
-  
-
     if len(running):
-        print "VM running on:"
+        print "VM(s) running on:"
         for i in running : print '\t',i
     else :
         print "No VMs are running"
@@ -177,4 +206,5 @@ elif args.cmd == 'start':
    for i in nodes: i.vmstart()
 elif args.cmd == 'stop':
    for i in nodes: i.vmstop()
-
+elif args.cmd == 'doctor' :
+   for i in nodes : i.vmdoctor()