import os
import sys
import time
import re
from PyQt4.QtCore import *
from PyQt4.QtXml import QDomDocument
from sface.config import config
from sface.logwindow import LogIO
from sface.rspecwindow import RSpecWindow, DomModel
def find_executable(exec_name):
"""find the given executable in $PATH"""
paths = os.getenv("PATH").split(':')
for p in paths:
exec_path = os.path.join(p, exec_name)
if os.path.exists(exec_path):
return exec_path
return None
class SfiProcess(QObject):
def __init__(self, parent=None):
QObject.__init__(self, parent)
self.process = QProcess()
self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"),
self.processFinished)
self.xmltracker = XmlTracker()
def __init_command(self, args):
self.args = QStringList()
for arg in args:
self.args << QString(arg)
self.exe = find_executable("sfi.py")
if not self.exe:
print "FATAL.. Could not locate binary sfi.py - not much we can do without that"
def isRunning(self):
return self.process.state() != QProcess.NotRunning
def processFinished(self):
if self.process.exitStatus() == QProcess.CrashExit:
print self.readOutput()
print "Process exited with errors:",
err = self.process.error()
if err == QProcess.FailedToStart:
print "FailedToStart"
elif err == QProcess.Crashed:
print "Crashed"
elif err == QProcess.Timedout:
print "Timedout"
elif err == QProcess.WriteError:
print "WriteError"
elif err == QProcess.ReadError:
print "ReadError"
elif err == QProcess.UnknownError:
print "UnknownError"
self.trace_end()
self.emit(SIGNAL("finished()"))
def __getRSpec(self, mgr):
slice = config.getSlice()
# Write RSpec to file for testing.
filename = os.path.expanduser("~/.sfi/" + slice + ".rspec")
try:
os.remove(filename)
except:
pass
args = ["-u", config.getUser(), "-a", config.getAuthority(),
"-r", config.getRegistry(), "-s", mgr, "resources",
"-o", filename, slice]
self.__init_command(args)
self.start()
return filename
def getRSpecFromSM(self):
return self.__getRSpec(config.getSlicemgr())
def getRSpecFromAM(self):
return self.__getRSpec(config.getAggmgr())
def getRecord(self, hrn):
args = ["-u", config.getUser(), "-a", config.getAuthority(),
"-r", config.getRegistry(), "-s", config.getSlicemgr(), "show", hrn]
self.__init_command(args)
self.start()
def applyRSpec(self, rspec):
filename = config.getSliceRSpecFile() + "_new"
rspec.save(filename)
args = ["-u", config.getUser(), "-a", config.getAuthority(),
"-r", config.getRegistry(), "-s", config.getSlicemgr(), "create",
config.getSlice(), filename]
self.__init_command(args)
self.start()
return filename
def start(self):
self.args.prepend(QString('-D'))
self.trace_command()
self.process.start(self.exe, self.args)
print self.args
def readOutput(self):
if self.process.state() == QProcess.NotRunning:
return self.process.readAll()
def trace_command (self):
if config.verbose:
self._trace=time.time()
command = "%s %s" % (self.exe, self.args.join(" "))
print time.strftime('%M:%S'),'Invoking',command
#self.xmltracker.startTracking()
#print "tracking"
def trace_end (self):
if config.verbose:
#print "stop tracking"
#self.xmltracker.stopTracking()
command = "%s %s" % (self.exe, self.args.join(" "))
print time.strftime('%M:%S'),"[%.3f s]"%(time.time()-self._trace),command,'Done'
self.xmltracker.getAndPrint(self.process.readAllStandardOutput())
class XmlTracker():
def __init__(self):
self.xmlrpcwindow = XmlrpcWindow()
def getAndPrint(self, rawOutput):
self.store(rawOutput)
self.extractXml()
self.xmlrpcwindow.setData(self.xml)
self.showXmlrpc()
self.test()
def showXmlrpc(self):
# set all camel case
self.xmlrpcwindow.show()
self.xmlrpcwindow.resize(500, 640)
self.xmlrpcwindow.raise_()
self.xmlrpcwindow.activateWindow()
def store(self, rawOutput):
self.rawOutput = rawOutput
def extractXml(self):
pttrnAsk = '.*?'
pttrnAns = '.*?'
answers = re.compile(pttrnAsk, re.DOTALL).findall(self.rawOutput)
replies = re.compile(pttrnAns, re.DOTALL).findall(self.rawOutput)
# cleaning
answers = map(lambda x: x.replace('\\n','\n'), answers)
replies = map(lambda x: x.replace('\\n','\n').replace("'body: '", ''), replies)
# A well-formed XML document must have one, and only one, top-level element
self.xml = ''
for ans in answers:
self.xml += ans + replies.pop()
self.xml += ''
def test(self):
print self.xml
def stats(self):
# statistics: round-trip time, size of the com
pass
def prettyPrint(self, XmlComs):
# just for testing
print XmlComs
class XmlrpcWindow(RSpecWindow):
def __init__(self, parent=None):
# super __init__() calls updateView,
# which assumes you have some data
self.data = ''
RSpecWindow.__init__(self, parent)
def setData(self, XmlrpcCom):
self.data = XmlrpcCom
def updateView(self):
del self.document
del self.model
self.document = None
self.model = None
self.document = QDomDocument("RSpec")
self.document.setContent(self.data)
self.model = DomModel(self.document, self)
self.view.setModel(self.model)
self.view.expand(self.model.index(0, 0)) #expand first level only