Several execution fixes:
[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
59     def do_create(self):
60         # Create node elements per XML data
61         super(TestbedController, self).do_create()
62         
63         # Perform resource discovery if we don't have
64         # specific resources assigned yet
65         self.do_resource_discovery()
66         
67         # Create PlanetLab slivers
68         self.do_provisioning()
69         
70         # Wait for all nodes to be ready
71         self.wait_nodes()
72     
73     def do_resource_discovery(self):
74         # Do what?
75         pass
76
77     def do_provisioning(self):
78         # Que te recontra?
79         pass
80     
81     def wait_nodes(self):
82         # Suuure...
83         pass
84
85     def set(self, time, guid, name, value):
86         super(TestbedController, self).set(time, guid, name, value)
87         # TODO: take on account schedule time for the task 
88         element = self._elements[guid]
89         if element:
90             setattr(element, name, value)
91
92     def get(self, time, guid, name):
93         # TODO: take on account schedule time for the task
94         element = self._elements.get(guid)
95         if element:
96             try:
97                 if hasattr(element, name):
98                     # Runtime attribute
99                     return getattr(element, name)
100                 else:
101                     # Try design-time attributes
102                     return self.box_get(time, guid, name)
103             except KeyError, AttributeError:
104                 return None
105
106     def get_route(self, guid, index, attribute):
107         # TODO: fetch real data from planetlab
108         try:
109             return self.box_get_route(guid, int(index), attribute)
110         except KeyError, AttributeError:
111             return None
112
113     def get_address(self, guid, index, attribute='Address'):
114         # TODO: fetch real data from planetlab
115         try:
116             return self.box_get_address(guid, int(index), attribute)
117         except KeyError, AttributeError:
118             return None
119
120
121     def action(self, time, guid, action):
122         raise NotImplementedError
123
124     def shutdown(self):
125         for trace in self._traces.values():
126             trace.close()
127         for element in self._elements.values():
128             element.destroy()
129
130     def trace_filename(self, guid, trace_id):
131         # TODO: Need to be defined inside a home!!!! with and experiment id_code
132         return os.path.join(self.home_directory, "%d_%s" % (guid, trace_id))
133
134     def follow_trace(self, trace_id, trace):
135         self._traces[trace_id] = trace
136
137     def _make_node(self, parameters):
138         node = self._node.Node(self.plapi)
139         
140         # Note: there is 1-to-1 correspondence between attribute names
141         #   If that changes, this has to change as well
142         for attr,val in parameters.iteritems():
143             setattr(node, attr, val)
144         
145         return node
146     
147     def _make_node_iface(self, parameters):
148         iface = self._interfaces.NodeIface(self.plapi)
149         
150         # Note: there is 1-to-1 correspondence between attribute names
151         #   If that changes, this has to change as well
152         for attr,val in parameters.iteritems():
153             setattr(iface, attr, val)
154         
155         return iface
156     
157     def _make_tun_iface(self, parameters):
158         iface = self._interfaces.TunIface(self.plapi)
159         
160         # Note: there is 1-to-1 correspondence between attribute names
161         #   If that changes, this has to change as well
162         for attr,val in parameters.iteritems():
163             setattr(iface, attr, val)
164         
165         return iface
166     
167     def _make_internet(self, parameters):
168         return self._interfaces.Internet(self.plapi)
169     
170     def _make_application(self, parameters):
171         app = self._app.Application(self.plapi)
172         
173         # Note: there is 1-to-1 correspondence between attribute names
174         #   If that changes, this has to change as well
175         for attr,val in parameters.iteritems():
176             setattr(app, attr, val)
177         
178         return app
179         
180
181