8 from PyQt4.QtCore import *
9 from PyQt4.QtGui import *
10 from sface.config import config
11 from sface.sfiprocess import SfiProcess
12 #from sface.sfithread import SfiThread
13 from sface.sliceview import SliceView, SliceModel
15 class SfiRenewer(QObject):
16 def __init__(self, hrn, newExpiration, parent=None):
17 QObject.__init__(self, parent)
19 self.newExpiration = newExpiration
20 self.faultString = None
22 self.renewProcess = SfiProcess(self)
23 self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
24 self.renewProcess.getRecord(hrn=hrn, filename="/tmp/slicerecord")
26 def finishedGetRecord(self):
27 self.faultString = self.renewProcess.getFaultString()
29 self.emitFinished("fault", self.faultString)
32 f = open("/tmp/slicerecord", "r")
36 # find the expiration time
37 exp = re.compile('expires="[^"]*"')
38 if exp.search(data)==None:
40 self.faultString = "failed to find expiration in slice record"
41 self.emitFinished("failure", self.faultString)
44 # change the expiration time
45 delta = 24*60*60 # always extend the slice by one extra day to cover slop for time zone differences
46 data = exp.sub('expires="' + str(calendar.timegm(self.newExpiration.timetuple())+delta) + '"', data)
48 open("/tmp/slicerecord", "w").write(data)
50 self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
51 self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
53 self.renewProcess.updateRecord("/tmp/slicerecord")
55 def finishedUpdateRecord(self):
56 self.faultString = self.renewProcess.getFaultString()
58 self.emitFinished("fault", self.faultString)
61 # we have to force sfi.py to download an updated slice credential
62 sliceCredName = config.fullpath("slice_" + self.hrn.split(".")[-1] + ".cred")
63 if os.path.exists(sliceCredName):
64 os.remove(sliceCredName)
66 # newer SFA has a slightly different slice credential name
67 sliceCredName = config.fullpath(self.hrn + ".slice.cred")
68 if os.path.exists(sliceCredName):
69 os.remove(sliceCredName)
71 open("/tmp/expiration", "w").write(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
73 # call renewSlivers on the aggregate
74 self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
75 self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedRenewSlivers)
76 self.renewProcess.renewSlivers(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"), slice = self.hrn)
78 def finishedRenewSlivers(self):
79 self.faultString = self.renewProcess.getFaultString()
81 self.emitFinished("fault", self.faultString)
84 self.emitFinished("success")
86 def emitFinished(self, status, statusMsg=None):
88 self.statusMsg = statusMsg
89 self.emit(SIGNAL("finished()"))
91 def getFaultString(self):
92 return self.faultString
94 class RenewWindow(QDialog):
95 def __init__(self, batch=False, parent=None):
96 super(RenewWindow, self).__init__(parent)
97 self.setWindowTitle("Renew Slivers")
101 self.renewProcess = None
103 durationLabel = QLabel("Duration:")
104 self.duration = QComboBox()
106 self.expirations = []
108 durations = ( (1, "One Week"), (2, "Two Weeks"), (3, "Three Weeks"), (4, "One Month") )
110 now = datetime.datetime.utcnow()
111 for (weeks, desc) in durations:
112 exp = now + datetime.timedelta(days = weeks * 7)
113 desc = desc + " " + exp.strftime("%Y-%m-%d %H:%M:%S")
114 self.expirations.append(exp)
115 self.duration.addItem(desc)
117 self.duration.setCurrentIndex(0)
120 sliceLabel = QLabel("Slices:")
121 self.sliceView = SliceView()
123 self.status = QLabel("")
124 self.status.setMaximumWidth(640)
126 self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
127 self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
130 self.buttonBox.addButton("Batch", QDialogButtonBox.ActionRole)
132 layout = QVBoxLayout()
133 layout.addWidget(durationLabel)
134 layout.addWidget(self.duration)
136 layout.addWidget(sliceLabel)
137 layout.addWidget(self.sliceView)
138 layout.addWidget(self.status)
139 layout.addWidget(self.buttonBox)
140 self.setLayout(layout)
142 self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
143 self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
144 self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton *)"), self.clicked)
147 self.sliceModel = SliceModel()
148 self.refreshAuthority()
150 def clicked(self, button):
151 if button.text() == "Batch":
152 # close ourself, and reopen the batch renew window
154 dlg = RenewWindow(batch=True, parent=self.parent())
159 self.slicesToRenew = self.sliceModel.getSelectedSlices()
160 if self.slicesToRenew == []:
161 QMessageBox.warning(self, "No Slices", "Please add at least on slice by double-clicking on a slice name")
164 self.slicesToRenew = [config.getSlice()]
166 self.duration.setEnabled(False)
167 self.buttonBox.setEnabled(False)
169 self.sliceView.setEnabled(False)
171 self.renewNextSlice()
173 def setStatus(self, x):
174 self.status.setText(x)
176 def renewNextSlice(self):
177 self.sliceName = self.slicesToRenew.pop(0)
178 self.renewProcess = SfiRenewer(self.sliceName, self.get_new_expiration(), self)
179 self.connect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
180 self.setStatus("<font color='green'>Renewing: %s.</font>" % self.sliceName)
182 def renewFinished(self):
183 self.disconnect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
185 faultString = self.renewProcess.getFaultString()
187 self.setStatus("<font color='red'>Renew %s Error: %s</font>" % (self.sliceName, faultString))
188 self.buttonBox.setEnabled(True)
190 self.setStatus("<font color='green'>Renew %s Success</font>" % self.sliceName)
192 if (self.slicesToRenew != []):
193 self.renewNextSlice()
195 # give the user the <close> button
196 self.buttonBox.clear()
197 self.buttonBox.addButton(QDialogButtonBox.Close)
198 self.buttonBox.setEnabled(True)
200 def get_new_expiration(self):
201 index = self.duration.currentIndex()
202 return self.expirations[index]
204 def refreshAuthority(self):
205 self.process = SfiProcess(self)
206 self.connect(self.process, SIGNAL('finished()'), self.getAuthorityRecordFinished)
208 self.process.listRecords(config.getAuthority(), None)
209 self.setStatus("Refreshing slice list. This will take a moment...")
211 def getAuthorityRecordFinished(self):
212 self.disconnect(self.process, SIGNAL('finished()'), self.getAuthorityRecordFinished)
214 faultString = self.process.getFaultString()
216 self.setStatus("<font color='green'>Slice list refreshed.</font>")
217 self.updateSliceView()
219 self.setStatus("<font color='red'>Authority rec refresh error: %s</font>" % (faultString))
221 def updateSliceView(self):
222 self.sliceModel.updateModel()
224 self.sliceView.setModel(self.sliceModel)
225 self.sliceView.resizeColumnToContents(0)