Netref fixes - oh goodie
[nepi.git] / src / nepi / testbeds / planetlab / execute.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from constants import TESTBED_ID
5 from nepi.core import testbed_impl
6 import os
7
8 class TestbedController(testbed_impl.TestbedController):
9     def __init__(self, testbed_version):
10         super(TestbedController, self).__init__(TESTBED_ID, testbed_version)
11         self._home_directory = None
12         self.slicename = None
13         self._traces = dict()
14         
15         import node, interfaces, application
16         self._node = node
17         self._interfaces = interfaces
18         self._app = application
19
20     @property
21     def home_directory(self):
22         return self._home_directory
23     
24     @property
25     def plapi(self):
26         if not hasattr(self, '_plapi'):
27             import plcapi
28             
29             if self.authUser:
30                 self._plapi = plcapi.PLCAPI(
31                     username = self.authUser,
32                     password = self.authString)
33             else:
34                 # anonymous access - may not be enough for much
35                 self._plapi = plcapi.PLCAPI()
36         return self._plapi
37     
38     @property
39     def slice_id(self):
40         if not hasattr(self, '_slice_id'):
41             slices = self.plapi.GetSlices(self.slicename, fields=('slice_id',))
42             if slices:
43                 self._slice_id = slices[0]['slice_id']
44             else:
45                 # If it wasn't found, don't remember this failure, keep trying
46                 return None
47         return self._slice_id
48
49     def do_setup(self):
50         self._home_directory = self._attributes.\
51             get_attribute_value("homeDirectory")
52         self.slicename = self._attributes.\
53             get_attribute_value("slice")
54         self.authUser = self._attributes.\
55             get_attribute_value("authUser")
56         self.authString = self._attributes.\
57             get_attribute_value("authPass")
58         self.sliceSSHKey = self._attributes.\
59             get_attribute_value("sliceSSHKey")
60
61     def do_create(self):
62         # Create node elements per XML data
63         super(TestbedController, self).do_create()
64         
65         # Perform resource discovery if we don't have
66         # specific resources assigned yet
67         self.do_resource_discovery()
68         
69         # Create PlanetLab slivers
70         self.do_provisioning()
71         
72         # Wait for all nodes to be ready
73         self.wait_nodes()
74     
75     def do_resource_discovery(self):
76         # Do what?
77         pass
78
79     def do_provisioning(self):
80         # Que te recontra?
81         pass
82     
83     def wait_nodes(self):
84         # Suuure...
85         pass
86
87     def set(self, time, guid, name, value):
88         super(TestbedController, self).set(time, guid, name, value)
89         # TODO: take on account schedule time for the task 
90         element = self._elements[guid]
91         if element:
92             setattr(element, name, value)
93
94     def get(self, time, guid, name):
95         # TODO: take on account schedule time for the task
96         element = self._elements.get(guid)
97         if element:
98             try:
99                 if hasattr(element, name):
100                     # Runtime attribute
101                     return getattr(element, name)
102                 else:
103                     # Try design-time attributes
104                     return self.box_get(time, guid, name)
105             except KeyError, AttributeError:
106                 return None
107
108     def get_route(self, guid, index, attribute):
109         # TODO: fetch real data from planetlab
110         try:
111             return self.box_get_route(guid, int(index), attribute)
112         except KeyError, AttributeError:
113             return None
114
115     def get_address(self, guid, index, attribute='Address'):
116         index = int(index)
117         
118         # try the real stuff
119         iface = self._elements.get(guid)
120         if iface and index == 0:
121             if attribute == 'Address':
122                 return iface.address
123             elif attribute == 'NetPrefix':
124                 return iface.netprefix
125             elif attribute == 'Broadcast':
126                 return iface.broadcast
127         
128         # if all else fails, query box
129         try:
130             return self.box_get_address(guid, index, attribute)
131         except KeyError, AttributeError:
132             return None
133
134
135     def action(self, time, guid, action):
136         raise NotImplementedError
137
138     def shutdown(self):
139         for trace in self._traces.values():
140             trace.close()
141         for element in self._elements.values():
142             pass
143             #element.destroy()
144
145     def trace(self, guid, trace_id, attribute='value'):
146         app = self._elements[guid]
147         
148         if attribute == 'value':
149             path = app.sync_trace(self.home_directory, trace_id)
150             if path:
151                 fd = open(path, "r")
152                 content = fd.read()
153                 fd.close()
154             else:
155                 content = None
156         elif attribute == 'path':
157             content = app.remote_trace_path(trace_id)
158         else:
159             content = None
160         return content
161         
162     def follow_trace(self, trace_id, trace):
163         self._traces[trace_id] = trace
164
165     def _make_node(self, parameters):
166         node = self._node.Node(self.plapi)
167         
168         # Note: there is 1-to-1 correspondence between attribute names
169         #   If that changes, this has to change as well
170         for attr,val in parameters.iteritems():
171             setattr(node, attr, val)
172         
173         return node
174     
175     def _make_node_iface(self, parameters):
176         iface = self._interfaces.NodeIface(self.plapi)
177         
178         # Note: there is 1-to-1 correspondence between attribute names
179         #   If that changes, this has to change as well
180         for attr,val in parameters.iteritems():
181             setattr(iface, attr, val)
182         
183         return iface
184     
185     def _make_tun_iface(self, parameters):
186         iface = self._interfaces.TunIface(self.plapi)
187         
188         # Note: there is 1-to-1 correspondence between attribute names
189         #   If that changes, this has to change as well
190         for attr,val in parameters.iteritems():
191             setattr(iface, attr, val)
192         
193         return iface
194     
195     def _make_internet(self, parameters):
196         return self._interfaces.Internet(self.plapi)
197     
198     def _make_application(self, parameters):
199         app = self._app.Application(self.plapi)
200         
201         # Note: there is 1-to-1 correspondence between attribute names
202         #   If that changes, this has to change as well
203         for attr,val in parameters.iteritems():
204             setattr(app, attr, val)
205         
206         return app
207         
208
209