47ddf2a7160c2e40f06b49bbc27f89a64015468d
[sface.git] / sface / sfirenew.py
1 import calendar
2 import datetime
3 import os
4 import re
5 import sys
6 import time
7
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
14 class SfiRenewer(QObject):
15     def __init__(self, hrn, newExpiration, parent=None):
16         QObject.__init__(self, parent)
17         self.hrn = hrn
18         self.newExpiration = newExpiration
19         self.faultString = None
20
21         self.renewProcess = SfiProcess(self)
22         self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
23         self.renewProcess.getRecord(hrn=config.getSlice(), filename="/tmp/slicerecord")
24
25     def finishedGetRecord(self):
26         faultString = self.renewProcess.getFaultString()
27         if faultString:
28             self.emitFinished("fault", faultString)
29             return
30
31         f = open("/tmp/slicerecord", "r")
32         data = f.read()
33         f.close()
34
35         # find the expiration time
36         exp = re.compile('expires="[^"]*"')
37         if exp.search(data)==None:
38             # didn't find it
39             self.emitFinished("failure", "failed to find expiration in slice record")
40             return
41
42         # change the expiration time
43         delta = 24*60*60 # always extend the slice by one extra day to cover slop for time zone differences
44         data = exp.sub('expires="' + str(calendar.timegm(self.newExpiration.timetuple())+delta) + '"', data)
45
46         open("/tmp/slicerecord", "w").write(data)
47
48         self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedGetRecord)
49         self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
50
51         self.renewProcess.updateRecord("/tmp/slicerecord")
52
53     def finishedUpdateRecord(self):
54         faultString = self.renewProcess.getFaultString()
55         if faultString:
56             self.emitFinished("fault", faultString)
57             return
58
59         # we have to force sfi.py to download an updated slice credential
60         sliceCredName = config.fullpath("slice_" + self.hrn.split(".")[-1] + ".cred")
61         if os.path.exists(sliceCredName):
62             os.remove(sliceCredName)
63
64         open("/tmp/expiration", "w").write(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
65
66         # call renewSlivers on the aggregate
67         self.disconnect(self.renewProcess, SIGNAL('finished()'), self.finishedUpdateRecord)
68         self.connect(self.renewProcess, SIGNAL('finished()'), self.finishedRenewSlivers)
69         self.renewProcess.renewSlivers(self.newExpiration.strftime("%Y-%m-%dT%H:%M:%SZ"))
70
71     def finishedRenewSlivers(self):
72         faultString = self.renewProcess.getFaultString()
73         if faultString:
74             self.emitFinished("fault", faultString)
75             return
76
77         self.emitFinished("success")
78
79     def emitFinished(self, status, statusMsg=None):
80         self.status = status
81         self.statusMsg = statusMsg
82         self.emit(SIGNAL("finished()"))
83
84 class RenewWindow(QDialog):
85     def __init__(self, parent=None):
86         super(RenewWindow, self).__init__(parent)
87         self.setWindowTitle("Renew Slivers")
88
89         self.renewProcess = None
90
91         self.duration = QComboBox()
92
93         self.expirations = []
94
95         durations = ( (1, "One Week"), (2, "Two Weeks"), (3, "Three Weeks"), (4, "One Month") )
96
97         now = datetime.datetime.utcnow()
98         for (weeks, desc) in durations:
99             exp = now + datetime.timedelta(days = weeks * 7)
100             desc = desc + " " + exp.strftime("%Y-%m-%d %H:%M:%S")
101             self.expirations.append(exp)
102             self.duration.addItem(desc)
103
104         self.duration.setCurrentIndex(0)
105
106         self.status = QLabel("")
107         self.status.setMaximumWidth(640)
108
109         self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
110         self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
111
112         layout = QVBoxLayout()
113         layout.addWidget(self.duration)
114         layout.addWidget(self.status)
115         layout.addWidget(self.buttonBox)
116         self.setLayout(layout)
117
118         #self.status.hide()
119
120         self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
121         self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
122
123     def accept(self):
124         self.setStatus("Renewing Slice...")
125
126         self.renewProcess = SfiRenewer(config.getSlice(), self.get_new_expiration(), self)
127         self.connect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
128
129         self.duration.setEnabled(False)
130         self.buttonBox.setEnabled(False)
131
132     def setStatus(self, x):
133         self.status.setText(x)
134
135     def renewFinished(self):
136         if self.renewProcess.status == "success":
137             color = "green"
138             # give the user the <close> button
139             self.buttonBox.clear()
140             self.buttonBox.addButton(QDialogButtonBox.Close)
141         else:
142             color = "red"
143
144         if self.renewProcess.statusMsg:
145             self.setStatus("<font color='%s'>Renew %s: %s</font>" % (color, self.renewProcess.status, self.renewProcess.statusMsg))
146         else:
147             self.setStatus("<font color='%s'>Renew %s</font>" % (color, self.renewProcess.status))
148
149         self.buttonBox.setEnabled(True)
150
151         self.disconnect(self.renewProcess, SIGNAL('finished()'), self.renewFinished)
152         self.renewProcess = None
153
154     def get_new_expiration(self):
155         index = self.duration.currentIndex()
156         return self.expirations[index]