--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Experiment Topology:
+#
+# n1 --- n2
+# 0.1 0.2
+#
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+import getpass
+import logging
+import tempfile
+import time
+
+logging.basicConfig(level=logging.DEBUG)
+
+root_dir = tempfile.mkdtemp()
+
+exp_desc = ExperimentDescription()
+
+testbed_id = "omf"
+omf_provider = FactoriesProvider(testbed_id)
+omf_desc = exp_desc.add_testbed_description(omf_provider)
+omf_desc.set_attribute_value("homeDirectory", root_dir)
+omf_desc.set_attribute_value("enableDebug", True)
+omf_desc.set_attribute_value("xmppSlice", "default_slice")
+omf_desc.set_attribute_value("xmppHost", "xmpp-plexus.onelab.eu")
+omf_desc.set_attribute_value("xmppPort", 5222)
+omf_desc.set_attribute_value("xmppPassword", "1234")
+
+# Add node1
+node1 = omf_desc.create("Node")
+node1.set_attribute_value("hostname", "omf.plexus.wlab17")
+
+# Add configuration for interface 1
+iface1 = omf_desc.create("WifiInterface")
+iface1.set_attribute_value("alias", "w0")
+iface1.set_attribute_value("mode", "adhoc")
+iface1.set_attribute_value("channel", "6")
+iface1.set_attribute_value("type", "g")
+iface1.set_attribute_value("essid", "cvlcmode")
+iface1.set_attribute_value("ip", "192.168.0.17")
+node1.connector("devs").connect(iface1.connector("node"))
+
+# Add multicast route to node 1
+route1 = node1.add_route()
+route1.set_attribute_value("Destination", "224.0.0.0")
+route1.set_attribute_value("NetPrefix", 4)
+route1.set_attribute_value("Device", "wlan0")
+
+# Add node2
+node2 = omf_desc.create("Node")
+node2.set_attribute_value("hostname", "omf.plexus.wlab37")
+
+# Add configuration for interface 2
+iface2 = omf_desc.create("WifiInterface")
+iface2.set_attribute_value("alias", "w0")
+iface2.set_attribute_value("mode", "adhoc")
+iface2.set_attribute_value("channel", "6")
+iface2.set_attribute_value("type", "g")
+iface2.set_attribute_value("essid", "cvlcmode")
+iface2.set_attribute_value("ip", "192.168.0.37")
+node2.connector("devs").connect(iface2.connector("node"))
+
+# Add multicast route to node 2
+route2 = node2.add_route()
+route2.set_attribute_value("Destination", "224.0.0.0")
+route2.set_attribute_value("NetPrefix", 4)
+route2.set_attribute_value("Device", "wlan0")
+
+# Add a channel... this could be ommited
+channel = omf_desc.create("Channel")
+channel.set_attribute_value("mode", "adhoc")
+channel.set_attribute_value("channel", "6")
+channel.set_attribute_value("type", "g")
+channel.set_attribute_value("essid", "cvlcmode")
+channel.connector("devs").connect(iface1.connector("chan"))
+channel.connector("devs").connect(iface2.connector("chan"))
+
+# Add a vlc server to stream a video using multicast
+app1 = omf_desc.create("OmfApplication")
+app1.set_attribute_value("appId", "Vlc#1")
+app1.set_attribute_value("arguments", "/opt/bbb_240p_mpeg4_lq.ts --sout '#rtp{dst=239.255.0.1,port=1234,mux=ts}' vlc://quit")
+app1.set_attribute_value("path", "/opt/vlc-1.1.13/cvlc")
+app1.set_attribute_value("env", "DISPLAY=localhost:10.0 XAUTHORITY=/root/.Xauthority")
+app1.connector("node").connect(node1.connector("apps"))
+
+# Add a vlc client to receive the video stream
+app2 = omf_desc.create("OmfApplication")
+app2.set_attribute_value("appId", "Vlc#2")
+app2.set_attribute_value("arguments", "rtp://239.255.0.1:1234")
+app2.set_attribute_value("path", "/opt/vlc-1.1.13/cvlc")
+# To see the stream to a ssh -X connection, the DISPLAY variable must be set to the value of the node.
+# Also don't forget to execute in 'xhost + localhost' in the node
+app2.set_attribute_value("env", "DISPLAY=localhost:10.0 XAUTHORITY=/root/.Xauthority")
+app2.connector("node").connect(node2.connector("apps"))
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+controller.start()
+#while not (controller.is_finished(app1.guid) and \
+# controller.is_finished(app2.guid)):
+# time.sleep(0.5)
+
+time.sleep(30)
+
+controller.set(iface2.guid, "channel", "1")
+
+time.sleep(15)
+
+controller.stop()
+controller.shutdown()
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Experiment Topology:
+#
+# n1 --- n2
+# 0.1 0.2
+#
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+import getpass
+import logging
+import tempfile
+import time
+
+logging.basicConfig(level=logging.DEBUG)
+
+root_dir = tempfile.mkdtemp()
+
+exp_desc = ExperimentDescription()
+
+testbed_id = "omf"
+omf_provider = FactoriesProvider(testbed_id)
+omf_desc = exp_desc.add_testbed_description(omf_provider)
+omf_desc.set_attribute_value("homeDirectory", root_dir)
+omf_desc.set_attribute_value("enableDebug", True)
+omf_desc.set_attribute_value("xmppSlice", "default_slice")
+omf_desc.set_attribute_value("xmppHost", "xmpp-plexus.onelab.eu")
+omf_desc.set_attribute_value("xmppPort", 5222)
+omf_desc.set_attribute_value("xmppPassword", "1234")
+
+node1 = omf_desc.create("Node")
+node1.set_attribute_value("hostname", "omf.plexus.wlab17")
+
+app1 = omf_desc.create("OmfApplication")
+app1.set_attribute_value("appId", "xeyes#1")
+app1.set_attribute_value("path", "/usr/bin/xeyes")
+app1.set_attribute_value("env", "DISPLAY=localhost:10.0 XAUTHORITY=/root/.Xauthority")
+app1.connector("node").connect(node1.connector("apps"))
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+controller.start()
+
+time.sleep(30)
+
+controller.stop()
+controller.shutdown()
+
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#
-# Experiment Topology:
-#
-# n1 --- n2
-# 0.1 0.2
-#
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-import getpass
-import tempfile
-import time
-
-root_dir = tempfile.mkdtemp()
-
-exp_desc = ExperimentDescription()
-
-testbed_id = "omf"
-omf_provider = FactoriesProvider(testbed_id)
-omf_desc = exp_desc.add_testbed_description(omf_provider)
-omf_desc.set_attribute_value("homeDirectory", root_dir)
-omf_desc.set_attribute_value("enableDebug", True)
-omf_desc.set_attribute_value("xmppSlice", "default_slice")
-omf_desc.set_attribute_value("xmppHost", "xmpp-omf.onelab.eu")
-omf_desc.set_attribute_value("xmppPort", 5222)
-omf_desc.set_attribute_value("xmppPassword", "1234")
-
-node1 = omf_desc.create("Node")
-node1.set_attribute_value("hostname", "omf.my.wlab18")
-node2 = omf_desc.create("Node")
-node2.set_attribute_value("hostname", "omf.my.wlab49")
-
-iface12 = omf_desc.create("WifiInterface")
-iface12.set_attribute_value("mode", "adhoc")
-iface12.set_attribute_value("channel", "6")
-iface12.set_attribute_value("type", "g")
-iface12.set_attribute_value("essid", "cvlcmode")
-iface12.set_attribute_value("ip", "192.168.0.18")
-node1.connector("devs").connect(iface12.connector("node"))
-
-iface21 = omf_desc.create("WifiInterface")
-iface21.set_attribute_value("mode", "adhoc")
-iface21.set_attribute_value("channel", "6")
-iface21.set_attribute_value("type", "g")
-iface21.set_attribute_value("essid", "cvlcmode")
-iface21.set_attribute_value("ip", "192.168.0.49")
-node2.connector("devs").connect(iface21.connector("node"))
-
-channel = omf_desc.create("Channel")
-channel.set_attribute_value("mode", "adhoc")
-channel.set_attribute_value("channel", "6")
-channel.set_attribute_value("type", "g")
-channel.set_attribute_value("essid", "cvlcmode")
-channel.connector("devs").connect(iface12.connector("chan"))
-channel.connector("devs").connect(iface21.connector("chan"))
-
-app2 = omf_desc.create("OmfApplication")
-app2.set_attribute_value("appId", "Vlc#2")
-app2.set_attribute_value("arguments", "rtp://239.255.0.1:1234")
-app2.set_attribute_value("path", "/opt/vlc-1.1.13/vlc")
-app2.connector("node").connect(node2.connector("apps"))
-
-app1 = omf_desc.create("OmfApplication")
-app1.set_attribute_value("appId", "Vlc#1")
-app1.set_attribute_value("arguments", "/opt/10-by-p0d.avi --sout '#duplicate{dst=display,dst=rtp{mux=ts,dst=239.255.0.1,port=1234}}'")
-app1.set_attribute_value("path", "/opt/vlc-1.1.13/vlc")
-app1.connector("node").connect(node1.connector("apps"))
-
-xml = exp_desc.to_xml()
-
-controller = ExperimentController(xml, root_dir)
-controller.start()
-#while not (controller.is_finished(app1.guid) and \
-# controller.is_finished(app2.guid)):
-# time.sleep(0.5)
-
-time.sleep(20)
-
-controller.set(iface21.guid, "channel", "1")
-
-time.sleep(15)
-
-controller.stop()
-controller.shutdown()
-
value = 0,
flags = Attribute.NoDefaultValue,
validation_function = validation.is_integer)
+ self.add_attribute(name = "Device",
+ help = "Device name",
+ type = Attribute.STRING,
+ value = None,
+ flags = Attribute.NoDefaultValue,
+ validation_function = validation.is_string)
class Box(AttributesMap, Taggable):
def __init__(self, guid, factory, testbed_guid, container = None):
"""Instructs the addition of an address"""
raise NotImplementedError
- def defer_add_route(self, guid, destination, netprefix, nexthop, metric = 0):
+ def defer_add_route(self, guid, destination, netprefix, nexthop,
+ metric = 0, device = None):
"""Instructs the addition of a route"""
raise NotImplementedError
testbed.defer_add_address(guid, address, netprefix,
broadcast)
# routes
- for (destination, netprefix, nexthop, metric) in data.get_route_data(guid):
- testbed.defer_add_route(guid, destination, netprefix, nexthop, metric)
+ for (destination, netprefix, nexthop, metric, device) in \
+ data.get_route_data(guid):
+ testbed.defer_add_route(guid, destination, netprefix, nexthop,
+ metric, device)
# store connections data
for (connector_type_name, other_guid, other_connector_type_name) \
in data.get_connection_data(guid):
self._add_address[guid] = list()
self._add_address[guid].append((address, netprefix, broadcast))
- def defer_add_route(self, guid, destination, netprefix, nexthop, metric = 0):
+ def defer_add_route(self, guid, destination, netprefix, nexthop,
+ metric = 0, device = None):
self._validate_guid(guid)
self._validate_allow_routes(guid)
if not guid in self._add_route:
self._add_route[guid] = list()
- self._add_route[guid].append((destination, netprefix, nexthop, metric))
+ self._add_route[guid].append((destination, netprefix, nexthop,
+ metric, device))
def do_setup(self):
self._root_directory = self._attributes.\
return
routes = testbed_instance._add_route[guid]
for route in routes:
- (destination, netprefix, nexthop, metric) = route
+ (destination, netprefix, nexthop, metric, device) = route
element.add_route(prefix = destination, prefix_len = netprefix,
nexthop = nexthop, metric = metric)
ns3 = testbed_instance.ns3
routes = testbed_instance._add_route[guid]
for route in routes:
- (destination, netprefix, nexthop, metric) = route
+ (destination, netprefix, nexthop, metric, device) = route
address = ns3.Ipv4Address(destination)
if nexthop:
nexthop_address = ns3.Ipv4Address(nexthop)
break
if ifindex < 0:
# Check previous ptp routes
- for chaindest, chainprefix, chainhop, metric in routes:
+ for chaindest, chainprefix, chainhop, metric, device in routes:
if chaindest == nexthop and chainprefix == 32:
chainhop_address = ns3.Ipv4Address(chainhop)
for ifidx in xrange(nifaces):
port = self._attributes.get_attribute_value("xmppPort")
password = self._attributes.get_attribute_value("xmppPassword")
- self._api = OmfAPI(slice, host, port, password)
+ xmpp_root = self._attributes.get_attribute_value("xmppRoot")
+ self._api = OmfAPI(slice, host, port, password, xmpp_root)
super(TestbedController, self).do_setup()
# -*- coding: utf-8 -*-
import functools
+import random
import weakref
from constants import TESTBED_ID, TESTBED_VERSION
from nepi.core import metadata
from nepi.core.attributes import Attribute
-from nepi.util import tags, validation
+from nepi.util import tags, validation, ipaddr2
from nepi.util.constants import ApplicationStatus as AS, \
FactoryCategories as FC, DeploymentConfiguration as DC
def tc(self):
return self._tc and self._tc()
+ @property
+ def guid(self):
+ return self._guid
+
def configure(self):
pass
self.hostname = self.tc._get_parameters(guid)['hostname']
self.tc.api.enroll_host(self.hostname)
+ def configure(self):
+ routes = self.tc._add_route.get(self.guid, [])
+ iface_guids = self.tc.get_connected(self.guid, "devs", "node")
+
+ for route in routes:
+ (destination, netprefix, nexthop, metric, device) = route
+ netmask = ipaddr2.ipv4_mask2dot(netprefix)
+
+ # Validate that the interface is associated to the node
+ for iface_guid in iface_guids:
+ iface = self.tc.elements.get(iface_guid)
+ if iface.devname == device:
+ self.tc.api.execute(self.hostname,
+ "Id#%s" % str(random.getrandbits(128)),
+ "add -net %s netmask %s dev %s" % (destination, netmask, iface.devname),
+ "/sbin/route", # path
+ None, # env
+ )
+ break
+
## APPLICATION ################################################################
class OmfApplication(OmfResource):
## WIFIIFACE ########################################################
class OmfWifiInterface(OmfResource):
+ alias2name = dict({'w0':'wlan0', 'w1':'wlan1'})
+
def __init__(self, guid, tc):
super(OmfWifiInterface, self).__init__(guid, tc)
node_guids = tc.get_connected(guid, "node", "devs")
raise RuntimeError("Can't instantiate interface %d outside node" % guid)
self._node_guid = node_guids[0]
+ self.alias = None
self.mode = None
self.type = None
self.essid = None
self.channel = None
self.ip = None
+ self.devname = None
def __setattr__(self, name, value):
+ if name == "alias":
+ self.devname = self.alias2name.get(value)
+
if name in ["ip", "mode", "type", "essid", "channel"]:
node = self.tc.elements.get(self._node_guid)
- attribute = "net/w0/%s" % name
+ attribute = "net/%s/%s" % (self.alias, name)
self._tc().api.configure(node.hostname, attribute, value)
- else:
- super(OmfWifiInterface, self).__setattr__(name, value)
+
+ super(OmfWifiInterface, self).__setattr__(name, value)
# Factories
NODE = "Node"
def configure(testbed_instance, guid):
element = testbed_instance.elements.get(guid)
- return element.status()
+ return element.configure()
### Factory information ###
"flags": Attribute.NoDefaultValue,
"validation_function": validation.is_ip4_address
}),
-
-
-
+ "alias": dict({
+ "name": "alias",
+ "help": "Alias for device (e.g. w0, w1, etc)",
+ "type": Attribute.STRING,
+ "value": "w0",
+ "flags": Attribute.NoDefaultValue,
+ "validation_function": validation.is_string
+ }),
})
traces = dict()
"help": "OMF Node",
"category": FC.CATEGORY_NODES,
"create_function": functools.partial(create, NODE),
+ "configure_function": configure,
"box_attributes": ["hostname"],
"connector_types": ["devs", "apps"],
"tags": [tags.NODE, tags.ALLOW_ROUTES],
"category": FC.CATEGORY_DEVICES,
"create_function": functools.partial(create, WIFIIFACE),
"configure_function": configure,
- "box_attributes": ["mode", "type", "channel", "essid", "ip"],
+ "box_attributes": ["mode", "type", "channel", "essid", "ip", "alias"],
"connector_types": ["node", "chan"],
"tags": [tags.INTERFACE, tags.HAS_ADDRESSES],
}),
"flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
"validation_function": validation.is_string
}),
+ "xmppRoot": dict({
+ "name": "xmppRoot",
+ "help": "Root node of the xmpp server pubsub tree",
+ "type": Attribute.STRING,
+ "value": "OMF",
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+ "validation_function": validation.is_string
+ }),
})
supported_recovery_policies = [
from nepi.testbeds.omf.omf_messages import MessageHandler
class OmfAPI(object):
- def __init__(self, slice, host, port, password):
+ def __init__(self, slice, host, port, password, xmpp_root = None):
date = datetime.datetime.now().strftime("%Y-%m-%dt%H.%M.%S")
tz = -time.altzone if time.daylight != 0 else -time.timezone
date += "%+06.2f" % (tz / 3600) # timezone difference is in seconds
self._port = port
self._password = password
self._hostnames = []
+ self._xmpp_root = xmpp_root or "OMF"
self._logger = logging.getLogger("nepi.testbeds.omf")
self._client.create(xmpp_node)
self._client.subscribe(xmpp_node)
- address = "/%s/OMF/%s/%s" % (self._host, self._slice, self._user)
+ address = "/%s/%s/%s/%s" % (self._host, self._xmpp_root, self._slice, self._user)
payload = self._message.newexpfunction(self._user, address)
- slice_sid = "/OMF/%s" % (self._slice)
+ slice_sid = "/%s/%s" % (self._xmpp_root, self._slice)
self._client.publish(payload, slice_sid)
def _enroll_logger(self):
self._client.publish(payload, xmpp_node)
def _host_session_id(self, hostname):
- return "/OMF/%s/%s/%s" % (self._slice, self._user, hostname)
+ return "/%s/%s/%s/%s" % (self._xmpp_root, self._slice, self._user, hostname)
def _host_resource_id(self, hostname):
- return "/OMF/%s/resources/%s" % (self._slice, hostname)
+ return "/%s/%s/resources/%s" % (self._xmpp_root, self._slice, hostname)
@property
def _exp_session_id(self):
- return "/OMF/%s/%s" % (self._slice, self._user)
+ return "/%s/%s/%s" % (self._xmpp_root, self._slice, self._user)
@property
def _logger_session_id(self):
- return "/OMF/%s/%s/LOGGER" % (self._slice, self._user)
+ return "/%s/%s/%s/LOGGER" % (self._xmpp_root, self._slice, self._user)
def delete(self, hostname):
if not hostname in self._hostnames:
if pointopoint:
prefix = 32
- dest, destprefix, nexthop, metric = route
+ dest, destprefix, nexthop, metric, device = route
myNet = ipaddr.IPv4Network("%s/%d" % (addr, prefix))
gwIp = ipaddr.IPv4Network(nexthop)
vsys_vnet = ipaddr.IPv4Network(vsys_vnet)
for route in routes:
- dest, prefix, nexthop, metric = route
+ dest, prefix, nexthop, metric, device = route
dest = ipaddr.IPv4Network("%s/%d" % (dest,prefix))
nexthop = ipaddr.IPAddress(nexthop)
if dest not in vsys_vnet or nexthop not in vsys_vnet:
return 'vroute'
def format_route(self, route, dev, method, action):
- dest, prefix, nexthop, metric = route
+ dest, prefix, nexthop, metric, device = route
if method == 'vroute':
return (
"%s %s%s gw %s %s" % (
def routes_data_to_xml(self, doc, parent_tag, guid, data):
routes_tag = doc.createElement("routes")
- for (destination, netprefix, nexthop, metric) \
+ for (destination, netprefix, nexthop, metric, device) \
in data.get_route_data(guid):
route_tag = doc.createElement("route")
routes_tag.appendChild(route_tag)
route_tag.setAttribute("NetPrefix", xmlencode(netprefix))
route_tag.setAttribute("NextHop", xmlencode(nexthop))
route_tag.setAttribute("Metric", xmlencode(metric))
+ route_tag.setAttribute("Device", xmlencode(device))
if routes_tag.hasChildNodes():
parent_tag.appendChild(routes_tag)
nexthop = xmldecode(route_tag.getAttribute("NextHop"))
metric = int(route_tag.getAttribute("Metric")) \
if route_tag.hasAttribute("Metric") else 0
+ device = xmldecode(route_tag.getAttribute("Device"))
data.add_route_data(guid, destination, netprefix,
- nexthop, metric)
+ nexthop, metric, device)
def connections_data_from_xml(self, tag, guid, data):
connections_tag_list = tag.getElementsByTagName("connections")
address_data["Broadcast"] = broadcast
addresses_data.append(address_data)
- def add_route_data(self, guid, destination, netprefix, nexthop, metric):
+ def add_route_data(self, guid, destination, netprefix, nexthop, metric, device):
data = self.data[guid]
if not "routes" in data:
data["routes"] = list()
"Destination": destination,
"NetPrefix": netprefix,
"NextHop": nexthop,
- "Metric": metric
+ "Metric": metric,
+ "Device": device
})
routes_data.append(route_data)
return [(data["Destination"],
data["NetPrefix"],
data["NextHop"],
- data["Metric"]) \
+ data["Metric"],
+ data["Device"]) \
for data in routes_data]
class ExperimentParser(object):
netprefix = route.get_attribute_value("NetPrefix")
nexthop = route.get_attribute_value("NextHop")
metric = route.get_attribute_value("Metric")
- data.add_route_data(guid, destination, netprefix, nexthop, metric)
+ device = route.get_attribute_value("Device")
+ data.add_route_data(guid, destination, netprefix, nexthop,
+ metric, device)
def from_data(self, experiment_description, data):
box_guids = list()
addr.set_attribute_value("Broadcast", broadcast)
def routes_from_data(self, box, data):
- for (destination, netprefix, nexthop, metric) \
+ for (destination, netprefix, nexthop, metric, device) \
in data.get_route_data(box.guid):
addr = box.add_route()
addr.set_attribute_value("Destination", destination)
addr.set_attribute_value("NetPrefix", netprefix)
addr.set_attribute_value("NextHop", nexthop)
addr.set_attribute_value("Metric", metric)
+ addr.set_attribute_value("Device", device)
def connections_from_data(self, experiment_description, guids, data):
for guid in guids:
@Marshalling.handles(ADD_ROUTE)
@Marshalling.args(int, str, int, str, int)
@Marshalling.retvoid
- def defer_add_route(self, guid, destination, netprefix, nexthop, metric):
- self._testbed.defer_add_route(guid, destination, netprefix, nexthop, metric)
+ def defer_add_route(self, guid, destination, netprefix, nexthop,
+ metric, device):
+ self._testbed.defer_add_route(guid, destination, netprefix, nexthop,
+ metric, device)
@Marshalling.handles(DO_SETUP)
@Marshalling.args()