1 # -*- coding: utf-8 -*-
7 from constants import TESTBED_ID, TESTBED_VERSION
8 from nepi.core import metadata
9 from nepi.core.attributes import Attribute
10 from nepi.util import tags, validation, ipaddr2
11 from nepi.util.constants import ApplicationStatus as AS, \
12 FactoryCategories as FC, DeploymentConfiguration as DC
14 ##############################################################################
16 class OmfResource(object):
17 def __init__(self, guid, tc):
18 super(OmfResource, self).__init__()
19 self._tc = weakref.ref(tc)
24 return self._tc and self._tc()
45 ## NODE #######################################################################
47 class OmfNode(OmfResource):
48 def __init__(self, guid, tc):
49 super(OmfNode, self).__init__(guid, tc)
50 self.hostname = self.tc._get_parameters(guid)['hostname']
51 self.tc.api.enroll_host(self.hostname)
54 routes = self.tc._add_route.get(self.guid, [])
55 iface_guids = self.tc.get_connected(self.guid, "devs", "node")
58 (destination, netprefix, nexthop, metric, device) = route
59 netmask = ipaddr2.ipv4_mask2dot(netprefix)
61 # Validate that the interface is associated to the node
62 for iface_guid in iface_guids:
63 iface = self.tc.elements.get(iface_guid)
64 if iface.devname == device:
65 self.tc.api.execute(self.hostname,
66 "Id#%s" % str(random.getrandbits(128)),
67 "add -net %s netmask %s dev %s" % (destination, netmask, iface.devname),
73 ## APPLICATION ################################################################
75 class OmfApplication(OmfResource):
76 def __init__(self, guid, tc):
77 super(OmfApplication, self).__init__(guid, tc)
78 node_guids = tc.get_connected(guid, "node", "apps")
79 if len(node_guids) == 0:
80 raise RuntimeError("Can't instantiate interface %d outside node" % guid)
82 self._node_guid = node_guids[0]
89 node = self.tc.elements.get(self._node_guid)
90 self.tc.api.execute(node.hostname,
97 node = self.tc.elements.get(self._node_guid)
98 self.tc.api.exit(node.hostname,
102 if guid not in testbed_instance.elements.keys():
103 return AS.STATUS_NOT_STARTED
104 return AS.STATUS_RUNNING
106 #return AS.STATUS_FINISHED
109 ## WIFIIFACE ########################################################
111 class OmfWifiInterface(OmfResource):
112 alias2name = dict({'w0':'wlan0', 'w1':'wlan1'})
114 def __init__(self, guid, tc):
115 super(OmfWifiInterface, self).__init__(guid, tc)
116 node_guids = tc.get_connected(guid, "node", "devs")
117 if len(node_guids) == 0:
118 raise RuntimeError("Can't instantiate interface %d outside node" % guid)
120 self._node_guid = node_guids[0]
121 self.alias = self.tc._get_parameters(self.guid)['alias']
122 self.devname = self.alias2name.get(self.alias)
129 def __setattr__(self, name, value):
130 if name in ["ip", "mode", "type", "essid", "channel"]:
131 if value is not None:
132 node = self.tc.elements.get(self._node_guid)
133 attribute = "net/%s/%s" % (self.alias, name)
134 self._tc().api.configure(node.hostname, attribute, value)
136 super(OmfWifiInterface, self).__setattr__(name, value)
140 WIFIIFACE = "WifiInterface"
142 OMFAPPLICATION = "OmfApplication"
144 def create(factory, testbed_instance, guid):
148 elif factory == OMFAPPLICATION:
149 clazz = OmfApplication
150 elif factory == WIFIIFACE:
151 clazz = OmfWifiInterface
153 element = clazz(guid, testbed_instance)
154 #import pdb; pdb.set_trace()
155 testbed_instance._elements[guid] = element
157 def start(testbed_instance, guid):
158 element = testbed_instance.elements.get(guid)
161 def stop(testbed_instance, guid):
162 element = testbed_instance.elements.get(guid)
165 def status(testbed_instance, guid):
166 element = testbed_instance.elements.get(guid)
167 return element.status()
169 def configure(testbed_instance, guid):
170 element = testbed_instance.elements.get(guid)
171 return element.configure()
173 ### Factory information ###
175 connector_types = dict({
177 "help": "Connector from node to applications",
183 "help": "Connector to network interfaces",
189 "help": "Connector from a device to a channel",
195 "help": "Connector to a Node",
204 "from": (TESTBED_ID, NODE, "devs"),
205 "to": (TESTBED_ID, WIFIIFACE, "node"),
209 "from": (TESTBED_ID, WIFIIFACE, "chan"),
210 "to": (TESTBED_ID, CHANNEL, "devs"),
214 "from": (TESTBED_ID, NODE, "apps"),
215 "to": (TESTBED_ID, OMFAPPLICATION, "node"),
223 "help": "Application id",
224 "type": Attribute.STRING,
225 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
226 "validation_function": validation.is_string
230 "help": "Application arguments",
231 "type": Attribute.STRING,
232 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
233 "validation_function": validation.is_string
237 "help": "Path to binary (e.g '/opt/vlc-1.1.13/vlc')",
238 "type": Attribute.STRING,
239 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
240 "validation_function": validation.is_string
244 "help": "String with space separated values of environment variables to set before starting application (e.g 'FOO=foo BAR=bar')",
245 "type": Attribute.STRING,
246 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
247 "validation_function": validation.is_string
251 "help": "Hostname for the target OMF node",
252 "type": Attribute.STRING,
253 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
254 "validation_function": validation.is_string
258 "help": "Corresponds to the OMF attributes net/w0/mode",
259 "type": Attribute.STRING,
260 "flags": Attribute.NoDefaultValue,
261 "validation_function": validation.is_string
265 "help": "Corresponds to the OMF attributes net/w0/type",
266 "type": Attribute.STRING,
267 "flags": Attribute.NoDefaultValue,
268 "validation_function": validation.is_string
272 "help": "Corresponds to the OMF attributes net/w0/channel",
273 "type": Attribute.STRING,
274 "flags": Attribute.NoDefaultValue,
275 "validation_function": validation.is_string
279 "help": "Corresponds to the OMF attributes net/w0/essid",
280 "type": Attribute.STRING,
281 "flags": Attribute.NoDefaultValue,
282 "validation_function": validation.is_string
286 "help": "Corresponds to the OMF attributes net/w0/ip",
287 "type": Attribute.STRING,
288 "flags": Attribute.NoDefaultValue,
289 "validation_function": validation.is_ip4_address
293 "help": "Alias for device (e.g. w0, w1, etc)",
294 "type": Attribute.STRING,
296 "flags": Attribute.NoDefaultValue,
297 "validation_function": validation.is_string
303 create_order = [ NODE, WIFIIFACE, CHANNEL, OMFAPPLICATION ]
304 configure_order = [ WIFIIFACE, NODE, CHANNEL, OMFAPPLICATION ]
306 factories_info = dict({
309 "category": FC.CATEGORY_NODES,
310 "create_function": functools.partial(create, NODE),
311 "configure_function": configure,
312 "box_attributes": ["hostname"],
313 "connector_types": ["devs", "apps"],
314 "tags": [tags.NODE, tags.ALLOW_ROUTES],
317 "help": "Wireless network interface",
318 "category": FC.CATEGORY_DEVICES,
319 "create_function": functools.partial(create, WIFIIFACE),
320 "configure_function": configure,
321 "box_attributes": ["mode", "type", "channel", "essid", "ip", "alias"],
322 "connector_types": ["node", "chan"],
323 "tags": [tags.INTERFACE, tags.HAS_ADDRESSES],
326 "help": "Wireless channel",
327 "category": FC.CATEGORY_DEVICES,
328 "create_function": create,
329 "create_function": functools.partial(create, CHANNEL),
330 "box_attributes": ["mode", "type", "channel", "essid"],
331 "connector_types": ["devs"],
333 OMFAPPLICATION: dict({
334 "help": "Generic executable command line application",
335 "category": FC.CATEGORY_APPLICATIONS,
336 "create_function": functools.partial(create, OMFAPPLICATION),
337 "start_function": start,
338 "stop_function": stop,
339 "status_function": status,
340 "box_attributes": ["appId", "arguments", "path", "env"],
341 "connector_types": ["node"],
342 "tags": [tags.APPLICATION],
346 testbed_attributes = dict({
347 "enable_debug": dict({
348 "name": "enableDebug",
349 "help": "Enable netns debug output",
350 "type": Attribute.BOOL,
352 "validation_function": validation.is_bool
357 "type": Attribute.STRING,
358 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
359 "validation_function": validation.is_string
363 "help": "OMF XMPP server host",
364 "type": Attribute.STRING,
365 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
366 "validation_function": validation.is_string
370 "help": "OMF XMPP service port",
371 "type": Attribute.INTEGER,
372 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
373 "validation_function": validation.is_integer
375 "xmppPassword": dict({
376 "name": "xmppPassword",
377 "help": "OMF XMPP slice password",
378 "type": Attribute.STRING,
379 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
380 "validation_function": validation.is_string
384 "help": "Root node of the xmpp server pubsub tree",
385 "type": Attribute.STRING,
387 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
388 "validation_function": validation.is_string
392 supported_recovery_policies = [
396 class MetadataInfo(metadata.MetadataInfo):
398 def connector_types(self):
399 return connector_types
402 def connections(self):
406 def attributes(self):
414 def create_order(self):
418 def configure_order(self):
419 return configure_order
422 def factories_info(self):
423 return factories_info
426 def testbed_attributes(self):
427 return testbed_attributes
430 def testbed_id(self):
434 def testbed_version(self):
435 return TESTBED_VERSION
438 def supported_recover_policies(self):
439 return supported_recovery_policies