7 from util.geniserver import *
8 from util.cert import *
9 from util.trustedroot import *
10 from util.excep import *
11 from util.misc import *
12 from util.config import Config
14 class Aggregate(GeniServer):
18 components_file = None
29 def __init__(self, ip, port, key_file, cert_file, config = "/usr/share/geniwrapper/util/geni_config"):
30 GeniServer.__init__(ip, port, keyfile, cert_file)
33 basedir = conf.GENI_BASE_DIR + os.sep
34 server_basedir = basedir + os.sep + "plc" + os.sep
35 self.hrn = conf.GENI_INTERFACE_HRN
36 self.components_file = os.sep.join([server_basedir, 'components', hrn + '.comp'])
37 self.slices_file = os.sep.join([server_basedir, 'components', hrn + '.slices'])
38 self.timestamp_file = os.sep.join([server_basedir, 'components', hrn + '.timestamp'])
39 self.components_ttl = components_ttl
44 Connect to the plc api interface. First attempt to impor thte shell, if that fails
45 try to connect to the xmlrpc server.
47 self.auth = {'Username': conf.GENI_PLC_USER,
48 'AuthMethod': 'password',
49 'AuthString': conf.GENI_PLC_PASSWORD}
52 # try to import PLC.Shell directly
53 sys.path.append(conf.GENI_PLC_SHELL_PATH)
55 self.shell = PLC.Shell.Shell(globals())
56 self.shell.AuthCheck()
58 # connect to plc api via xmlrpc
59 plc_host = conf.GENI_PLC_HOST
60 plc_port = conf.GENI_PLC_PORT
61 plc_api_path = conf.GENI_PLC_API_PATH
62 url = "https://%(plc_host)s:%(plc_port)s/%(plc_api_path)s/" % locals()
63 self.auth = {'Username': conf.GENI_PLC_USER,
64 'AuthMethod': 'password',
65 'AuthString': conf.GENI_PLC_PASSWORD}
67 self.shell = xmlrpclib.Server(url, verbose = 0, allow_none = True)
68 self.shell.AuthCheck(self.auth)
70 def hostname_to_hrn(self, login_base, hostname):
72 Convert hrn to plantelab name.
74 genihostname = "_".join(hostname.split("."))
75 return ".".join([self.hrn, login_base, genihostname])
77 def slicename_to_hrn(self, slicename):
79 Convert hrn to planetlab name.
81 slicename = slicename.replace("_", ".")
82 return ".".join([self.hrn, slicename])
84 def refresh_components(self):
86 Update the cached list of nodes and slices.
89 # resolve component hostnames
90 nodes = self.shell.GetNodes(self.auth, {}, ['hostname', 'site_id'])
93 slices = self.shell.GetSlices(self.auth, {}, ['name', 'site_id'])
95 # resolve site login_bases
96 site_ids = [node['site_id'] for node in nodes]
97 sites = self.shell.GetSites(self.auth, site_ids, ['site_id', 'login_base'])
100 site_dict[site['site_id']] = site['login_base']
102 # convert plc names to geni hrn
103 self.components = [self.hostname_to_hrn(site_dict[node['site_id']], node['hostname']) for node in nodes]
104 self.slices = [self.slicename_to_hrn(slice['name']) for slice in slices]
106 # update timestamp and threshold
107 self.timestamp = datetime.datetime.now()
108 delta = datetime.timedelta(hours=self.components_ttl)
109 self.threshold = self.timestamp + delta
111 f = open(self.components_file, 'w')
112 f.write(str(self.components))
114 f = open(self.slices_file, 'w')
115 f.write(str(self.slices))
117 f = open(self.timestamp_file, 'w')
118 f.write(str(self.threshold))
121 def load_components(self):
123 Read cached list of nodes and slices.
126 # Read component list from cached file
127 if os.path.exists(self.components_file):
128 f = open(self.components_file, 'r')
129 self.components = eval(f.read())
132 if os.path.exists(self.slices_file):
133 f = open(self.components_file, 'r')
134 self.slices = eval(f.read())
137 time_format = "%Y-%m-%d %H:%M:%S"
138 if os.path.exists(self.timestamp_file):
139 f = open(self.timestamp_file, 'r')
140 timestamp = str(f.read()).split(".")[0]
141 self.timestamp = datetime.datetime.fromtimestamp(time.mktime(time.strptime(timestamp, time_format)))
142 delta = datetime.timedelta(hours=self.components_ttl)
143 self.threshold = self.timestamp + delta
146 def get_components(self):
148 Return a list of components at this aggregate.
150 # Reload components list
151 now = datetime.datetime.now()
152 #self.load_components()
153 if not self.threshold or not self.timestamp or now > self.threshold:
154 self.refresh_components()
155 elif now < self.threshold and not self.components:
156 self.load_components()
157 return self.components
160 def get_slices(self):
162 Return a list of instnatiated slices at this aggregate.
164 now = datetime.datetime.now()
165 #self.load_components()
166 if not self.threshold or not self.timestamp or now > self.threshold:
167 self.refresh_components()
168 elif now < self.threshold and not self.slices:
169 self.load_components()
172 def get_rspec(self, hrn, type):
175 nodes = self.shell.GetNodes(self.auth)
176 elif type in ['slice']:
177 slices = self.shell.GetSlices(self.auth)
178 elif type in ['aggregate']:
181 def get_resources(self, slice_hrn):
183 Return the current rspec for the specified slice.
185 slicename = hrn_to_plcslicename(slice_hrn)
186 rspec = self.get_rspec(slicenamem, 'slice' )
190 def create_slice(self, slice_hrn, rspec):
192 Instantiate the specified slice according to whats defined in the rspec.
194 slicename = self.hrn_to_plcslicename(slice_hrn)
196 #components = spec.components()
197 #shell.AddSliceToNodes(self.auth, slicename, components)
200 def delete_slice_(self, slice_hrn):
202 Remove this slice from all components it was previouly associated with and
203 free up the resources it was using.
205 slicename = self.hrn_to_plcslicename(slice_hrn)
206 rspec = self.get_resources(slice_hrn)
207 components = rspec.components()
208 shell.DeleteSliceFromNodes(self.auth, slicename, components)
211 def start_slice(self, slice_hrn):
213 Stop the slice at plc.
215 slicename = hrn_to_plcslicename(slice_hrn)
216 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
218 raise RecordNotFound(slice_hrn)
220 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
221 attribute_id = attreibutes[0]
222 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "1" )
225 def stop_slice(self, slice_hrn):
227 Stop the slice at plc
229 slicename = hrn_to_plcslicename(slice_hrn)
230 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
232 raise RecordNotFound(slice_hrn)
234 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
235 attribute_id = attreibutes[0]
236 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "0")
239 def reset_slice(self, slice_hrn):
243 slicename = self.hrn_to_plcslicename(slice_hrn)
246 def get_policy(self):
248 Return this aggregates policy as an rspec
250 rspec = self.get_rspec(self.hrn, 'aggregate')
255 ##############################
256 ## Server methods here for now
257 ##############################
260 return self..get_components()
263 return self.get_slices()
265 def resources(self, cred, hrn):
266 self.decode_authentication(cred, 'info')
267 self.verify_object_belongs_to_me(hrn)
269 return self.get_resources(hrn)
271 def create(self, cred, hrn, rspec):
272 self.decode_authentication(cred, 'embed')
273 self.verify_object_belongs_to_me(hrn, rspec)
274 return self.create(hrn)
276 def delete(self, cred, hrn):
277 self.decode_authentication(cred, 'embed')
278 self.verify_object_belongs_to_me(hrn)
279 return self.delete_slice(hrn)
281 def start(self, cred, hrn):
282 self.decode_authentication(cred, 'control')
283 return self.start(hrn)
285 def stop(self, cred, hrn):
286 self.decode_authentication(cred, 'control')
287 return self.stop(hrn)
289 def reset(self, cred, hrn):
290 self.decode_authentication(cred, 'control')
291 return self.reset(hrn)
293 def policy(self, cred):
294 self.decode_authentication(cred, 'info')
295 return self.get_policy()
297 def register_functions(self):
298 GeniServer.register_functions(self)
300 # Aggregate interface methods
301 self.server.register_function(self.components)
302 self.server.register_function(self.slices)
303 self.server.register_function(self.resources)
304 self.server.register_function(self.create)
305 self.server.register_function(self.delete)
306 self.server.register_function(self.start)
307 self.server.register_function(self.stop)
308 self.server.register_function(self.reset)
309 self.server.register_function(self.policy)