AVMaster/lib/core/VMManager.py
import subprocess
import sys
import os
from time import sleep
from datetime import datetime
from ConfigParser import ConfigParser
from pysphere import VIServer
class vSphere:
hostname = ""
username = ""
password = ""
def __init__(self, vm_path):
self.vm_path = vm_path
def __enter__(self):
self.server = VIServer()
self.server.connect(self.hostname, self.username, self.password)
print "DBG connect"
vm = self.server.get_vm_by_path(self.vm_path)
return vm
def __exit__(self, type, value, traceback):
try:
self.server.disconnect()
print "DBG disconnect"
except VIException as e:
print "DBG problem in disconnection. Fault is: %s" % e.fault
pass
class VMRun:
def __init__(self, config_file):
self.config = ConfigParser()
self.config.read(config_file)
self.path = self.config.get("vsphere", "path")
self.host = self.config.get("vsphere", "host")
self.domain = self.config.get("vsphere", "domain")
self.user = self.config.get("vsphere", "user")
self.passwd = self.config.get("vsphere", "passwd")
def _run_cmd(self, vmx, cmd, args=[], vmx_creds=[], popen=False, bg=False, timeout=40):
pargs = [ self.path,
"-T", "vc",
"-h", self.host,
"-u", "%s\\%s" % (self.domain,self.user), "-p", self.passwd, cmd, vmx.path ]
if vmx_creds != [] and len(vmx_creds) == 2:
idx = pargs.index("-p")+2
cred = "-gu %s -gp %s" % ( vmx_creds[0], vmx_creds[1] )
pargs = pargs[0:idx] + cred.split() + pargs[idx:]
pargs.extend(args)
if popen == True:
return self._run_popen(pargs, timeout)
elif bg == True:
print "DBG running in bg mode"
return self._run_bg(pargs)
else:
return self._run_call(pargs)
def _run_call(self, pargs):
return subprocess.call(pargs)
def _run_bg(self, pargs):
subprocess.Popen(pargs, stdout=subprocess.PIPE)
def _run_popen(self, pargs, timeout=40):
p = subprocess.Popen(pargs, stdout=subprocess.PIPE)
executed = False
tick = 0
while executed is False:
sleep(20)
tick += 1
if p.poll() != None: #process is executed and ret.poll() has the return code
executed = True
if tick >= timeout * 3:
print "DBG run_popen timeout"
return []
if p.poll() == 0:
return p.communicate()[0]
else:
print "DBG p.poll is 0"
return []
def startup(self, vmx):
sys.stdout.write("[%s] Starting!\r\n" % vmx)
self._run_cmd(vmx, "start")
def shutdown(self, vmx):
sys.stdout.write("[%s] Stopping!\r\n" % vmx)
self._run_cmd(vmx, "stop")
def shutdownUpgrade(self, vmx):
r = self.executeCmd(vmx, "c:\\WINDOWS\\system32\\shutdown.exe", ["/s"], timeout=105) #["/s","/t","0"])
if r is False:
print "DBG executeCmd failed for %s" % vmx
return False
return True
def reboot(self, vmx):
sys.stdout.write("[%s] Rebooting!\r\n" % vmx)
self._run_cmd(vmx, "reset", ["hard"])
def suspend(self, vmx):
sys.stdout.write("[%s] Suspending!\r\n" % vmx)
self._run_cmd(vmx, "suspend", ["soft"])
def createSnapshot(self, vmx, snapshot):
sys.stdout.write("[%s] Creating snapshot %s.\n" % (vmx, snapshot))
self._run_cmd(vmx, "snapshot", [snapshot])
def deleteSnapshot(self, vmx, snapshot):
sys.stdout.write("[%s] Deleting snapshot %s.\n" % (vmx, snapshot))
self._run_cmd(vmx, "deleteSnapshot", [snapshot])
def revertSnapshot(self, vmx, snapshot):
sys.stdout.write("[%s] Reverting snapshot %s.\n" % (vmx, snapshot))
self._run_cmd(vmx, "revertToSnapshot", [snapshot])
def refreshSnapshot(self, vmx, delete=True):
untouchables = [ "ready", "activated", "_datarecovery_" ]
sys.stdout.write("[%s] Refreshing snapshot.\n" % vmx)
# create new snapshot
date = datetime.now().strftime('%Y%m%d-%H%M')
self.createSnapshot(vmx, "%s" % date)
if delete == True:
snaps = self.listSnapshots(vmx)
print "DBG snapshots %s" % snaps
if len(snaps) > 0 and snaps[-2] not in untouchables and "manual" not in snaps[-2]:
print "DBG deleting %s" % snaps[-2]
self.deleteSnapshot(vmx, snaps[-2])
def revertLastSnapshot(self,vmx):
snap = self.listSnapshots(vmx)
if len(snap) > 0:
for s in range(len(snap)-1,-1,-1):
snapshot = snap[s]
if snapshot != "_datarecovery_":
self.revertSnapshot(vmx, snap[s])
return "[%s] Reverted with snapshot %s" % (vmx, snap[s])
else:
print "DBG snapshot _datarecovery_ found!"
return "[%s] ERROR: no more snapshot to try" % vmx
else:
return "[%s] ERROR: no snapshots!" % vmx
def mkdirInGuest(self, vmx, dir_path):
sys.stdout.write("[%s] Creating directory %s.\n" % (vmx,dir_path))
self._run_cmd(vmx, "CreateDirectoryInGuest", [dir_path], [vmx.user,vmx.passwd])
def listDirectoryInGuest(self, vmx, dir_path):
sys.stdout.write("[%s] Listing directory %s.\n" % (vmx,dir_path))
return self._run_cmd(vmx, "listDirectoryInGuest", [dir_path], [vmx.user,vmx.passwd], popen=True)
def deleteDirectoryInGuest(self, vmx, dir_path):
sys.stdout.write("[%s] Delete directory %s.\n" % (vmx,dir_path))
self._run_cmd(vmx, "DeleteDirectoryInGuest", [dir_path], [vmx.user,vmx.passwd])
def copyFileToGuest(self, vmx, src_file, dst_file):
sys.stdout.write("[%s] Copying file from %s to %s.\n" % (vmx, src_file, dst_file))
self._run_cmd(vmx, "CopyFileFromHostToGuest", [src_file, dst_file], [vmx.user, vmx.passwd])
def copyFileFromGuest(self, vmx, src_file, dst_file):
sys.stdout.write("[%s] Copying file from %s to %s.\n" % (vmx, src_file, dst_file))
self._run_cmd(vmx, "CopyFileFromGuestToHost", [src_file, dst_file], [vmx.user, vmx.passwd])
def executeCmd(self, vmx, cmd, args=[], timeout=40, interactive=False, bg=False):
sys.stdout.write("[%s] Executing %s\n" % (vmx,cmd))
cmds = []
if interactive is True:
cmds.append("-interactive")
cmds.append(cmd)
cmds.extend(args)
print "DBG background execution is %s" % bg
return self._run_cmd(vmx,
"runProgramInGuest",
cmds,
[vmx.user, vmx.passwd],
bg=bg, timeout=timeout)
def listProcesses(self, vmx):
sys.stdout.write("[%s] List processes\n" % vmx)
return self._run_cmd(vmx, "listProcessesInGuest", vmx_creds=[vmx.user,vmx.passwd], popen=True)
def takeScreenshot(self, vmx, out_img):
sys.stdout.write("[%s] Taking screenshot.\n" % vmx)
self._run_cmd(vmx, "captureScreen", [out_img], [vmx.user, vmx.passwd])
def VMisRunning(self, vmx):
res = self._run_cmd(vmx, "list", popen=True)
if vmx.path[1:-1] in res:
return True
return False
def listSnapshots(self, vmx):
out = self._run_cmd(vmx, "listSnapshots", popen=True).split("\n")
return out[1:-1]