pl_desc.set_attribute_value("plcHost", plchost)
pl_desc.set_attribute_value("tapPortBase", self.port_base)
pl_desc.set_attribute_value("p2pDeployment", not self.no_p2p_deploy)
- pl_desc.set_attribute_value("dedicatedSlice", True)
+ pl_desc.set_attribute_value("cleanProc", True)
pl_desc.set_attribute_value("plLogLevel", "INFO")
return pl_desc, exp_desc
<attribute name="slice" type="STRING" value="##plslice##"/>
<attribute name="plLogLevel" type="STRING" value="INFO"/>
<attribute name="logLevel" type="STRING" value="Debug"/>
- <attribute name="dedicatedSlice" type="BOOL" value="True"/>
+ <attribute name="cleanProc" type="BOOL" value="True"/>
<attribute name="plcUrl" type="STRING" value="https://%(hostname)s:443/PLCAPI/"/>
<attribute name="recoveryPolicy" type="STRING" value="Recover"/>
<attribute name="p2pDeployment" type="BOOL" value="False"/>
<attribute name="slice" type="STRING" value="##plslice##"/>
<attribute name="plLogLevel" type="STRING" value="INFO"/>
<attribute name="logLevel" type="STRING" value="Debug"/>
- <attribute name="dedicatedSlice" type="BOOL" value="True"/>
+ <attribute name="cleanProc" type="BOOL" value="True"/>
<attribute name="plcUrl" type="STRING" value="https://%(hostname)s:443/PLCAPI/"/>
<attribute name="recoveryPolicy" type="STRING" value="Recover"/>
<attribute name="p2pDeployment" type="BOOL" value="False"/>
--- /dev/null
+(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org
--- /dev/null
+#!/usr/bin/env python
+
+##
+## Experiment topology:
+##
+## ccncatchunks ccnsendchunks
+## | |
+## .-> node1 -- .. -- nodei -- .. -- nodeN <-.
+##
+##
+## - Nodes are connected through an overlay network over the Intenet
+## - On each node runs a CCNx daemon
+## - Static multicast entries are added to the CCNx FIB on each node to communicate them in series.
+## (Nodes only have FIB entries to at most two nodes)
+##
+
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util.constants import ApplicationStatus as AS
+import ipaddr
+import math
+from optparse import OptionParser, SUPPRESS_HELP
+import os
+import signal
+import string
+import subprocess
+import tempfile
+import time
+
+# Trak SIGTERM, and set global termination flag instead of dying
+TERMINATE = []
+def _finalize(sig,frame):
+ global TERMINATE
+ TERMINATE.append(None)
+signal.signal(signal.SIGTERM, _finalize)
+signal.signal(signal.SIGINT, _finalize)
+
+def create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, exp_desc):
+ pl_provider = FactoriesProvider("planetlab")
+ slice_desc = exp_desc.add_testbed_description(pl_provider)
+ slice_desc.set_attribute_value("homeDirectory", root_dir)
+ slice_desc.set_attribute_value("slice", slicename)
+ slice_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
+ slice_desc.set_attribute_value("authUser", pl_user)
+ slice_desc.set_attribute_value("authPass", pl_pwd)
+ slice_desc.set_attribute_value("plcHost", plc_host)
+ slice_desc.set_attribute_value("tapPortBase", port_base)
+ # Kills all running processes before starting the experiment
+ slice_desc.set_attribute_value("cleanProc", True)
+ # NOTICE: Setting 'cleanHome' to 'True' will erase all previous
+ # folders in the sliver Home directory, including result files!
+ #slice_desc.set_attribute_value("cleanHome", True)
+ slice_desc.set_attribute_value("plLogLevel", "DEBUG")
+ return slice_desc
+
+def create_node(hostname, pl_inet, slice_desc):
+ pl_node = slice_desc.create("Node")
+ pl_node.set_attribute_value("hostname", hostname)
+ pl_node.set_attribute_value("label", hostname)
+ pl_iface = slice_desc.create("NodeInterface")
+ pl_iface.connector("inet").connect(pl_inet.connector("devs"))
+ pl_node.connector("devs").connect(pl_iface.connector("node"))
+ return pl_node
+
+def create_tunnel(node, peer, pl_nodes, slice_desc, subnet):
+ pl_node = pl_nodes[node]
+ pl_peer = pl_nodes[peer]
+
+ pl_tun = slice_desc.create("TunInterface")
+ pl_tun.set_attribute_value("label", "tun_%s%s" % (node, peer))
+ pl_node.connector("devs").connect(pl_tun.connector("node"))
+
+ pl_tunpeer = slice_desc.create("TunInterface")
+ pl_tunpeer.set_attribute_value("label", "tun_%s%s" % (peer, node))
+ pl_peer.connector("devs").connect(pl_tunpeer.connector("node"))
+
+ pl_tun.connector("udp").connect(pl_tunpeer.connector("udp"))
+
+ iterhosts = subnet.iterhosts()
+ addr = iterhosts.next()
+ ip = pl_tun.add_address()
+ ip.set_attribute_value("Address", addr.exploded)
+ ip.set_attribute_value("NetPrefix", subnet.prefixlen)
+
+ peeraddr = iterhosts.next()
+ peerip = pl_tunpeer.add_address()
+ peerip.set_attribute_value("Address", peeraddr.exploded)
+ peerip.set_attribute_value("NetPrefix", subnet.prefixlen)
+
+def create_ccnd(pl_node, port, hostname, routes, slice_desc):
+ pl_app = slice_desc.create("CCNxDaemon")
+ # We use a wildcard to replace the TUN IP address of the node during runtime
+ routes = "|".join(map(lambda route: "udp 224.0.23.170 %d 3 1 {#[tun_%s%s].addr[0].[Address]#}" \
+ % (route[1], hostname, route[0]), routes))
+ # Add multicast ccn routes
+ pl_app.set_attribute_value("ccnRoutes", routes)
+ # Use a specific port to bind the CCNx daemon
+ if port:
+ pl_app.set_attribute_value("ccnLocalPort", port)
+ pl_app.enable_trace("stdout")
+ pl_app.enable_trace("stderr")
+ pl_app.connector("node").connect(pl_node.connector("apps"))
+
+def create_ccnsendchunks(pl_node, port, slice_desc):
+ pl_app = slice_desc.create("Application")
+ path_to_video = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "../big_buck_bunny_240p_mpeg4_lq.ts")
+ pl_app.set_attribute_value("stdin", path_to_video)
+
+ command = "ccnsendchunks ccnx:/VIDEO"
+ if port:
+ command = "CCN_LOCAL_PORT=%d %s " % (port, command)
+ pl_app.set_attribute_value("command", command)
+
+ pl_app.enable_trace("stdout")
+ pl_app.enable_trace("stderr")
+ pl_app.connector("node").connect(pl_node.connector("apps"))
+ return pl_app
+
+def exec_ccncatchunks(slicename, port, hostname):
+ print "Starting Vlc streamming ..."
+
+ command = 'PATH=$PATH:$(ls | egrep nepi-ccnd- | head -1)/bin;'
+ if port:
+ command += "CCN_LOCAL_PORT=%d " % port
+ command += ' ccncatchunks2 ccnx:/VIDEO'
+
+ login = "%s@%s" % (slicename, hostname)
+ proc1 = subprocess.Popen(['ssh', login, command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = False)
+ proc2 = subprocess.Popen(['vlc',
+ '--sub-filter', 'marq',
+ '--marq-marquee',
+ '(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org',
+ '--marq-position=8',
+ '--no-video-title-show', '-'],
+ stdin=proc1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ return proc2
+
+def create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, port):
+
+ # Create the experiment description object
+ exp_desc = ExperimentDescription()
+
+ # Create the slice description object
+ slice_desc = create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, exp_desc)
+
+ # Create the Internet box object
+ pl_inet = slice_desc.create("Internet")
+
+ # Create the Node boxes
+ pl_nodes = dict()
+ ccn_routes = dict()
+ prev_hostname = None
+ mport = port
+ for hostname in hostnames:
+ pl_node = create_node(hostname, pl_inet, slice_desc)
+ pl_nodes[hostname] = pl_node
+
+ ccn_routes[hostname] = list()
+ if prev_hostname:
+ ccn_routes[hostname].append((prev_hostname, mport))
+ ccn_routes[prev_hostname].append((hostname, mport))
+ mport = port if mport != port else port + 1
+ prev_hostname = hostname
+
+ # Get the base network segment (slice vsys_vnet) to assign all the IP addresses
+ # to the virtual interfaces
+ base = ipaddr.IPNetwork(vsys_vnet)
+
+ # Calculate the number of virtual networks required to connect all the nodes
+ # with all other nodes as the binomial coeficient C(n, 2), with n = #nodes
+ n = len(hostnames)
+ c = n * (n-1) / 2
+
+ # Validate that we can get 'c' /30 subnetworks
+ if c > math.pow(2, (30 - base.prefixlen)):
+ raise RuntimeError("Insufficient address segment %s for experiment", vsys_vnet)
+
+ # Create the subnetwors iterator
+ iter_sub = base.iter_subnets(new_prefix=30)
+
+ # Create tunnels between nodes
+ for i, node in enumerate(hostnames):
+ peers = hostnames[i+1:]
+ for peer in peers:
+ subnet = iter_sub.next()
+ create_tunnel(node, peer, pl_nodes, slice_desc, subnet)
+
+ # Create ccnd daemons in all nodes
+ for hostname, pl_node in pl_nodes.iteritems():
+ routes = ccn_routes[hostname]
+ create_ccnd(pl_node, port, hostname, routes, slice_desc)
+
+ # Create a ccnsendchunks application box in the first node
+ hostname = hostnames[0]
+ pl_node = pl_nodes[hostname]
+ pl_app = create_ccnsendchunks(pl_node, port, slice_desc)
+
+ return exp_desc, pl_nodes, hostname, pl_app
+
+def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, port):
+
+ exp_desc, pl_nodes, hostname, pl_app = create_ed(hostnames, vsys_vnet,
+ slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base,
+ root_dir, port)
+
+ xml = exp_desc.to_xml()
+ controller = ExperimentController(xml, root_dir)
+ controller.start()
+
+ while not TERMINATE and controller.status(pl_app.guid) == AS.STATUS_NOT_STARTED:
+ time.sleep(0.5)
+
+ proc = None
+ if not TERMINATE:
+ hostname = hostnames[-1]
+ proc = exec_ccncatchunks(slicename, port, hostname)
+
+ while not TERMINATE and proc and proc.poll() is None:
+ time.sleep(0.5)
+
+ if proc:
+ if proc.poll() < 1:
+ err = proc.stderr.read()
+ print "ERROR ", err
+ else:
+ out = proc.stdout.read()
+ print "OUTPUT ", out
+
+ controller.stop()
+ controller.shutdown()
+
+if __name__ == '__main__':
+ root_dir = tempfile.mkdtemp()
+ slicename = os.environ.get("PL_SLICE")
+ pl_host = os.environ.get("PL_HOST", "www.planet-lab.eu")
+ port_base = 2000 + (os.getpid() % 1000) * 13
+ pl_ssh_key = os.environ.get(
+ "PL_SSH_KEY",
+ "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+ pl_user = os.environ.get('PL_USER')
+ pl_pwd = os.environ.get('PL_PASS')
+ pl_vsys_vnet = os.environ.get('PL_VSYS_NET')
+ pl_hostnames = os.environ.get('PL_HOSTNAMES')
+ default_hostnames = ['openlab02.pl.sophia.inria.fr',
+ 'ple4.ipv6.lip6.fr',
+ 'planetlab2.di.unito.it',
+ 'merkur.planetlab.haw-hamburg.de',
+ 'planetlab1.cs.uit.no',
+ 'planetlab3.cs.st-andrews.ac.uk',
+ 'planetlab2.cs.uoi.gr',
+ 'planetlab3.xeno.cl.cam.ac.uk',
+ 'planet2.inf.tu-dresden.de',
+ 'planetlab2.csg.uzh.ch',
+ 'planetlab2.upm.ro',
+ 'planetlab-um00.di.uminho.pt',
+ 'planetlabpc2.upf.edu',
+ 'planet2.elte.hu',
+ 'planetlab2.esprit-tn.com' ]
+ ccn_local_port = os.environ.get('CCN_LOCAL_PORT', 49695)
+
+ usage = "usage: %prog -s <pl_slice> -H <pl_host> -k <ssh_key> -u <pl_user> -p <pl_password> -v <vsys_vnet> -N <host_names> -c <node_count> -P <ccn-local-port>"
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-s", "--slicename", dest="slicename",
+ help="PlanetLab slicename", default=slicename, type="str")
+ parser.add_option("-H", "--pl-host", dest="pl_host",
+ help="PlanetLab site (e.g. www.planet-lab.eu)",
+ default=pl_host, type="str")
+ parser.add_option("-k", "--ssh-key", dest="pl_ssh_key",
+ help="Path to private ssh key used for PlanetLab authentication",
+ default=pl_ssh_key, type="str")
+ parser.add_option("-u", "--pl-user", dest="pl_user",
+ help="PlanetLab account user (i.e. Registration email address)",
+ default=pl_user, type="str")
+ parser.add_option("-p", "--pl-pwd", dest="pl_pwd",
+ help="PlanetLab account password", default=pl_pwd, type="str")
+ parser.add_option("-v", "--vsys-vnet", dest="vsys_vnet",
+ help="Value of the vsys_vnet tag addigned to your slice. (e.g. 192.168.3.0/16)",
+ default=pl_vsys_vnet, type="str")
+ parser.add_option("-N", "--host-names", dest="hostnames",
+ help="Comma separated list of PlanetLab hostnames to use",
+ default=pl_hostnames, type="str")
+ parser.add_option("-c", "--node-count", dest="node_count",
+ help="Number of nodes to use",
+ default=5, type="str")
+ parser.add_option("-P", "--ccn-local-port", dest="port",
+ help="Port to bind the CCNx daemon",
+ default=ccn_local_port, type="int")
+
+ (options, args) = parser.parse_args()
+
+ hostnames = map(string.strip, options.hostnames.split(",")) if options.hostnames else default_hostnames
+ if options.node_count > 0 and options.node_count < len(hostnames):
+ hostnames = hostnames[0:options.node_count]
+ vsys_vnet = options.vsys_vnet
+ slicename = options.slicename
+ pl_host = options.pl_host
+ pl_user= options.pl_user
+ pl_pwd = options.pl_pwd
+ pl_ssh_key = options.pl_ssh_key
+ port = options.port
+
+ run(hostnames, vsys_vnet, slicename, pl_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, port)
+
--- /dev/null
+#!/usr/bin/env python
+
+##
+## Experiment topology:
+##
+## ccncatchunks ccnsendchunks
+## | |
+## .-> node1 -- .. -- nodei -- .. -- nodeN <-.
+##
+##
+## - Nodes are connected through Intenet
+## - On each node runs a CCNx daemon
+## - Static entries are added to the CCNx FIB on each node to communicate them in series.
+## (Nodes only have FIB entries to at most two nodes)
+##
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util.constants import ApplicationStatus as AS
+import ipaddr
+import math
+from optparse import OptionParser, SUPPRESS_HELP
+import os
+import signal
+import string
+import subprocess
+import tempfile
+import time
+
+# Trak SIGTERM, and set global termination flag instead of dying
+TERMINATE = []
+def _finalize(sig,frame):
+ global TERMINATE
+ TERMINATE.append(None)
+signal.signal(signal.SIGTERM, _finalize)
+signal.signal(signal.SIGINT, _finalize)
+
+def create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, exp_desc):
+ pl_provider = FactoriesProvider("planetlab")
+ slice_desc = exp_desc.add_testbed_description(pl_provider)
+ slice_desc.set_attribute_value("homeDirectory", root_dir)
+ slice_desc.set_attribute_value("slice", slicename)
+ slice_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
+ slice_desc.set_attribute_value("authUser", pl_user)
+ slice_desc.set_attribute_value("authPass", pl_pwd)
+ slice_desc.set_attribute_value("plcHost", plc_host)
+ slice_desc.set_attribute_value("tapPortBase", port_base)
+ slice_desc.set_attribute_value("p2pDeployment", True)
+ # Kills all running processes before starting the experiment
+ slice_desc.set_attribute_value("cleanProc", True)
+ # NOTICE: Setting 'cleanHome' to 'True' will erase all previous
+ # folders in the sliver Home directory, including result files!
+ #slice_desc.set_attribute_value("cleanHome", True)
+ slice_desc.set_attribute_value("plLogLevel", "DEBUG")
+ return slice_desc
+
+def create_node(hostname, pl_inet, slice_desc):
+ pl_node = slice_desc.create("Node")
+ pl_node.set_attribute_value("hostname", hostname)
+ pl_node.set_attribute_value("label", hostname)
+ pl_iface = slice_desc.create("NodeInterface")
+ pl_iface.set_attribute_value("label", "iface_%s" % hostname)
+ pl_iface.connector("inet").connect(pl_inet.connector("devs"))
+ pl_node.connector("devs").connect(pl_iface.connector("node"))
+ return pl_node
+
+def create_ccnd(pl_node, port, routes, slice_desc):
+ pl_app = slice_desc.create("CCNxDaemon")
+
+ # We can specify a default ccnx version to be either ccnx-0.5.1 or ccnx-0.6.0
+ #pl_app.set_attribute_value("ccnxVersion", "ccnx-0.5.1")
+ # We can also specify a custom local source and build and install directives
+ path_to_source = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "ccnx-0.6.0rc3.tar.gz")
+ pl_app.set_attribute_value("sources", path_to_source)
+ pl_app.set_attribute_value("build",
+ "tar xzf ${SOURCES}/ccnx-0.6.0rc3.tar.gz && "
+ "cd ./ccnx-0.6.0rc3 && "
+ "./configure && make ")
+ pl_app.set_attribute_value("install", "cp -r ./ccnx-0.6.0rc3/bin ${SOURCES}")
+
+ # We use a wildcard to replace the public IP address of the node during runtime,
+ # once this IP is known
+ routes = "|".join(map(lambda route: "udp {#[iface_%s].addr[0].[Address]#}" % route, routes))
+
+ # Add unicast ccn routes
+ pl_app.set_attribute_value("ccnRoutes", routes)
+
+ # Use a specific port to bind the CCNx daemon
+ if port:
+ pl_app.set_attribute_value("ccnLocalPort", port)
+
+ pl_app.enable_trace("stdout")
+ pl_app.enable_trace("stderr")
+ pl_app.connector("node").connect(pl_node.connector("apps"))
+
+def create_ccnsendchunks(pl_node, port, slice_desc):
+ pl_app = slice_desc.create("Application")
+ path_to_video = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "../big_buck_bunny_240p_mpeg4_lq.ts")
+ pl_app.set_attribute_value("stdin", path_to_video)
+
+ command = "ccnsendchunks ccnx:/VIDEO"
+ if port:
+ command = "CCN_LOCAL_PORT=%d %s " % (port, command)
+ pl_app.set_attribute_value("command", command)
+
+ pl_app.enable_trace("stdout")
+ pl_app.enable_trace("stderr")
+ pl_app.connector("node").connect(pl_node.connector("apps"))
+ return pl_app
+
+def exec_ccncatchunks(slicename, port, hostname):
+ print "Getting video chunks from %s ..." % hostname
+
+ command = 'PATH=$PATH:$(ls | egrep nepi-ccnd- | head -1)/bin;'
+ if port:
+ command += "CCN_LOCAL_PORT=%d " % port
+ command += ' ccncatchunks2 ccnx:/VIDEO'
+
+ login = "%s@%s" % (slicename, hostname)
+ proc1 = subprocess.Popen(['ssh', login, command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = False)
+
+ proc2 = subprocess.Popen(['vlc',
+ '--sub-filter', 'marq',
+ '--marq-marquee',
+ '(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org',
+ '--marq-position=8',
+ '--no-video-title-show', '-'],
+ stdin=proc1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ return proc2
+
+def create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, delay, port):
+
+ # Create the experiment description object
+ exp_desc = ExperimentDescription()
+
+ # Create the slice description object
+ slice_desc = create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, exp_desc)
+
+ # Create the Internet box object
+ pl_inet = slice_desc.create("Internet")
+
+ # Create the Node boxes
+ pl_nodes = dict()
+ ccn_routes = dict()
+ prev_hostname = None
+ for hostname in hostnames:
+ pl_node = create_node(hostname, pl_inet, slice_desc)
+ pl_nodes[hostname] = pl_node
+
+ ccn_routes[hostname] = list()
+ if prev_hostname:
+ ccn_routes[hostname].append(prev_hostname)
+ ccn_routes[prev_hostname].append(hostname)
+ prev_hostname = hostname
+
+ for hostname in hostnames:
+ pl_node = pl_nodes[hostname]
+ routes = ccn_routes[hostname]
+ create_ccnd(pl_node, port, routes, slice_desc)
+
+ # Create a ccnsendchunks application box in the first node
+ hostname = hostnames[0]
+ pl_node = pl_nodes[hostname]
+ pl_app = create_ccnsendchunks(pl_node, port, slice_desc)
+
+ return exp_desc, pl_nodes, hostname, pl_app
+
+def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, delay, port):
+
+ exp_desc, pl_nodes, hostname, pl_app = create_ed(hostnames, vsys_vnet,
+ slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base,
+ root_dir, delay, port)
+
+ xml = exp_desc.to_xml()
+ controller = ExperimentController(xml, root_dir)
+ controller.start()
+
+ while not TERMINATE and controller.status(pl_app.guid) == AS.STATUS_NOT_STARTED:
+ time.sleep(0.5)
+
+ proc1 = None
+ if not TERMINATE:
+ hostname = hostnames[-1]
+ proc1 = exec_ccncatchunks(slicename, port, hostname)
+
+ if not TERMINATE and proc1:
+ time.sleep(delay)
+
+ proc2 = None
+ if not TERMINATE:
+ hostname = hostnames[-2]
+ proc2 = exec_ccncatchunks(slicename, port, hostname)
+
+ while not TERMINATE and proc1 and proc2 and proc2.poll() is None:
+ time.sleep(0.5)
+
+ if proc1:
+ if proc1.poll() < 1:
+ err = proc1.stderr.read()
+ print "Stream 1 ERROR ", err
+ else:
+ out = proc1.stdout.read()
+ print "Stream 1 OUTPUT ", out
+
+ if proc2:
+ if proc2.poll() < 1:
+ err = proc2.stderr.read()
+ print "Stream 2 ERROR ", err
+ else:
+ out = proc2.stdout.read()
+ print "Stream 2 OUTPUT ", out
+
+ controller.stop()
+ controller.shutdown()
+
+if __name__ == '__main__':
+ root_dir = tempfile.mkdtemp()
+ slicename = os.environ.get("PL_SLICE")
+ pl_host = os.environ.get("PL_HOST", "www.planet-lab.eu")
+ port_base = 2000 + (os.getpid() % 1000) * 13
+ pl_ssh_key = os.environ.get(
+ "PL_SSH_KEY",
+ "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+ pl_user = os.environ.get('PL_USER')
+ pl_pwd = os.environ.get('PL_PASS')
+ pl_vsys_vnet = os.environ.get('PL_VSYS_NET')
+ pl_hostnames = os.environ.get('PL_HOSTNAMES')
+ default_hostnames = ['openlab02.pl.sophia.inria.fr',
+ 'ple4.ipv6.lip6.fr',
+ 'planetlab2.di.unito.it',
+ 'merkur.planetlab.haw-hamburg.de',
+ 'planetlab1.cs.uit.no',
+ 'planetlab3.cs.st-andrews.ac.uk',
+ 'planetlab2.cs.uoi.gr',
+ 'planetlab3.xeno.cl.cam.ac.uk',
+ 'planet2.inf.tu-dresden.de',
+ 'planetlab2.csg.uzh.ch',
+ 'planetlab2.upm.ro',
+ 'planetlab-um00.di.uminho.pt',
+ 'planetlabpc2.upf.edu',
+ 'planet2.elte.hu',
+ 'planetlab2.esprit-tn.com' ]
+ ccn_local_port = os.environ.get('CCN_LOCAL_PORT')
+
+ usage = "usage: %prog -s <pl_slice> -H <pl_host> -k <ssh_key> -u <pl_user> -p <pl_password> -v <vsys_vnet> -N <host_names> -c <node_count> -d <delay> -P <ccn-local-port>"
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-s", "--slicename", dest="slicename",
+ help="PlanetLab slicename", default=slicename, type="str")
+ parser.add_option("-H", "--pl-host", dest="pl_host",
+ help="PlanetLab site (e.g. www.planet-lab.eu)",
+ default=pl_host, type="str")
+ parser.add_option("-k", "--ssh-key", dest="pl_ssh_key",
+ help="Path to private ssh key used for PlanetLab authentication",
+ default=pl_ssh_key, type="str")
+ parser.add_option("-u", "--pl-user", dest="pl_user",
+ help="PlanetLab account user (i.e. Registration email address)",
+ default=pl_user, type="str")
+ parser.add_option("-p", "--pl-pwd", dest="pl_pwd",
+ help="PlanetLab account password", default=pl_pwd, type="str")
+ parser.add_option("-v", "--vsys-vnet", dest="vsys_vnet",
+ help="Value of the vsys_vnet tag addigned to your slice. (e.g. 192.168.3.0/16)",
+ default=pl_vsys_vnet, type="str")
+ parser.add_option("-N", "--host-names", dest="hostnames",
+ help="Comma separated list of PlanetLab hostnames to use",
+ default=pl_hostnames, type="str")
+ parser.add_option("-c", "--node-count", dest="node_count",
+ help="Number of nodes to use",
+ default=9, type="str")
+ parser.add_option("-d", "--delay", dest="delay",
+ help="Time to wait before retrieveing the second video stream in seconds",
+ default=40, type="int")
+ parser.add_option("-P", "--ccn-local-port", dest="port",
+ help="Port to bind the CCNx daemon",
+ default=ccn_local_port, type="int")
+ (options, args) = parser.parse_args()
+
+ hostnames = map(string.strip, options.hostnames.split(",")) if options.hostnames else default_hostnames
+ if options.node_count > 0 and options.node_count < len(hostnames):
+ hostnames = hostnames[0:options.node_count]
+ vsys_vnet = options.vsys_vnet
+ slicename = options.slicename
+ pl_host = options.pl_host
+ pl_user= options.pl_user
+ pl_pwd = options.pl_pwd
+ pl_ssh_key = options.pl_ssh_key
+ delay = options.delay
+ port = options.port
+
+ run(hostnames, vsys_vnet, slicename, pl_host, pl_user, pl_pwd, pl_ssh_key,
+ port_base, root_dir, delay, port)
+
--- /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
+from nepi.util import proxy
+from nepi.util.constants import DeploymentConfiguration as DC
+import getpass
+import tempfile
+import time
+import os
+
+user = getpass.getuser()
+root_dir = tempfile.mkdtemp()
+netns_dir = os.path.join(root_dir, "netns")
+daemon_dir = os.path.join(netns_dir, "daemon")
+os.makedirs(daemon_dir)
+
+
+exp_desc = ExperimentDescription()
+
+netns_provider = FactoriesProvider("netns")
+netns_desc = exp_desc.add_testbed_description(netns_provider)
+netns_desc.set_attribute_value("homeDirectory", netns_dir)
+#netns_desc.set_attribute_value("enableDebug", True)
+netns_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
+netns_desc.set_attribute_value(DC.ROOT_DIRECTORY, daemon_dir)
+netns_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
+netns_desc.set_attribute_value(DC.USE_SUDO, True)
+
+node1 = netns_desc.create("Node")
+node2 = netns_desc.create("Node")
+
+iface12 = netns_desc.create("P2PNodeInterface")
+iface12.set_attribute_value("up", True)
+node1.connector("devs").connect(iface12.connector("node"))
+
+iface21 = netns_desc.create("P2PNodeInterface")
+iface21.set_attribute_value("up", True)
+node2.connector("devs").connect(iface21.connector("node"))
+
+iface12.connector("p2p").connect(iface21.connector("p2p"))
+
+ip12 = iface12.add_address()
+ip12.set_attribute_value("Address", "192.168.0.1")
+ip12.set_attribute_value("NetPrefix", 30)
+
+ip21 = iface21.add_address()
+ip21.set_attribute_value("Address", "192.168.0.2")
+ip21.set_attribute_value("NetPrefix", 30)
+
+app1 = netns_desc.create("Application")
+app1.set_attribute_value("command", "ping -qc 10 192.168.0.1")
+app1.set_attribute_value("user", user)
+app1.connector("node").connect(node1.connector("apps"))
+
+app1.enable_trace("stdout")
+
+xml = exp_desc.to_xml()
+
+controller_access_config = proxy.AccessConfiguration()
+controller_access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
+controller_access_config.set_attribute_value(DC.ROOT_DIRECTORY, root_dir)
+controller_access_config.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
+
+controller = proxy.create_experiment_controller(xml, controller_access_config)
+
+controller.start()
+while not controller.is_finished(app1.guid):
+ time.sleep(0.5)
+
+result = controller.trace(app1.guid, "stdout")
+
+controller.stop()
+controller.shutdown()
+
+print result
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Experiment Topology:
+#
+# ns-3 | NETNS
+# |
+
+# fd
+# n1 --- n2 ----- n3 --- n4
+#
+# 0.0 1.0 2.0
+
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+import getpass
+import tempfile
+import time
+
+user = getpass.getuser()
+root_dir = tempfile.mkdtemp()
+
+def create_ns3_node(ns3_desc):
+ node = ns3_desc.create("ns3::Node")
+ ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
+ arp = ns3_desc.create("ns3::ArpL3Protocol")
+ icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
+ udp = ns3_desc.create("ns3::UdpL4Protocol")
+ node.connector("protos").connect(ipv4.connector("node"))
+ node.connector("protos").connect(arp.connector("node"))
+ node.connector("protos").connect(icmp.connector("node"))
+ node.connector("protos").connect(udp.connector("node"))
+ return node
+
+exp_desc = ExperimentDescription()
+
+ns3_provider = FactoriesProvider("ns3")
+ns3_desc = exp_desc.add_testbed_description(ns3_provider)
+ns3_desc.set_attribute_value("homeDirectory", root_dir)
+ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
+ns3_desc.set_attribute_value("ChecksumEnabled", True)
+
+node1 = create_ns3_node(ns3_desc)
+iface12 = ns3_desc.create("ns3::PointToPointNetDevice")
+queue12 = ns3_desc.create("ns3::DropTailQueue")
+node1.connector("devs").connect(iface12.connector("node"))
+iface12.connector("queue").connect(queue12.connector("dev"))
+ip12 = iface12.add_address()
+ip12.set_attribute_value("Address", "10.0.0.1")
+
+node2 = create_ns3_node(ns3_desc)
+iface21 = ns3_desc.create("ns3::PointToPointNetDevice")
+queue21 = ns3_desc.create("ns3::DropTailQueue")
+node2.connector("devs").connect(iface21.connector("node"))
+iface21.connector("queue").connect(queue21.connector("dev"))
+ip21 = iface21.add_address()
+ip21.set_attribute_value("Address", "10.0.0.2")
+
+chan = ns3_desc.create("ns3::PointToPointChannel")
+iface12.connector("chan").connect(chan.connector("dev2"))
+iface21.connector("chan").connect(chan.connector("dev2"))
+
+iface23 = ns3_desc.create("ns3::FdNetDevice")
+node2.connector("devs").connect(iface23.connector("node"))
+ip23 = iface23.add_address()
+ip23.set_attribute_value("Address", "10.0.1.1")
+
+netns_provider = FactoriesProvider("netns")
+netns_desc = exp_desc.add_testbed_description(netns_provider)
+netns_desc.set_attribute_value("homeDirectory", root_dir)
+#netns_desc.set_attribute_value("enableDebug", True)
+
+node3 = netns_desc.create("Node")
+iface32 = netns_desc.create("TapNodeInterface")
+iface32.set_attribute_value("up", True)
+node3.connector("devs").connect(iface32.connector("node"))
+ip32 = iface32.add_address()
+ip32.set_attribute_value("Address", "10.0.1.2")
+
+iface23.connector("->fd").connect(iface32.connector("fd->"))
+
+iface34 = netns_desc.create("P2PNodeInterface")
+iface34.set_attribute_value("up", True)
+node3.connector("devs").connect(iface34.connector("node"))
+ip34 = iface34.add_address()
+ip34.set_attribute_value("Address", "10.0.2.1")
+
+node4 = netns_desc.create("Node")
+node4.set_attribute_value("forward_X11", True)
+iface43 = netns_desc.create("P2PNodeInterface")
+iface43.set_attribute_value("up", True)
+node4.connector("devs").connect(iface43.connector("node"))
+ip43 = iface43.add_address()
+ip43.set_attribute_value("Address", "10.0.2.2")
+
+iface34.connector("p2p").connect(iface43.connector("p2p"))
+
+route = node1.add_route()
+route.set_attribute_value("Destination", "10.0.2.0")
+route.set_attribute_value("NextHop", "10.0.0.2")
+
+route = node2.add_route()
+route.set_attribute_value("Destination", "10.0.2.0")
+route.set_attribute_value("NextHop", "10.0.1.2")
+
+route = node3.add_route()
+route.set_attribute_value("Destination", "10.0.0.0")
+route.set_attribute_value("NextHop", "10.0.1.1")
+
+route = node4.add_route()
+route.set_attribute_value("Destination", "10.0.0.0")
+route.set_attribute_value("NextHop", "10.0.2.1")
+
+app = netns_desc.create("Application")
+app.set_attribute_value("command", "ping -qc 3 10.0.0.1")
+app.set_attribute_value("user", user)
+app.connector("node").connect(node4.connector("apps"))
+app.enable_trace("stdout")
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+
+controller.start()
+while not controller.is_finished(app.guid):
+ time.sleep(0.5)
+
+result = controller.trace(app.guid, "stdout")
+
+controller.stop()
+controller.shutdown()
+
+print result
+
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import getpass
-from optparse import OptionParser
-import os
-import sys
-import shutil
-import tempfile
-import time
-import struct
-import socket
-import operator
-import ipaddr
-import gzip
-import random
-import math
-
-sys.path.append("../../src")
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from nepi.util import proxy
-from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
-from nepi.testbeds.planetlab import util as plutil
-
-class PlanetLabMulticastOverlay:
- testbed_id = "planetlab"
- slicename = "inria_nepi12"
- plchost = "www.planet-lab.eu"
- plkey = os.environ.get(
- "PL_SSH_KEY",
- "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
- pluser = os.environ.get("PL_USER")
- plpass = os.environ.get("PL_PASS")
- vnet = "192.168.2.0"
-
- port_base = 2000 + (os.getpid() % 1000) * 13
-
- def setUp(self):
- self.root_dir = tempfile.mkdtemp()
- self.__class__.port_base = self.__class__.port_base + 100
-
- def tearDown(self):
- try:
- shutil.rmtree(self.root_dir)
- except:
- # retry
- time.sleep(0.1)
- shutil.rmtree(self.root_dir)
-
- def make_experiment_desc(self):
- testbed_id = self.testbed_id
- slicename = self.slicename
- plchost = self.plchost
- pl_ssh_key = self.plkey
- pl_user = self.pluser
- pl_pwd = self.plpass
-
- exp_desc = ExperimentDescription()
- pl_provider = FactoriesProvider(testbed_id)
- pl_desc = exp_desc.add_testbed_description(pl_provider)
- pl_desc.set_attribute_value("homeDirectory", self.root_dir)
- pl_desc.set_attribute_value("slice", slicename)
- pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
- pl_desc.set_attribute_value("authUser", pl_user)
- pl_desc.set_attribute_value("authPass", pl_pwd)
- pl_desc.set_attribute_value("plcHost", plchost)
- pl_desc.set_attribute_value("tapPortBase", self.port_base)
- pl_desc.set_attribute_value("p2pDeployment", True)
- pl_desc.set_attribute_value("dedicatedSlice", True)
- pl_desc.set_attribute_value("plLogLevel", "INFO")
-
- netns_provider = FactoriesProvider("netns")
- netns = exp_desc.add_testbed_description(netns_provider)
- netns.set_attribute_value("homeDirectory", self.root_dir)
- netns.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- netns_root_dir = os.path.join(self.root_dir, "netns")
- os.mkdir(netns_root_dir)
- netns.set_attribute_value(DC.ROOT_DIRECTORY, netns_root_dir)
- netns.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- netns.set_attribute_value(DC.USE_SUDO, True)
-
- return pl_desc, netns, exp_desc
-
- def make_pl_tapnode(self, pl, ip, inet = None, label = None, hostname = None, routes = None, mcast = False, mcastrouter = False):
- if not isinstance(ip, list):
- ips = [ip]
- else:
- ips = ip
- node1 = pl.create("Node")
- if label:
- node1.set_attribute_value("label", label)
- if hostname:
- node1.set_attribute_value("hostname", hostname)
- iface1 = pl.create("NodeInterface")
- if label:
- iface1.set_attribute_value("label", label+"iface")
- tap1 = []
- tap1ip = []
- for i,ip in enumerate(ips):
- _tap1 = pl.create("TapInterface")
- _tap1.set_attribute_value("multicast", True)
- _tap1.enable_trace("pcap") # for error output
- if label:
- _tap1.set_attribute_value("label", label+"tap"+(str(i+1) if i else ""))
-
- _tap1ip = self.add_ip_address(_tap1, ip, 32)
-
- node1.connector("devs").connect(_tap1.connector("node"))
-
- tap1.append(_tap1)
- tap1ip.append(_tap1ip)
-
- inet = inet or pl.create("Internet")
- node1.connector("devs").connect(iface1.connector("node"))
- iface1.connector("inet").connect(inet.connector("devs"))
-
- for destip, destprefix, nexthop in routes:
- r1 = self.add_route(node1, destip, destprefix, nexthop)
-
- if mcast:
- fwd = pl.create("MulticastForwarder")
- fwd.enable_trace("stderr")
- fwd.connector("node").connect(node1.connector("apps"))
- if mcastrouter:
- mrt = pl.create("MulticastRouter")
- mrt.connector("fwd").connect(fwd.connector("router"))
- mrt.enable_trace("stderr")
-
- return node1, iface1, tap1, tap1ip, inet
-
- def add_ip_address(self, iface, address, netprefix, broadcast = False):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
- ip.set_attribute_value("NetPrefix", netprefix)
- ip.set_attribute_value("Broadcast", broadcast)
- return ip
-
- def add_route(self, node, destination, netprefix, nexthop):
- route = node.add_route()
- route.set_attribute_value("Destination", destination)
- route.set_attribute_value("NetPrefix", netprefix)
- route.set_attribute_value("NextHop", nexthop)
- return route
-
- def add_vlc_base(self, pl, node):
- app = pl.create("Application")
- app.set_attribute_value("rpmFusion", True)
- app.set_attribute_value("depends", "vlc")
- app.set_attribute_value("command", "vlc --version")
- app.enable_trace("stdout")
- app.enable_trace("stderr")
- node.connector("apps").connect(app.connector("node"))
- return app
-
- def add_vlc_restreamer(self, pl, node):
- hostname = node.get_attribute_value("hostname")
- app = self.add_vlc_base(pl, node)
- app.set_attribute_value("label","vlc_restreamer_%d" % (node.guid,))
- app.set_attribute_value("command",
- "vlc -vvv -I dummy"
- " udp://@239.255.12.42"
- " --sout '#rtp{port=6060,sdp=rtsp://"+hostname+":8080/test.sdp}'")
- return app
-
- def add_vlc_dumper(self, pl, node):
- app = self.add_vlc_base(pl, node)
- app.set_attribute_value("label","vlc_dumper_%d" % (node.guid,))
- app.set_attribute_value("command",
- "vlc -vvv -I dummy"
- " udp://@239.255.12.42"
- " --sout output")
- app.enable_trace("output")
- return app
-
- def add_vlc_source(self, netns, node, iflabel):
- app = netns.create("Application")
- app.set_attribute_value("user", self.user)
- app.set_attribute_value("label","vlc_source_%d" % (node.guid,))
- app.set_attribute_value("command",
- "vlc -vvv -I dummy "
- +os.path.basename(self.movie_source)
- +"--miface-addr {#[%s].addr[0].[Address]#} " % (iflabel,)
- +"--sout '#udp{dst=239.255.12.42,ttl=64}'")
- app.connector("node").connect(node.connector("apps"))
- return app
-
- def add_net_monitor(self, pl, node):
- app = pl.create("Application")
- app.set_attribute_value("label","network_monitor_%d" % (node.guid,))
- app.set_attribute_value("command",
- r"""head -n 2 /proc/net/dev ; while true ; do cat /proc/net/dev | sed -r 's/.*/'"$(date -R)"': \0/' | grep eth0 ; sleep 1 ; done""")
- app.enable_trace("stdout")
- node.connector("apps").connect(app.connector("node"))
- return app
-
- def make_ns_in_pl(self, pl, exp, node1, iface1, root):
- ns3_testbed_id = "ns3"
-
- # Add NS3 support in node1
- plnepi = pl.create("NepiDependency")
- plns3 = pl.create("NS3Dependency")
- plnepi.connector("node").connect(node1.connector("deps"))
- plns3.connector("node").connect(node1.connector("deps"))
-
- # Create NS3 testbed running in node1
- ns3_provider = FactoriesProvider(ns3_testbed_id)
- ns = exp.add_testbed_description(ns3_provider)
- ns.set_attribute_value("rootDirectory", root)
- ns.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
- ns.set_attribute_value("ChecksumEnabled", True)
- ns.set_attribute_value(DC.DEPLOYMENT_HOST, "{#[%s].addr[0].[Address]#}" % (
- iface1.get_attribute_value("label"),))
- ns.set_attribute_value(DC.DEPLOYMENT_USER,
- pl.get_attribute_value("slice"))
- ns.set_attribute_value(DC.DEPLOYMENT_KEY,
- pl.get_attribute_value("sliceSSHKey"))
- ns.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- ns.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
- ns.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP,
- "{#[%s].[%s]#}" % (
- node1.get_attribute_value("label"),
- ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP,))
- ns.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
-
- return ns
-
- def add_pl_ns_node(self, pl_desc, inet, label_prefix):
- node = pl_desc.create("Node")
- node.set_attribute_value("label", label_prefix)
- iface = pl_desc.create("NodeInterface")
- iface.set_attribute_value("label", label_prefix+"iface")
- iface.connector("inet").connect(inet.connector("devs"))
- node.connector("devs").connect(iface.connector("node"))
- forwarder = pl_desc.create("MulticastForwarder")
- forwarder.enable_trace("stderr")
- node.connector("apps").connect(forwarder.connector("node"))
- return node, iface
-
- def add_pl_ns_connection(self, pl_desc, pl_node, pl_addr,
- ns, ns_node, ns_addr):
- pl_tap = pl_desc.create("TapInterface")
- pl_tap.set_attribute_value("tun_cipher", "PLAIN")
- self.add_ip_address(pl_tap, pl_addr, 31)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
- ns_fdnd = ns.create("ns3::FdNetDevice")
- ns_node.connector("devs").connect(ns_fdnd.connector("node"))
- self.add_ip_address(ns_fdnd, ns_addr, 31)
- pl_tap.connector("fd->").connect(ns_fdnd.connector("->fd"))
-
- def add_pl_ns_tunchan_connection(self, pl_desc, pl_node, pl_addr,
- ns, ns_node, ns_addr):
- pl_tap = pl_desc.create("TunInterface")
- self.add_ip_address(pl_tap, pl_addr, 31)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
- ns_fdnd = ns.create("ns3::FdNetDevice")
- ns_fdnd.enable_trace("FdPcapTrace")
- self.add_ip_address(ns_fdnd, ns_addr, 31)
- ns_node.connector("devs").connect(ns_fdnd.connector("node"))
- ns_tc = ns.create("ns3::Nepi::TunChannel")
- ns_tc.connector("fd->").connect(ns_fdnd.connector("->fd"))
- pl_tap.connector("tcp").connect(ns_tc.connector("tcp"))
-
- def make_netns_node(self, netns):
- node = netns.create("Node")
- node.set_attribute_value("forward_X11", True)
- command = "xterm"
- app = netns.create("Application")
- app.set_attribute_value("command", command)
- app.set_attribute_value("user", self.user)
- app.connector("node").connect(node.connector("apps"))
- return node
-
- def make_pl_netns_connection(self, pl_desc, pl_node, netns,
- netns_node, netns_iface_label):
- base=struct.unpack('!L',socket.inet_aton(self.vnet))[0]
- netns_addr = socket.inet_ntoa(struct.pack('!L',(base | 1)))
- pl_addr = socket.inet_ntoa(struct.pack('!L',(base | 2)))
- pl_tap = pl_desc.create("TunInterface")
- pl_tap.set_attribute_value("multicast", True)
- #pl_tap.set_attribute_value("tun_cipher", "PLAIN")
- #pl_tap.enable_trace("pcap")
- #pl_tap.enable_trace("packets")
- self.add_ip_address(pl_tap, pl_addr, 31)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
-
- netns_tap = netns.create("TunNodeInterface")
- netns_tap.set_attribute_value("label", netns_iface_label)
- netns_tap.set_attribute_value("up", True)
- netns_tap.set_attribute_value("mtu", 1448)
- self.add_ip_address(netns_tap, netns_addr, 31)
- self.add_route(netns_node, self.vnet, 24, pl_addr)
- netns_node.connector("devs").connect(netns_tap.connector("node"))
-
- netns_tunchannel = netns.create("TunChannel")
- #netns_tunchannel.set_attribute_value("tun_cipher", "PLAIN")
- netns_tunchannel.connector("->fd").connect(netns_tap.connector("fd->"))
- pl_tap.connector("tcp").connect(netns_tunchannel.connector("tcp"))
-
- def add_ns_fdnd(self, ns, node):
- fdnd = ns.create("ns3::FdNetDevice")
- node.connector("devs").connect(fdnd.connector("node"))
- #fdnd.enable_trace("FdPcapTrace")
- return fdnd
-
- def add_ns_node(self, ns):
- node = ns.create("ns3::Node")
- ipv4 = ns.create("ns3::Ipv4L3Protocol")
- arp = ns.create("ns3::ArpL3Protocol")
- icmp = ns.create("ns3::Icmpv4L4Protocol")
- udp = ns.create("ns3::UdpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- return node
-
- def add_ns_wifi_dev(self, ns, node, access_point = False):
- wifi = ns.create("ns3::WifiNetDevice")
- node.connector("devs").connect(wifi.connector("node"))
-
- phy = ns.create("ns3::YansWifiPhy")
- error = ns.create("ns3::NistErrorRateModel")
- manager = ns.create("ns3::ArfWifiManager")
- if access_point:
- mac = ns.create("ns3::ApWifiMac")
- else:
- mac = ns.create("ns3::StaWifiMac")
-
- phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- phy.connector("err").connect(error.connector("phy"))
- wifi.connector("phy").connect(phy.connector("dev"))
- wifi.connector("mac").connect(mac.connector("dev"))
- wifi.connector("manager").connect(manager.connector("dev"))
-
- #phy.enable_trace("YansWifiPhyPcapTrace")
- return wifi, phy
-
- def add_ns_constant_mobility(self, ns, node, x, y, z):
- mobility = ns.create("ns3::ConstantPositionMobilityModel")
- position = "%d:%d:%d" % (x, y, z)
- mobility.set_attribute_value("Position", position)
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns_wifi_channel(self, ns):
- channel = ns.create("ns3::YansWifiChannel")
- delay = ns.create("ns3::ConstantSpeedPropagationDelayModel")
- loss = ns.create("ns3::LogDistancePropagationLossModel")
- channel.connector("delay").connect(delay.connector("chan"))
- channel.connector("loss").connect(loss.connector("prev"))
- return channel
-
- def make_ns_wifi(self, ns, pl, pl_ns_root, inet, numwifinodes, nextip):
- base=struct.unpack('!L',socket.inet_aton(self.vnet))[0]
- error = False
- for i in xrange(2, 6):
- nr = int(math.pow(2, i))
- if nr <= (numwifinodes + 2):
- break
- else:
- error = True
-
- # how many IPs will we need?
- # 1 for the AP, 2 for each station and one for each extra PL node
- # BUT we need to also reserve IPs to sum up to a posible subnetwork
- # number of nodes: 2, 4, 8, 16, etc ...
- # And finally, we need 2 extra IPs for the PL-AP iface
-
- nrips = (1 + 2*numwifinodes + nr + 2)
- if nrips + nextip[0] > 255:
- error = True
- if error:
- raise RuntimeError("There are not enough IP addresses for the wireless network", )
-
- netprefix = 32 - i
- _nextwifiip = [254]
- def nextwifiip():
- ip = socket.inet_ntoa(struct.pack('!L',(base | _nextwifiip[0])))
- _nextwifiip[0] -= 1
- return ip
-
- _nextnstapip = [(254 - nr -1)]
- def nextnstapip():
- ip = socket.inet_ntoa(struct.pack('!L',(base | _nextnstapip[0])))
- _nextnstapip[0] -= 1
- return ip
-
- _nexttapip = [(254 - nr - 1 - numwifinodes)]
- def nexttapip():
- ip = socket.inet_ntoa(struct.pack('!L',(base | _nexttapip[0])))
- _nexttapip[0] -= 1
- return ip
-
- # WIFI network
- wifi_chan = self.add_ns_wifi_channel(ns)
-
- # AP node
- ap_node = self.add_ns_node(ns)
- self.add_ns_constant_mobility(ns, ap_node, 0, 0, 0)
- ap_wifi, ap_phy = self.add_ns_wifi_dev(ns, ap_node, access_point = True)
- ap_phy.connector("chan").connect(wifi_chan.connector("phys"))
-
- # connect AP to PL
- _nextplip = (254 - nrips)
- pl_ip = socket.inet_ntoa(struct.pack('!L',(base | _nextplip)))
- print "PL IP %s" % pl_ip
- _nextplip -= 1
- ns_ip = socket.inet_ntoa(struct.pack('!L',(base | _nextplip)))
- print "NS IP %s" % ns_ip
- self.add_pl_ns_connection(pl, pl_ns_root, pl_ip, ns, ap_node, ns_ip)
-
- # routes in and out ns
- self.add_route(ap_node, self.vnet, 24, pl_ip)
- net = 256 - nr
- ip = socket.inet_ntoa(struct.pack('!L',(base | net)))
- self.add_route(pl_ns_root, ip, netprefix, ns_ip)
-
- ap_ip = nextwifiip()
- print "AP IP %s" % ap_ip
- self.add_ip_address(ap_wifi, ap_ip, netprefix)
-
- r = 50
- # STA nodes
- for i in xrange(0, numwifinodes):
- stai = self.add_ns_node(ns)
- angi = (360/numwifinodes)*i
- xi = r*math.cos(angi)
- yi = r*math.sin(angi)
- self.add_ns_constant_mobility(ns, stai, xi, yi, 0)
- wifi, phy = self.add_ns_wifi_dev(ns, stai, access_point = False)
- phy.connector("chan").connect(wifi_chan.connector("phys"))
-
- wifi_ip = nextwifiip()
- print "WIFI IP %s" % wifi_ip
- self.add_ip_address(wifi, wifi_ip, netprefix)
- self.add_route(stai, self.vnet, 24, ap_ip)
-
- """
- pl_nodei, pl_ifacei = self.add_pl_ns_node(pl, inet,
- "node2%d_pl"%i)
-
- pl_addr = (self.base_addr%(net+1))
- ns3_addr = (self.base_addr%(net+2))
- self.add_pl_ns_tunchan_connection(pl_desc, pl_nodei, pl_addr,
- ns, stai, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%32), 27, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%0), 30, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%4), 30, ns3_addr)
-
- network = (self.base_addr%net)
- self.add_route(netns_node, network, 30, (self.base_addr%2))
- self.add_route(pl_node1, network, 30, (self.base_addr%6))
- self.add_route(ap_node, network, 30, wifi_addr)
- """
-
- def make_pl_overlay(self, numnodes, numwifinodes):
- print "make_pl_overlay ..."
- ns3_testbed_id = "ns3"
-
- pl, netns, exp = self.make_experiment_desc()
- # We'll make a distribution spanning tree using prefix matching as a distance
- api = plutil.getAPI(self.pluser, self.plpass)
- nodes = plutil.getNodes(api, numnodes, operatingSystem = 'f12')
- root = min(nodes, key=operator.attrgetter('hostname'))
- links = list(plutil.getSpanningTree(nodes, root=root))
-
- for node in nodes:
- node.vif_ips = set()
- node.children = []
- node.childips = set()
-
- # Build an explicit tree
- for slave, master in links:
- master.children.append(slave)
-
- # We have to assign IPs and routes.
- # The IP will be assigned sequentially, depth-first.
- # This will result in rather compact routing rules
- nextip = [128-numnodes]
- def traverse(traverse, node, parent=None, base=struct.unpack('!L',socket.inet_aton(self.vnet))[0]):
- if nextip[0] >= 254:
- raise RuntimeError, "Too many IPs to assign!"
-
- node.vif_addr = base | (nextip[0])
- nips = 1+len(node.children) # one vif per child, plus one for the parent
- nextip[0] += nips
-
- for i in xrange(nips):
- node.vif_ips.add(node.vif_addr+i)
-
- if parent:
- parent.childips.update(node.vif_ips)
-
- for i,child in enumerate(node.children):
- traverse(traverse, child, node, base)
-
- if parent:
- parent.childips.update(node.childips)
-
- print "traverse..."
- traverse(traverse, root)
-
- def printtree(printtree, node, indent=''):
- print indent, '-', socket.inet_ntoa(struct.pack('!L',node.vif_addr)), node.country, node.city, node.site
- for child in node.children:
- childips = map(ipaddr.IPAddress, child.childips)
- childnets = ipaddr.collapse_address_list(childips)
- cip = ipaddr.IPAddress(child.vif_addr)
- for cnet in childnets:
- print indent, '|- R', cnet, '->', cip
- printtree(printtree, child, indent+' | ')
- printtree(printtree, root)
-
- inet = pl.create("Internet")
-
- ns_chosen = []
-
- def maketree(maketree, node, parent=None, parentIp=None):
- routes = []
- ctaps = []
- for i,child in enumerate(node.children):
- childips = map(ipaddr.IPAddress, child.childips)
- childnets = ipaddr.collapse_address_list(childips)
- cip = ipaddr.IPAddress(child.vif_addr)
- pip = ipaddr.IPAddress(node.vif_addr+1+i)
- for cnet in childnets:
- routes.append((cnet.ip.exploded, cnet.prefixlen, cip.exploded))
- ctaps.append( maketree(maketree, child, node, pip) )
-
- if parentIp:
- routes.append((self.vnet,24,parentIp))
-
- if not parent:
- label = "root"
- else:
- label = None
- if not ns_chosen and node.children:
- ns_chosen.append(True)
- label = "ns_root"
- ips = [ ipaddr.IPAddress(node.vif_addr+i) for i in xrange(1+len(node.children)) ]
- node1, iface1, tap1, tap1ip, _ = self.make_pl_tapnode(pl, ips, inet,
- hostname = node.hostname,
- routes = routes,
- mcastrouter = bool(node.children),
- mcast = True,
- label = label )
-
- for tap, ctap in zip(tap1[1:], ctaps):
- tap.connector("udp").connect(ctap.connector("udp"))
-
- self.add_net_monitor(pl, node1)
- self.add_vlc_restreamer(pl, node1)
- if random.random() < 0.1 and parent:
- self.add_vlc_dumper(pl, node1)
-
- return tap1[0]
-
- print "maketree..."
- maketree(maketree, root)
-
- # create a netns node and connect it to the root pl node
- pl_root = exp.get_element_by_label("root")
- netns_source = self.make_netns_node(netns)
- iflabel = "source-iface"
- self.make_pl_netns_connection(pl, pl_root, netns,
- netns_source, iflabel)
- self.add_vlc_source(netns, netns_source, iflabel)
-
- # add ns wireless network
- pl_ns_root = exp.get_element_by_label("ns_root")
- pl_ns_root_iface = exp.get_element_by_label("ns_rootiface")
- ns = self.make_ns_in_pl(pl, exp, pl_ns_root, pl_ns_root_iface, "ns3")
- self.make_ns_wifi(ns, pl, pl_ns_root, inet, numwifinodes, nextip)
-
- xml = exp.to_xml()
- test_dir = "./results"
-
- try:
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
-
- print >>sys.stderr, "Press CTRL-C to shut down"
- try:
- while True:
- time.sleep(10)
- except KeyboardInterrupt:
- pass
-
- # download results
- for testbed_guid, guids in controller.traces_info().iteritems():
- for guid, traces in guids.iteritems():
- for name, data in traces.iteritems():
- path = data["filepath"]
-
- if not path:
- continue
-
- print >>sys.stderr, "Downloading trace", path
-
- filepath = os.path.join(test_dir, path)
-
- try:
- trace = controller.trace(guid, name)
- except:
- traceback.print_exc(file=sys.stderr)
- continue
- try:
- if not os.path.exists(os.path.dirname(filepath)):
- os.makedirs(os.path.dirname(filepath))
- except:
- traceback.print_exc(file=sys.stderr)
-
- try:
- if len(trace) >= 2**20:
- # Bigger than 1M, compress
- tracefile = gzip.GzipFile(filepath+".gz", "wb")
- else:
- tracefile = open(filepath,"wb")
- try:
- tracefile.write(trace)
- finally:
- tracefile.close()
- except:
- traceback.print_exc(file=sys.stderr)
- finally:
- try:
- controller.stop()
- except:
- import traceback
- traceback.print_exc()
- try:
- controller.shutdown()
- except:
- import traceback
- traceback.print_exc()
-
-
-if __name__ == '__main__':
- usage = "usage: %prog -n number_sta -m movie -u user"
- parser = OptionParser(usage=usage)
- parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str", default=os.getlogin())
- parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
- parser.add_option("-n", "--nsta", dest="nsta", help="Number of wifi stations", type="int")
- parser.add_option("-N", "--nodes", dest="nsta", help="Number of overlay nodes", type="int")
- parser.add_option("-a", "--base_addr", dest="base_addr", help="Base address segment for the experiment", type="str")
- parser.add_option("-s", "--slicename", dest="slicename", help="PlanetLab slice", type="str")
- (options, args) = parser.parse_args()
- if not options.movie:
- parser.error("Missing 'movie' option.")
- if options.user == 'root':
- parser.error("Missing or invalid 'user' option.")
- if options.nsta and options.nsta > 8:
- parser.error("Try a number of stations under 9.")
-
- exp = PlanetLabMulticastOverlay()
- exp.movie_source = options.movie
- exp.user = options.user
- try:
- exp.setUp()
- exp.make_pl_overlay(5, 2)
- finally:
- exp.tearDown()
-
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Experiment Topology:
+#
+# n1 --- n2 --- n3
+# 0.1 0.2 1.1 1.2
+#
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+import getpass
+import tempfile
+import time
+
+user = getpass.getuser()
+root_dir = tempfile.mkdtemp()
+
+exp_desc = ExperimentDescription()
+
+testbed_id = "netns"
+netns_provider = FactoriesProvider(testbed_id)
+netns_desc = exp_desc.add_testbed_description(netns_provider)
+netns_desc.set_attribute_value("homeDirectory", root_dir)
+#netns_desc.set_attribute_value("enableDebug", True)
+
+node1 = netns_desc.create("Node")
+node2 = netns_desc.create("Node")
+node3 = netns_desc.create("Node")
+
+iface12 = netns_desc.create("P2PNodeInterface")
+iface12.set_attribute_value("up", True)
+node1.connector("devs").connect(iface12.connector("node"))
+
+iface21 = netns_desc.create("P2PNodeInterface")
+iface21.set_attribute_value("up", True)
+node2.connector("devs").connect(iface21.connector("node"))
+
+iface23 = netns_desc.create("P2PNodeInterface")
+iface23.set_attribute_value("up", True)
+node2.connector("devs").connect(iface23.connector("node"))
+
+iface32 = netns_desc.create("P2PNodeInterface")
+iface32.set_attribute_value("up", True)
+node3.connector("devs").connect(iface32.connector("node"))
+
+iface12.connector("p2p").connect(iface21.connector("p2p"))
+iface23.connector("p2p").connect(iface32.connector("p2p"))
+
+ip12 = iface12.add_address()
+ip12.set_attribute_value("Address", "192.168.0.1")
+ip12.set_attribute_value("NetPrefix", 30)
+
+ip21 = iface21.add_address()
+ip21.set_attribute_value("Address", "192.168.0.2")
+ip21.set_attribute_value("NetPrefix", 30)
+
+ip23 = iface23.add_address()
+ip23.set_attribute_value("Address", "192.168.1.1")
+ip23.set_attribute_value("NetPrefix", 30)
+
+ip32 = iface32.add_address()
+ip32.set_attribute_value("Address", "192.168.1.2")
+ip32.set_attribute_value("NetPrefix", 30)
+
+route1 = node1.add_route()
+route1.set_attribute_value("Destination", "192.168.1.0")
+route1.set_attribute_value("NetPrefix", 30)
+route1.set_attribute_value("NextHop", "192.168.0.2")
+
+route2 = node3.add_route()
+route2.set_attribute_value("Destination", "192.168.0.0")
+route2.set_attribute_value("NetPrefix", 30)
+route2.set_attribute_value("NextHop", "192.168.1.1")
+
+app1 = netns_desc.create("Application")
+app1.set_attribute_value("command", "ping -qc 3 192.168.1.2")
+app1.set_attribute_value("user", user)
+app1.connector("node").connect(node1.connector("apps"))
+
+app1.enable_trace("stdout")
+
+app2 = netns_desc.create("Application")
+app2.set_attribute_value("command", "ping -qc 3 192.168.0.1")
+app2.set_attribute_value("user", user)
+app2.connector("node").connect(node3.connector("apps"))
+
+app2.enable_trace("stdout")
+
+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)
+
+result1 = controller.trace(app1.guid, "stdout")
+result2 = controller.trace(app2.guid, "stdout")
+
+controller.stop()
+controller.shutdown()
+
+print result1
+print result2
--- /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
+
+user = getpass.getuser()
+root_dir = tempfile.mkdtemp()
+
+exp_desc = ExperimentDescription()
+
+testbed_id = "netns"
+netns_provider = FactoriesProvider(testbed_id)
+netns_desc = exp_desc.add_testbed_description(netns_provider)
+netns_desc.set_attribute_value("homeDirectory", root_dir)
+#netns_desc.set_attribute_value("enableDebug", True)
+
+node1 = netns_desc.create("Node")
+node1.set_attribute_value("forward_X11", True)
+node2 = netns_desc.create("Node")
+node2.set_attribute_value("forward_X11", True)
+
+iface12 = netns_desc.create("P2PNodeInterface")
+iface12.set_attribute_value("up", True)
+node1.connector("devs").connect(iface12.connector("node"))
+
+iface21 = netns_desc.create("P2PNodeInterface")
+iface21.set_attribute_value("up", True)
+node2.connector("devs").connect(iface21.connector("node"))
+
+iface12.connector("p2p").connect(iface21.connector("p2p"))
+
+ip12 = iface12.add_address()
+ip12.set_attribute_value("Address", "192.168.0.1")
+ip12.set_attribute_value("NetPrefix", 30)
+
+ip21 = iface21.add_address()
+ip21.set_attribute_value("Address", "192.168.0.2")
+ip21.set_attribute_value("NetPrefix", 30)
+
+app1 = netns_desc.create("Application")
+app1.set_attribute_value("command", "xterm")
+app1.set_attribute_value("user", user)
+app1.connector("node").connect(node1.connector("apps"))
+
+app2 = netns_desc.create("Application")
+app2.set_attribute_value("command", "xterm")
+app2.set_attribute_value("user", user)
+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)
+
+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 tempfile
+import time
+
+root_dir = tempfile.mkdtemp()
+
+exp_desc = ExperimentDescription()
+
+testbed_id = "ns3"
+ns3_provider = FactoriesProvider(testbed_id)
+ns3_desc = exp_desc.add_testbed_description(ns3_provider)
+ns3_desc.set_attribute_value("homeDirectory", root_dir)
+ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
+ns3_desc.set_attribute_value("ChecksumEnabled", True)
+
+node1 = ns3_desc.create("ns3::Node")
+ipv41 = ns3_desc.create("ns3::Ipv4L3Protocol")
+arp1 = ns3_desc.create("ns3::ArpL3Protocol")
+icmp1 = ns3_desc.create("ns3::Icmpv4L4Protocol")
+node1.connector("protos").connect(ipv41.connector("node"))
+node1.connector("protos").connect(arp1.connector("node"))
+node1.connector("protos").connect(icmp1.connector("node"))
+iface1 = ns3_desc.create("ns3::PointToPointNetDevice")
+queue1 = ns3_desc.create("ns3::DropTailQueue")
+node1.connector("devs").connect(iface1.connector("node"))
+iface1.connector("queue").connect(queue1.connector("dev"))
+trace1 = iface1.enable_trace("P2PAsciiTrace")
+ip1 = iface1.add_address()
+ip1.set_attribute_value("Address", "10.0.0.1")
+
+node2 = ns3_desc.create("ns3::Node")
+ipv42 = ns3_desc.create("ns3::Ipv4L3Protocol")
+arp2 = ns3_desc.create("ns3::ArpL3Protocol")
+icmp2 = ns3_desc.create("ns3::Icmpv4L4Protocol")
+node2.connector("protos").connect(ipv42.connector("node"))
+node2.connector("protos").connect(arp2.connector("node"))
+node2.connector("protos").connect(icmp2.connector("node"))
+iface2 = ns3_desc.create("ns3::PointToPointNetDevice")
+queue2 = ns3_desc.create("ns3::DropTailQueue")
+node2.connector("devs").connect(iface2.connector("node"))
+iface2.connector("queue").connect(queue2.connector("dev"))
+trace2 = iface2.enable_trace("P2PAsciiTrace")
+ip2 = iface2.add_address()
+ip2.set_attribute_value("Address", "10.0.0.2")
+
+chan = ns3_desc.create("ns3::PointToPointChannel")
+chan.set_attribute_value("Delay", "0ns")
+iface1.connector("chan").connect(chan.connector("dev2"))
+iface2.connector("chan").connect(chan.connector("dev2"))
+
+app = ns3_desc.create("ns3::V4Ping")
+app.set_attribute_value("Remote", "10.0.0.2")
+app.set_attribute_value("Verbose", True)
+app.set_attribute_value("StartTime", "0s")
+app.set_attribute_value("StopTime", "20s")
+
+app.connector("node").connect(node1.connector("apps"))
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+controller.start()
+
+time.sleep(5)
+
+controller.set(chan.guid, "Delay", "10s")
+
+time.sleep(5)
+
+controller.set(chan.guid, "Delay", "0s")
+
+while not controller.is_finished(app.guid):
+ time.sleep(0.5)
+
+controller.stop()
+controller.shutdown()
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import getpass
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util import proxy
+from nepi.util.constants import DeploymentConfiguration as DC
+import os
+import shutil
+import tempfile
+import time
+
+root_dir = tempfile.mkdtemp()
+user = getpass.getuser()
+slicename = os.environ["PL_SLICE"]
+plchost = "www.planet-lab.eu"
+port_base = 2000 + (os.getpid() % 1000) * 13
+pl_ssh_key = os.environ.get(
+ "PL_SSH_KEY",
+ "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+pl_user = os.environ.get('PL_USER')
+pl_pwd = os.environ.get('PL_PASS')
+
+exp_desc = ExperimentDescription()
+
+pl_provider = FactoriesProvider("planetlab")
+pl_desc = exp_desc.add_testbed_description(pl_provider)
+pl_desc.set_attribute_value("homeDirectory", root_dir)
+pl_desc.set_attribute_value("slice", slicename)
+pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
+pl_desc.set_attribute_value("authUser", pl_user)
+pl_desc.set_attribute_value("authPass", pl_pwd)
+pl_desc.set_attribute_value("plcHost", plchost)
+pl_desc.set_attribute_value("tapPortBase", port_base)
+pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
+pl_desc.set_attribute_value("cleanProc", True)
+pl_desc.set_attribute_value("plLogLevel", "DEBUG")
+
+pl_inet = pl_desc.create("Internet")
+
+pl_node1 = pl_desc.create("Node")
+pl_iface1 = pl_desc.create("NodeInterface")
+pl_iface1.set_attribute_value("label", "iface1")
+pl_iface1.connector("inet").connect(pl_inet.connector("devs"))
+pl_node1.connector("devs").connect(pl_iface1.connector("node"))
+
+pl_node2 = pl_desc.create("Node")
+pl_iface2 = pl_desc.create("NodeInterface")
+pl_iface2.set_attribute_value("label", "iface2")
+pl_iface2.connector("inet").connect(pl_inet.connector("devs"))
+pl_node2.connector("devs").connect(pl_iface2.connector("node"))
+
+pl_app1 = pl_desc.create("Application")
+pl_app1.set_attribute_value("command", "ping -qc3 {#[iface2].addr[0].[Address]#}")
+pl_app1.enable_trace("stdout")
+pl_app1.connector("node").connect(pl_node1.connector("apps"))
+
+pl_app2 = pl_desc.create("Application")
+pl_app2.set_attribute_value("command", "ping -qc3 {#[iface1].addr[0].[Address]#}")
+pl_app2.enable_trace("stdout")
+pl_app2.connector("node").connect(pl_node2.connector("apps"))
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+controller.start()
+while (not controller.is_finished(pl_app1.guid) or not controller.is_finished(pl_app1.guid)):
+ time.sleep(0.5)
+
+ping_result1 = controller.trace(pl_app1.guid, "stdout")
+print ping_result1
+ping_result2 = controller.trace(pl_app2.guid, "stdout")
+print ping_result2
+
+controller.stop()
+controller.shutdown()
+
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from optparse import OptionParser, SUPPRESS_HELP
-from nepi.util import proxy
-from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
-import os
-import shutil
-import tempfile
-import time
-import sys
-import random
-
-def pl_auth():
- user = os.environ.get('PL_USER')
- pwd = os.environ.get('PL_PASS')
-
- if user and pwd:
- return (user,pwd)
- else:
- return None
-
-class Roads09Ns3PLExample(object):
- testbed_id = "planetlab"
- slicename = "inria_nepi"
- plchost = "nepiplc.pl.sophia.inria.fr"
-
- host1 = "nepi1.pl.sophia.inria.fr"
- host2 = "nepi2.pl.sophia.inria.fr"
- host3 = "nepi3.pl.sophia.inria.fr"
- host4 = "nepi5.pl.sophia.inria.fr"
-
- def __init__(self):
- #usage = "usage: %prog -m movie -u user"
- #parser = OptionParser(usage=usage)
- #parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
- #parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
- #(options, args) = parser.parse_args()
- #if not options.movie:
- # parser.error("Missing 'movie' option.")
- #if options.user == 'root':
- # parser.error("Missing or invalid 'user' option.")
-
- #self.user = options.user if options.user else os.getlogin()
- #self.movie = options.movie
-
- if not pl_auth():
- print "Example requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)"
- sys.exit(1)
-
- self.root_dir = tempfile.mkdtemp()
-
-
- def make_experiment_desc(self):
- testbed_id = self.testbed_id
- slicename = self.slicename
- plchost = self.plchost
- pl_ssh_key = os.environ.get(
- "PL_SSH_KEY",
- "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
- pl_user, pl_pwd = pl_auth()
-
- exp_desc = ExperimentDescription()
- pl_provider = FactoriesProvider(testbed_id)
- pl_desc = exp_desc.add_testbed_description(pl_provider)
- pl_desc.set_attribute_value("homeDirectory", self.root_dir)
- pl_desc.set_attribute_value("slice", slicename)
- pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
- pl_desc.set_attribute_value("authUser", pl_user)
- pl_desc.set_attribute_value("authPass", pl_pwd)
- pl_desc.set_attribute_value("plcHost", plchost)
-
- return pl_desc, exp_desc
-
- def make_ns_in_pl(self, pl, exp, node1, iface1, root):
- ns3_testbed_id = "ns3"
-
- # Add NS3 support in node1
- plnepi = pl.create("NepiDependency")
- plns3 = pl.create("NS3Dependency")
- plnepi.connector("node").connect(node1.connector("deps"))
- plns3.connector("node").connect(node1.connector("deps"))
-
- # Create NS3 testbed running in node1
- ns3_provider = FactoriesProvider(ns3_testbed_id)
- ns3_desc = exp.add_testbed_description(ns3_provider)
- ns3_desc.set_attribute_value("rootDirectory", root)
- ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
- ns3_desc.set_attribute_value("ChecksumEnabled", True)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_HOST, "{#[%s].addr[0].[Address]#}" % (
- iface1.get_attribute_value("label"),))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_USER,
- pl.get_attribute_value("slice"))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_KEY,
- pl.get_attribute_value("sliceSSHKey"))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP,
- "{#[%s].[%s]#}" % (
- node1.get_attribute_value("label"),
- ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP,))
- ns3_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
-
- return ns3_desc
-
-
-
- def add_ns3_fdnd(self, node, ns3_desc):
- fdnd = ns3_desc.create("ns3::FdNetDevice")
- node.connector("devs").connect(fdnd.connector("node"))
- fdnd.enable_trace("FdPcapTrace")
- return fdnd
-
- def add_ns3_node(self, ns3_desc):
- node = ns3_desc.create("ns3::Node")
- ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
- arp = ns3_desc.create("ns3::ArpL3Protocol")
- icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
- udp = ns3_desc.create("ns3::UdpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- return node
-
- def add_ns3_wifi(self, node, ns3_desc, access_point = False, ip = None, prefix = 24):
- wifi = ns3_desc.create("ns3::WifiNetDevice")
- node.connector("devs").connect(wifi.connector("node"))
-
- phy = ns3_desc.create("ns3::YansWifiPhy")
- error = ns3_desc.create("ns3::NistErrorRateModel")
- manager = ns3_desc.create("ns3::ArfWifiManager")
- if access_point:
- mac = ns3_desc.create("ns3::QapWifiMac")
- else:
- mac = ns3_desc.create("ns3::QstaWifiMac")
-
- phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- phy.connector("err").connect(error.connector("phy"))
- wifi.connector("phy").connect(phy.connector("dev"))
- wifi.connector("mac").connect(mac.connector("dev"))
- wifi.connector("manager").connect(manager.connector("dev"))
-
- if ip:
- self.add_ip_address(wifi, ip, prefix)
-
- phy.enable_trace("YansWifiPhyPcapTrace")
- return wifi, phy
-
- def add_ns3_random_mobility(self, node, ns3_desc, x, y, z, speed,
- bounds_width, bounds_height):
- position = "%f:%f:%f" % (x, y, z)
- bounds = "0|%f|0|%f" % (bounds_width, bounds_height)
- speed = "Constant:%f" % speed
- mobility = ns3_desc.create("ns3::RandomDirection2dMobilityModel")
- mobility.set_attribute_value("Position", position)
- mobility.set_attribute_value("Bounds", bounds)
- mobility.set_attribute_value("Speed", speed)
- mobility.set_attribute_value("Pause", "Constant:1")
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns3_constant_mobility(self, node, ns3_desc, x, y, z):
- mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel")
- position = "%f:%f:%f" % (x, y, z)
- mobility.set_attribute_value("Position", position)
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns3_wifi_channel(self, ns3_desc):
- channel = ns3_desc.create("ns3::YansWifiChannel")
- delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
- loss = ns3_desc.create("ns3::LogDistancePropagationLossModel")
- channel.connector("delay").connect(delay.connector("chan"))
- channel.connector("loss").connect(loss.connector("prev"))
- return channel
-
- def add_ip_address(self, iface, address, prefix = 24):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
- ip.set_attribute_value("Broadcast", True)
- ip.set_attribute_value("NetPrefix", prefix)
- return ip
-
- def add_route(self, nodes, destination, netprefix, nexthop):
- for node in nodes:
- route = node.add_route()
- route.set_attribute_value("Destination", destination)
- route.set_attribute_value("NetPrefix", netprefix)
- route.set_attribute_value("NextHop", nexthop)
-
- def make_pl_router(self, pl, hostname, label, ip, inet = None):
- pl1 = pl.create("Node")
- pl1.set_attribute_value("hostname", hostname)
- pl1.set_attribute_value("label", label)
- pl1.set_attribute_value("emulation", True)
- pl1if = pl.create("NodeInterface")
- pl1if.set_attribute_value("label", label+"if")
- pl1tap = pl.create("TapInterface")
- pl1tap.enable_trace("packets") # for error output
- pl1tap.set_attribute_value("label", label+"tap")
- pl1tap.set_attribute_value("snat", False)
- inet = inet or pl.create("Internet")
- pl1.connector("devs").connect(pl1if.connector("node"))
- pl1.connector("devs").connect(pl1tap.connector("node"))
- pl1if.connector("inet").connect(inet.connector("devs"))
-
- pl1tapip = pl1tap.add_address()
- pl1tapip.set_attribute_value("Address", ip)
- pl1tapip.set_attribute_value("NetPrefix", 24)
- pl1tapip.set_attribute_value("Broadcast", False)
-
- return pl1, pl1if, pl1tap, pl1tapip, inet
-
- def make_mesh(self, pl, exp, inet):
- scale = 1.0
- walkdistance = 1.0
- walkspeed = 0.1
-
- # Router 1 & NS3 host in PL
- pl1, pl1if, pl1tap, pl1tapip, inet = self.make_pl_router(pl,
- self.host1, "mesh_pl1", "192.168.2.2", inet)
-
- # Add NS3 support in pl1
- ns3 = self.make_ns_in_pl(pl, exp, pl1, pl1if, "tb-ns3-roads09-1")
-
- # Add WiFi channel
- chan = self.add_ns3_wifi_channel(ns3)
-
- # Add APs
- ap1 = self.add_ns3_node(ns3)
- ap2 = self.add_ns3_node(ns3)
- ap3 = self.add_ns3_node(ns3)
- ap4 = self.add_ns3_node(ns3)
- ap1wifi, ap1phy = self.add_ns3_wifi(ap1, ns3, False, "192.168.2.3", 26)
- ap2wifi, ap2phy = self.add_ns3_wifi(ap2, ns3, True, "192.168.2.4", 26)
- ap3wifi, ap3phy = self.add_ns3_wifi(ap3, ns3, False, "192.168.2.5", 26)
- ap4wifi, ap4phy = self.add_ns3_wifi(ap4, ns3, False, "192.168.2.6", 26)
- self.add_ns3_constant_mobility(ap1, ns3, -scale, -scale, 0.0)
- self.add_ns3_constant_mobility(ap2, ns3, +scale, -scale, 0.0)
- self.add_ns3_constant_mobility(ap3, ns3, -scale, +scale, 0.0)
- self.add_ns3_constant_mobility(ap4, ns3, +scale, +scale, 0.0)
-
- # Add WiFi nodes
- wnode1 = self.add_ns3_node(ns3)
- wnode2 = self.add_ns3_node(ns3)
- wnode3 = self.add_ns3_node(ns3)
- wnode4 = self.add_ns3_node(ns3)
- wnode5 = self.add_ns3_node(ns3)
- wnode1wifi, wnode1phy = self.add_ns3_wifi(wnode1, ns3, False, "192.168.2.7", 26)
- wnode2wifi, wnode2phy = self.add_ns3_wifi(wnode2, ns3, False, "192.168.2.8", 26)
- wnode3wifi, wnode3phy = self.add_ns3_wifi(wnode3, ns3, False, "192.168.2.9", 26)
- wnode4wifi, wnode4phy = self.add_ns3_wifi(wnode4, ns3, False, "192.168.2.10", 26)
- wnode5wifi, wnode5phy = self.add_ns3_wifi(wnode5, ns3, False, "192.168.2.11", 26)
- self.add_ns3_random_mobility(wnode1, ns3, -2*scale, -2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode2, ns3, -2*scale, +scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode3, ns3, -scale, +2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode4, ns3, +scale, +2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode5, ns3, +2*scale, +2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
-
- # Connect all WiFi phys to the channel
- ap1phy.connector("chan").connect(chan.connector("phys"))
- ap2phy.connector("chan").connect(chan.connector("phys"))
- ap3phy.connector("chan").connect(chan.connector("phys"))
- ap4phy.connector("chan").connect(chan.connector("phys"))
- wnode1phy.connector("chan").connect(chan.connector("phys"))
- wnode2phy.connector("chan").connect(chan.connector("phys"))
- wnode3phy.connector("chan").connect(chan.connector("phys"))
- wnode4phy.connector("chan").connect(chan.connector("phys"))
- wnode5phy.connector("chan").connect(chan.connector("phys"))
-
- # Add inet connection to AP
- ap2fdnd = self.add_ns3_fdnd(ap2, ns3)
- ap2fdndip = self.add_ip_address(ap2fdnd, "192.168.2.20")
- ap2fdndip.set_attribute_value("NetPrefix", 32) # p2p
- pl1tap.connector("fd->").connect(ap2fdnd.connector("->fd"))
- pl1tap.set_attribute_value("pointopoint", "192.168.2.20")
- r = ap2.add_route()
- r.set_attribute_value("Destination", "192.168.2.2")
- r.set_attribute_value("NetPrefix", 32)
- r.set_attribute_value("NextHop", "192.168.2.20")
-
- # return mesh router
- return (
- pl1, pl1if, pl1tap, pl1tapip,
- (wnode1, wnode2, wnode3, wnode4, wnode5),
- (wnode1wifi, wnode2wifi, wnode3wifi, wnode4wifi, wnode5wifi),
- (ap1, ap2, ap3, ap4),
- (ap1wifi, ap2wifi, ap3wifi, ap4wifi),
- ns3,
- inet,
- )
-
- def make_wifi_hotspot(self, pl, exp, inet):
- scale = 1.0
- walkdistance = 1.0
- walkspeed = 0.1
-
- # Router 1 & NS3 host in PL
- pl1, pl1if, pl1tap, pl1tapip, inet = self.make_pl_router(pl,
- self.host2, "hs_pl1", "192.168.2.65", inet)
-
- # Add NS3 support in pl1
- ns3 = self.make_ns_in_pl(pl, exp, pl1, pl1if, "tb-ns3-roads09-2")
-
- # Add WiFi channel
- chan = self.add_ns3_wifi_channel(ns3)
-
- # Add APs
- ap1 = self.add_ns3_node(ns3)
- ap1wifi, ap1phy = self.add_ns3_wifi(ap1, ns3, True, "192.168.2.66", 26)
- self.add_ns3_constant_mobility(ap1, ns3, 0.0, 0.0, 0.0)
-
- # Add WiFi nodes
- wnode1 = self.add_ns3_node(ns3)
- wnode2 = self.add_ns3_node(ns3)
- wnode3 = self.add_ns3_node(ns3)
- wnode4 = self.add_ns3_node(ns3)
- wnode1wifi, wnode1phy = self.add_ns3_wifi(wnode1, ns3, False, "192.168.2.67", 26)
- wnode2wifi, wnode2phy = self.add_ns3_wifi(wnode2, ns3, False, "192.168.2.68", 26)
- wnode3wifi, wnode3phy = self.add_ns3_wifi(wnode3, ns3, False, "192.168.2.69", 26)
- wnode4wifi, wnode4phy = self.add_ns3_wifi(wnode4, ns3, False, "192.168.2.70", 26)
- self.add_ns3_random_mobility(wnode1, ns3, +scale, -2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode2, ns3, -scale, -2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode3, ns3, -2*scale, +scale, 0.0,
- walkspeed, walkdistance, walkdistance)
- self.add_ns3_random_mobility(wnode4, ns3, -2*scale, +2*scale, 0.0,
- walkspeed, walkdistance, walkdistance)
-
- # Connect all WiFi phys to the channel
- ap1phy.connector("chan").connect(chan.connector("phys"))
- wnode1phy.connector("chan").connect(chan.connector("phys"))
- wnode2phy.connector("chan").connect(chan.connector("phys"))
- wnode3phy.connector("chan").connect(chan.connector("phys"))
- wnode4phy.connector("chan").connect(chan.connector("phys"))
-
- # Add inet connection to AP2
- ap1fdnd = self.add_ns3_fdnd(ap1, ns3)
- ap1fdndip = self.add_ip_address(ap1fdnd, "192.168.2.80")
- ap1fdndip.set_attribute_value("NetPrefix", 32) # p2p
- pl1tap.connector("fd->").connect(ap1fdnd.connector("->fd"))
- pl1tap.set_attribute_value("pointopoint", "192.168.2.80")
- r = ap1.add_route()
- r.set_attribute_value("Destination", "192.168.2.65")
- r.set_attribute_value("NetPrefix", 32)
- r.set_attribute_value("NextHop", "192.168.2.80")
-
- # return mesh router
- return (
- pl1, pl1if, pl1tap, pl1tapip,
- (wnode1, wnode2, wnode3, wnode4),
- (wnode1wifi, wnode2wifi, wnode3wifi, wnode4wifi),
- ap1, ap1wifi,
- ns3,
- inet,
- )
-
- def run(self):
- pl, exp = self.make_experiment_desc()
-
- pl1, pl1if, pl1tap, pl1tapip, \
- mesh_nodes, mesh_node_ifs, \
- mesh_aps, mesh_ap_ifs, \
- mesh_ns, \
- inet = self.make_mesh(pl, exp, None)
- pl2, pl2if, pl2tap, pl2tapip, \
- hs_nodes, hs_node_ifs, \
- hs_ap, hs_apif, \
- hs_ns, \
- inet = self.make_wifi_hotspot(pl, exp, inet)
-
- # Connect the routers
- pl1etap = pl.create("TapInterface")
- pl1etap.enable_trace("packets") # for error output
- pl1etap.set_attribute_value("label", "pl1etap")
- pl1etapip = pl1etap.add_address()
- pl1etapip.set_attribute_value("Address", "192.168.2.1")
- pl1etapip.set_attribute_value("NetPrefix", 24)
- pl1etapip.set_attribute_value("Broadcast", False)
-
- pl2etap = pl.create("TapInterface")
- pl2etap.enable_trace("packets") # for error output
- pl2etap.set_attribute_value("label", "pl2etap")
- pl2etapip = pl2etap.add_address()
- pl2etapip.set_attribute_value("Address", "192.168.2.81")
- pl2etapip.set_attribute_value("NetPrefix", 24)
- pl2etapip.set_attribute_value("Broadcast", False)
-
- pl1etap.connector("node").connect(pl1.connector("devs"))
- pl2etap.connector("node").connect(pl2.connector("devs"))
- pl1etap.connector("udp").connect(pl2etap.connector("udp"))
- pl1etap.set_attribute_value("pointopoint", "192.168.2.81")
- pl2etap.set_attribute_value("pointopoint", "192.168.2.1")
-
- # Connect the networks
-
- # apn -> ap2 (n != 2)
- for ap in mesh_aps[:1] + mesh_aps[2:]:
- r = ap.add_route()
- r.set_attribute_value("Destination", "192.168.2.64")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop",
- mesh_ap_ifs[1].addresses[0].get_attribute_value("Address") )
-
- for wn in mesh_nodes:
- apif = mesh_ap_ifs[ random.randint(0,len(mesh_aps)-1) ]
- r = wn.add_route()
- r.set_attribute_value("Destination", "192.168.2.64")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop",
- apif.addresses[0].get_attribute_value("Address"))
-
- r = mesh_aps[1].add_route()
- r.set_attribute_value("Destination", "192.168.2.64")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.2")
-
- r = pl1.add_route()
- r.set_attribute_value("Destination", "192.168.2.64")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.81")
-
- r = pl2.add_route()
- r.set_attribute_value("Destination", "192.168.2.64")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.80")
-
- for wn in hs_nodes:
- r = wn.add_route()
- r.set_attribute_value("Destination", "192.168.2.0")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.66")
-
- r = hs_ap.add_route()
- r.set_attribute_value("Destination", "192.168.2.0")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.65")
-
- r = pl2.add_route()
- r.set_attribute_value("Destination", "192.168.2.0")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.1")
-
- r = pl1.add_route()
- r.set_attribute_value("Destination", "192.168.2.0")
- r.set_attribute_value("NetPrefix", 26)
- r.set_attribute_value("NextHop", "192.168.2.20")
-
- # Add pinger app inside the mesh
- hs_node_ifs[0].set_attribute_value("label", "hotspot_node_1if")
- mesh_node_ifs[0].set_attribute_value("label", "mesh_node_1if")
- ping = mesh_ns.create("ns3::V4Ping")
- ping.set_attribute_value("Remote", "192.168.2.67") #"{#[hotspot_node_1if].addr[0].[Address]#}")
- ping.set_attribute_value("StartTime", "0s")
- ping.set_attribute_value("StopTime", "10s")
- ping.connector("node").connect(mesh_aps[0].connector("apps"))
-
- xml = exp.to_xml()
-
- print xml
-
- try:
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
-
- while not controller.is_finished(ping.guid):
- time.sleep(0.5)
-
- taptrace = controller.trace(pl.guid, pl1tap.guid, "packets")
-
- finally:
- controller.stop()
- controller.shutdown()
-
- print "Pakcets at router:"
- print taptrace
-
- def clean(self):
- shutil.rmtree(self.root_dir)
-
-if __name__ == '__main__':
- example = Roads09Ns3PLExample()
- example.run()
- example.clean()
-
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import getpass
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util import proxy
+from nepi.util.constants import DeploymentConfiguration as DC
+import os
+import shutil
+import tempfile
+import time
+
+root_dir = tempfile.mkdtemp()
+netns_root_dir = os.path.join(root_dir, "netns")
+os.makedirs(netns_root_dir)
+user = getpass.getuser()
+slicename = os.environ["PL_SLICE"]
+plchost = "www.planet-lab.eu"
+port_base = 2000 + (os.getpid() % 1000) * 13
+pl_ssh_key = os.environ.get(
+ "PL_SSH_KEY",
+ "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+pl_user = os.environ.get('PL_USER')
+pl_pwd = os.environ.get('PL_PASS')
+
+exp_desc = ExperimentDescription()
+
+pl_provider = FactoriesProvider("planetlab")
+pl_desc = exp_desc.add_testbed_description(pl_provider)
+pl_desc.set_attribute_value("homeDirectory", root_dir)
+pl_desc.set_attribute_value("slice", slicename)
+pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
+pl_desc.set_attribute_value("authUser", pl_user)
+pl_desc.set_attribute_value("authPass", pl_pwd)
+pl_desc.set_attribute_value("plcHost", plchost)
+pl_desc.set_attribute_value("tapPortBase", port_base)
+pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
+pl_desc.set_attribute_value("cleanProc", True)
+pl_desc.set_attribute_value("plLogLevel", "DEBUG")
+
+pl_inet = pl_desc.create("Internet")
+
+pl_node = pl_desc.create("Node")
+pl_iface = pl_desc.create("NodeInterface")
+pl_iface.connector("inet").connect(pl_inet.connector("devs"))
+pl_node.connector("devs").connect(pl_iface.connector("node"))
+
+pl_tap = pl_desc.create("TunInterface")
+pl_tap.enable_trace("pcap")
+pl_tap.enable_trace("packets")
+pl_node.connector("devs").connect(pl_tap.connector("node"))
+
+ip1 = pl_tap.add_address()
+ip1.set_attribute_value("Address", "192.168.3.1")
+ip1.set_attribute_value("NetPrefix", 24)
+
+netns_provider = FactoriesProvider("netns")
+netns_desc = exp_desc.add_testbed_description(netns_provider)
+netns_desc.set_attribute_value("homeDirectory", root_dir)
+netns_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
+netns_desc.set_attribute_value(DC.ROOT_DIRECTORY, netns_root_dir)
+netns_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
+netns_desc.set_attribute_value(DC.USE_SUDO, True)
+
+netns_node = netns_desc.create("Node")
+netns_node.set_attribute_value("forward_X11", True)
+
+netns_tap = netns_desc.create("TunNodeInterface")
+netns_tap.set_attribute_value("up", True)
+netns_tap.set_attribute_value("mtu", 1448)
+netns_node.connector("devs").connect(netns_tap.connector("node"))
+netns_tunchannel = netns_desc.create("TunChannel")
+netns_tunchannel.connector("->fd").connect(netns_tap.connector("fd->"))
+
+pl_tap.connector("tcp").connect(netns_tunchannel.connector("tcp"))
+
+ip2 = netns_tap.add_address()
+ip2.set_attribute_value("Address", "192.168.3.2")
+ip2.set_attribute_value("NetPrefix", 30)
+
+app = netns_desc.create("Application")
+app.set_attribute_value("command", "xterm")
+app.set_attribute_value("user", user)
+app.connector("node").connect(netns_node.connector("apps"))
+
+xml = exp_desc.to_xml()
+
+controller = ExperimentController(xml, root_dir)
+controller.start()
+while not controller.is_finished(app.guid):
+ time.sleep(0.5)
+
+controller.stop()
+controller.shutdown()
+
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from optparse import OptionParser, SUPPRESS_HELP
-from nepi.util import proxy
-import os
-import shutil
-import tempfile
-import test_util
-import time
-
-class VlcWirelessNetnsNs3Example(object):
- def __init__(self):
- usage = "usage: %prog -m movie -u user"
- parser = OptionParser(usage=usage)
- parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
- parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
- (options, args) = parser.parse_args()
- if not options.movie:
- parser.error("Missing 'movie' option.")
- if options.user == 'root':
- parser.error("Missing or invalid 'user' option.")
-
- self.user = options.user if options.user else os.getlogin()
- self.movie = options.movie
- self.root_dir = tempfile.mkdtemp()
-
- def add_netns_tap(self, node, netns_desc):
- tap = netns_desc.create("TapNodeInterface")
- tap.set_attribute_value("up", True)
- node.connector("devs").connect(tap.connector("node"))
- return tap
-
- def add_ns3_fdnd(self, node, ns3_desc):
- fdnd = ns3_desc.create("ns3::FdNetDevice")
- node.connector("devs").connect(fdnd.connector("node"))
- fdnd.enable_trace("FdPcapTrace")
- return fdnd
-
- def add_ns3_node(self, ns3_desc):
- node = ns3_desc.create("ns3::Node")
- ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
- arp = ns3_desc.create("ns3::ArpL3Protocol")
- icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
- udp = ns3_desc.create("ns3::UdpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- return node
-
- def add_ns3_wifi(self, node, ns3_desc, access_point = False):
- wifi = ns3_desc.create("ns3::WifiNetDevice")
- node.connector("devs").connect(wifi.connector("node"))
-
- phy = ns3_desc.create("ns3::YansWifiPhy")
- error = ns3_desc.create("ns3::NistErrorRateModel")
- manager = ns3_desc.create("ns3::ArfWifiManager")
- if access_point:
- mac = ns3_desc.create("ns3::ApWifiMac")
- else:
- mac = ns3_desc.create("ns3::StaWifiMac")
-
- phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- phy.connector("err").connect(error.connector("phy"))
- wifi.connector("phy").connect(phy.connector("dev"))
- wifi.connector("mac").connect(mac.connector("dev"))
- wifi.connector("manager").connect(manager.connector("dev"))
-
- phy.enable_trace("YansWifiPhyPcapTrace")
- return wifi, phy
-
- def add_ns3_random_mobility(self, node, ns3_desc, x, y, z, speed,
- bounds_width, bounds_height):
- position = "%d:%d:%d" % (x, y, z)
- bounds = "0|%d|0|%d" % (bounds_width, bounds_height)
- speed = "Constant:%d" % speed
- mobility = ns3_desc.create("ns3::RandomDirection2dMobilityModel")
- mobility.set_attribute_value("Position", position)
- mobility.set_attribute_value("Bounds", bounds)
- mobility.set_attribute_value("Speed", speed)
- mobility.set_attribute_value("Pause", "Constant:1")
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns3_constant_mobility(self, node, ns3_desc, x, y, z):
- mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel")
- position = "%d:%d:%d" % (x, y, z)
- mobility.set_attribute_value("Position", position)
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns3_wifi_channel(self, ns3_desc):
- channel = ns3_desc.create("ns3::YansWifiChannel")
- delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
- loss = ns3_desc.create("ns3::LogDistancePropagationLossModel")
- channel.connector("delay").connect(delay.connector("chan"))
- channel.connector("loss").connect(loss.connector("prev"))
- return channel
-
- def add_ip_address(self, iface, address):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
-
- def add_route(self, node, destination, netprefix, nexthop):
- route = node.add_route()
- route.set_attribute_value("Destination", destination)
- route.set_attribute_value("NetPrefix", netprefix)
- route.set_attribute_value("NextHop", nexthop)
-
- def run(self):
- bounds_width = bounds_height = 200
- x = y = 100
- speed = 7
-
- exp_desc = ExperimentDescription()
-
- ## NS3 Testbed instance description ##
- testbed_id = "ns3"
- ns3_provider = FactoriesProvider(testbed_id)
- ns3_desc = exp_desc.add_testbed_description(ns3_provider)
- ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
- ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
- ns3_desc.set_attribute_value("ChecksumEnabled", True)
- # create node 1
- node1 = self.add_ns3_node(ns3_desc)
- mobility1 = self.add_ns3_constant_mobility(node1, ns3_desc, x, y, 0)
- wifi1, phy1 = self.add_ns3_wifi(node1, ns3_desc, access_point = False)
- self.add_ip_address(wifi1, "10.0.1.1")
- fdnd1 = self.add_ns3_fdnd(node1, ns3_desc)
- self.add_ip_address(fdnd1, "10.0.0.1")
- # create node 2
- node2 = self.add_ns3_node(ns3_desc)
- mobility2 = self.add_ns3_random_mobility(node2, ns3_desc, x, y, 0,
- speed, bounds_width, bounds_height)
- wifi2, phy2 = self.add_ns3_wifi(node2, ns3_desc, access_point = True)
- self.add_ip_address(wifi2, "10.0.1.2")
- fdnd2 = self.add_ns3_fdnd(node2, ns3_desc)
- self.add_ip_address(fdnd2, "10.0.2.1")
- # interconnect nodes with a wifi channel
- wifichan = self.add_ns3_wifi_channel(ns3_desc)
- phy1.connector("chan").connect(wifichan.connector("phys"))
- phy2.connector("chan").connect(wifichan.connector("phys"))
-
- ## NETNS testbed description 1 ##
- testbed_id = "netns"
- netns_provider = FactoriesProvider(testbed_id)
- netns_desc1 = exp_desc.add_testbed_description(netns_provider)
- netns_desc1.set_attribute_value("homeDirectory", self.root_dir)
- #netns_desc1.set_attribute_value("enableDebug", True)
- # create node 3
- node3 = netns_desc1.create("Node")
- node3.set_attribute_value("forward_X11", True)
- tap1 = self.add_netns_tap(node3, netns_desc1)
- self.add_ip_address(tap1, "10.0.0.2")
- # create vlc server
- # DEBUG!! target = "{#[vlc_client].addr[0].[Address]#}"
- target = "10.0.2.2"
- command = "vlc -I dummy %s --sout '#rtp{dst=%s,port=5004,mux=ts}' vlc://quit" \
- % (self.movie, target)
- vlc_server = netns_desc1.create("Application")
- vlc_server.set_attribute_value("command", command)
- vlc_server.set_attribute_value("user", self.user)
- vlc_server.connector("node").connect(node3.connector("apps"))
-
- #command = "xterm"
- #xterm1 = netns_desc1.create("Application")
- #xterm1.set_attribute_value("command", command)
- #xterm1.set_attribute_value("user", self.user)
- #xterm1.connector("node").connect(node3.connector("apps"))
-
- ## NETNS testbed description 2 ##
- netns_desc2 = exp_desc.add_testbed_description(netns_provider)
- netns_desc2.set_attribute_value("homeDirectory", self.root_dir)
- #netns_desc2.set_attribute_value("enableDebug", True)
- # create node 4
- node4 = netns_desc2.create("Node")
- node4.set_attribute_value("forward_X11", True)
- node4.set_attribute_value("label", "vlc_client")
- tap2 = self.add_netns_tap(node4, netns_desc2)
- self.add_ip_address(tap2, "10.0.2.2")
- # create vlc client
- vlc_client = netns_desc2.create("Application")
- command = "vlc rtp://%s:5004/test.ts" % target
- vlc_client.set_attribute_value("command", command)
- vlc_client.set_attribute_value("user", self.user)
- vlc_client.connector("node").connect(node4.connector("apps"))
-
- #command = "xterm"
- #xterm2 = netns_desc2.create("Application")
- #xterm2.set_attribute_value("command", command)
- #xterm2.set_attribute_value("user", self.user)
- #xterm2.connector("node").connect(node4.connector("apps"))
-
- ## testbed_interconnection
- fdnd1.connector("->fd").connect(tap1.connector("fd->"))
- fdnd2.connector("->fd").connect(tap2.connector("fd->"))
-
- self.add_route(node4, "10.0.0.0", 24, "10.0.2.1")
- self.add_route(node4, "10.0.1.0", 24, "10.0.2.1")
- self.add_route(node3, "10.0.2.0", 24, "10.0.0.1")
- self.add_route(node3, "10.0.1.0", 24, "10.0.0.1")
-
- self.add_route(node2, "10.0.0.0", 24, "10.0.1.1")
- self.add_route(node1, "10.0.2.0", 24, "10.0.1.2")
-
- xml = exp_desc.to_xml()
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
- while not controller.is_finished(vlc_server.guid) and \
- not controller.is_finished(vlc_client.guid):
- time.sleep(0.5)
- controller.stop()
- controller.shutdown()
-
- def clean(self):
- shutil.rmtree(self.root_dir)
-
-if __name__ == '__main__':
- example = VlcWirelessNetnsNs3Example()
- example.run()
- example.clean()
-
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from optparse import OptionParser, SUPPRESS_HELP
-from nepi.util import proxy
-import os
-import shutil
-import tempfile
-import test_util
-import time
-
-class Roads09Example(object):
- def __init__(self):
- self.root_dir = tempfile.mkdtemp()
-
- def add_ns3_node(self, ns3_desc):
- node = ns3_desc.create("ns3::Node")
- ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
- arp = ns3_desc.create("ns3::ArpL3Protocol")
- icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
- udp = ns3_desc.create("ns3::UdpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- return node
-
- def add_ns3_wimax_bs(self, ns3_desc, node, channel):
- bs = ns3_desc.create("ns3::BaseStationNetDevice")
- node.connector("devs").connect(bs.connector("node"))
- bs.connector("chan").connect(channel.connector("devs"))
- phy = ns3_desc.create("ns3::SimpleOfdmWimaxPhy")
- bs.connector("phy").connect(phy.connector("dev"))
- uplink = ns3_desc.create("ns3::UplinkSchedulerSimple")
- bs.connector("uplnk").connect(uplink.connector("dev"))
- bssched = ns3_desc.create("ns3::BSSchedulerSimple")
- bs.connector("dwnlnk").connect(bssched.connector("dev"))
- bs.enable_trace("WimaxPcapTrace")
- bs.enable_trace("WimaxAsciiTrace")
- return bs
-
- def add_ns3_wimax_ss(self, ns3_desc, node, channel):
- ss = ns3_desc.create("ns3::SubscriberStationNetDevice")
- node.connector("devs").connect(ss.connector("node"))
- ss.connector("chan").connect(channel.connector("devs"))
- phy = ns3_desc.create("ns3::SimpleOfdmWimaxPhy")
- ss.connector("phy").connect(phy.connector("dev"))
- ss.enable_trace("WimaxPcapTrace")
- ss.enable_trace("WimaxAsciiTrace")
- return ss
-
- def add_ns3_service_flow(self, ns3_desc, ss, src_address, src_mask,
- dst_address, dst_mask, src_portlow, src_porthigh, dst_portlow,
- dst_porthigh, protocol, priority, direction, scheduling_type):
- classifier = ns3_desc.create("ns3::IpcsClassifierRecord")
- classifier.set_attribute_value("SrcAddress", src_address)
- classifier.set_attribute_value("SrcMask", src_mask)
- classifier.set_attribute_value("DstAddress", dst_address)
- classifier.set_attribute_value("DstMask", dst_mask)
- classifier.set_attribute_value("SrcPortLow", src_portlow)
- classifier.set_attribute_value("SrcPortHigh",src_porthigh)
- classifier.set_attribute_value("DstPortLow", dst_portlow)
- classifier.set_attribute_value("DstPortHigh", dst_porthigh)
- classifier.set_attribute_value("Protocol", protocol)
- classifier.set_attribute_value("Priority", priority)
- sflow = ns3_desc.create("ns3::ServiceFlow")
- sflow.set_attribute_value("Direction", direction)
- sflow.set_attribute_value("SchedulingType", scheduling_type)
- sflow.connector("classif").connect(classifier.connector("sflow"))
- ss.connector("sflows").connect(sflow.connector("dev"))
-
- def add_ip_address(self, iface, address):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
-
- def run(self):
- exp_desc = ExperimentDescription()
-
- testbed_id = "ns3"
- ns3_provider = FactoriesProvider(testbed_id)
- ns3_desc = exp_desc.add_testbed_description(ns3_provider)
- ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
- ns3_desc.set_attribute_value("StopTime", "7.1s")
-
- node1 = self.add_ns3_node(ns3_desc)
- node2 = self.add_ns3_node(ns3_desc)
- node3 = self.add_ns3_node(ns3_desc)
-
- channel = ns3_desc.create("ns3::SimpleOfdmWimaxChannel")
-
- ss1 = self.add_ns3_wimax_ss(ns3_desc, node1, channel)
- ss2 = self.add_ns3_wimax_ss(ns3_desc, node2, channel)
- bs = self.add_ns3_wimax_bs(ns3_desc, node3, channel)
-
- self.add_ns3_service_flow(ns3_desc, ss1, "0.0.0.0", "0.0.0.0",
- "10.1.1.1", "255.255.255.255", 0, 65000, 100, 100,
- "UdpL4Protocol", 1, "SF_DIRECTION_DOWN", "SF_TYPE_RTPS")
- self.add_ns3_service_flow(ns3_desc, ss2, "10.1.1.2", "255.255.255.255",
- "0.0.0.0", "0.0.0.0", 0, 65000, 100, 100, "UdpL4Protocol",
- 1, "SF_DIRECTION_UP", "SF_TYPE_RTPS")
-
- self.add_ip_address(ss1, "10.1.1.1")
- self.add_ip_address(ss2, "10.1.1.2")
- self.add_ip_address(bs, "10.1.1.3")
-
- udp_server = ns3_desc.create("ns3::UdpServer")
- udp_server.set_attribute_value("Port", 100)
- udp_server.set_attribute_value("StartTime", "6s")
- udp_server.set_attribute_value("StopTime", "7s")
- udp_server.connector("node").connect(node1.connector("apps"))
-
- udp_client = ns3_desc.create("ns3::UdpClient")
- udp_client.set_attribute_value("RemotePort", 100)
- udp_client.set_attribute_value("RemoteAddress", "10.1.1.1")
- udp_client.set_attribute_value("MaxPackets", 1200)
- udp_client.set_attribute_value("Interval", "0.5s")
- udp_client.set_attribute_value("PacketSize", 1024)
- udp_client.set_attribute_value("StartTime", "6s")
- udp_client.set_attribute_value("StopTime", "7s")
- udp_client.connector("node").connect(node2.connector("apps"))
-
- xml = exp_desc.to_xml()
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
- while not (controller.is_finished(udp_server.guid) and controller.is_finished(udp_client.guid)):
- time.sleep(0.5)
- time.sleep(0.1)
- controller.stop()
- controller.shutdown()
-
- def clean(self):
- print self.root_dir
- #shutil.rmtree(self.root_dir)
- pass
-
-if __name__ == '__main__':
- example = Roads09Example()
- example.run()
- example.clean()
-
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from optparse import OptionParser, SUPPRESS_HELP
-from nepi.util.constants import DeploymentConfiguration as DC
-import os
-import shutil
-import tempfile
-import time
-
-class WimaxOverlayExample(object):
- def __init__(self):
- #usage = "usage: %prog -m movie -u user"
- #parser = OptionParser(usage=usage)
- #parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
- #parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
- #(options, args) = parser.parse_args()
- #if not options.movie:
- # parser.error("Missing 'movie' option.")
- #if options.user == 'root':
- # parser.error("Missing or invalid 'user' option.")
-
- #self.user = options.user if options.user else os.getlogin()
- self.user = os.getlogin()
- #self.movie = options.movie
- self.root_dir = tempfile.mkdtemp()
-
- def add_ns3_node(self, ns3_desc):
- node = ns3_desc.create("ns3::Node")
- ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
- arp = ns3_desc.create("ns3::ArpL3Protocol")
- icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
- udp = ns3_desc.create("ns3::UdpL4Protocol")
- tcp = ns3_desc.create("ns3::TcpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- node.connector("protos").connect(tcp.connector("node"))
- return node
-
- def add_ns3_wimax_bs(self, ns3_desc, node, channel):
- bs = ns3_desc.create("ns3::BaseStationNetDevice")
- node.connector("devs").connect(bs.connector("node"))
- bs.connector("chan").connect(channel.connector("devs"))
- phy = ns3_desc.create("ns3::SimpleOfdmWimaxPhy")
- bs.connector("phy").connect(phy.connector("dev"))
- uplink = ns3_desc.create("ns3::UplinkSchedulerSimple")
- bs.connector("uplnk").connect(uplink.connector("dev"))
- bssched = ns3_desc.create("ns3::BSSchedulerSimple")
- bs.connector("dwnlnk").connect(bssched.connector("dev"))
- bs.enable_trace("WimaxPcapTrace")
- bs.enable_trace("WimaxAsciiTrace")
- return bs
-
- def add_ns3_wimax_ss(self, ns3_desc, node, channel):
- ss = ns3_desc.create("ns3::SubscriberStationNetDevice")
- node.connector("devs").connect(ss.connector("node"))
- ss.connector("chan").connect(channel.connector("devs"))
- phy = ns3_desc.create("ns3::SimpleOfdmWimaxPhy")
- ss.connector("phy").connect(phy.connector("dev"))
- ss.enable_trace("WimaxPcapTrace")
- ss.enable_trace("WimaxAsciiTrace")
- return ss
-
- def add_ns3_p2p(self, ns3_desc, node, channel):
- iface = ns3_desc.create("ns3::PointToPointNetDevice")
- queue = ns3_desc.create("ns3::DropTailQueue")
- node.connector("devs").connect(iface.connector("node"))
- iface.connector("queue").connect(queue.connector("dev"))
- trace = iface.enable_trace("P2PAsciiTrace")
- iface.connector("chan").connect(channel.connector("dev2"))
- return iface
-
- def add_ns3_service_flow(self, ns3_desc, ss, src_address, src_mask,
- dst_address, dst_mask, src_portlow, src_porthigh, dst_portlow,
- dst_porthigh, protocol, priority, direction, scheduling_type):
- classifier = ns3_desc.create("ns3::IpcsClassifierRecord")
- classifier.set_attribute_value("SrcAddress", src_address)
- classifier.set_attribute_value("SrcMask", src_mask)
- classifier.set_attribute_value("DstAddress", dst_address)
- classifier.set_attribute_value("DstMask", dst_mask)
- classifier.set_attribute_value("SrcPortLow", src_portlow)
- classifier.set_attribute_value("SrcPortHigh",src_porthigh)
- classifier.set_attribute_value("DstPortLow", dst_portlow)
- classifier.set_attribute_value("DstPortHigh", dst_porthigh)
- classifier.set_attribute_value("Protocol", protocol)
- classifier.set_attribute_value("Priority", priority)
- sflow = ns3_desc.create("ns3::ServiceFlow")
- sflow.set_attribute_value("Direction", direction)
- sflow.set_attribute_value("SchedulingType", scheduling_type)
- sflow.connector("classif").connect(classifier.connector("sflow"))
- ss.connector("sflows").connect(sflow.connector("dev"))
-
- def add_netns_tap(self, netns_desc, node):
- tap = netns_desc.create("TapNodeInterface")
- tap.set_attribute_value("up", True)
- node.connector("devs").connect(tap.connector("node"))
- return tap
-
- def add_ns3_fdnd(self, ns3_desc, node):
- fdnd = ns3_desc.create("ns3::FdNetDevice")
- node.connector("devs").connect(fdnd.connector("node"))
- fdnd.enable_trace("FdPcapTrace")
- return fdnd
-
- def add_ip_address(self, iface, address, netprefix):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
- ip.set_attribute_value("NetPrefix", netprefix)
-
- def add_route(self, node, destination, netprefix, nexthop):
- route = node.add_route()
- route.set_attribute_value("Destination", destination)
- route.set_attribute_value("NetPrefix", netprefix)
- route.set_attribute_value("NextHop", nexthop)
-
- def run(self):
- base_addr = "192.168.4.%d"
- exp_desc = ExperimentDescription()
-
- # NS3
- ns3_provider = FactoriesProvider("ns3")
- ns3_desc = exp_desc.add_testbed_description(ns3_provider)
- ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
- ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
- ns3_desc.set_attribute_value("ChecksumEnabled", True)
-
- ## WIMAX network 32/27
- node_bs = self.add_ns3_node(ns3_desc)
- node_ss1 = self.add_ns3_node(ns3_desc)
- node_ss2 = self.add_ns3_node(ns3_desc)
- node_ss3 = self.add_ns3_node(ns3_desc)
- node_ss4 = self.add_ns3_node(ns3_desc)
- node_ss5 = self.add_ns3_node(ns3_desc)
- node_ss6 = self.add_ns3_node(ns3_desc)
-
- wimax_channel = ns3_desc.create("ns3::SimpleOfdmWimaxChannel")
-
- bs = self.add_ns3_wimax_bs(ns3_desc, node_bs, wimax_channel)
- ss1 = self.add_ns3_wimax_ss(ns3_desc, node_ss1, wimax_channel)
- ss2 = self.add_ns3_wimax_ss(ns3_desc, node_ss2, wimax_channel)
- ss3 = self.add_ns3_wimax_ss(ns3_desc, node_ss3, wimax_channel)
- ss4 = self.add_ns3_wimax_ss(ns3_desc, node_ss4, wimax_channel)
- ss5 = self.add_ns3_wimax_ss(ns3_desc, node_ss5, wimax_channel)
- ss6 = self.add_ns3_wimax_ss(ns3_desc, node_ss6, wimax_channel)
-
- self.add_ip_address(bs, (base_addr%33), 27)
- self.add_ip_address(ss1, (base_addr%34), 27)
- self.add_ip_address(ss2, (base_addr%35), 27)
- self.add_ip_address(ss3, (base_addr%36), 27)
- self.add_ip_address(ss4, (base_addr%37), 27)
- self.add_ip_address(ss5, (base_addr%38), 27)
- self.add_ip_address(ss6, (base_addr%39), 27)
-
- #self.add_ns3_service_flow(ns3_desc, ss1, "0.0.0.0", "0.0.0.0",
- # "10.1.1.1", "255.255.255.255", 0, 65000, 100, 100,
- # "UdpL4Protocol", 1, "SF_DIRECTION_DOWN", "SF_TYPE_RTPS")
- #self.add_ns3_service_flow(ns3_desc, ss2, "10.1.1.2", "255.255.255.255",
- # "0.0.0.0", "0.0.0.0", 0, 65000, 100, 100, "UdpL4Protocol",
- # 1, "SF_DIRECTION_UP", "SF_TYPE_RTPS")
-
- self.add_ns3_service_flow(ns3_desc, ss1, "0.0.0.0", "0.0.0.0",
- "192.168.4.35", "255.255.255.225", 0, 65000, 11, 11, "Icmpv4L4Protocol",
- 1, "SF_DIRECTION_DOWN", "SF_TYPE_RTPS")
-
- self.add_ns3_service_flow(ns3_desc, ss2, "192.168.4.34", "255.255.255.255",
- "0.0.0.0", "0.0.0.0", 0, 65000, 11, 11, "Icmpv4L4Protocol",
- 1, "SF_DIRECTION_UP", "SF_TYPE_RTPS")
-
- ## Point-to-Point wimax/fdnd 224/30
- node_fdnd = self.add_ns3_node(ns3_desc)
- p2p_channel = ns3_desc.create("ns3::PointToPointChannel")
-
- p2p1 = self.add_ns3_p2p(ns3_desc, node_ss1, p2p_channel)
- p2p2 = self.add_ns3_p2p(ns3_desc, node_fdnd, p2p_channel)
-
- self.add_ip_address(p2p1, (base_addr%225), 30)
- self.add_ip_address(p2p2, (base_addr%226), 30)
-
- # NETNS
- netns_provider = FactoriesProvider("netns")
- netns_desc = exp_desc.add_testbed_description(netns_provider)
- netns_desc.set_attribute_value("homeDirectory", self.root_dir)
- netns_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- netns_root_dir = os.path.join(self.root_dir, "netns_instance")
- os.mkdir(netns_root_dir)
- netns_desc.set_attribute_value(DC.ROOT_DIRECTORY, netns_root_dir)
- netns_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- netns_desc.set_attribute_value(DC.USE_SUDO, True)
-
- node_netns = netns_desc.create("Node")
- node_netns.set_attribute_value("forward_X11", True)
- tap = self.add_netns_tap(netns_desc, node_netns)
-
- command = "xterm"
- app = netns_desc.create("Application")
- app.set_attribute_value("command", command)
- app.set_attribute_value("user", self.user)
- app.connector("node").connect(node_netns.connector("apps"))
-
- ## Point-to-Point NS3::fdnd/NETNS::tap 228/30
- fdnd = self.add_ns3_fdnd(ns3_desc, node_fdnd)
-
- fdnd.connector("->fd").connect(tap.connector("fd->"))
-
- self.add_ip_address(fdnd, (base_addr%229), 30)
- self.add_ip_address(tap, (base_addr%230), 30)
-
- # ROUTES
- self.add_route(node_netns, (base_addr%32), 27, (base_addr%229))
- self.add_route(node_netns, (base_addr%224), 30, (base_addr%229))
-
- self.add_route(node_fdnd, (base_addr%32), 27, (base_addr%225))
- self.add_route(node_ss1, (base_addr%228), 30, (base_addr%226))
-
- self.add_route(node_ss2, (base_addr%224), 30, (base_addr%34))
- self.add_route(node_ss2, (base_addr%228), 30, (base_addr%34))
- self.add_route(node_bs, (base_addr%224), 30, (base_addr%34))
- self.add_route(node_bs, (base_addr%228), 30, (base_addr%34))
-
-
- xml = exp_desc.to_xml()
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
- while not controller.is_finished(app.guid):
- time.sleep(0.5)
- time.sleep(0.1)
- controller.stop()
- controller.shutdown()
-
- def clean(self):
- #shutil.rmtree(self.root_dir)
- print self.root_dir
- pass
-
-if __name__ == '__main__':
- example = WimaxOverlayExample()
- example.run()
- example.clean()
-
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from nepi.core.design import ExperimentDescription, FactoriesProvider
-from nepi.core.execute import ExperimentController
-from optparse import OptionParser, SUPPRESS_HELP
-from nepi.util import proxy
-from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
-import test_util
-import os
-import shutil
-import tempfile
-import itertools
-import time
-import math
-
-"""
-
- ___________________________________________________________
- | NETNS |
- | |
- | __________ |
- | |netns_node| VLC_SERVER |
- | |__________| |
- | |
- | 1/30 |
- | ----------- |
- |_________________________|_________________________________|
- |
- | 0/30
- _________________________|_________________________________
- | PL1 | |
- | ------------ |
- | 2/30 |
- | |
- | 5/30 |
- | ------------- |
- |_________________________|_________________________________|
- |
- | 4/30
- _________________________|_________________________________
- | NS-3 | |
- | -------- |
- | 6/30 |
- | ______ |
- | | AP | |
- | |______| |
- | 33/27 |
- | -------- |
- | ((*)) |
- | |
- | |
- | ((*)) ((*)) ((*)) ((*)) |
- | ------- -------- ------- ------- |
- | 34/27 35/27 36/27 37/27 |
- | +-----+ +-----+ +-----+ +-----+ |
- | |sta0 | |sta1 | |sta2 | |sta3 | |
- | +-----+ +-----+ +-----+ +-----+ |
- | 66/30 70/30 74/30 78/30 |
- | ------- ------- ------- ------- |
- |_______|___________|__________|__________|_________________|
- | | | |
- ______|____ ____|____ ___|____ ___|____
- | PL2 | | |PL3 | | |PL4| | |PL5| |
- | | | | | | | | | | | |
- | ------- | | ------- | | ------ | |------- |
- | 65/30 | | 69/30 | | 73/30 | | 77/30 |
- |___________| |_________| |________| |________|
-
-"""
-
-class WirelessOverlay(object):
- def __init__(self):
- usage = "usage: %prog -n number_sta -m movie -u user"
- parser = OptionParser(usage=usage)
- parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
- parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
- parser.add_option("-n", "--nsta", dest="nsta", help="Number of wifi stations", type="int")
- parser.add_option("-a", "--base_addr", dest="base_addr", help="Base address segment for the experiment", type="str")
- parser.add_option("-s", "--slicename", dest="slicename", help="PlanetLab slice", type="str")
- (options, args) = parser.parse_args()
- if not options.movie:
- parser.error("Missing 'movie' option.")
- if options.user == 'root':
- parser.error("Missing or invalid 'user' option.")
- if options.user == 'root':
- parser.error("Missing or invalid 'user' option.")
- if options.nsta and options.nsta > 8:
- parser.error("Try a number of stations under 9.")
-
- self.user = options.user if options.user else os.getlogin()
- self.movie = options.movie
- self.nsta = options.nsta if options.nsta else 3
- self.slicename = options.slicename if options.slicename else "inria_nepi3"
- base = options.base_addr if options.base_addr else "192.168.4"
- self.base_addr = base + ".%d"
- self.root_dir = tempfile.mkdtemp()
-
- def add_ip_address(self, iface, address, netprefix):
- ip = iface.add_address()
- ip.set_attribute_value("Address", address)
- ip.set_attribute_value("NetPrefix", netprefix)
-
- def add_route(self, node, destination, netprefix, nexthop):
- route = node.add_route()
- route.set_attribute_value("Destination", destination)
- route.set_attribute_value("NetPrefix", netprefix)
- route.set_attribute_value("NextHop", nexthop)
-
- def add_ns3_fdnd(self, ns3_desc, node):
- fdnd = ns3_desc.create("ns3::FdNetDevice")
- node.connector("devs").connect(fdnd.connector("node"))
- #fdnd.enable_trace("FdPcapTrace")
- return fdnd
-
- def add_ns3_node(self, ns3_desc):
- node = ns3_desc.create("ns3::Node")
- ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
- arp = ns3_desc.create("ns3::ArpL3Protocol")
- icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
- udp = ns3_desc.create("ns3::UdpL4Protocol")
- node.connector("protos").connect(ipv4.connector("node"))
- node.connector("protos").connect(arp.connector("node"))
- node.connector("protos").connect(icmp.connector("node"))
- node.connector("protos").connect(udp.connector("node"))
- return node
-
- def add_ns3_wifi(self, ns3_desc, node, access_point = False):
- wifi = ns3_desc.create("ns3::WifiNetDevice")
- node.connector("devs").connect(wifi.connector("node"))
-
- phy = ns3_desc.create("ns3::YansWifiPhy")
- error = ns3_desc.create("ns3::NistErrorRateModel")
- manager = ns3_desc.create("ns3::ArfWifiManager")
- if access_point:
- mac = ns3_desc.create("ns3::ApWifiMac")
- else:
- mac = ns3_desc.create("ns3::StaWifiMac")
-
- phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
- phy.connector("err").connect(error.connector("phy"))
- wifi.connector("phy").connect(phy.connector("dev"))
- wifi.connector("mac").connect(mac.connector("dev"))
- wifi.connector("manager").connect(manager.connector("dev"))
-
- #phy.enable_trace("YansWifiPhyPcapTrace")
- return wifi, phy
-
- def add_ns3_constant_mobility(self, ns3_desc, node, x, y, z):
- mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel")
- position = "%d:%d:%d" % (x, y, z)
- mobility.set_attribute_value("Position", position)
- node.connector("mobility").connect(mobility.connector("node"))
- return mobility
-
- def add_ns3_wifi_channel(self, ns3_desc):
- channel = ns3_desc.create("ns3::YansWifiChannel")
- delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
- loss = ns3_desc.create("ns3::LogDistancePropagationLossModel")
- channel.connector("delay").connect(delay.connector("chan"))
- channel.connector("loss").connect(loss.connector("prev"))
- return channel
-
- def add_pl_testbed(self, exp_desc):
- plchost = "nepiplc.pl.sophia.inria.fr"
- port_base = 2000 + (os.getpid() % 1000) * 13
- pl_ssh_key = os.environ.get(
- "PL_SSH_KEY",
- "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
- pl_user, pl_pwd = test_util.pl_auth()
-
- pl_provider = FactoriesProvider("planetlab")
- pl_desc = exp_desc.add_testbed_description(pl_provider)
- pl_desc.set_attribute_value("homeDirectory", self.root_dir)
- pl_desc.set_attribute_value("slice", self.slicename)
- pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
- pl_desc.set_attribute_value("authUser", pl_user)
- pl_desc.set_attribute_value("authPass", pl_pwd)
- pl_desc.set_attribute_value("plcHost", plchost)
- pl_desc.set_attribute_value("tapPortBase", port_base)
- pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc.set_attribute_value("dedicatedSlice", True)
- pl_desc.set_attribute_value("plLogLevel", "DEBUG")
- return pl_desc
-
- def add_pl_node(self, pl_desc, inet, label_prefix):
- node = pl_desc.create("Node")
- node.set_attribute_value("label", label_prefix)
- iface = pl_desc.create("NodeInterface")
- iface.set_attribute_value("label", label_prefix+"iface")
- iface.connector("inet").connect(inet.connector("devs"))
- node.connector("devs").connect(iface.connector("node"))
- forwarder = pl_desc.create("MulticastForwarder")
- forwarder.enable_trace("stderr")
- node.connector("apps").connect(forwarder.connector("node"))
- return node, iface
-
- def add_ns3_in_pl(self, exp_desc, pl_desc, pl_node, pl_iface, root):
- # Add NS3 support in node
- plnepi = pl_desc.create("NepiDependency")
- plns3 = pl_desc.create("NS3Dependency")
- plnepi.connector("node").connect(pl_node.connector("deps"))
- plns3.connector("node").connect(pl_node.connector("deps"))
-
- # Create NS3 testbed running in pl_node
- ns3_provider = FactoriesProvider("ns3")
- ns3_desc = exp_desc.add_testbed_description(ns3_provider)
- ns3_desc.set_attribute_value("rootDirectory", root)
- ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
- ns3_desc.set_attribute_value("ChecksumEnabled", True)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_HOST, "{#[%s].addr[0].[Address]#}" % (
- pl_iface.get_attribute_value("label"),))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_USER,
- pl_desc.get_attribute_value("slice"))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_KEY,
- pl_desc.get_attribute_value("sliceSSHKey"))
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
- ns3_desc.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP,
- "{#[%s].[%s]#}" % (
- pl_node.get_attribute_value("label"),
- ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP,))
- ns3_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- return ns3_desc
-
- def add_netns_testbed(self, exp_desc):
- netns_provider = FactoriesProvider("netns")
- netns_desc = exp_desc.add_testbed_description(netns_provider)
- netns_desc.set_attribute_value("homeDirectory", self.root_dir)
- netns_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
- netns_root_dir = os.path.join(self.root_dir, "netns")
- os.mkdir(netns_root_dir)
- netns_desc.set_attribute_value(DC.ROOT_DIRECTORY, netns_root_dir)
- netns_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- netns_desc.set_attribute_value(DC.USE_SUDO, True)
- return netns_desc
-
- def add_netns_node(self, netns_desc):
- node = netns_desc.create("Node")
- node.set_attribute_value("forward_X11", True)
- return node
-
- def add_pl_ns3_connection(self, pl_desc, pl_node, pl_addr,
- ns3_desc, ns3_node, ns3_addr):
- pl_tap = pl_desc.create("TapInterface")
- pl_tap.set_attribute_value("tun_cipher", "PLAIN")
- self.add_ip_address(pl_tap, pl_addr, 30)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
- ns3_fdnd = ns3_desc.create("ns3::FdNetDevice")
- ns3_node.connector("devs").connect(ns3_fdnd.connector("node"))
- self.add_ip_address(ns3_fdnd, ns3_addr, 30)
- pl_tap.connector("fd->").connect(ns3_fdnd.connector("->fd"))
-
- def add_pl_ns3_tunchan_connection(self, pl_desc, pl_node, pl_addr,
- ns3_desc, ns3_node, ns3_addr):
- pl_tap = pl_desc.create("TunInterface")
- self.add_ip_address(pl_tap, pl_addr, 30)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
- ns3_fdnd = ns3_desc.create("ns3::FdNetDevice")
- ns3_fdnd.enable_trace("FdPcapTrace")
- self.add_ip_address(ns3_fdnd, ns3_addr, 30)
- ns3_node.connector("devs").connect(ns3_fdnd.connector("node"))
- ns3_tc = ns3_desc.create("ns3::Nepi::TunChannel")
- ns3_tc.connector("fd->").connect(ns3_fdnd.connector("->fd"))
- pl_tap.connector("tcp").connect(ns3_tc.connector("tcp"))
-
- def add_pl_netns_connection(self, pl_desc, pl_node, pl_addr,
- netns_desc, netns_node, netns_addr):
- pl_tap = pl_desc.create("TunInterface")
- #pl_tap.set_attribute_value("tun_cipher", "PLAIN")
- pl_tap.set_attribute_value("multicast", True)
- #pl_tap.enable_trace("pcap")
- #pl_tap.enable_trace("packets")
- self.add_ip_address(pl_tap, pl_addr, 30)
- pl_node.connector("devs").connect(pl_tap.connector("node"))
- netns_tap = netns_desc.create("TunNodeInterface")
- netns_tap.set_attribute_value("up", True)
- netns_tap.set_attribute_value("mtu", 1448)
- self.add_ip_address(netns_tap, netns_addr, 30)
- netns_node.connector("devs").connect(netns_tap.connector("node"))
- netns_tunchannel = netns_desc.create("TunChannel")
- #netns_tunchannel.set_attribute_value("tun_cipher", "PLAIN")
- netns_tunchannel.connector("->fd").connect(netns_tap.connector("fd->"))
- pl_tap.connector("tcp").connect(netns_tunchannel.connector("tcp"))
-
- def run(self):
- exp_desc = ExperimentDescription()
-
- ## PL ##
- pl_desc = self.add_pl_testbed(exp_desc)
- pl_inet = pl_desc.create("Internet")
- pl_node1, pl_iface1 = self.add_pl_node(pl_desc, pl_inet,
- "node1_pl")
-
- ## NETNS ##
- netns_desc = self.add_netns_testbed(exp_desc)
- netns_node = self.add_netns_node(netns_desc)
-
- ## NS3 ##
- ns3_desc = self.add_ns3_in_pl(exp_desc, pl_desc, pl_node1, pl_iface1, "ns3")
- wifi_chan = self.add_ns3_wifi_channel(ns3_desc)
-
- # AP node
- ap_node = self.add_ns3_node(ns3_desc)
- self.add_ns3_constant_mobility(ns3_desc, ap_node, 0, 0, 0)
- ap_wifi, ap_phy = self.add_ns3_wifi(ns3_desc, ap_node, access_point = True)
- self.add_ip_address(ap_wifi, (self.base_addr%33), 27)
- ap_phy.connector("chan").connect(wifi_chan.connector("phys"))
-
- # wifi network 32/27
- r = 50
- # STA nodes
- for i in xrange(0, self.nsta):
- stai = self.add_ns3_node(ns3_desc)
- angi = (360/self.nsta)*i
- xi = r*math.cos(angi)
- yi = r*math.sin(angi)
- self.add_ns3_constant_mobility(ns3_desc, stai, xi, yi, 0)
- wifi, phy= self.add_ns3_wifi(ns3_desc, stai, access_point = False)
- wifi_addr = self.base_addr%(34 + i)
- self.add_ip_address(wifi, wifi_addr, 27)
- phy.connector("chan").connect(wifi_chan.connector("phys"))
-
- self.add_route(stai, (self.base_addr%0), 30, (self.base_addr%33))
- self.add_route(stai, (self.base_addr%4), 30, (self.base_addr%33))
-
- net = 64 + i*4
- pl_nodei, pl_ifacei = self.add_pl_node(pl_desc, pl_inet,
- "node2%d_pl"%i)
-
- pl_addr = (self.base_addr%(net+1))
- ns3_addr = (self.base_addr%(net+2))
- self.add_pl_ns3_tunchan_connection(pl_desc, pl_nodei, pl_addr,
- ns3_desc, stai, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%32), 27, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%0), 30, ns3_addr)
- self.add_route(pl_nodei, (self.base_addr%4), 30, ns3_addr)
-
- network = (self.base_addr%net)
- self.add_route(netns_node, network, 30, (self.base_addr%2))
- self.add_route(pl_node1, network, 30, (self.base_addr%6))
- self.add_route(ap_node, network, 30, wifi_addr)
-
- # connection PL1/NETNS
- pl_addr = (self.base_addr%2)
- netns_addr = (self.base_addr%1)
- self.add_pl_netns_connection(pl_desc, pl_node1, pl_addr,
- netns_desc, netns_node, netns_addr)
-
- # connection PL1/NS3
- pl_addr = (self.base_addr%5)
- ns3_addr = (self.base_addr%6)
- self.add_pl_ns3_connection(pl_desc, pl_node1, pl_addr,
- ns3_desc, ap_node, ns3_addr)
-
- # APPLICATIONS
- command = "xterm"
- app = netns_desc.create("Application")
- app.set_attribute_value("command", command)
- app.set_attribute_value("user", self.user)
- app.connector("node").connect(netns_node.connector("apps"))
-
- # applications
- #target = "{#[%s].addr[0].[Address]#}" % label
- servers = []
- clients = []
- net = 0
- target = self.base_addr%2
- local = self.base_addr%1
- port = 5065
- command = "sleep 2; vlc -I dummy %s --miface-addr=%s --sout '#udp{dst=%s:%d}' vlc://quit" \
- % (local,self.movie, target, port)
- vlc_server = netns_desc.create("Application")
- vlc_server.set_attribute_value("command", command)
- vlc_server.set_attribute_value("user", self.user)
- vlc_server.connector("node").connect(netns_node.connector("apps"))
- servers.append(vlc_server.guid)
-
- command = "sudo dbus-uuidgen --ensure; vlc -vvv -I dummy udp://@%s:%d --sout '#std{access=file,mux=ts,dst=big_buck_bunny_stream.ts}' " % (target, port)
- vlc_client = pl_desc.create("Application")
- vlc_client.set_attribute_value("buildDepends", "vlc")
- vlc_client.set_attribute_value("rpmFusion", True)
- vlc_client.set_attribute_value("command", command)
- vlc_client.enable_trace("stdout")
- vlc_client.enable_trace("stderr")
- vlc_client.connector("node").connect(pl_node1.connector("apps"))
- clients.append(vlc_client.guid)
-
- # ROUTES
- self.add_route(netns_node, (self.base_addr%32), 27, (self.base_addr%2))
- self.add_route(netns_node, (self.base_addr%4), 30, (self.base_addr%2))
-
- self.add_route(pl_node1, (self.base_addr%32), 27, (self.base_addr%6))
-
- self.add_route(ap_node, (self.base_addr%0), 30, (self.base_addr%5))
-
- xml = exp_desc.to_xml()
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
- while not controller.is_finished(app.guid):
- time.sleep(0.5)
- time.sleep(0.1)
- controller.stop()
- controller.shutdown()
-
- """
- xml = exp_desc.to_xml()
- controller = ExperimentController(xml, self.root_dir)
- controller.start()
- stop = False
- while not stop:
- time.sleep(0.5)
- stop = True
- for guid in clients:
- if not controller.is_finished(guid):
- stop = False
- time.sleep(0.1)
- controller.stop()
- controller.shutdown()
- """
-
- def clean(self):
- shutil.rmtree(self.root_dir)
-
-if __name__ == '__main__':
- example = WirelessOverlay()
- example.run()
- example.clean()
-
#!/usr/bin/env python
# vim: set fileencoding=utf-8
-from distutils.core import setup, Extension, Command
+from distutils.core import setup
+import sys
setup(
name = "nepi",
version = "0.2",
description = "High-level abstraction for running network experiments",
author = "Mathieu Lacage, Alina Quereilhac, MartÃn Ferrari and Claudio Freire",
- url = "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/nepi/",
+ url = "http://nepi.pl.sophia.inria.fr/code/nepi",
license = "GPLv2",
platforms = "Linux",
packages = [
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Attribute(object):
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
self._connections.append(connector)
connector._connections.append(self)
+ def get_connected_box(self, idx = 0):
+ if len(self._connections) == 0:
+ return None
+ return self._connections[idx].box
+
def disconnect(self, connector):
if connector not in self._connections or\
self not in connector._connections:
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.core.attributes import Attribute, AttributesMap
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.core.attributes import AttributesMap, Attribute
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.core.attributes import Attribute, AttributesMap
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.core import execute
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_ID
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
TESTBED_ID = "netns"
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
for trace_id, (trace, filename) in traces.iteritems():
if hasattr(trace, "close"):
trace.close()
+ if hasattr(trace, "signal"):
+ trace.signal()
for guid, element in self._elements.iteritems():
if isinstance(element, self.TunChannel):
element.cleanup()
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from factories_metadata import wifi_standards, l4_protocols, \
"flags" : Attribute.ExecImmutable | Attribute.Metadata,
"validation_function" : validation.is_enum,
}),
+ "Up" : dict({
+ "name" : "Up",
+ "help" : "Flag to enable or disable interface",
+ "type" : Attribute.BOOL,
+ "value" : True,
+ "validation_function" : validation.is_integer,
+ }),
})
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
TESTBED_ID = "ns3"
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from util import _get_ipv4_protocol_guid, _get_node_guid, _get_dev_number
from nepi.core import testbed_impl
from nepi.core.attributes import Attribute
from constants import TESTBED_ID, TESTBED_VERSION
if factory_id in self.LOCAL_FACTORIES:
setattr(element, name, value)
elif not factory.box_attributes.is_attribute_metadata(name):
- ns3_value = self._to_ns3_value(guid, name, value)
- self._set_attribute(name, ns3_value, element)
+ if name == "Up":
+ ipv4_guid = _get_ipv4_protocol_guid(self, guid)
+ if not ipv4_guid in self._elements:
+ return
+ ipv4 = self._elements[ipv4_guid]
+ if value == False:
+ nint = ipv4.GetNInterfaces()
+ for i in xrange(0, nint):
+ ipv4.SetDown(i)
+ else:
+ nint = ipv4.GetNInterfaces()
+ for i in xrange(0, nint):
+ ipv4.SetUp(i)
+ else:
+ ns3_value = self._to_ns3_value(guid, name, value)
+ self._set_attribute(name, ns3_value, element)
def get(self, guid, name, time = TIME_NOW):
value = super(TestbedController, self).get(guid, name, time)
return getattr(element, name)
else:
return value
+ else:
+ if name == "Up":
+ ipv4_guid = _get_ipv4_protocol_guid(self, guid)
+ if not ipv4_guid in self._elements:
+ return True
+ ipv4 = self._elements[ipv4_guid]
+ nint = ipv4.GetNInterfaces()
+ value = True
+ for i in xrange(0, nint):
+ value = ipv4.IsUp(i)
+ if not value: break
+ return value
+
if factory.box_attributes.is_attribute_metadata(name):
return value
TypeId = self.ns3.TypeId()
typeid = TypeId.LookupByName(factory_id)
- info = TypeId.AttributeInfo()
+ info = TypeId.AttributeInformation()
if not typeid or not typeid.LookupAttributeByName(name, info):
raise AttributeError("Invalid attribute %s for element type %d" % \
(name, guid))
self._get_attribute(name, ns3_value, element)
value = ns3_value.SerializeToString(checker)
attr_type = factory.box_attributes.get_attribute_type(name)
+
if attr_type == Attribute.INTEGER:
return int(value)
if attr_type == Attribute.DOUBLE:
def _schedule_event(self, condition, func, *args):
"""Schedules event on running experiment"""
- def execute_event(condition, has_event_occurred, func, *args):
+ def execute_event(contextId, condition, has_event_occurred, func, *args):
# exec func
try:
func(*args)
factory_id = self._create[guid]
TypeId = self.ns3.TypeId()
typeid = TypeId.LookupByName(factory_id)
- info = TypeId.AttributeInfo()
+ info = TypeId.AttributeInformation()
if not typeid.LookupAttributeByName(name, info):
raise RuntimeError("Attribute %s doesn't belong to element %s" \
% (name, factory_id))
TypeId = self.ns3.TypeId()
typeid = TypeId.LookupByName(factory_id)
for name, value in params.iteritems():
- info = self.ns3.TypeId.AttributeInfo()
+ info = self.ns3.TypeId.AttributeInformation()
found = typeid.LookupAttributeByName(name, info)
if found and \
(info.flags & TypeId.ATTR_CONSTRUCT == TypeId.ATTR_CONSTRUCT):
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from util import _get_ipv4_protocol_guid, _get_node_guid, _get_dev_number
from nepi.util import tags
from nepi.util.constants import AF_INET, ApplicationStatus as AS, \
FactoryCategories as FC
"SF_TYPE_ALL": 255
})
-def _get_ipv4_protocol_guid(testbed_instance, node_guid):
- # search for the Ipv4L3Protocol asociated with the device
- protos_guids = testbed_instance.get_connected(node_guid, "protos", "node")
- if len(protos_guids) == 0:
- raise RuntimeError("No protocols where found for the node %d" % node_guid)
- ipv4_guid = None
- for proto_guid in protos_guids:
- proto_factory_id = testbed_instance._create[proto_guid]
- if proto_factory_id == "ns3::Ipv4L3Protocol":
- ipv4_guid = proto_guid
- break
- if not ipv4_guid:
- raise RuntimeError("No Ipv4L3Protocol associated to node %d. Can't add Ipv4 addresses" % node_guid)
- return ipv4_guid
-
-def _get_node_guid(testbed_instance, guid):
- # search for the node asociated with the device
- node_guids = testbed_instance.get_connected(guid, "node", "devs")
- if len(node_guids) == 0:
- raise RuntimeError("Can't instantiate interface %d outside node" % guid)
- node_guid = node_guids[0]
- return node_guid
-
-def _get_dev_number(testbed_instance, guid):
- node_guid = _get_node_guid(testbed_instance, guid)
- dev_guids = testbed_instance.get_connected(node_guid, "devs", "node")
- interface_number = 0
- for guid_ in dev_guids:
- if guid_ == guid:
- break
- interface_number += 1
- return interface_number
-
def _follow_trace(testbed_instance, guid, trace_id, filename):
testbed_instance.follow_trace(guid, trace_id, filename)
filepath = testbed_instance.trace_filepath(guid, trace_id)
"configure_function": configure_node,
"help": "",
"connector_types": ["devs", "apps", "protos", "mobility"],
+ "box_attributes": ["Up"],
"tags": [tags.NODE, tags.ALLOW_ROUTES],
}),
"ns3::GridPositionAllocator": dict({
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
from ns.olsr import *
from ns.aodv import *
from ns.dsdv import *
-from ns.click import *
+#from ns.click import *
from ns.mobility import *
from ns.wifi import *
from ns.netanim import *
from ns.topology_read import *
from ns.energy import *
from ns.tools import *
-from ns.visualizer import *
+#from ns.visualizer import *
from ns.point_to_point_layout import *
from ns.fd_net_device import *
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
traces = dict({
--- /dev/null
+def _get_ipv4_protocol_guid(testbed_instance, node_guid):
+ # search for the Ipv4L3Protocol asociated with the device
+ protos_guids = testbed_instance.get_connected(node_guid, "protos", "node")
+ if len(protos_guids) == 0:
+ raise RuntimeError("No protocols where found for the node %d" % node_guid)
+ ipv4_guid = None
+ for proto_guid in protos_guids:
+ proto_factory_id = testbed_instance._create[proto_guid]
+ if proto_factory_id == "ns3::Ipv4L3Protocol":
+ ipv4_guid = proto_guid
+ break
+ if not ipv4_guid:
+ raise RuntimeError("No Ipv4L3Protocol associated to node %d. Can't add Ipv4 addresses" % node_guid)
+ return ipv4_guid
+
+def _get_node_guid(testbed_instance, guid):
+ # search for the node asociated with the device
+ node_guids = testbed_instance.get_connected(guid, "node", "devs")
+ if len(node_guids) == 0:
+ raise RuntimeError("Can't instantiate interface %d outside node" % guid)
+ node_guid = node_guids[0]
+ return node_guid
+
+def _get_dev_number(testbed_instance, guid):
+ node_guid = _get_node_guid(testbed_instance, guid)
+ dev_guids = testbed_instance.get_connected(node_guid, "devs", "node")
+ interface_number = 0
+ for guid_ in dev_guids:
+ if guid_ == guid:
+ break
+ interface_number += 1
+ return interface_number
+
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
# TODO: Allow netrefs!
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
from nepi.util.constants import ApplicationStatus as AS
+_ccnre = re.compile("\s*(udp|tcp)\s+(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\s*$")
+
class Dependency(object):
"""
A Dependency is in every respect like an application.
raise RuntimeError, "Failed to set up application %s: %s %s" % (self.home_path, e.args[0], e.args[1],)
if self.stdin:
+ stdin = self.stdin
+ if not os.path.isfile(stdin):
+ stdin = cStringIO.StringIO(self.stdin)
+
# Write program input
try:
- self._popen_scp(
- cStringIO.StringIO(self.stdin),
+ self._popen_scp(stdin,
'%s@%s:%s' % (self.node.slicename, self.node.hostname,
os.path.join(self.home_path, 'stdin') ),
)
def _do_install(self):
if self.install:
self._logger.info("Installing %s at %s", self, self.node.hostname)
-
+
# Install application
try:
self._popen_ssh_command(
def __init__(self, api = None):
super(NS3Dependency, self).__init__(api)
- self.buildDepends = 'make waf gcc gcc-c++ gccxml unzip'
+ self.buildDepends = 'make waf gcc gcc-c++ gccxml unzip bzr'
# We have to download the sources, untar, build...
- pybindgen_source_url = "http://yans.pl.sophia.inria.fr/trac/nepi/raw-attachment/wiki/WikiStart/pybindgen-r794.tar.gz"
pygccxml_source_url = "http://leaseweb.dl.sourceforge.net/project/pygccxml/pygccxml/pygccxml-1.0/pygccxml-1.0.0.zip"
- ns3_source_url = "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/ns-3.11-nepi/archive/tip.tar.gz"
- passfd_source_url = "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/python-passfd/archive/tip.tar.gz"
+ ns3_source_url = "http://nepi.pl.sophia.inria.fr/code/nepi-ns3.13/archive/tip.tar.gz"
+ passfd_source_url = "http://nepi.pl.sophia.inria.fr/code/python-passfd/archive/tip.tar.gz"
+
+ pybindgen_version = "797"
+
self.build =(
" ( "
" cd .. && "
# Not working, rebuild
# Archive SHA1 sums to check
"echo '7158877faff2254e6c094bf18e6b4283cac19137 pygccxml-1.0.0.zip' > archive_sums.txt && "
- "echo 'a18c2ccffd0df517bc37e2f3a2475092517c43f2 pybindgen-src.tar.gz' >> archive_sums.txt && "
" ( " # check existing files
" sha1sum -c archive_sums.txt && "
" test -f passfd-src.tar.gz && "
" test -f ns3-src.tar.gz "
" ) || ( " # nope? re-download
- " rm -f pybindgen-src.zip pygccxml-1.0.0.zip passfd-src.tar.gz ns3-src.tar.gz && "
- " wget -q -c -O pybindgen-src.tar.gz %(pybindgen_source_url)s && " # continue, to exploit the case when it has already been dl'ed
+ " rm -rf pybindgen pygccxml-1.0.0.zip passfd-src.tar.gz ns3-src.tar.gz && "
+ " bzr checkout lp:pybindgen -r %(pybindgen_version)s && " # continue, to exploit the case when it has already been dl'ed
" wget -q -c -O pygccxml-1.0.0.zip %(pygccxml_source_url)s && "
" wget -q -c -O passfd-src.tar.gz %(passfd_source_url)s && "
" wget -q -c -O ns3-src.tar.gz %(ns3_source_url)s && "
" sha1sum -c archive_sums.txt " # Check SHA1 sums when applicable
" ) && "
"unzip -n pygccxml-1.0.0.zip && "
- "mkdir -p pybindgen-src && "
"mkdir -p ns3-src && "
"mkdir -p passfd-src && "
"tar xzf ns3-src.tar.gz --strip-components=1 -C ns3-src && "
"tar xzf passfd-src.tar.gz --strip-components=1 -C passfd-src && "
- "tar xzf pybindgen-src.tar.gz --strip-components=1 -C pybindgen-src && "
"rm -rf target && " # mv doesn't like unclean targets
"mkdir -p target && "
"cd pygccxml-1.0.0 && "
"python setup.py build && "
"python setup.py install --install-lib ${BUILD}/target && "
"python setup.py clean && "
- "cd ../pybindgen-src && "
+ "cd ../pybindgen && "
"export PYTHONPATH=$PYTHONPATH:${BUILD}/target && "
"./waf configure --prefix=${BUILD}/target -d release && "
"./waf && "
"./waf &&"
"./waf install && "
"rm -f ${BUILD}/target/lib/*.so && "
- "cp -a ${BUILD}/ns3-src/build/release/libns3*.so ${BUILD}/target/lib && "
- "cp -a ${BUILD}/ns3-src/build/release/bindings/python/ns ${BUILD}/target/lib &&"
+ "cp -a ${BUILD}/ns3-src/build/libns3*.so ${BUILD}/target/lib && "
+ "cp -a ${BUILD}/ns3-src/build/bindings/python/ns ${BUILD}/target/lib &&"
"./waf clean "
" )"
% dict(
- pybindgen_source_url = server.shell_escape(pybindgen_source_url),
+ pybindgen_version = server.shell_escape(pybindgen_version),
pygccxml_source_url = server.shell_escape(pygccxml_source_url),
ns3_source_url = server.shell_escape(ns3_source_url),
passfd_source_url = server.shell_escape(passfd_source_url),
r')',
re.I)
return badre.search(out) or badre.search(err) or self.node.check_bad_host(out,err)
+
+
+class CCNxDaemon(Application):
+ """
+ An application also has dependencies, but also a command to be ran and monitored.
+
+ It adds the output of that command as traces.
+ """
+
+ def __init__(self, api=None):
+ super(CCNxDaemon,self).__init__(api)
+
+ # Attributes
+ self.ccnLocalPort = None
+ self.ccnRoutes = None
+ self.ccnxVersion = "ccnx-0.6.0"
+
+ self.ccnx_0_5_1_sources = "http://www.ccnx.org/releases/ccnx-0.5.1.tar.gz"
+ self.ccnx_0_6_0_sources = "http://www.ccnx.org/releases/ccnx-0.6.0.tar.gz"
+ self.buildDepends = 'make gcc development-tools openssl-devel expat-devel libpcap-devel libxml2-devel'
+
+ self.ccnx_0_5_1_build = (
+ " ( "
+ " cd .. && "
+ " test -d ccnx-0.5.1-src/build/bin "
+ " ) || ( "
+ # Not working, rebuild
+ "("
+ " mkdir -p ccnx-0.5.1-src && "
+ " wget -q -c -O ccnx-0.5.1-src.tar.gz %(ccnx_source_url)s &&"
+ " tar xf ccnx-0.5.1-src.tar.gz --strip-components=1 -C ccnx-0.5.1-src "
+ ") && "
+ "cd ccnx-0.5.1-src && "
+ "mkdir -p build/include &&"
+ "mkdir -p build/lib &&"
+ "mkdir -p build/bin &&"
+ "I=$PWD/build && "
+ "INSTALL_BASE=$I ./configure &&"
+ "make && make install"
+ " )") % dict(
+ ccnx_source_url = server.shell_escape(self.ccnx_0_5_1_sources),
+ )
+
+ self.ccnx_0_5_1_install = (
+ " ( "
+ " test -d ${BUILD}/ccnx-0.5.1-src/build/bin && "
+ " cp -r ${BUILD}/ccnx-0.5.1-src/build/bin ${SOURCES}"
+ " )"
+ )
+
+ self.ccnx_0_6_0_build = (
+ " ( "
+ " cd .. && "
+ " test -d ccnx-0.6.0-src/build/bin "
+ " ) || ( "
+ # Not working, rebuild
+ "("
+ " mkdir -p ccnx-0.6.0-src && "
+ " wget -q -c -O ccnx-0.6.0-src.tar.gz %(ccnx_source_url)s &&"
+ " tar xf ccnx-0.6.0-src.tar.gz --strip-components=1 -C ccnx-0.6.0-src "
+ ") && "
+ "cd ccnx-0.6.0-src && "
+ "./configure && make"
+ " )") % dict(
+ ccnx_source_url = server.shell_escape(self.ccnx_0_6_0_sources),
+ )
+
+ self.ccnx_0_6_0_install = (
+ " ( "
+ " test -d ${BUILD}/ccnx-0.6.0-src/bin && "
+ " cp -r ${BUILD}/ccnx-0.6.0-src/bin ${SOURCES}"
+ " )"
+ )
+
+ self.env['PATH'] = "$PATH:${SOURCES}/bin"
+
+ def setup(self):
+ # setting ccn sources
+ if not self.build:
+ if self.ccnxVersion == 'ccnx-0.6.0':
+ self.build = self.ccnx_0_6_0_build
+ elif self.ccnxVersion == 'ccnx-0.5.1':
+ self.build = self.ccnx_0_5_1_build
+
+ if not self.install:
+ if self.ccnxVersion == 'ccnx-0.6.0':
+ self.install = self.ccnx_0_6_0_install
+ elif self.ccnxVersion == 'ccnx-0.5.1':
+ self.install = self.ccnx_0_5_1_install
+
+ super(CCNxDaemon, self).setup()
+
+ def start(self):
+ self.command = ""
+ if self.ccnLocalPort:
+ self.command = "export CCN_LOCAL_PORT=%s ; " % self.ccnLocalPort
+ self.command += " ccndstart "
+
+ # configure ccn routes
+ if self.ccnRoutes:
+ routes = self.ccnRoutes.split("|")
+
+ if self.ccnLocalPort:
+ routes = map(lambda route: "%s %s" %(route,
+ self.ccnLocalPort) if _ccnre.match(route) else route,
+ routes)
+
+ routes = map(lambda route: "ccndc add ccnx:/ %s" % route,
+ routes)
+
+ routescmd = " ; ".join(routes)
+ self.command += " ; "
+ self.command += routescmd
+
+ # Start will be invoked in prestart step
+ super(CCNxDaemon, self).start()
+
+ def kill(self):
+ self._logger.info("Killing %s", self)
+
+ command = "${SOURCES}/bin/ccndstop"
+
+ if self.ccnLocalPort:
+ self.command = "export CCN_LOCAL_PORT=%s; %s" % (self.ccnLocalPort, command)
+
+ cmd = self._replace_paths(command)
+ command = cStringIO.StringIO()
+ command.write(cmd)
+ command.seek(0)
+
+ try:
+ self._popen_scp(
+ command,
+ '%s@%s:%s' % (self.node.slicename, self.node.hostname,
+ os.path.join(self.home_path, "kill.sh"))
+ )
+ except RuntimeError, e:
+ raise RuntimeError, "Failed to kill ccndxdaemon: %s %s" \
+ % (e.args[0], e.args[1],)
+
+
+ script = "bash ./kill.sh"
+ (out,err),proc = rspawn.remote_spawn(
+ script,
+ pidfile = 'kill-pid',
+ home = self.home_path,
+ stdin = '/dev/null',
+ stdout = 'killlog',
+ stderr = rspawn.STDOUT,
+
+ host = self.node.hostname,
+ port = None,
+ user = self.node.slicename,
+ agent = None,
+ ident_key = self.node.ident_path,
+ server_key = self.node.server_key,
+ hostip = self.node.hostip,
+ )
+
+ if proc.wait():
+ raise RuntimeError, "Failed to kill cnnxdaemon: %s %s" % (out,err,)
+
+ super(CCNxDaemon, self).kill()
+
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
TESTBED_ID = "planetlab"
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
self._just_provisioned = set()
self._load_blacklist()
-
+
+ self._slice_id = None
+ self._plcapi = None
+ self._sliceapi = None
+ self._vsys_vnet = None
+
self._logger = logging.getLogger('nepi.testbeds.planetlab')
self.recovering = False
return self._home_directory
@property
- def plapi(self):
- if not hasattr(self, '_plapi'):
+ def plcapi(self):
+ if not self._plcapi:
import plcapi
-
- if self.authUser:
- self._plapi = plcapi.PLCAPI(
- username = self.authUser,
- password = self.authString,
- hostname = self.plcHost,
- urlpattern = self.plcUrl
+ self._plcapi = plcapi.plcapi(
+ self.authUser,
+ self.authString,
+ self.plcHost,
+ self.plcUrl
)
+ return self._plcapi
+
+ @property
+ def sliceapi(self):
+ if not self._sliceapi:
+ if not self.sfa:
+ self._sliceapi = self.plcapi
else:
- # anonymous access - may not be enough for much
- self._plapi = plcapi.PLCAPI()
- return self._plapi
+ from nepi.util import sfiapi
+ self._sliceapi = sfiapi.sfiapi(self.slice_id)
+ return self._sliceapi
@property
def slice_id(self):
- if not hasattr(self, '_slice_id'):
- slices = self.plapi.GetSlices(self.slicename, fields=('slice_id',))
- if slices:
- self._slice_id = slices[0]['slice_id']
- else:
- # If it wasn't found, don't remember this failure, keep trying
- return None
+ if not self._slice_id:
+ self._slice_id = self.sliceapi.GetSliceId(self.slicename)
return self._slice_id
@property
def vsys_vnet(self):
- if not hasattr(self, '_vsys_vnet'):
- self._vsys_vnet = plutil.getVnet(
- self.plapi,
- self.slicename)
+ if not self._vsys_vnet:
+ self._vsys_vnet = self.sliceapi.GetSliceVnetSysTag(self.slicename)
return self._vsys_vnet
-
+
def _load_blacklist(self):
blpath = environ.homepath('plblacklist')
try:
self._blacklist = set(
- map(int,
- map(str.strip, bl.readlines())
- )
+ map(str.strip, bl.readlines())
)
finally:
bl.close()
get_attribute_value("tapPortBase")
self.p2pDeployment = self._attributes.\
get_attribute_value("p2pDeployment")
- self.dedicatedSlice = self._attributes.\
- get_attribute_value("dedicatedSlice")
-
+ self.cleanProc = self._attributes.\
+ get_attribute_value("cleanProc")
+ self.cleanHome = self._attributes.\
+ get_attribute_value("cleanHome")
+ self.sfa = self._attributes.\
+ get_attribute_value("sfa")
+ if self.sfa:
+ self._slice_id = self._attributes.\
+ get_attribute_value("sliceHrn")
+
if not self.slicename:
raise RuntimeError, "Slice not set"
if not self.authUser:
reserved = set(self._blacklist)
for guid, node in self._elements.iteritems():
if isinstance(node, self._node.Node) and node._node_id is not None:
- reserved.add(node._node_id)
+ reserved.add(node.hostname)
# Initial algo:
# look for perfectly defined nodes
filter_slice_id = self.slice_id)
node_id = None
+ candidate_hosts = set(candidates.keys() if candidates else [])
reserve_lock.acquire()
try:
- candidates -= reserved
- if len(candidates) == 1:
- node_id = iter(candidates).next()
- reserved.add(node_id)
- elif not candidates:
+ candidate_hosts -= reserved
+ if len(candidate_hosts) == 1:
+ hostname = iter(candidate_hosts).next()
+ node_id = candidates[hostname]
+ reserved.add(hostname)
+ elif not candidate_hosts:
# Try again including unassigned nodes
reserve_lock.release()
try:
candidates = node.find_candidates()
finally:
reserve_lock.acquire()
- candidates -= reserved
- if len(candidates) > 1:
+ candidate_hosts = set(candidates.keys() if candidates else [])
+ candidate_hosts -= reserved
+ if len(candidate_hosts) > 1:
return
- if len(candidates) == 1:
- node_id = iter(candidates).next()
+ if len(candidate_hosts) == 1:
+ hostname = iter(candidate_hosts).next()
+ node_id = candidates[hostname]
to_provision.add(node_id)
- reserved.add(node_id)
+ reserved.add(hostname)
elif not candidates:
- raise RuntimeError, "Cannot assign resources for node %s, no candidates sith %s" % (guid,
+ raise RuntimeError, "Cannot assign resources for node %s, no candidates with %s" % (guid,
node.make_filter_description())
finally:
reserve_lock.release()
-
+
if node_id is not None:
node.assign_node_id(node_id)
# If we have only one candidate, simply use it
candidates = node.find_candidates(
filter_slice_id = filter_slice_id)
- candidates -= reserved
- reqs.append(candidates)
+ for r in reserved:
+ if candidates.has_key(r):
+ del candidates[r]
+ reqs.append(candidates.values())
nodes.append(node)
for guid, node in self._elements.iteritems():
if isinstance(node, self._node.Node) and node._node_id is None:
runner.put(genreqs, node, self.slice_id)
runner.sync()
-
+
if nodes and reqs:
if recover:
raise RuntimeError, "Impossible to recover: unassigned host for Nodes %r" % (nodes,)
def do_provisioning(self):
if self._to_provision:
# Add new nodes to the slice
- cur_nodes = self.plapi.GetSlices(self.slicename, ['node_ids'])[0]['node_ids']
+ cur_nodes = self.sliceapi.GetSliceNodes(self.slice_id)
new_nodes = list(set(cur_nodes) | self._to_provision)
- self.plapi.UpdateSlice(self.slicename, nodes=new_nodes)
+ self.sliceapi.AddSliceNodes(self.slice_id, nodes=new_nodes)
# cleanup
self._just_provisioned = self._to_provision
if isinstance(node, self._node.Node):
if not node.is_alive():
self._logger.warn("Blacklisting %s for unresponsiveness", node.hostname)
- self._blacklist.add(node._node_id)
+ self._blacklist.add(node.hostname)
node.unassign_node()
try:
# TODO: take on account schedule time for the task
element = self._elements[guid]
if element:
+ if name == "up":
+ if value == True:
+ element.if_up()
+ else:
+ element.if_down()
+
try:
setattr(element, name, value)
except:
Parallel(metadata.NS3DEPENDENCY),
Parallel(metadata.DEPENDENCY),
Parallel(metadata.APPLICATION),
+ Parallel(metadata.CCNXDAEMON),
])
# Tunnels are not harmed by configuration after
finally:
self.recovering = True
- def _make_generic(self, parameters, kind):
- app = kind(self.plapi)
+ def _make_generic(self, parameters, kind, **kwargs):
+ args = dict({'api': self.plcapi})
+ args.update(kwargs)
+ app = kind(**args)
app.testbed = weakref.ref(self)
# Note: there is 1-to-1 correspondence between attribute names
return app
def _make_node(self, parameters):
- node = self._make_generic(parameters, self._node.Node)
- node.enable_cleanup = self.dedicatedSlice
+ args = dict({'sliceapi': self.sliceapi})
+ node = self._make_generic(parameters, self._node.Node, **args)
+ node.enable_proc_cleanup = self.cleanProc
+ node.enable_home_cleanup = self.cleanHome
return node
def _make_node_iface(self, parameters):
def _make_internet(self, parameters):
return self._make_generic(parameters, self._interfaces.Internet)
- def _make_application(self, parameters):
- return self._make_generic(parameters, self._app.Application)
+ def _make_application(self, parameters, clazz = None):
+ if not clazz:
+ clazz = self._app.Application
+ return self._make_generic(parameters, clazz)
def _make_dependency(self, parameters):
return self._make_generic(parameters, self._app.Dependency)
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
if self.node is None or self.node._node_id is None:
raise RuntimeError, "Cannot pick interface without an assigned node"
-
+
+ # HACK: SFA doesnt give the node_id!!
+ if not isinstance(self.node._node_id, int):
+ node_data = self._api.GetNodes(filters={'hostname':self.node.hostname}, fields=('node_id',))[0]
+ node_id = node_data['node_id']
+ else:
+ node_id = self.node._node_id
+
avail = self._api.GetInterfaces(
- node_id=self.node._node_id,
+ node_id=node_id,
is_primary=self.primary,
fields=('interface_id','mac','netmask','ip') )
if self.peer_proto_impl:
return self.peer_proto_impl.if_name
+ def if_up(self):
+ if self.peer_proto_impl:
+ return self.peer_proto_impl.if_up()
+
+ def if_down(self):
+ if self.peer_proto_impl:
+ return self.peer_proto_impl.if_down()
+
def routes_here(self, route):
"""
Returns True if the route should be attached to this interface
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
TUNIFACE = "TunInterface"
TAPIFACE = "TapInterface"
APPLICATION = "Application"
+CCNXDAEMON = "CCNxDaemon"
DEPENDENCY = "Dependency"
NEPIDEPENDENCY = "NepiDependency"
NS3DEPENDENCY = "NS3Dependency"
if app.depends:
node.required_packages.update(set(
app.depends.split() ))
-
+
if app.add_to_path:
if app.home_path and app.home_path not in node.pythonpath:
node.pythonpath.append(app.home_path)
testbed_instance.elements[guid] = element
+def create_ccnxdaemon(testbed_instance, guid):
+ parameters = testbed_instance._get_parameters(guid)
+ element = testbed_instance._make_application(parameters,
+ clazz = testbed_instance._app.CCNxDaemon )
+
+ # Just inject configuration stuff
+ element.home_path = "nepi-ccnd-%s" % (guid,)
+
+ testbed_instance.elements[guid] = element
+
def create_dependency(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
element = testbed_instance._make_dependency(parameters)
### Start/Stop functions ###
+def prestart_ccnxdaemon(testbed_instance, guid):
+ # ccnx daemon needs to start before the rest of the
+ # ccn applications
+ start_application(testbed_instance, guid)
+
+def stop_ccndaemon(testbed_instance, guid):
+ app = testbed_instance.elements[guid]
+ app.kill()
+
def start_application(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
traces = testbed_instance._get_traces(guid)
}),
dict({
"from": (TESTBED_ID, NODE, "apps"),
- "to": (TESTBED_ID, (APPLICATION, MULTICASTANNOUNCER), "node"),
+ "to": (TESTBED_ID, (APPLICATION, CCNXDAEMON, MULTICASTANNOUNCER), "node"),
"init_code": connect_dep,
"can_cross": False
}),
"flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
"validation_function": validation.is_number,
}),
-
+ "timeframe": dict({
+ "name": "timeframe",
+ "help": "Past time period in which to check information about the node. Values are year,month, week, latest",
+ "type": Attribute.ENUM,
+ "value": "week",
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+ "allowed": ["latest",
+ "week",
+ "month",
+ "year"],
+ "validation_function": validation.is_enum,
+ }),
+
"up": dict({
"name": "up",
"help": "Link up",
"flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
"validation_function": validation.is_string
}),
- "sudo": dict({
+ "ccnroutes": dict({
+ "name": "ccnRoutes",
+ "help": "Route can be static (e.g. udp ip) or multicast (e.g. udp 224.0.0.204 2869). To separate different route use '|' ",
+ "type": Attribute.STRING,
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+ "validation_function": validation.is_string
+ }),
+ "sudo": dict({
"name": "sudo",
"help": "Run with root privileges",
"type": Attribute.BOOL,
"flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
"validation_function": validation.is_string
}),
+ "ccnxversion": dict({
+ "name": "ccnxVersion",
+ "help": "Version of ccnx source code to install in the node.",
+ "type": Attribute.ENUM,
+ "value": "ccnx-0.6.0",
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+ "allowed": ["ccnx-0.6.0",
+ "ccnx-0.5.1"],
+ "validation_function": validation.is_enum,
+ }),
+ "ccnlocalport" : dict({
+ "name" : "ccnLocalPort",
+ "help" : "Local port to bind the ccn daemon. (i.e. CCN_LOCAL_PORT=)",
+ "type" : Attribute.INTEGER,
+ "flags" : Attribute.DesignInvisible | \
+ Attribute.ExecInvisible | \
+ Attribute.ExecImmutable | \
+ Attribute.Metadata,
+ "validation_function" : validation.is_integer,
+ }),
"build": dict({
"name": "build",
"help": "Build commands to execute after deploying the sources. "
INTERNET, NODE, NODEIFACE, CLASSQUEUEFILTER, TOSQUEUEFILTER,
MULTICASTANNOUNCER, MULTICASTFORWARDER, MULTICASTROUTER,
TUNFILTER, TAPIFACE, TUNIFACE, NETPIPE,
- NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, APPLICATION ]
+ NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, CCNXDAEMON, APPLICATION ]
configure_order = [
INTERNET, Parallel(NODE),
NODEIFACE,
Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER),
Parallel(TAPIFACE), Parallel(TUNIFACE), NETPIPE,
- Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ]
+ Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON),
+ Parallel(APPLICATION)]
# Start (and prestart) node after ifaces, because the node needs the ifaces in order to set up routes
start_order = [ INTERNET,
Parallel(TAPIFACE), Parallel(TUNIFACE),
Parallel(NODE), NETPIPE,
Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER),
- Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ]
+ Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON),
+ Parallel(APPLICATION)]
# cleanup order
shutdown_order = [
Parallel(APPLICATION),
+ Parallel (CCNXDAEMON),
Parallel(MULTICASTROUTER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTANNOUNCER),
Parallel(TAPIFACE), Parallel(TUNIFACE), Parallel(NETPIPE),
Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY),
"max_load",
"min_cpu",
"max_cpu",
+ "timeframe",
# NEPI-in-NEPI attributes
ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP,
"traces": ["stdout", "stderr", "buildlog", "output"],
"tags": [tags.APPLICATION],
}),
+
+ CCNXDAEMON: dict({
+ "help": "CCNx daemon",
+ "category": FC.CATEGORY_APPLICATIONS,
+ "create_function": create_ccnxdaemon,
+ "prestart_function": prestart_ccnxdaemon,
+ "status_function": status_application,
+ "stop_function": stop_application,
+ "configure_function": configure_application,
+ "box_attributes": ["ccnroutes", "build", "ccnlocalport",
+ "install", "ccnxversion", "sources"],
+ "connector_types": ["node"],
+ "traces": ["stdout", "stderr", "buildlog", "output"],
+ "tags": [tags.APPLICATION],
+ }),
DEPENDENCY: dict({
"help": "Requirement for package or application to be installed on some node",
"category": FC.CATEGORY_APPLICATIONS,
})
testbed_attributes = dict({
+ "slice_hrn": dict({
+ "name": "sliceHrn",
+ "help": "The hierarchical Resource Name (HRN) for the PlanetLab slice.",
+ "type": Attribute.STRING,
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable | Attribute.NoDefaultValue,
+ "validation_function": validation.is_string
+ }),
+ "sfa": dict({
+ "name": "sfa",
+ "help": "Activates the use of SFA for node reservation.",
+ "type": Attribute.BOOL,
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable | Attribute.NoDefaultValue,
+ "validation_function": validation.is_bool
+ }),
"slice": dict({
"name": "slice",
"help": "The name of the PlanetLab slice to use",
"pl_log_level": dict({
"name": "plLogLevel",
"help": "Verbosity of logging of planetlab events.",
- "value": "ERROR",
+ "value": "INFO",
"type": Attribute.ENUM,
"allowed": ["DEBUG",
"INFO",
"range": (2000,30000),
"validation_function": validation.is_integer_range(2000,30000)
}),
- "dedicated_slice": dict({
- "name": "dedicatedSlice",
+ "clean_proc": dict({
+ "name": "cleanProc",
"help": "Set to True if the slice will be dedicated to this experiment. "
- "NEPI will perform node and slice cleanup, making sure slices are "
+ "NEPI will perform node and slice process cleanup, making sure slices are "
"in a clean, repeatable state before running the experiment.",
"type": Attribute.BOOL,
"value": False,
"flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
"validation_function": validation.is_bool
}),
+ "clean_home": dict({
+ "name": "cleanHome",
+ "help": "Set to True all preexistent directories in the home "
+ "directory of each sliver will be removed before the "
+ "start of the experiment.",
+ "type": Attribute.BOOL,
+ "value": False,
+ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+ "validation_function": validation.is_bool
+ }),
})
supported_recovery_policies = [
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
minLoad = _castproperty(float, '_minLoad')
maxLoad = _castproperty(float, '_maxLoad')
- def __init__(self, api=None):
+ def __init__(self, api=None, sliceapi=None):
if not api:
api = plcapi.PLCAPI()
self._api = api
+ self._sliceapi = sliceapi or api
# Attributes
self.hostname = None
self.maxLoad = None
self.min_num_external_ifaces = None
self.max_num_external_ifaces = None
- self.timeframe = 'm'
+ self._timeframe = 'w'
# Applications and routes add requirements to connected nodes
self.required_packages = set()
self.ident_path = None
self.server_key = None
self.home_path = None
- self.enable_cleanup = False
+ self.enable_proc_cleanup = False
+ self.enable_home_cleanup = False
# Those are filled when an actual node is allocated
self._node_id = None
# Logging
self._logger = logging.getLogger('nepi.testbeds.planetlab')
+
+ def set_timeframe(self, timeframe):
+ if timeframe == "latest":
+ self._timeframe = ""
+ elif timeframe == "month":
+ self._timeframe = "m"
+ elif timeframe == "year":
+ self._timeframe = "y"
+ else:
+ self._timeframe = "w"
+
+ def get_timeframe(self):
+ if self._timeframe == "":
+ return "latest"
+ if self._timeframe == "m":
+ return "month"
+ if self._timeframe == "y":
+ return "year"
+ return "week"
+
+ timeframe = property(get_timeframe, set_timeframe)
def _nepi_testbed_environment_setup_get(self):
command = cStringIO.StringIO()
for envval in envvals:
command.write(' ; export %s=%s' % (envkey, envval))
return command.getvalue()
+
def _nepi_testbed_environment_setup_set(self, value):
pass
+
_nepi_testbed_environment_setup = property(
_nepi_testbed_environment_setup_get,
_nepi_testbed_environment_setup_set)
self._logger.info("Finding candidates for %s", self.make_filter_description())
fields = ('node_id',)
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
# get initial candidates (no tag filters)
basefilters = self.build_filters({}, self.BASEFILTERS)
extra['peer'] = self.site
candidates = set(map(operator.itemgetter('node_id'),
- self._api.GetNodes(filters=basefilters, fields=fields, **extra)))
-
+ self._sliceapi.GetNodes(filters=basefilters, fields=fields, **extra)))
+
# filter by tag, one tag at a time
applicable = self.applicable_filters
for tagfilter in self.TAGFILTERS.iteritems():
if attr in applicable:
tagfilter = rootfilters.copy()
tagfilter['tagname'] = tagname % replacements
- tagfilter[expr % replacements] = getattr(self,attr)
+ tagfilter[expr % replacements] = str(getattr(self,attr))
tagfilter['node_id'] = list(candidates)
-
+
candidates &= set(map(operator.itemgetter('node_id'),
- self._api.GetNodeTags(filters=tagfilter, fields=fields)))
-
+ self._sliceapi.GetNodeTags(filters=tagfilter, fields=fields)))
+
# filter by vsys tags - special case since it doesn't follow
# the usual semantics
if self.required_vsys:
newcandidates = collections.defaultdict(set)
- vsys_tags = self._api.GetNodeTags(
+ vsys_tags = self._sliceapi.GetNodeTags(
tagname='vsys',
node_id = list(candidates),
fields = ['node_id','value'])
-
+
vsys_tags = map(
operator.itemgetter(['node_id','value']),
vsys_tags)
filters = basefilters.copy()
filters['node_id'] = list(candidates)
ifaces = dict(map(operator.itemgetter('node_id','interface_ids'),
- self._api.GetNodes(filters=basefilters, fields=('node_id','interface_ids')) ))
+ self._sliceapi.GetNodes(filters=basefilters, fields=('node_id','interface_ids')) ))
# filter candidates by interface count
if self.min_num_external_ifaces is not None and self.max_num_external_ifaces is not None:
len(ifaces.get(node_id,())) <= self.max_num_external_ifaces )
candidates = set(filter(predicate, candidates))
-
+
# make sure hostnames are resolvable
+ hostnames = dict()
if candidates:
self._logger.info(" Found %s candidates. Checking for reachability...", len(candidates))
-
+
hostnames = dict(map(operator.itemgetter('node_id','hostname'),
- self._api.GetNodes(list(candidates), ['node_id','hostname'])
+ self._sliceapi.GetNodes(list(candidates), ['node_id','hostname'])
))
+
def resolvable(node_id):
try:
addr = socket.gethostbyname(hostnames[node_id])
maxthreads = 16))
self._logger.info(" Found %s reachable candidates.", len(candidates))
-
- return candidates
+
+ for h in hostnames.keys():
+ if h not in candidates:
+ del hostnames[h]
+
+ hostnames = dict((v,k) for k, v in hostnames.iteritems())
+
+ return hostnames
def make_filter_description(self):
"""
def rate_nodes(self, nodes):
rates = collections.defaultdict(int)
tags = collections.defaultdict(dict)
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
tagnames = [ tagname % replacements
for tagname, weight, default in self.RATE_FACTORS ]
-
- taginfo = self._api.GetNodeTags(
+
+ taginfo = self._sliceapi.GetNodeTags(
node_id=list(nodes),
tagname=tagnames,
fields=('node_id','tagname','value'))
-
+
unpack = operator.itemgetter('node_id','tagname','value')
for value in taginfo:
node, tagname, value = unpack(value)
if value and value.lower() != 'n/a':
- tags[tagname][int(node)] = float(value)
+ tags[tagname][node] = float(value)
for tagname, weight, default in self.RATE_FACTORS:
taginfo = tags[tagname % replacements].get
def fetch_node_info(self):
orig_attrs = {}
- self._api.StartMulticall()
- info = self._api.GetNodes(self._node_id)
- tags = self._api.GetNodeTags(node_id=self._node_id, fields=('tagname','value'))
- info, tags = self._api.FinishMulticall()
+ info, tags = self._sliceapi.GetNodeInfo(self._node_id)
info = info[0]
tags = dict( (t['tagname'],t['value'])
orig_attrs['max_num_external_ifaces'] = self.max_num_external_ifaces
self.min_num_external_ifaces = None
self.max_num_external_ifaces = None
- self.timeframe = 'm'
+ if not self._timeframe: self._timeframe = 'w'
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
+
for attr, tag in self.BASEFILTERS.iteritems():
if tag in info:
value = info[tag]
if 'peer_id' in info:
orig_attrs['site'] = self.site
- self.site = self._api.peer_map[info['peer_id']]
+ self.site = self._sliceapi.peer_map[info['peer_id']]
if 'interface_ids' in info:
self.min_num_external_ifaces = \
raise UnresponsiveNodeError, "Unresponsive host %s" % (self.hostname,)
# Ensure the node is clean (no apps running that could interfere with operations)
- if self.enable_cleanup:
- self.do_cleanup()
-
+ if self.enable_proc_cleanup:
+ self.do_proc_cleanup()
+ if self.enable_home_cleanup:
+ self.do_home_cleanup()
+
def wait_dependencies(self, pidprobe=1, probe=0.5, pidmax=10, probemax=10):
# Wait for the p2p installer
if self._yum_dependencies and not self._installed:
return False
def destroy(self):
- if self.enable_cleanup:
- self.do_cleanup()
+ if self.enable_proc_cleanup:
+ self.do_proc_cleanup()
+ if self.enable_home_cleanup:
+ self.do_home_cleanup()
def blacklist(self):
if self._node_id:
self._logger.warn("Blacklisting malfunctioning node %s", self.hostname)
import util
- util.appendBlacklist(self._node_id)
+ util.appendBlacklist(self.hostname)
- def do_cleanup(self):
+ def do_proc_cleanup(self):
if self.testbed().recovering:
# WOW - not now
return
- self._logger.info("Cleaning up %s", self.hostname)
+ self._logger.info("Cleaning up processes on %s", self.hostname)
cmds = [
"sudo -S killall python tcpdump || /bin/true ; "
retry = 3
)
proc.wait()
-
+
+ def do_home_cleanup(self):
+ if self.testbed().recovering:
+ # WOW - not now
+ return
+
+ self._logger.info("Cleaning up home on %s", self.hostname)
+
+ cmds = [
+ "find . -maxdepth 1 ! -name '.bash*' ! -name '.' -execdir rm -rf {} + "
+ ]
+
+ for cmd in cmds:
+ (out,err),proc = server.popen_ssh_command(
+ # Some apps need two kills
+ cmd % {
+ 'slicename' : self.slicename ,
+ },
+ host = self.hostname,
+ port = None,
+ user = self.slicename,
+ agent = None,
+ ident_key = self.ident_path,
+ server_key = self.server_key,
+ tty = True, # so that ps -N -T works as advertised...
+ timeout = 60,
+ retry = 3
+ )
+ proc.wait()
+
def prepare_dependencies(self):
# Configure p2p yum dependency installer
if self.required_packages and not self._installed:
return rv
class PLCAPI(object):
+
_expected_methods = set(
['AddNodeTag', 'AddConfFile', 'DeletePersonTag', 'AddNodeType', 'DeleteBootState', 'SliceListNames', 'DeleteKey',
'SliceGetTicket', 'SliceUsersList', 'SliceUpdate', 'GetNodeGroups', 'SliceCreate', 'GetNetworkMethods', 'GetNodeFlavour',
filters = kw.pop('filters',{})
filters.update(kw)
return _retry(self.mcapi.GetSliceTags)(self.auth, filters, *fieldstuple)
-
def GetInterfaces(self, interfaceIdOrIp=None, fields=None, **kw):
if fields is not None:
def UpdateSlice(self, sliceIdOrName, **kw):
return _retry(self.mcapi.UpdateSlice)(self.auth, sliceIdOrName, kw)
-
def StartMulticall(self):
self.threadlocal.mc = xmlrpclib.MultiCall(self.mcapi)
mc = self.threadlocal.mc
del self.threadlocal.mc
return _retry(mc)()
+
+ def GetSliceNodes(self, slicename):
+ return self.GetSlices(slicename, ['node_ids'])[0]['node_ids']
+
+ def AddSliceNodes(self, slicename, nodes = None):
+ self.UpdateSlice(slicename, nodes = nodes)
+
+ def GetNodeInfo(self, node_id):
+ self.StartMulticall()
+ info = self.GetNodes(node_id)
+ tags = self.GetNodeTags(node_id=node_id, fields=('tagname','value'))
+ info, tags = self.FinishMulticall()
+ return info, tags
+
+ def GetSliceId(self, slicename):
+ slice_id = None
+ slices = self.GetSlices(slicename, fields=('slice_id',))
+ if slices:
+ slice_id = slices[0]['slice_id']
+ # If it wasn't found, don't remember this failure, keep trying
+ return slice_id
+
+ def GetSliceVnetSysTag(self, slicename):
+ slicetags = self.GetSliceTags(
+ name = slicename,
+ tagname = 'vsys_vnet',
+ fields=('value',))
+ if slicetags:
+ return slicetags[0]['value']
+ else:
+ return None
+
+def plcapi(auth_user, auth_string, plc_host, plc_url):
+ api = None
+ if auth_user:
+ api = PLCAPI(
+ username = auth_user,
+ password = auth_string,
+ hostname = plc_host,
+ urlpattern = plc_url
+ )
+ else:
+ # anonymous access - may not be enough for much
+ api = PLCAPI()
+ return api
+
+
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import itertools
def tun_fwd(tun, remote, reconnect = None, accept_local = None, accept_remote = None, slowlocal = True, bwlimit = None):
global TERMINATE
+ global SUSPEND
tunqueue = options.vif_txqueuelen or 1000
tunkqueue = 500
cipher_key = options.cipher_key,
udp = options.protocol == 'udp',
TERMINATE = TERMINATE,
+ SUSPEND = SUSPEND,
stderr = None,
reconnect = reconnect,
tunqueue = tunqueue,
TERMINATE.append(None)
signal.signal(signal.SIGTERM, _finalize)
+# SIGUSR1 suspends forwading, SIGUSR2 resumes forwarding
+SUSPEND = []
+def _suspend(sig,frame):
+ global SUSPEND
+ if not SUSPEND:
+ SUSPEND.append(None)
+signal.signal(signal.SIGUSR1, _suspend)
+
+def _resume(sig,frame):
+ global SUSPEND
+ if SUSPEND:
+ SUSPEND.remove(None)
+signal.signal(signal.SIGUSR2, _resume)
+
try:
tcpdump = None
reconnect = None
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import weakref
self._ppid = None
self._if_name = None
+ self._pointopoint = None
+ self._netprefix = None
+ self._address = None
+
# Logging
self._logger = logging.getLogger('nepi.testbeds.planetlab')
)
% {
'home' : server.shell_escape(self.home_path),
- 'passfd_url' : "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/python-passfd/archive/2a6472c64c87.tar.gz",
- 'iovec_url' : "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/python-iovec/archive/tip.tar.gz",
+ 'passfd_url' : "http://nepi.pl.sophia.inria.fr/code/python-passfd/archive/tip.tar.gz",
+ 'iovec_url' : "http://nepi.pl.sophia.inria.fr/code/python-iovec/archive/tip.tar.gz",
} )
(out,err),proc = server.popen_ssh_command(
cmd,
local_port = self.port
local_cap = local.capture
- local_addr = local.address
- local_mask = local.netprefix
+ self._address = local_addr = local.address
+ self._netprefix = local_mask = local.netprefix
local_snat = local.snat
local_txq = local.txqueuelen
- local_p2p = local.pointopoint
+ self._pointopoint = local_p2p = local.pointopoint
local_cipher=local.tun_cipher
local_mcast= local.multicast
local_bwlim= local.bwlimit
local_mcastfwd = local.multicast_forwarder
if not local_p2p and hasattr(peer, 'address'):
- local_p2p = peer.address
+ self._pointopoint = local_p2p = peer.address
if check_proto != peer_proto:
raise RuntimeError, "Peering protocol mismatch: %s != %s" % (check_proto, peer_proto)
timeout = 60,
err_on_timeout = False
)
- proc.wait()
+ proc.wait()
+
+ def if_down(self):
+ # TODO!!! need to set the vif down with vsys/vif_down.in ... which
+ # doesn't currently work.
+ local = self.local()
+
+ if local:
+ (out,err),proc = server.eintr_retry(server.popen_ssh_command)(
+ "sudo -S bash -c 'kill -s USR1 %d'" % (self._pid,),
+ host = local.node.hostname,
+ port = None,
+ user = local.node.slicename,
+ agent = None,
+ ident_key = local.node.ident_path,
+ server_key = local.node.server_key,
+ timeout = 60,
+ err_on_timeout = False
+ )
+ proc.wait()
+
+ def if_up(self):
+ # TODO!!! need to set the vif up with vsys/vif_up.in ... which
+ # doesn't currently work.
+ local = self.local()
+
+ if local:
+ (out,err),proc = server.eintr_retry(server.popen_ssh_command)(
+ "sudo -S bash -c 'kill -s USR2 %d'" % (self._pid,),
+ host = local.node.hostname,
+ port = None,
+ user = local.node.slicename,
+ agent = None,
+ ident_key = local.node.ident_path,
+ server_key = local.node.server_key,
+ timeout = 60,
+ err_on_timeout = False
+ )
+ proc.wait()
+
_TRACEMAP = {
# tracename : (remotename, localname)
'packets' : ('capture','capture'),
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
bl.close()
def getVnet(api, slicename):
- slicetags = api.GetSliceTags(
- name = slicename,
- tagname = 'vsys_vnet',
- fields=('value',))
- if slicetags:
- return slicetags[0]['value']
- else:
- return None
+ return api.GetSliceVsysNetTag(slicename)
def getNodes(api, num, **constraints):
# Now do the backtracking search for a suitable solution
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
AF_INET = 0
-# vim:ts=4:sw=4:et:ai:sts=4
import os, subprocess, os.path
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# vim:ts=4:sw=4:et:ai:sts=4
class GraphicalInfo(object):
""" This class allows to describe the position and dimensions of a
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
class GuidGenerator(object):
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
import struct
import random
import socket
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import threading
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.core.attributes import Attribute
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
--- /dev/null
+# -*- coding: utf-8 -*-
+
+from xml.dom import minidom
+
+import sys
+
+def xmlencode(s):
+ if isinstance(s, str):
+ rv = s.decode("latin1")
+ elif not isinstance(s, unicode):
+ rv = unicode(s)
+ else:
+ rv = s
+ return rv.replace(u'\x00',u'�')
+
+def xmldecode(s):
+ return s.replace(u'�',u'\x00').encode("utf8")
+
+def get_child_text(tag, name):
+ tags = tag.getElementsByTagName(name)
+ if not tags:
+ return ""
+ return get_text(tags[0])
+
+def get_name(tag):
+ return xmldecode(tag.tagName)
+
+def get_text(tag):
+ text = ''.join(t.nodeValue for t in tag.childNodes if t.nodeType == t.TEXT_NODE)
+ return xmldecode(text)
+
+def set_text(doc, tag, text):
+ ttag = doc.createTextNode(text)
+ tag.appendChild(ttag)
+
+def get_attribute(p_tag, name):
+ return xmldecode(p_tag.getAttribute(name))
+
+def has_sliver(node_tag):
+ sliver_tag = node_tag.getElementsByTagName("sliver")
+ return len(sliver_tag) > 0
+
+class SFAResourcesParser(object):
+ def resources_from_xml(self, xml):
+ data = dict()
+ doc = minidom.parseString(xml)
+ rspec_tag = doc.getElementsByTagName("RSpec")[0]
+ network_tags = rspec_tag.getElementsByTagName("network")
+ for network_tag in network_tags:
+ if network_tag.nodeType == doc.ELEMENT_NODE:
+ node_data = self.nodes_from_xml(doc, network_tag)
+ data.update(node_data)
+ return data
+
+ def slice_info_from_xml(self, xml):
+ nodes_data = dict()
+ doc = minidom.parseString(xml)
+ rspec_tag = doc.getElementsByTagName("RSpec")[0]
+ network_tags = rspec_tag.getElementsByTagName("network")
+ for network_tag in network_tags:
+ if network_tag.nodeType == doc.ELEMENT_NODE:
+ node_data = self.nodes_from_xml(doc, network_tag, in_sliver = True)
+ nodes_data.update(node_data)
+ nodes_data = set(nodes_data.keys())
+ tags_data = self.slice_tags_from_xml(doc, rspec_tag)
+ return tags_data, nodes_data
+
+ def nodes_from_xml(self, doc, network_tag, in_sliver = False):
+ nodes_data = dict()
+ network_name = get_attribute(network_tag, 'name')
+ node_tags = network_tag.getElementsByTagName('node')
+ for node_tag in node_tags:
+ if node_tag.nodeType == doc.ELEMENT_NODE:
+ if in_sliver and not has_sliver(node_tag):
+ continue
+ node_data = dict()
+ node_data['network_name'] = network_name
+ node_name = get_attribute(node_tag, 'component_name')
+ nodes_data[node_name] = node_data
+ for name in ['component_id', 'component_manager_id',
+ 'boot_state', 'component_name', 'site_id']:
+ node_data[name] = get_attribute(node_tag, name)
+ location_tag = node_tag.getElementsByTagName('location')
+ if location_tag:
+ for name in ['longitud' , 'latitude']:
+ node_data[name] = get_attribute(location_tag[0], name)
+ for name in ['hostname', 'pldistro', 'arch', 'fcdistro',
+ 'stype', 'reliabilityw', 'loadm', 'cpuy', 'cpum',
+ 'slicesm', 'slicesw', 'cpuw', 'loady', 'memy',
+ 'memw', 'reliabilityy', 'reliability', 'reliabilitym',
+ 'responsey', 'bww', 'memem', 'bwm', 'slicey', 'responsem',
+ 'response', 'loadw', 'country', 'load', 'mem', 'slices',
+ 'region', 'asnumber', 'bw', 'hrn', 'city', 'responsew',
+ 'bwy', 'cpu']:
+ node_data[name] = get_child_text(node_tag, name)
+ iface_tags = node_tag.getElementsByTagName('interface')
+ ifaces_data = dict()
+ iface_ids = list()
+ for iface_tag in iface_tags:
+ if iface_tag.nodeType == doc.ELEMENT_NODE:
+ for name in ['component_id', 'ipv4']:
+ value = get_attribute(iface_tag, name)
+ ifaces_data[name] = value
+ if name == 'component_id':
+ iface_ids.append(value)
+ node_data['interfaces'] = ifaces_data
+ node_data['interface_ids'] = iface_ids
+ return nodes_data
+
+ def slice_tags_from_xml(self, doc, rspec_tag):
+ tags_data = dict()
+ sliver_tag = rspec_tag.getElementsByTagName('sliver_defaults')
+ if len(sliver_tag) == 0:
+ return tags_data
+ for child_tag in sliver_tag[0].childNodes:
+ if child_tag.nodeType == doc.ELEMENT_NODE:
+ name = get_name(child_tag)
+ value = get_text(child_tag)
+ tags_data[name] = value
+ return tags_data
+
+ def create_slice_xml(self, node_data, slice_tags):
+ doc = minidom.Document()
+ rspec_tag = doc.createElement("RSpec")
+ doc.appendChild(rspec_tag)
+ rspec_tag.setAttribute("type", "SFA")
+ slice_defaults_tag = self.slice_defaults_xml(doc, slice_tags)
+
+ networks = dict()
+ for k, data in node_data.iteritems():
+ network_name = data["network_name"]
+ if network_name not in networks:
+ networks[network_name] = dict()
+ networks[network_name][k] = data
+
+ for n, netdata in networks.iteritems():
+ network_tag = doc.createElement("testbeds")
+ network_tag.setAttribute("name", n)
+ rspec_tag.appendChild(network_tag)
+ for k, data in netdata.iteritems():
+ node_tag = doc.createElement("node")
+ node_tag.setAttribute("component_manager_id", data["component_manager_id"])
+ node_tag.setAttribute("component_id", data["component_id"])
+ node_tag.setAttribute("component_name", data["component_name"])
+ node_tag.setAttribute("boot_state", data["boot_state"])
+ node_tag.setAttribute("site_id", data["site_id"])
+ hostname_tag = doc.createElement("hostname")
+ set_text(doc, hostname_tag, data["hostname"])
+ node_tag.appendChild(hostname_tag)
+ sliver_tag = doc.createElement("sliver")
+ node_tag.appendChild(sliver_tag)
+ network_tag.appendChild(node_tag)
+ network_tag.appendChild(slice_defaults_tag)
+ return doc.toxml()
+
+ def slice_defaults_xml(self, doc, slice_tags):
+ slice_defaults_tag = doc.createElement("sliver_defaults")
+ for name, value in slice_tags.iteritems():
+ tag = doc.createElement(name)
+ set_text(doc, tag, value)
+ slice_defaults_tag.appendChild(tag)
+ return slice_defaults_tag
+
+"""
+if __name__ == "__main__":
+ path = sys.argv[1]
+ fd = open(path, 'r')
+ xml = fd.read()
+ fd.close()
+ p = SFAResourcesParser()
+ tags, nodes = p.slice_info_from_xml(xml)
+ print tags, nodes
+"""
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nepi.util.constants import DeploymentConfiguration as DC
SHELL_SAFE = re.compile('^[-a-zA-Z0-9_=+:.,/]*$')
+hostbyname_cache = dict()
+
def openssh_has_persist():
global OPENSSH_HAS_PERSIST
if OPENSSH_HAS_PERSIST is None:
host = '%s:%s' % (host,port)
# Create a temporary server key file
tmp_known_hosts = tempfile.NamedTemporaryFile()
-
+
+ hostbyname = hostbyname_cache.get(host)
+ if not hostbyname:
+ hostbyname = socket.gethostbyname(host)
+ hostbyname_cache[host] = hostbyname
+
# Add the intended host key
- tmp_known_hosts.write('%s,%s %s\n' % (host, socket.gethostbyname(host), server_key))
+ tmp_known_hosts.write('%s,%s %s\n' % (host, hostbyname, server_key))
# If we're not in strict mode, add user-configured keys
if os.environ.get('NEPI_STRICT_AUTH_MODE',"").lower() not in ('1','true','on'):
--- /dev/null
+# -*- coding: utf-8 -*-
+
+
+import logging
+
+from nepi.util.parser import sfa
+
+###
+# TODO: This API is a mega hack to adapt the sfa interface to the plc interface.
+# The right way to implement this would be to make node.py invoke generic
+# methods and to adapt the sfa and plc APIs to provide the reuired
+# data.
+
+class SFIAPI(object):
+ def __init__(self, slice_id):
+ self._slice_tags = dict()
+ self._slice_nodes = set()
+ self._all_nodes = dict()
+ self._slice_id = slice_id
+
+ self._logger = logging.getLogger('nepi.utils.sfiapi')
+
+ self.FetchSliceInfo()
+
+ def FetchSliceInfo(self):
+ p = sfa.SFAResourcesParser()
+ import commands
+ xml = commands.getoutput("sfi.py resources")
+ try:
+ self._all_nodes = p.resources_from_xml(xml)
+ xml = commands.getoutput("sfi.py resources %s" % self._slice_id)
+ self._slice_tags, self._slice_nodes = p.slice_info_from_xml(xml)
+ except:
+ self._logger.error("Error in SFA responds: %s", xml)
+ raise
+
+ def GetSliceNodes(self, slicename):
+ return list(self._slice_nodes)
+
+ def GetNodeInfo(self, node_id):
+ # TODO: thread-unsafe!! sanitize!
+ info = self.GetNodes(node_id)
+ tags = self.GetNodeTags(node_id=node_id, fields=('tagname','value'))
+ return info, tags
+
+ def GetSliceId(self, slicename):
+ return self._slice_id
+
+ def GetSliceVnetSysTag(self, slicename):
+ return self._slice_tags.get('vsys_net')
+
+ def GetNodeTags(self, node_id=None, fields=None, **kw):
+ nodes = self._all_nodes
+ if node_id is not None:
+ node_ids = node_id
+ if not isinstance(node_id, list):
+ node_ids = [node_ids]
+ nodes = self._FilterByNodeId(nodes, node_ids)
+ else:
+ filters = kw.pop('filters',{})
+ if '|slice_ids' in filters:
+ nodes = self._FilterByNodeId(nodes, self._slice_nodes)
+ del filters['|slice_ids']
+ nodes = self._FilterByFilters(nodes, filters)
+ tagnames = kw.pop('tagname',[])
+ return self._GetTagInfo(nodes, tagnames, fields)
+
+ def GetNodes(self, nodeIdOrName=None, fields=[], **kw):
+ #TODO: filter - peer
+ nodes = self._all_nodes
+ if nodeIdOrName is not None:
+ node_ids = nodeIdOrName
+ if not isinstance(nodeIdOrName, list):
+ node_ids = [node_ids]
+ nodes = self._FilterByNodeId(nodes, node_ids)
+ else:
+ filters = kw.pop('filters',{})
+ if '|slice_ids' in filters:
+ nodes = self._FilterByNodeId(nodes, self._slice_nodes)
+ del filters['|slice_ids']
+ # TODO: Remove this!! need to allow filter '>last_contact' !!!
+ for f in ['>last_contact', 'node_type', 'run_level']:
+ if f in filters:
+ del filters[f]
+ nodes = self._FilterByFilters(nodes, filters)
+ return self._GetNodeFieldsInfo(nodes, fields)
+
+ def _FilterByNodeId(self, nodes, node_ids):
+ return dict((k, nodes[k]) for k in node_ids if k in nodes)
+
+ def _FilterByFilters(self, nodes, filters):
+ def has_all_tags(node_id):
+ data = nodes[node_id]
+ for name, value in filters.iteritems():
+ if name == 'value' or name == 'tagname':
+ tagname = filters['tagname']
+ tagval = filters['value']
+ if data[tagname] != tagval:
+ return False
+ elif name == 'node_id':
+ node_ids = list(value)
+ if node_id not in node_ids:
+ return False
+ else:
+ #if (name == '>last_contact' and data['lastcontact'] > value) or \
+ if (not name in data or data[name] != value):
+ return False
+ return True
+ return dict((k, value) for k, value in nodes.iteritems() if has_all_tags(k))
+
+ def _GetNodeFieldsInfo(self, nodes, fields):
+ result = list()
+ for k, data in nodes.iteritems():
+ if not fields:
+ result.append(data)
+ continue
+ r_data = dict()
+ for f in fields:
+ if f == "node_id":
+ value = k
+ else:
+ value = data[f]
+ r_data[f] = value
+ result.append(r_data)
+ return result
+
+ def _GetTagInfo(self, nodes, tagnames, fields):
+ result = list()
+ for k, data in nodes.iteritems():
+ for name, value in data.iteritems():
+ r_data = dict()
+ if tagnames and name not in tagnames:
+ continue
+ for f in fields:
+ if f == "node_id":
+ val = k
+ if f == "tagname":
+ val = name
+ if f == "value":
+ val = value
+ r_data[f] = val
+ result.append(r_data)
+ return result
+
+ def AddSliceNodes(self, slicename, nodes=None):
+ import os, commands, tempfile
+ nodes = set(nodes)
+ nodes.update(self._slice_nodes)
+ nodes_data = dict((k, self._all_nodes[k]) for k in nodes)
+ p = sfa.SFAResourcesParser()
+ xml = p.create_slice_xml(nodes_data, self._slice_tags)
+ fh, fname = tempfile.mkstemp()
+ os.write(fh, xml)
+ os.close(fh)
+ out = commands.getoutput("sfi.py create %s %s" % (self._slice_id, fname))
+ os.remove(fname)
+ #print out
+
+def sfiapi(slice_id):
+ api = SFIAPI(slice_id)
+ return api
+
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
MOBILE = "mobile"
'8864' : 'PPPoE',
'86dd' : 'ipv6',
}
+
def etherProto(packet, len=len):
if len(packet) > 14:
if packet[12] == "\x81" and packet[13] == "\x00":
return packet[12:14]
# default: ip
return "\x08\x00"
+
def formatPacket(packet, ether_mode):
if ether_mode:
stripped_packet = etherStrip(packet)
# Just ignore
return False
-def tun_fwd(tun, remote, with_pi, ether_mode, cipher_key, udp, TERMINATE, stderr=sys.stderr, reconnect=None, rwrite=None, rread=None, tunqueue=1000, tunkqueue=1000,
- cipher='AES', accept_local=None, accept_remote=None, slowlocal=True, queueclass=None, bwlimit=None,
- len=len, max=max, min=min, buffer=buffer, OSError=OSError, select=select.select, selecterror=select.error, os=os, socket=socket,
+def tun_fwd(tun, remote, with_pi, ether_mode, cipher_key, udp, TERMINATE, SUSPEND,
+ stderr = sys.stderr, reconnect = None, rwrite = None, rread = None,
+ tunqueue = 1000, tunkqueue = 1000, cipher = 'AES', accept_local = None,
+ accept_remote = None, slowlocal = True, queueclass = None,
+ bwlimit = None, len = len, max = max, min = min, buffer = buffer,
+ OSError = OSError, select = select.select, selecterror = select.error,
+ os = os, socket = socket,
retrycodes=(os.errno.EWOULDBLOCK, os.errno.EAGAIN, os.errno.EINTR) ):
crypto_mode = False
crypter = None
while not TERMINATE:
+ # The SUSPEND flag has been set. This means we need to wait on
+ # the SUSPEND condition until it is released.
+ while SUSPEND and not TERMINATE:
+ time.sleep(0.5)
+
wset = []
if packetReady(bkbuf):
wset.append(tun)
continue
else:
traceback.print_exc(file=sys.stderr)
- raise
+ # If the SUSPEND flag has been set, then the TUN will be in a bad
+ # state and the select error should be ignores.
+ if SUSPEND:
+ continue
+ else:
+ raise
# check for errors
if errs:
# some state
self.prepared = False
self._terminate = [] # terminate signaller
+ self._suspend = [] # suspend signaller
self._exc = [] # exception store, to relay exceptions from the forwarder thread
self._connected = threading.Event()
self._forwarder_thread = None
self._terminate.append(None)
self._forwarder_thread.join()
+ def suspend(self):
+ if not self._suspend:
+ self._suspend.append(None)
+
+ def resume(self):
+ if self._suspend:
+ self._suspend.remove(None)
+
def _launch(self):
# Launch forwarder thread with a weak reference
# to self, so that we don't create any strong cycles
raise RuntimeError, "Misconfigured TUN: %s" % (self,)
TERMINATE = self._terminate
+ SUSPEND = self._suspend
cipher_key = self.tun_key
tun = self.tun_socket
udp = local_proto == 'udp'
cipher_key = cipher_key,
udp = udp,
TERMINATE = TERMINATE,
+ SUSPEND = SUSPEND,
stderr = stderr,
cipher = local_cipher
)
public_addr = os.popen(
"/sbin/ifconfig "
"| grep $(ip route | grep default | awk '{print $3}' "
- "| awk -F. '{print $1\"[.]\"$2}') "
+ "| awk -F. '{print $1\"[.]\"$2}' | head -1) "
"| head -1 | awk '{print $2}' "
"| awk -F : '{print $2}'").read().rstrip()
element.tun_addr = public_addr
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ipaddr
class DesignTestCase(unittest.TestCase):
def setUp(self):
+ # hack to add the mock testbed on the correct module path
sys.modules["nepi.testbeds.mock.metadata"] = mock.metadata
def test_design(self):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+import getpass
from nepi.util import tags
from nepi.util.constants import ApplicationStatus as AS
-import getpass
import mock
import mock.metadata
import sys
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+import getpass
from nepi.core.design import ExperimentDescription, FactoriesProvider
from nepi.util import proxy
from nepi.util.constants import DeploymentConfiguration as DC
-import getpass
import mock
import mock.metadata
import mock2
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
TESTBED_ID = "mock"
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
TESTBED_ID = "mock2"
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
-#!/usr/bin/env python
-
import nepi.util.environ
import ctypes
import imp
class NetnsDesignTestCase(unittest.TestCase):
def test_design_if(self):
- exp_desc = ExperimentDescription()
testbed_id = "netns"
+ exp_desc = ExperimentDescription()
provider = FactoriesProvider(testbed_id)
+
tstbd_desc = exp_desc.add_testbed_description(provider)
tstbd_desc.set_attribute_value("enableDebug", True)
node1 = tstbd_desc.create("Node")
app = tstbd_desc.create("Application")
app.set_attribute_value("command", "ping -qc10 10.0.0.2")
app.connector("node").connect(node1.connector("apps"))
+
xml = exp_desc.to_xml()
exp_desc2 = ExperimentDescription()
exp_desc2.from_xml(xml)
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(7) != AS.STATUS_FINISHED:
time.sleep(0.5)
ping_result = instance.trace(7, "stdout")
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(6) != AS.STATUS_FINISHED:
time.sleep(0.5)
ping_result = instance.trace(6, "stdout")
user = getpass.getuser()
instance = netns.TestbedController()
instance.defer_configure("homeDirectory", self.root_dir)
+ #instance.defer_configure("enableDebug", True)
instance.defer_create(2, "Node")
instance.defer_create(3, "Node")
instance.defer_create(4, "Node")
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(11) != AS.STATUS_FINISHED:
time.sleep(0.5)
ping_result = instance.trace(11, "stdout")
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(6) != AS.STATUS_FINISHED:
time.sleep(0.5)
+
pcap_result = instance.trace(2, "pcap")
self.assertEquals(len(pcap_result), 1024)
instance.stop()
def _test_switched(self, controller_access_config = None,
testbed_access_config = None):
- exp_desc = ExperimentDescription()
testbed_id = "netns"
+ exp_desc = ExperimentDescription()
user = getpass.getuser()
netns_provider = FactoriesProvider(testbed_id)
+
netns_desc = exp_desc.add_testbed_description(netns_provider)
netns_desc.set_attribute_value("homeDirectory", self.root_dir)
#netns_desc.set_attribute_value("enableDebug", True)
class Ns3DesignTestCase(unittest.TestCase):
def test_design_if(self):
- exp_desc = ExperimentDescription()
testbed_id = "ns3"
+ exp_desc = ExperimentDescription()
provider = FactoriesProvider(testbed_id)
tstbd_desc = exp_desc.add_testbed_description(provider)
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
from nepi.util.constants import ApplicationStatus as AS
from nepi.testbeds import ns3
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(17) != AS.STATUS_FINISHED:
time.sleep(0.1)
ping_result = instance.trace(14, "P2PAsciiTrace")
ping_rtt = instance.trace(17, "Rtt")
- comp_result = "- 9.021 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 ttl 64 id 9 protocol 1 offset 0 flags [none] length: 84 10.0.0.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=9)"
+ comp_result = "- 9.021 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 9 protocol 1 offset (bytes) 0 flags [none] length: 84 10.0.0.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=9)"
comp_rtt_result = """+41992186.0ns\t+41992186.0ns
+1041992186.0ns\t+41992186.0ns
+2041992186.0ns\t+41992186.0ns
+6041992186.0ns\t+41992186.0ns
+7041992186.0ns\t+41992186.0ns
+8041992186.0ns\t+41992186.0ns
-+9041992186.0ns\t+41992186.0ns"""
++9041992186.0ns\t+41992186.0ns
+"""
+
self.assertNotEqual(ping_result.find(comp_result), -1)
self.assertEqual(ping_rtt.strip(), comp_rtt_result.strip())
instance.stop()
instance.do_configure()
instance.do_prestart()
instance.start()
+
while instance.status(27) != AS.STATUS_FINISHED:
time.sleep(0.1)
ping_result = instance.trace(24, "P2PAsciiTrace")
- comp_result = "- 9.04199 /NodeList/2/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 ttl 64 id 9 protocol 1 offset 0 flags [none] length: 84 10.0.1.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=9)"
+ comp_result = "- 9.04199 /NodeList/2/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 9 protocol 1 offset (bytes) 0 flags [none] length: 84 10.0.1.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=9)"
+
self.assertNotEqual(ping_result.find(comp_result), -1)
instance.stop()
instance.shutdown()
def _test_fd_net_device(self, daemonize_testbed,
controller_access_configuration):
- exp_desc = ExperimentDescription()
testbed_id = "ns3"
+ exp_desc = ExperimentDescription()
ns3_provider = FactoriesProvider(testbed_id)
ns3_desc1 = exp_desc.add_testbed_description(ns3_provider)
root_dir1 = os.path.join(self.root_dir, "1")
while not controller.is_finished(app.guid):
time.sleep(0.5)
ping_result = controller.trace(iface2.guid, "P2PAsciiTrace")
- comp_result = "- 19.021 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 ttl 64 id 19 protocol 1 offset 0 flags [none] length: 84 10.0.0.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=19)"
+
+ comp_result = "- 19.021 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 19 protocol 1 offset (bytes) 0 flags [none] length: 84 10.0.0.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=19)"
+
if ping_result.find(comp_result) == -1:
self.fail("Unexpected trace: %s" % (ping_result,))
finally:
class PlanetlabDesignTestCase(unittest.TestCase):
def make_test_design(self):
- exp_desc = ExperimentDescription()
testbed_id = "planetlab"
+ exp_desc = ExperimentDescription()
provider = FactoriesProvider(testbed_id)
tstbd_desc = exp_desc.add_testbed_description(provider)
tstbd_desc.set_attribute_value("slice", "inria_nepi")
from nepi.util.constants import ApplicationStatus as AS
from nepi.testbeds import planetlab
import os
+import re
import shutil
+import sys
import tempfile
+import test_util
import time
import unittest
-import re
-import test_util
-import sys
class PlanetLabExecuteTestCase(unittest.TestCase):
testbed_id = "planetlab"
instance.defer_configure("plcHost", plchost)
instance.defer_configure("tapPortBase", self.port_base)
instance.defer_configure("p2pDeployment", False) # it's interactive, we don't want it in tests
- instance.defer_configure("dedicatedSlice", True)
+ instance.defer_configure("cleanProc", True)
# Hack, but we need vsys_vnet
instance.do_setup()
# -*- coding: utf-8 -*-
import getpass
+import logging
from nepi.core.design import ExperimentDescription, FactoriesProvider
from nepi.core.execute import ExperimentController
from nepi.util import proxy
from nepi.util.constants import DeploymentConfiguration as DC
import os
+import re
import shutil
+import sys
import tempfile
import test_util
import time
import unittest
-import re
-import sys
-import logging
class PlanetLabIntegrationTestCase(unittest.TestCase):
testbed_id = "planetlab"
slicename = "inria_nepi"
+ slicehrn = "nepi.inria.nepi"
plchost = "nepiplc.pl.sophia.inria.fr"
host1 = "nepi1.pl.sophia.inria.fr"
time.sleep(0.1)
shutil.rmtree(self.root_dir)
- def make_experiment_desc(self):
+ def make_experiment_desc(self, use_sfa = False):
testbed_id = self.testbed_id
slicename = self.slicename
plchost = self.plchost
pl_desc.set_attribute_value("plcHost", plchost)
pl_desc.set_attribute_value("tapPortBase", self.port_base)
pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc.set_attribute_value("dedicatedSlice", True)
- #pl_desc.set_attribute_value("plLogLevel", "DEBUG")
+ pl_desc.set_attribute_value("cleanProc", True)
+ pl_desc.set_attribute_value("plLogLevel", "DEBUG")
+ if use_sfa:
+ pl_desc.set_attribute_value("sfa", True)
+ pl_desc.set_attribute_value("sliceHrn", self.slicehrn)
return pl_desc, exp_desc
- def _test_simple(self, daemonize_testbed, controller_access_configuration, environ = None):
- pl, exp = self.make_experiment_desc()
+ def _test_simple(self, daemonize_testbed, controller_access_configuration,
+ environ = None, use_sfa = False):
+ pl, exp = self.make_experiment_desc(use_sfa)
node1 = pl.create("Node")
node2 = pl.create("Node")
import traceback
traceback.print_exc()
- @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
- @test_util.skipUnless(os.environ.get('NEPI_FULL_TESTS','').lower() in ('1','yes','true','on'),
- "Test is interactive, requires NEPI_FULL_TESTS=yes")
- def test_spanning_deployment(self):
- pl, exp = self.make_experiment_desc()
+ def _test_spanning_deployment(self, use_sfa = False):
+ pl, exp = self.make_experiment_desc(use_sfa)
pl.set_attribute_value("p2pDeployment", True) # we do want it here - even if interactive
import traceback
traceback.print_exc()
- @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
- def test_simple(self):
- self._test_simple(
- daemonize_testbed = False,
- controller_access_configuration = None)
-
- @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
- def test_simple_daemonized(self):
- access_config = proxy.AccessConfiguration({
- DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
- DC.ROOT_DIRECTORY : self.root_dir,
- DC.LOG_LEVEL : DC.DEBUG_LEVEL,
- })
-
- self._test_simple(
- daemonize_testbed = False,
- controller_access_configuration = access_config)
-
- @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
- def test_z_simple_ssh(self): # _z_ cause we want it last - it messes up the process :(
- # Recreate environment
- environ = ' ; '.join( map("export %s=%r".__mod__, os.environ.iteritems()) )
-
- env = test_util.test_environment()
-
- access_config = proxy.AccessConfiguration({
- DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
- DC.ROOT_DIRECTORY : self.root_dir,
- DC.LOG_LEVEL : DC.DEBUG_LEVEL,
- DC.DEPLOYMENT_COMMUNICATION : DC.ACCESS_SSH,
- DC.DEPLOYMENT_PORT : env.port,
- DC.USE_AGENT : True,
- DC.DEPLOYMENT_ENVIRONMENT_SETUP : environ,
- })
-
- self._test_simple(
- daemonize_testbed = False,
- controller_access_configuration = access_config,
- environ = environ)
-
-
- def _test_recover(self, daemonize_testbed, controller_access_configuration, environ = None):
- pl, exp = self.make_experiment_desc()
+ def _test_recover(self, daemonize_testbed, controller_access_configuration,
+ environ = None, use_sfa = False):
+ pl, exp = self.make_experiment_desc(use_sfa)
pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)
import traceback
traceback.print_exc()
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_simple(self):
+ self._test_simple(
+ daemonize_testbed = False,
+ controller_access_configuration = None)
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_simple_sfa(self):
+ self._test_simple(
+ daemonize_testbed = False,
+ controller_access_configuration = None,
+ use_sfa = True)
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ @test_util.skipUnless(os.environ.get('NEPI_FULL_TESTS','').lower() in ('1','yes','true','on'),
+ "Test is interactive, requires NEPI_FULL_TESTS=yes")
+ def test_spanning_deployment(self):
+ self._test_spanning_deployment()
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ @test_util.skipUnless(os.environ.get('NEPI_FULL_TESTS','').lower() in ('1','yes','true','on'),
+ "Test is interactive, requires NEPI_FULL_TESTS=yes")
+ def test_spanning_deployment_sfa(self):
+ self._test_spanning_deployment(use_sfa = True)
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_simple_daemonized(self):
+ access_config = proxy.AccessConfiguration({
+ DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
+ DC.ROOT_DIRECTORY : self.root_dir,
+ DC.LOG_LEVEL : DC.DEBUG_LEVEL,
+ })
+
+ self._test_simple(
+ daemonize_testbed = False,
+ controller_access_configuration = access_config)
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_simple_daemonized_sfa(self):
+ access_config = proxy.AccessConfiguration({
+ DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
+ DC.ROOT_DIRECTORY : self.root_dir,
+ DC.LOG_LEVEL : DC.DEBUG_LEVEL,
+ })
+
+ self._test_simple(
+ daemonize_testbed = False,
+ controller_access_configuration = access_config,
+ use_sfa = True)
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_z_simple_ssh(self): # _z_ cause we want it last - it messes up the process :(
+ # Recreate environment
+ environ = ' ; '.join( map("export %s=%r".__mod__, os.environ.iteritems()) )
+
+ env = test_util.test_environment()
+
+ access_config = proxy.AccessConfiguration({
+ DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
+ DC.ROOT_DIRECTORY : self.root_dir,
+ DC.LOG_LEVEL : DC.DEBUG_LEVEL,
+ DC.DEPLOYMENT_COMMUNICATION : DC.ACCESS_SSH,
+ DC.DEPLOYMENT_PORT : env.port,
+ DC.USE_AGENT : True,
+ DC.DEPLOYMENT_ENVIRONMENT_SETUP : environ,
+ })
+
+ self._test_simple(
+ daemonize_testbed = False,
+ controller_access_configuration = access_config,
+ environ = environ)
+
@test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
def test_recover(self):
self._test_recover(
daemonize_testbed = False,
controller_access_configuration = None)
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_recover_sfa(self):
+ self._test_recover(
+ daemonize_testbed = False,
+ controller_access_configuration = None,
+ use_sfa = True)
+
@test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
def test_recover_daemonized(self):
access_config = proxy.AccessConfiguration({
self._test_recover(
daemonize_testbed = False,
controller_access_configuration = access_config)
-
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_recover_daemonized_sfa(self):
+ access_config = proxy.AccessConfiguration({
+ DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
+ DC.ROOT_DIRECTORY : self.root_dir,
+ DC.LOG_LEVEL : DC.DEBUG_LEVEL,
+ })
+
+ self._test_recover(
+ daemonize_testbed = False,
+ controller_access_configuration = access_config,
+ use_sfa = True)
+
if __name__ == '__main__':
unittest.main()
from nepi.util import proxy
from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
import os
+import re
import shutil
import tempfile
import test_util
import time
import unittest
-import re
class PlanetLabMultiIntegrationTestCase(unittest.TestCase):
testbed_id = "planetlab"
pl_desc.set_attribute_value("plcHost", plchost1)
pl_desc.set_attribute_value("tapPortBase", self.port_base)
pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc.set_attribute_value("dedicatedSlice", True)
+ pl_desc.set_attribute_value("cleanProc", True)
pl_desc2 = exp_desc.add_testbed_description(pl_provider)
pl_desc2.set_attribute_value("homeDirectory", self.root_dir+"v2")
pl_desc2.set_attribute_value("plcHost", plchost2)
pl_desc2.set_attribute_value("tapPortBase", self.port_base+500)
pl_desc2.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc2.set_attribute_value("dedicatedSlice", True)
+ pl_desc2.set_attribute_value("cleanProc", True)
return pl_desc, pl_desc2, exp_desc
from nepi.util import proxy
from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
import os
+import re
import shutil
import tempfile
import test_util
import time
import unittest
-import re
class PlanetLabMultiIntegrationTestCase(unittest.TestCase):
testbed_id = "planetlab"
pl_desc.set_attribute_value("plcHost", plchost1)
pl_desc.set_attribute_value("tapPortBase", self.port_base)
pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc.set_attribute_value("dedicatedSlice", True)
- #pl_desc.set_attribute_value("plLogLevel", "DEBUG")
+ pl_desc.set_attribute_value("cleanProc", True)
+ pl_desc.set_attribute_value("plLogLevel", "DEBUG")
pl_desc2 = exp_desc.add_testbed_description(pl_provider)
pl_desc2.set_attribute_value("homeDirectory", self.root_dir+"v2")
pl_desc2.set_attribute_value("plcHost", plchost2)
pl_desc2.set_attribute_value("tapPortBase", self.port_base+500)
pl_desc2.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc2.set_attribute_value("dedicatedSlice", True)
- #pl_desc2.set_attribute_value("plLogLevel", "DEBUG")
+ pl_desc2.set_attribute_value("cleanProc", True)
+ pl_desc2.set_attribute_value("plLogLevel", "DEBUG")
return pl_desc, pl_desc2, exp_desc
from nepi.util import proxy
from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
import os
+import re
import shutil
import tempfile
import test_util
import time
import unittest
-import re
class PlanetLabCrossIntegrationTestCase(unittest.TestCase):
testbed_id = "planetlab"
pl_desc.set_attribute_value("plcHost", plchost)
pl_desc.set_attribute_value("tapPortBase", self.port_base)
pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests
- pl_desc.set_attribute_value("dedicatedSlice", True)
+ pl_desc.set_attribute_value("cleanProc", True)
#pl_desc.set_attribute_value("plLogLevel", "DEBUG")
return pl_desc, exp_desc
--- /dev/null
+#!/usr/bin/env python
+
+from nepi.util import tunchannel
+import socket
+import time
+import threading
+import unittest
+
+class TunnChannelTestCase(unittest.TestCase):
+ def test_send_suspend_terminate(self):
+ def tun_fwd(local, remote, TERMINATE, SUSPEND, STOPPED):
+ tunchannel.tun_fwd(local, remote, True, True, None, True,
+ TERMINATE, SUSPEND, None)
+ STOPPED.append(None)
+
+ TERMINATE = []
+ SUSPEND = []
+ STOPPED = []
+
+ s1, s2 = socket.socketpair()
+ s3, s4 = socket.socketpair()
+ s4.settimeout(2.0)
+
+ t = threading.Thread(target=tun_fwd, args=[s2, s3, TERMINATE, SUSPEND, STOPPED])
+ t.start()
+
+ txt = "0000|received"
+ s1.send(txt)
+ rtxt = s4.recv(len(txt))
+
+ self.assertTrue(rtxt == txt[4:])
+
+ # Let's try to suspend execution now
+ cond = threading.Condition()
+ SUSPEND.insert(0, cond)
+
+ txt = "0000|suspended"
+ s1.send(txt)
+
+ rtxt = "timeout"
+ try:
+ rtxt = s4.recv(len(txt))
+ except socket.timeout:
+ pass
+
+ self.assertTrue(rtxt == "timeout")
+
+ # Let's see if we can resume and receive the message
+ cond = SUSPEND[0]
+ SUSPEND.remove(cond)
+ cond.acquire()
+ cond.notify()
+ cond.release()
+
+ rtxt = s4.recv(len(txt))
+ self.assertTrue(rtxt == txt[4:])
+
+ # Stop forwarding
+ TERMINATE.append(None)
+
+ txt = "0000|never received"
+ s1.send(txt)
+
+ rtxt = "timeout"
+ try:
+ rtxt = s4.recv(len(txt))
+ except socket.timeout:
+ pass
+
+ self.assertTrue(rtxt == "timeout")
+ self.assertTrue(STOPPED)
+
+if __name__ == '__main__':
+ unittest.main()
+
--- /dev/null
+import nepi.testbeds.planetlab.plcapi
+from optparse import OptionParser, SUPPRESS_HELP
+import os
+import subprocess
+
+def do_maintenance(slicename, hostnames):
+ for hostname in hostnames:
+ login = "%s@%s" % (slicename, hostname)
+ command = 'sudo yum reinstall -y --nogpgcheck fedora-release'
+ proc = subprocess.Popen(['ssh', '-t', '-o', 'StrictHostKeyChecking=no', login, command],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = False)
+ retcode = proc.wait()
+ print hostname
+ print retcode
+ if retcode > 0:
+ print proc.stdout.read()
+ print proc.stderr.read()
+
+def run(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key):
+ api = nepi.testbeds.planetlab.plcapi.plcapi(pl_user, pl_pwd, plc_host,
+ "https://%(hostname)s:443/PLCAPI/")
+ node_ids = api.GetSliceNodes(slicename)
+ hostnames = [d['hostname'] for d in api.GetNodes(node_ids, ['hostname'])]
+
+ do_maintenance(slicename, hostnames)
+
+
+if __name__ == '__main__':
+ slicename = os.environ.get("PL_SLICE")
+ pl_host = os.environ.get("PL_HOST", "www.planet-lab.eu")
+ pl_ssh_key = os.environ.get(
+ "PL_SSH_KEY",
+ "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+ pl_user = os.environ.get('PL_USER')
+ pl_pwd = os.environ.get('PL_PASS')
+
+ usage = "usage: %prog -s <pl_slice> -H <pl_host> -k <ssh_key> -u <pl_user> -p <pl_password>"
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-s", "--slicename", dest="slicename",
+ help="PlanetLab slicename", default=slicename, type="str")
+ parser.add_option("-H", "--pl-host", dest="pl_host",
+ help="PlanetLab site (e.g. www.planet-lab.eu)",
+ default=pl_host, type="str")
+ parser.add_option("-k", "--ssh-key", dest="pl_ssh_key",
+ help="Path to private ssh key used for PlanetLab authentication",
+ default=pl_ssh_key, type="str")
+ parser.add_option("-u", "--pl-user", dest="pl_user",
+ help="PlanetLab account user (i.e. Registration email address)",
+ default=pl_user, type="str")
+ parser.add_option("-p", "--pl-pwd", dest="pl_pwd",
+ help="PlanetLab account password", default=pl_pwd, type="str")
+ (options, args) = parser.parse_args()
+
+ slicename = options.slicename
+ pl_host = options.pl_host
+ pl_user= options.pl_user
+ pl_pwd = options.pl_pwd
+ pl_ssh_key = options.pl_ssh_key
+
+ run(slicename, pl_host, pl_user, pl_pwd, pl_ssh_key)
+
else:
queueclass = None
TERMINATE = []
+ SUSPEND = []
+
def stopme():
time.sleep(100)
TERMINATE.append(None)
+
t = threading.Thread(target=stopme)
t.start()
- tunchannel.tun_fwd(tun, remote, True, True, passphrase, True, TERMINATE, None, tunkqueue=500,
- rwrite = rwrite, rread = rread, cipher=cipher, queueclass=queueclass,
- accept_local = accept, accept_remote = accept)
+ tunchannel.tun_fwd(tun, remote, True, True, passphrase, True, TERMINATE,
+ SUSPEND, None, tunkqueue=500, rwrite = rwrite, rread = rread,
+ cipher=cipher, queueclass=queueclass, accept_local = accept,
+ accept_remote = accept)
# Swallow exceptions on decryption
def decrypt(packet, crypter, super=tunchannel.decrypt):