""" NEPI, a framework to manage network experiments Copyright (C) 2013 INRIA This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Author: Alina Quereilhac Julien Tribino Example : - Testbed : Nitos - Explanation : CCN topology: content ccncat ccncat h1 h2 h3 h4 h5 0 ----- 0 ----- 0 ------ 0 ------------0 - Experiment: * t0 : h4 retrieves the content and we measure the time * t1 : h5 retrieve the content and should go faster than h4 """ #!/usr/bin/env python from nepi.execution.resource import ResourceFactory, ResourceAction, ResourceState from nepi.execution.ec import ExperimentController from optparse import OptionParser, SUPPRESS_HELP ### Define OMF Method to simplify definition of resources ### def add_node(ec, hostname, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): node = ec.register_resource("OMFNode") ec.set(node, 'hostname', hostname) ec.set(node, 'xmppServer', xmppServer) ec.set(node, 'xmppUser', xmppUser) ec.set(node, 'xmppPort', xmppPort) ec.set(node, 'xmppPassword', xmppPassword) ec.set(node, 'version', "5") return node def add_interface(ec, ip, xmppServer, xmppUser, essid = "ccn", name = "wlan0", mode = "adhoc", typ = "g", xmppPort = "5222", xmppPassword = "1234"): iface = ec.register_resource("OMFWifiInterface") ec.set(iface, 'name', name) ec.set(iface, 'mode', mode) ec.set(iface, 'hw_mode', typ) ec.set(iface, 'essid', essid) ec.set(iface, 'ip', ip) ec.set(iface, 'version', "5") return iface def add_channel(ec, channel, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): chan = ec.register_resource("OMFChannel") ec.set(chan, 'channel', channel) ec.set(chan, 'xmppServer', xmppServer) ec.set(chan, 'xmppUser', xmppUser) ec.set(chan, 'xmppPort', xmppPort) ec.set(chan, 'xmppPassword', xmppPassword) ec.set(chan, 'version', "5") return chan def add_app(ec, host, appid, command, env, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): app = ec.register_resource("OMFApplication") ec.set(app, 'appid', appid) ec.set(app, 'command', command) ec.set(app, 'env', env) ec.set(app, 'version', "5") ec.register_connection(app, host) return app ### Define a CCND application ### def add_ccnd(ec, host, peers, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root \ CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"' # BASH command -> ' ccndstart ; ccndc add ccnx:/ udp host ; ccnr ' command = "ccndc add ccnx:/ udp " + peers app = add_app(ec, host, "#ccnd", command, env, xmppServer, xmppUser, xmppPort = xmppPort, xmppPassword = xmppPassword) return app ### Define a CCN SeqWriter application ### def add_publish(ec, host, movie, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"' # BASH command -> 'ccnseqwriter -r ccnx:/VIDEO < movie' command = "ccnseqwriter -r ccnx:/VIDEO" command += " < " + movie app = add_app(ec, host, "#ccn_write", command, env, xmppServer, xmppUser, xmppPort = xmppPort, xmppPassword = xmppPassword) return app ### Define a streaming application ### def add_stream(ec, host, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"): env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"' command = " ddbus-uuidgen --ensure ; ( /root/ccnx-0.7.2/bin/ccncat ccnx:/VIDEO | /root/vlc-1.1.13/cvlc - ) " app = add_app(ec, host, "#ccn_stream", command, env, xmppServer, xmppUser, xmppPort = xmppPort, xmppPassword = xmppPassword) return app ### Many options to easily addapt the script #### def get_options(): usage = "usage: %prog -c -s -x -m " parser = OptionParser(usage=usage) parser.add_option("-c", "--channel", dest="channel", help="Channel of the communication", type="str") parser.add_option("-s", "--xmpp-slice", dest="xmpp_slice", help="Name of the slice XMPP", type="str") parser.add_option("-x", "--xmpp-host", dest="xmpp_host", help="Name of the host XMPP", type="str") #parser.add_option("-e", "--exp-id", dest="exp_id", # help="Label to identify experiment", type="str") (options, args) = parser.parse_args() return (options.channel, options.xmpp_slice, options.xmpp_host) ### Script itself ### if __name__ == '__main__': (channel, xmpp_slice, xmpp_host) = get_options() env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"' # Create the EC ec = ExperimentController() # Create the topology host1 = "omf.plexus.wlab5" host2 = "omf.plexus.wlab9" host3 = "omf.plexus.wlab10" host4 = "omf.plexus.wlab24" host5 = "omf.plexus.wlab29" # b1 ip1 = "10.0.0.5/24" ip2 = "10.0.0.9/24" ip3 = "10.0.0.10/24" ip4 = "10.0.0.24/24" ip5 = "10.0.0.29/24" all_hosts = [host1, host2, host3, host4, host5] all_ip = [ip1, ip2, ip3, ip4, ip5] ring_hosts = [host1, host2, host3, host4] nodes = dict() chann = add_channel(ec, channel, xmpp_slice, xmpp_host) for i in xrange(len(all_hosts)): node = add_node(ec,all_hosts[i], xmpp_slice, xmpp_host) iface = add_interface(ec, all_ip[i], xmpp_slice, xmpp_host) ec.register_connection(node, iface) ec.register_connection(iface, chann) nodes[all_hosts[i]] = node #### CCN setup for the node ### ccnds = dict() ### ccnrs = dict() ### for i in xrange(len(all_hosts)): ### ccndstart = add_app(ec, nodes[all_hosts[i]], "#ccndstart", "ccndstart &", ### env, xmpp_slice, xmpp_host) ### ccnr = add_app(ec, nodes[all_hosts[i]], "#ccnr", "ccnr &", ### env, xmpp_slice, xmpp_host) ### ccnds[all_hosts[i]] = ccndstart ### ccnrs[all_hosts[i]] = ccnr ### ec.register_condition(ccnr, ResourceAction.START, ccndstart, ResourceState.STARTED, "1s") #### CCNDC setup ### # l1 : h1 - h2 , h2 - h1 ### l1u = add_ccnd(ec, nodes[host1], ip2, xmpp_slice, xmpp_host) ### l1d = add_ccnd(ec, nodes[host2], ip1, xmpp_slice, xmpp_host) ### # l2 : h2 - h3 , h3 - h2 ### l2u = add_ccnd(ec, nodes[host2], ip3, xmpp_slice, xmpp_host) ### l2d = add_ccnd(ec, nodes[host3], ip2, xmpp_slice, xmpp_host) ### # l3 : h3 - h4 , h4 - h3 ### l3u = add_ccnd(ec, nodes[host3], ip4, xmpp_slice, xmpp_host) ### l3d = add_ccnd(ec, nodes[host4], ip3, xmpp_slice, xmpp_host) ### # l4 : h4 - h5 , h5 - h4 ### l4u = add_ccnd(ec, nodes[host4], ip5, xmpp_slice, xmpp_host) ### l4d = add_ccnd(ec, nodes[host5], ip4, xmpp_slice, xmpp_host) ### link = [l1u, l1d, l2u, l2d, l3u, l3d, l4u, l4d] #### List of condition ### for i in xrange(len(all_hosts)): ### ec.register_condition(ccnrs[all_hosts[i]], ResourceAction.START, ccnds[all_hosts[i]], ResourceState.STARTED, "1s") ### ec.register_condition(link, ResourceAction.START, ccnrs[all_hosts[i]], ResourceState.STARTED, "1s") # Do the iperf iperfserv = dict() iperfclient = dict() for i in xrange(len(all_hosts)): perfserv = add_app(ec, nodes[all_hosts[i]], "#perfserv", "iperf -s > /opt/iperfserv.txt", env, xmpp_slice, xmpp_host) iperfclient[all_hosts[i]] = [] if i > 0: cmd = "iperf -c " + all_ip[i-1] + " > /opt/iperclient1.txt" perfclient1 = add_app(ec, nodes[all_hosts[i]], "#perfclient1", cmd, env, xmpp_slice, xmpp_host) iperfclient[all_hosts[i]].append(perfclient1) if i < (len(all_hosts)-1): cmd = "iperf -c " + all_ip[i+1] + " > /opt/iperclient2.txt" perfclient2 = add_app(ec, nodes[all_hosts[i]], "#perfclient2", cmd, env, xmpp_slice, xmpp_host) iperfclient[all_hosts[i]].append(perfclient2) iperfserv[all_hosts[i]] = perfserv for i in xrange(len(all_hosts)): #ec.register_condition(iperfserv[all_hosts[i]], ResourceAction.START, link, ResourceState.STARTED, "2s") for elt in iperfclient[all_hosts[i]]: ec.register_condition(elt, ResourceAction.START, iperfserv[all_hosts[i]], ResourceState.STARTED, "3s") ## Streaming Server # pub = add_publish(ec, nodes[host5], movie, xmpp_slice, xmpp_host) ## Streaming client # stream = add_stream(ec, nodes[host6], xmpp_slice, xmpp_host) ## Streaming conditions # ec.register_condition(pub, ResourceAction.START, link, ResourceState.STARTED, "2s") # ec.register_condition(stream, ResourceAction.START, link, ResourceState.STARTED, "2s") # ec.register_condition(stream, ResourceAction.START, pub, ResourceState.STARTED, "2s") ### Cleanning ### # Cleaning when the experiment stop ## ccndstops = [] ## for i in xrange(len(all_hosts)): ## ccndstop = add_app(ec, nodes[all_hosts[i]], "#ccndstop", "ccndstop", env, xmpp_slice, xmpp_host) ## ccndstops.append(ccndstop) perfkill = dict() for i in xrange(len(all_hosts)): kill = add_app(ec, nodes[all_hosts[i]], "#kill", "killall iperf", "", xmpp_slice, xmpp_host) perfkill[all_hosts[i]] = kill # Condition to stop and clean the experiment apps = [] for i in xrange(len(all_hosts)): # apps.append(ccnds[all_hosts[i]]) # apps.append(ccnrs[all_hosts[i]]) apps.append(iperfserv[all_hosts[i]]) for elt in iperfclient[all_hosts[i]]: apps.append(elt) # apps += link #apps.append(pub) #apps.append(stream) ec.register_condition(apps, ResourceAction.STOP, apps, ResourceState.STARTED, "20s") # ec.register_condition(ccndstops + [killall], ResourceAction.START, apps, ResourceState.STOPPED, "1s") # ec.register_condition(ccndstops + [killall], ResourceAction.STOP, ccndstops, ResourceState.STARTED, "1s") killall = [] for i in xrange(len(all_hosts)): killall.append(perfkill[all_hosts[i]]) ec.register_condition(killall, ResourceAction.START, apps, ResourceState.STOPPED, "1s") ec.register_condition(killall, ResourceAction.STOP, killall, ResourceState.STARTED, "1s") ### Deploy and Wait ### # Deploy all ResourceManagers ec.deploy() # Wait until the applications are finished ec.wait_finished(killall) # Shutdown the experiment controller ec.shutdown()