added renew slice mechanism
authorsmbaker <smbaker@fc8clean.lan>
Mon, 6 Jun 2011 21:12:09 +0000 (14:12 -0700)
committersmbaker <smbaker@fc8clean.lan>
Mon, 6 Jun 2011 21:12:09 +0000 (14:12 -0700)
sface/screens/mainscreen.py
sface/sfiprocess.py
sface/sfirenew.py [new file with mode: 0644]

index 92cd687..92c2a12 100644 (file)
@@ -1,4 +1,5 @@
 
+import datetime
 import os
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
@@ -6,6 +7,7 @@ from PyQt4.QtGui import *
 #from sfa.util.rspecHelper import RSpec
 from sfa.rspecs.rspec_parser import parse_rspec
 from sface.config import config
+from sface.sfirenew import SfiRenewer
 from sface.sfiprocess import SfiProcess
 from sface.screens.sfascreen import SfaScreen
 
@@ -230,11 +232,14 @@ class SliceWidget(QWidget):
 
         refresh = QPushButton("Update Slice Data", self)
         refresh.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+        renew = QPushButton("Renew Slice", self)
+        renew.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
         submit = QPushButton("Submit", self)
         submit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
 
         bottomlayout = QHBoxLayout()
         bottomlayout.addWidget(refresh, 0, Qt.AlignLeft)
+        bottomlayout.addWidget(renew, 0, Qt.AlignLeft)
         bottomlayout.addStretch()
         bottomlayout.addWidget(submit, 0, Qt.AlignRight)
 
@@ -246,6 +251,7 @@ class SliceWidget(QWidget):
         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
 
         self.connect(refresh, SIGNAL('clicked()'), self.refresh)
+        self.connect(renew, SIGNAL('clicked()'), self.renew)
         self.connect(submit, SIGNAL('clicked()'), self.submit)
         self.connect(searchbox, SIGNAL('textChanged(QString)'), self.filter)
         self.connect(self.nodeView, SIGNAL('hostnameClicked(QString)'),
@@ -358,7 +364,22 @@ class SliceWidget(QWidget):
 
         self.process.applyRSpec(rspec)
         self.setStatus("Sending slice data (RSpec). This will take some time...")
-        
+
+    def renew(self):
+        dlg = RenewWindow(parent=self)
+        if (dlg.exec_() == QDialog.Accepted):
+            self.setStatus("Renewing Slice.")
+
+            self.renewProcess = SfiRenewer(config.getSlice(), dlg.get_new_expiration(), self)
+            self.connect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
+
+    def renewFinished(self):
+        if self.renewProcess.statusMsg:
+            self.setStatus("Renew " + self.renewProcess.status + ": " + self.renewProcess.statusMsg)
+        else:
+            self.setStatus("Renew " + self.renewProcess.status)
+        self.disconnect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
+        self.renewProcess = None
 
     def refresh(self):
         if not config.getSlice():
@@ -450,6 +471,44 @@ class SliceWidget(QWidget):
     def nodeSelectionChanged(self, hostname):
         self.parent().nodeSelectionChanged(hostname)
 
+class RenewWindow(QDialog):
+    def __init__(self, parent=None):
+        super(RenewWindow, self).__init__(parent)
+        self.setWindowTitle("Renew Slivers")
+
+        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)
+
+        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+        buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
+
+        layout = QVBoxLayout()
+        layout.addWidget(self.duration)
+        layout.addWidget(buttonBox)
+        self.setLayout(layout)
+
+        self.connect(buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
+        self.connect(buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
+
+    def accept(self):
+        QDialog.accept(self)
+
+    def get_new_expiration(self):
+        index = self.duration.currentIndex()
+        return self.expirations[index]
+
 class MainScreen(SfaScreen):
     def __init__(self, parent):
         SfaScreen.__init__(self, parent)
@@ -459,7 +518,7 @@ class MainScreen(SfaScreen):
 
     def rspecUpdated(self):
         self.mainwin.rspecWindow.updateView()
-        
+
     def configurationChanged(self):
         self.widget.updateSliceName()
         self.widget.updateView()
index cd98a31..bef0902 100644 (file)
@@ -103,22 +103,38 @@ class SfiProcess(QObject):
 #    def getRSpecFromAM(self):
 #        return self.__getRSpec(config.getAggmgr())
 
-    def getRecord(self, hrn):
-        args = ["-u", config.getUser(), "-a", config.getAuthority(), 
+    def getRecord(self, hrn, filename=None):
+        args = ["-u", config.getUser(), "-a", config.getAuthority(),
                 "-r", config.getRegistry(), "-s", config.getSlicemgr(), "show", hrn]
+        if filename:
+            args.append("-o")
+            args.append(filename)
         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", 
+        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 updateRecord(self, filename):
+        args = ["-u", config.getUser(), "-a", config.getAuthority(),
+                "-r", config.getRegistry(), "-s", config.getSlicemgr(), "update", filename]
+        self.__init_command(args)
+        self.start()
+
+    def renewSlivers(self, expiration):
+        args = ["-u", config.getUser(), "-a", config.getAuthority(),
+                "-r", config.getRegistry(), "-s", config.getSlicemgr(), "renew",
+                config.getSlice(), expiration]
+        self.__init_command(args)
+        self.start()
+
     def start(self):
         self.trace_command()
         self.process.start(self.exe, self.args)
diff --git a/sface/sfirenew.py b/sface/sfirenew.py
new file mode 100644 (file)
index 0000000..863b253
--- /dev/null
@@ -0,0 +1,65 @@
+import calendar
+import datetime
+import os
+import re
+import sys
+import time
+
+from PyQt4.QtCore import *
+from sface.config import config
+from sface.sfiprocess import SfiProcess
+
+class SfiRenewer(QObject):
+    def __init__(self, hrn, newExpiration, parent=None):
+        QObject.__init__(self, parent)
+        self.hrn = hrn
+        self.newExpiration = newExpiration
+
+        self.renewProcess = SfiProcess(self)
+        self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
+        self.renewProcess.getRecord(hrn=config.getSlice(), filename="/tmp/slicerecord")
+
+    def finishedGetRecord(self):
+        f = open("/tmp/slicerecord", "r")
+        data = f.read()
+        f.close()
+
+        # find the expiration time
+        exp = re.compile('expires="[^"]*"')
+        if exp.search(data)==None:
+            # didn't find it
+            self.emitFinished("failure", "failed to find expiration in slice record")
+            return
+
+        # change the expiration time
+        delta = 24*60*60 # always extend the slice by one extra day to cover slop for time zone differences
+        data = exp.sub('expires="' + str(calendar.timegm(self.newExpiration.timetuple())+delta) + '"', data)
+
+        open("/tmp/slicerecord", "w").write(data)
+
+        self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
+        self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
+
+        self.renewProcess.updateRecord("/tmp/slicerecord")
+
+    def finishedUpdateRecord(self):
+        # we have to force sfi.py to download an updated slice credential
+        sliceCredName = os.path.expanduser("~/.sfi/slice_" + self.hrn.split(".")[-1] + ".cred")
+        if os.path.exists(sliceCredName):
+            os.remove(sliceCredName)
+
+        open("/tmp/expiration", "w").write(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
+
+        # call renewSlivers on the aggregate
+        self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
+        self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedRenewSlivers)
+        self.renewProcess.renewSlivers(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
+
+    def finishedRenewSlivers(self):
+        self.emitFinished("success")
+
+    def emitFinished(self, status, statusMsg=None):
+        self.status = status
+        self.statusMsg = statusMsg
+        self.emit(SIGNAL("finished()"))
+