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 get_slice_rspec = get_rspec(hrn, 'slice')
179 get_node_rspec = get_rspec(hrn, 'node')
180 get_aggregate_rspec = get_rpsec(hrn, 'aggregate')
182 def get_resources(self, slice_hrn):
184 Return the current rspec for the specified slice.
186 slicename = hrn_to_plcslicename(slice_hrn)
187 rspec = self.get_slice_rspec(slicename)
191 def create_slice(self, slice_hrn, rspec):
193 Instantiate the specified slice according to whats defined in the rspec.
195 slicename = hrn_to_plcslicename(slice_hrn)
197 #components = spec.components()
198 #shell.AddSliceToNodes(self.auth, slicename, components)
201 def delete_slice_(self, slice_hrn):
203 Remove this slice from all components it was previouly associated with and
204 free up the resources it was using.
206 slicename = hrn_to_plcslicename(slice_hrn)
207 rspec = self.get_resources(slice_hrn)
208 components = rspec.components()
209 shell.DeleteSliceFromNodes(self.auth, slicename, components)
212 def start_slice(self, slice_hrn):
214 Stop the slice at plc.
216 slicename = hrn_to_plcslicename(slice_hrn)
217 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
219 raise RecordNotFound(slice_hrn)
221 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
222 attribute_id = attreibutes[0]
223 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "1" })
226 def stop_slice(self, slice_hrn):
228 Stop the slice at plc
230 slicename = hrn_to_plcslicename(slice_hrn)
231 slices = self.shell.GetSlices(self.auth, {'name': slicename}, ['slice_id'])
233 raise RecordNotFound(slice_hrn)
235 atrribtes = self.shell.GetSliceAttributes({'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
236 attribute_id = attreibutes[0]
237 self.shell.UpdateSliceAttribute(self.auth, attribute_id, "0"})
240 def reset_slice(self, slice_hrn):
244 slicename = hrn_to_plcslicename(slice_hrn)
247 def get_policy(self):
249 Return this aggregates policy as an rspec
251 rspec = get_aggregate_rspec(self.hrn):