Merge branch 'master' of ssh://git.onelab.eu/git/sface
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 8 Sep 2011 12:25:19 +0000 (14:25 +0200)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 8 Sep 2011 12:25:19 +0000 (14:25 +0200)
1  2 
sface/sfiprocess.py
sface/sfirenew.py

diff --combined sface/sfiprocess.py
@@@ -5,7 -5,7 +5,7 @@@ import tim
  
  from PyQt4.QtCore import *
  from sface.config import config
- from sface.xmlrpcwindow import XmlrpcTracker
+ from sface.xmlrpcwindow import XmlrpcTracker, XmlrpcReader
  
  def find_executable(exec_name):
      """find the given executable in $PATH"""
@@@ -28,7 -28,8 +28,8 @@@ class SfiProcess(QObject)
          self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"),
                       self.processFinished)
  
-         self.xmlrpctracker = XmlrpcTracker()
+         self.xmlrpcreader = XmlrpcReader() # this one is for parsing XMLRPC responses
+         self.xmlrpctracker = XmlrpcTracker() # this one is for the debug window
  
          # holds aggregate output from processStandardOutput(); used by xmlrpc
          # tracker.
          self.args << "-d"
          self.args << config.get_dirname()
  
-         if config.debug:
-             # this shows xmlrpc conversation, see sfi.py docs.
-             self.args << QString('-D')
+         # this shows xmlrpc conversation, see sfi.py docs.
+         # always do this, so we can parse the XML result for faults and show
+         # then to the users.
+         self.args << QString('-D')
          for arg in args:
              self.args << QString(arg)
  
                  print "ReadError"
              elif err == QProcess.UnknownError:
                  print "UnknownError"
+         # extract any faults from the XMLRPC response(s)
+         self.xmlrpcreader.responses = []
+         self.xmlrpcreader.store(self.output)
+         self.xmlrpcreader.extractXml()
+         self.responses = self.xmlrpcreader.responses
+         self.faults = [x for x in self.responses if (x["kind"]=="fault")]
          self.trace_end()
          self.emit(SIGNAL("finished()"))
  
+     def getFaultString(self):
+         if self.faults == []:
+             return None
+         return self.faults[0].get("faultString","") + " (" + self.faults[0].get("faultCode","") + ")"
      def __getRSpec(self, mgr):
          slice = config.getSlice()
          # Write RSpec to file for testing.
 -        filename = os.path.expanduser("~/.sfi/" + slice + ".rspec")
 +        filename = config.fullpath ("%s.rspec"%slice)
          try:
              os.remove(filename)
          except:
          self.start()
  
      def start(self):
+         self.respones = []
+         self.faults = []
          self.output = ""
          self.trace_command()
          self.process.start(self.exe, self.args)
diff --combined sface/sfirenew.py
@@@ -6,20 -6,28 +6,28 @@@ import sy
  import time
  
  from PyQt4.QtCore import *
+ from PyQt4.QtGui import *
  from sface.config import config
  from sface.sfiprocess import SfiProcess
+ #from sface.sfithread import SfiThread
  
  class SfiRenewer(QObject):
      def __init__(self, hrn, newExpiration, parent=None):
          QObject.__init__(self, parent)
          self.hrn = hrn
          self.newExpiration = newExpiration
+         self.faultString = None
  
          self.renewProcess = SfiProcess(self)
          self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
          self.renewProcess.getRecord(hrn=config.getSlice(), filename="/tmp/slicerecord")
  
      def finishedGetRecord(self):
+         faultString = self.renewProcess.getFaultString()
+         if faultString:
+             self.emitFinished("fault", faultString)
+             return
          f = open("/tmp/slicerecord", "r")
          data = f.read()
          f.close()
          self.renewProcess.updateRecord("/tmp/slicerecord")
  
      def finishedUpdateRecord(self):
+         faultString = self.renewProcess.getFaultString()
+         if faultString:
+             self.emitFinished("fault", faultString)
+             return
          # we have to force sfi.py to download an updated slice credential
 -        sliceCredName = os.path.expanduser("~/.sfi/slice_" + self.hrn.split(".")[-1] + ".cred")
 +        sliceCredName = config.fullpath("slice_" + self.hrn.split(".")[-1] + ".cred")
          if os.path.exists(sliceCredName):
              os.remove(sliceCredName)
  
          self.renewProcess.renewSlivers(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
  
      def finishedRenewSlivers(self):
+         faultString = self.renewProcess.getFaultString()
+         if faultString:
+             self.emitFinished("fault", faultString)
+             return
          self.emitFinished("success")
  
      def emitFinished(self, status, statusMsg=None):
          self.statusMsg = statusMsg
          self.emit(SIGNAL("finished()"))
  
+ class RenewWindow(QDialog):
+     def __init__(self, parent=None):
+         super(RenewWindow, self).__init__(parent)
+         self.setWindowTitle("Renew Slivers")
+         self.renewProcess = None
+         self.duration = QComboBox()
+         self.expirations = []
+         durations = ( (1, "One Week"), (2, "Two Weeks"), (3, "Three Weeks"), (4, "One Month") )
+         now = datetime.datetime.utcnow()
+         for (weeks, desc) in durations:
+             exp = now + datetime.timedelta(days = weeks * 7)
+             desc = desc + " " + exp.strftime("%Y-%m-%d %H:%M:%S")
+             self.expirations.append(exp)
+             self.duration.addItem(desc)
+         self.duration.setCurrentIndex(0)
+         self.status = QLabel("")
+         self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+         self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
+         layout = QVBoxLayout()
+         layout.addWidget(self.duration)
+         layout.addWidget(self.status)
+         layout.addWidget(self.buttonBox)
+         self.setLayout(layout)
+         #self.status.hide()
+         self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
+         self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
+     def accept(self):
+         self.setStatus("Renewing Slice...")
+         self.renewProcess = SfiRenewer(config.getSlice(), self.get_new_expiration(), self)
+         self.connect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
+         self.duration.setEnabled(False)
+         self.buttonBox.setEnabled(False)
+     def setStatus(self, x):
+         self.status.setText(x)
+     def renewFinished(self):
+         if self.renewProcess.status == "success":
+             color = "green"
+             # give the user the <close> button
+             self.buttonBox.clear()
+             self.buttonBox.addButton(QDialogButtonBox.Close)
+         else:
+             color = "red"
+         if self.renewProcess.statusMsg:
+             self.setStatus("<font color='%s'>Renew %s: %s</font>" % (color, self.renewProcess.status, self.renewProcess.statusMsg))
+         else:
+             self.setStatus("<font color='%s'>Renew %s</font>" % (color, self.renewProcess.status))
+         self.buttonBox.setEnabled(True)
+         self.disconnect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
+         self.renewProcess = None
+     def get_new_expiration(self):
+         index = self.duration.currentIndex()
+         return self.expirations[index]