7 from geniserver import *
10 from config import Config
13 basedir = conf.GENI_BASE_DIR + os.sep
14 server_basedir = basedir + os.sep + "plc" + os.sep
15 agg_hrn = conf.GENI_INTERFACE_HRN
21 components_file = None
32 def __init__(self, hrn = agg_hrn, components_ttl = 1):
34 self.components_file = os.sep.join([server_basedir, 'components', hrn + '.comp'])
35 self.slices_file = os.sep.join([server_basedir, 'components', hrn + '.slices'])
36 self.timestamp_file = os.sep.join([server_basedir, 'components', hrn + '.timestamp'])
37 self.components_ttl = components_ttl
41 Connect to the plc api interface. First attempt to impor thte shell, if that fails
42 try to connect to the xmlrpc server.
44 self.auth = {'Username': conf.GENI_PLC_USER,
45 'AuthMethod': 'password',
46 'AuthString': conf.GENI_PLC_PASSWORD}
49 # try to import PLC.Shell directly
50 sys.path.append(conf.GENI_PLC_SHELL_PATH)
52 self.shell = PLC.Shell.Shell(globals())
53 self.shell.AuthCheck()
55 # connect to plc api via xmlrpc
56 plc_host = conf.GENI_PLC_HOST
57 plc_port = conf.GENI_PLC_PORT
58 plc_api_path = conf.GENI_PLC_API_PATH
59 url = "https://%(plc_host)s:%(plc_port)s/%(plc_api_path)s/" % locals()
60 self.auth = {'Username': conf.GENI_PLC_USER,
61 'AuthMethod': 'password',
62 'AuthString': conf.GENI_PLC_PASSWORD}
64 self.shell = xmlrpclib.Server(url, verbose = 0, allow_none = True)
65 self.shell.AuthCheck(self.auth)
67 def hostname_to_hrn(self, login_base, hostname):
69 Convert hrn to plantelab name.
71 genihostname = "_".join(hostname.split("."))
72 return ".".join([self.hrn, login_base, genihostname])
74 def slicename_to_hrn(self, slicename):
76 Convert hrn to planetlab name.
78 slicename = slicename.replace("_", ".")
79 return ".".join([self.hrn, slicename])
81 def refresh_components(self):
83 Update the cached list of nodes and slices.
86 # resolve component hostnames
87 nodes = self.shell.GetNodes(self.auth, {}, ['hostname', 'site_id'])
90 slices = self.shell.GetSlices(self.auth, {}, ['name', 'site_id'])
92 # resolve site login_bases
93 site_ids = [node['site_id'] for node in nodes]
94 sites = self.shell.GetSites(self.auth, site_ids, ['site_id', 'login_base'])
97 site_dict[site['site_id']] = site['login_base']
99 # convert plc names to geni hrn
100 self.components = [self.hostname_to_hrn(site_dict[node['site_id']], node['hostname']) for node in nodes]
101 self.slices = [self.slicename_to_hrn(slice['name']) for slice in slices]
103 # update timestamp and threshold
104 self.timestamp = datetime.datetime.now()
105 delta = datetime.timedelta(hours=self.components_ttl)
106 self.threshold = self.timestamp + delta
108 f = open(self.components_file, 'w')
109 f.write(str(self.components))
111 f = open(self.slices_file, 'w')
112 f.write(str(self.slices))
114 f = open(self.timestamp_file, 'w')
115 f.write(str(self.threshold))
118 def load_components(self):
120 Read cached list of nodes and slices.
123 # Read component list from cached file
124 if os.path.exists(self.components_file):
125 f = open(self.components_file, 'r')
126 self.components = eval(f.read())
129 if os.path.exists(self.slices_file):
130 f = open(self.components_file, 'r')
131 self.slices = eval(f.read())
134 time_format = "%Y-%m-%d %H:%M:%S"
135 if os.path.exists(self.timestamp_file):
136 f = open(self.timestamp_file, 'r')
137 timestamp = str(f.read()).split(".")[0]
138 self.timestamp = datetime.datetime.fromtimestamp(time.mktime(time.strptime(timestamp, time_format)))
139 delta = datetime.timedelta(hours=self.components_ttl)
140 self.threshold = self.timestamp + delta
143 def get_components(self):
145 Return a list of components at this aggregate.
147 # Reload components list
148 now = datetime.datetime.now()
149 #self.load_components()
150 if not self.threshold or not self.timestamp or now > self.threshold:
151 self.refresh_components()
152 elif now < self.threshold and not self.components:
153 self.load_components()
154 return self.components
157 def get_slices(self):
159 Return a list of instnatiated slices at this aggregate.
161 now = datetime.datetime.now()
162 #self.load_components()
163 if not self.threshold or not self.timestamp or now > self.threshold:
164 self.refresh_components()
165 elif now < self.threshold and not self.slices:
166 self.load_components()
169 def get_rspec(self, hrn, type):
172 nodes = self.shell.GetNodes(self.auth)
173 elif type in ['slice']:
174 slices = self.shell.GetSlices(self.auth)
175 elif type in ['aggregate']:
178 def get_resources(self, slice_hrn):
180 Return the current rspec for the specified slice.
182 slicename = hrn_to_plcslicename(slice_hrn)
183 rspec = self.get_rspec(slicenamem, 'slice' )
187 def create_slice(self, slice_hrn, rspec):
189 Instantiate the specified slice according to whats defined in the rspec.
191 slicename = self.hrn_to_plcslicename(slice_hrn)
193 #components = spec.components()
194 #shell.AddSliceToNodes(self.auth, slicename, components)
197 def delete_slice_(self, slice_hrn):
199 Remove this slice from all components it was previouly associated with and
200 free up the resources it was using.
202 slicename = self.hrn_to_plcslicename(slice_hrn)
203 rspec = self.get_resources(slice_hrn)
204 components = rspec.components()
205 shell.DeleteSliceFromNodes(self.auth, slicename, components)
208 def start_slice(self, slice_hrn):
210 Stop the slice at plc.
212 slicename = hrn_to_plcslicename(slice_hrn)
213 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
215 raise RecordNotFound(slice_hrn)
217 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
218 attribute_id = attreibutes[0]
219 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "1" )
222 def stop_slice(self, slice_hrn):
224 Stop the slice at plc
226 slicename = hrn_to_plcslicename(slice_hrn)
227 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
229 raise RecordNotFound(slice_hrn)
231 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
232 attribute_id = attreibutes[0]
233 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "0")
236 def reset_slice(self, slice_hrn):
240 slicename = self.hrn_to_plcslicename(slice_hrn)
243 def get_policy(self):
245 Return this aggregates policy as an rspec
247 rspec = self.get_rspec(self.hrn, 'aggregate')