Add startup experiments for NLSR and current testbed topology
refs: #4785
Change-Id: I957b8c229ed0696b2f3fca9445f9f27274b0e197
diff --git a/bin/minindn b/bin/minindn
index eda63de..3d981bc 100755
--- a/bin/minindn
+++ b/bin/minindn
@@ -60,7 +60,7 @@
from mininet.topo import Topo
from mininet.net import Mininet
-from mininet.log import setLogLevel, output, info
+from mininet.log import setLogLevel, output, info, error, warn
from mininet.link import TCLink
from mininet.util import ipStr, ipParse
@@ -68,14 +68,13 @@
from mininet.examples.clustercli import ClusterCLI
from ndn import ExperimentManager
+from ndn.experiments.experiment import Experiment
from ndn.ndn_host import NdnHost, CpuLimitedNdnHost, RemoteNdnHost
from ndn.conf_parser import parse_hosts, parse_switches, parse_links
from ndn.remote_ndn_link import RemoteNdnLink, RemoteGRENdnLink
from ndn.placer import GuidedPlacer, PopulatePlacement
-from ndn.util import ssh, scp, MiniNDNCLI
-from ndn.nlsr import Nlsr, NlsrConfigGenerator
from ndn.nfd import Nfd
-from ndn.apps.nfdc import Nfdc
+from ndn.util import ssh, scp, MiniNDNCLI, ProgramOptions
import os.path, time
import shutil
@@ -110,30 +109,6 @@
sys.exit(0)
-class ProgramOptions:
- def __init__(self):
- self.ctime = 60
- self.experimentName = None
- self.nFaces = 3
- self.templateFile = "minindn.conf"
- self.routingType = "link-state"
- self.isNlsrEnabled = True
- self.isCliEnabled = True
- self.nlsrSecurity = False
- self.nPings = 300
- self.testbed = False
- self.workDir = "/tmp/minindn"
- self.resultDir = None
- self.pctTraffic = 1.0
- self.cluster = None
- self.servers = None
- self.guided = None
- self.placer = None
- self.tunnelType = None
- self.faceType = "udp"
- self.arguments = None
- self.csSize = 65536
-
def createResultsDir(resultDir, faces, rType):
if faces == 0:
faces = "all"
@@ -146,10 +121,10 @@
if not os.path.isdir(resultDir):
os.makedirs(resultDir)
else:
- print("Results directory (%s) already exists!" % resultDir)
+ warn("Results directory ({}) already exists!".format(resultDir))
sys.exit(1)
- print("Results will be stored at: %s" % resultDir)
+ info("Results will be stored at: {}".format(resultDir))
return resultDir
def parse_args():
@@ -252,11 +227,11 @@
options.arguments = args
if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
- print("No experiment named %s" % options.experimentName)
+ error("No experiment named {}".format(options.experimentName))
sys.exit(1)
if options.experimentName is not None and options.resultDir is None:
- print("No results folder specified; experiment results will remain in the working directory")
+ warn("No results folder specified; experiment results will remain in the working directory")
if options.cluster is not None:
servers = options.cluster.split(',')
@@ -268,13 +243,13 @@
options.placement = RoundRobinPlacer
elif options.placement == "guided":
if options.placeList is None or not re.match("^[0-9,]+$", options.placeList):
- print("Please specify correctly how many nodes you want to place on each node!")
+ error("Please specify correctly how many nodes you want to place on each node!")
sys.exit(1)
else:
try:
options.placeList = map(int, options.placeList.split(","))
except ValueError:
- print("Please specify the nodes correctly, no comma at the beginning/end!")
+ error("Please specify the nodes correctly, no comma at the beginning/end!")
sys.exit(1)
PopulatePlacement(options.placeList)
@@ -291,30 +266,23 @@
def __init__(self, conf_arq, workDir, **opts):
Topo.__init__(self, **opts)
- global hosts_conf
- global links_conf
- hosts_conf = parse_hosts(conf_arq)
- switches_conf = parse_switches(conf_arq)
- links_conf = parse_links(conf_arq)
+ self.hosts_conf = parse_hosts(conf_arq)
+ self.switches_conf = parse_switches(conf_arq)
+ self.links_conf = parse_links(conf_arq)
self.isTCLink = False
self.isLimited = False
- for host in hosts_conf:
+ for host in self.hosts_conf:
if host.cpu != None and self.isLimited != True:
self.isLimited = True
- self.addHost(host.name, app=host.app, params=host.uri_tuples, cpu=host.cpu,
+ self.addHost(host.name, app=host.app, params=host.params, cpu=host.cpu,
cores=host.cores,cache=host.cache, workdir=workDir)
- if (options.routingType != 'link-state' and (host.params.get('radius') is None
- or host.params.get('angle') is None)):
- info('Hyperbolic coordinates in topology file are either missing or misconfigured.\n' \
- 'Check that each node has one radius value and one or two angle value(s).\n')
- sys.exit(1)
- for switch in switches_conf:
+ for switch in self.switches_conf:
self.addSwitch(switch.name)
- for link in links_conf:
+ for link in self.links_conf:
if len(link.linkDict) == 0:
self.addLink(link.h1, link.h2)
else:
@@ -330,7 +298,7 @@
options.templateFile = INSTALL_DIR + 'minindn.testbed.conf'
if os.path.exists(options.templateFile) == False:
- info('Template file cannot be found. Exiting...\n')
+ error('Template file cannot be found. Exiting...\n')
sys.exit(1)
if options.cluster is not None and options.placement == GuidedPlacer:
@@ -341,7 +309,7 @@
num_nodes += 1
if sum(options.placeList) != num_nodes:
- print("Placement list sum is not equal to number of nodes!")
+ error("Placement list sum is not equal to number of nodes!")
sys.exit(1)
# Copy nfd.conf to remote hosts - this assumes that NDN versions across
@@ -349,19 +317,17 @@
if options.cluster is not None:
for server in options.servers:
if server != "localhost":
- login = "mininet@%s" % server
+ login = "mininet@{}".format(server)
src = nfdConfFile
- dst = "%s:/tmp/nfd.conf" % (login)
+ dst = "{}:/tmp/nfd.conf".format(login)
scp(src, dst)
- ssh(login, "sudo cp /tmp/nfd.conf %s" % src)
+ ssh(login, "sudo cp /tmp/nfd.conf {}".format(src))
if options.resultDir is not None:
options.resultDir = createResultsDir(options.resultDir, options.nFaces, options.routingType)
topo = NdnTopo(options.templateFile, options.workDir)
- t = datetime.datetime.now()
-
if topo.isTCLink == True and topo.isLimited == True:
net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
elif topo.isTCLink == True and topo.isLimited == False:
@@ -375,12 +341,6 @@
else:
net = Mininet(topo, host=NdnHost)
- t2 = datetime.datetime.now()
-
- delta = t2 - t
-
- info('Setup time: ' + str(delta.seconds) + '\n')
-
net.start()
# Giving proper IPs to intf so neighbor nodes can communicate
@@ -404,86 +364,50 @@
ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
time.sleep(2)
+
info('Starting NFD on nodes\n')
for host in net.hosts:
host.nfd = Nfd(host, options.csSize)
host.nfd.start()
- if options.isNlsrEnabled is True:
-
- # NLSR Security
- if options.nlsrSecurity is True:
- Nlsr.createKeysAndCertificates(net, options.workDir)
-
- # NLSR initialization
- info('Starting NLSR on nodes\n')
- for host in net.hosts:
- conf = next(x for x in hosts_conf if x.name == host.name)
- host.nlsrParameters = conf.nlsrParameters
-
- if options.nFaces is not None:
- host.nlsrParameters["max-faces-per-prefix"] = options.nFaces
-
- if options.routingType == 'dry':
- host.nlsrParameters["hyperbolic-state"] = "dry-run"
-
- elif options.routingType == 'hr':
- host.nlsrParameters["hyperbolic-state"] = "on"
-
- # Generate NLSR configuration file
- configGenerator = NlsrConfigGenerator(host, options.nlsrSecurity, options.faceType)
- configGenerator.createConfigFile()
-
- # Start NLSR
- host.nlsr = Nlsr(host, configGenerator.neighborIPs, options.faceType)
- host.nlsr.start()
-
for host in net.hosts:
if 'app' in host.params:
if host.params['app'] != '':
app = host.params['app']
- print("Starting " + app + " on node " + host.name)
- print(host.cmd(app))
+ info("Starting {} on node {}".format(app, host.name))
+ info(host.cmd(app))
- # Determine if each host is running NFD and NLSR
+ # Determine if each host is running NFD
for host in net.hosts:
nfdStatus = host.cmd("ps -g -U root | grep 'nfd --config {}/[n]fd.conf'".format(host.homeFolder))
- nlsrStatus = host.cmd("ps -g | grep 'nlsr -f {}/[n]lsr.conf'".format(host.homeFolder))
if not host.nfd.isRunning or not nfdStatus:
- print("NFD on host {} is not running. Printing log file and exiting...".format(host.name))
- print(host.cmd("cat {}/nfd.log".format(host.homeFolder)))
- net.stop()
- sys.exit(1)
- if options.isNlsrEnabled and (not host.nlsr.isRunning or not nlsrStatus):
- print("NLSR on host {} is not running. Printing log file and exiting...".format(host.name))
- print(host.cmd("cat {}/log/nlsr.log".format(host.homeFolder)))
+ error("NFD on host {} is not running. Printing log file and exiting...".format(host.name))
+ info(host.cmd("tail {}/nfd.log".format(host.homeFolder)))
net.stop()
sys.exit(1)
# Load experiment
experimentName = options.experimentName
- if experimentName is not None:
- print("Loading experiment: %s" % experimentName)
+ experimentArgs = {
+ "net": net,
+ "options": options
+ }
- experimentArgs = {
- "net": net,
- "ctime": options.ctime,
- "nPings": options.nPings,
- "strategy": Nfdc.STRATEGY_BEST_ROUTE,
- "pctTraffic": options.pctTraffic,
- "nlsrSecurity": options.nlsrSecurity,
- "workDir": options.workDir,
- "arguments" : options.arguments
- }
+ if experimentName is not None:
+ info("Loading experiment: {}".format(experimentName))
experiment = ExperimentManager.create(experimentName, experimentArgs)
if experiment is not None:
experiment.start()
else:
- print("ERROR: Experiment '%s' does not exist" % experimentName)
+ error("Experiment '{}' does not exist".format(experimentName))
return
+ else:
+ experiment = Experiment(experimentArgs)
+ if options.isNlsrEnabled:
+ experiment.startNlsr(checkConvergence = False)
if options.isCliEnabled is True:
MiniNDNCLI(net)
@@ -491,20 +415,20 @@
net.stop()
if options.resultDir is not None:
- print("Moving results to %s" % options.resultDir)
- for file in glob.glob('%s/*' % options.workDir):
+ info("Moving results to {}".format(options.resultDir))
+ for file in glob.glob('{}/*'.format(options.workDir)):
shutil.move(file, options.resultDir)
if options.cluster is not None:
for server in options.servers:
if server != "localhost":
- login = "mininet@%s" % server
- src = "%s:%s/*" % (login, options.workDir)
+ login = "mininet@{}".format(server)
+ src = "{}:{}/*".format(login, options.workDir)
dst = options.resultDir
scp(src, dst)
- print("Please clean work directories of other machines before running the cluster again")
+ info("Please clean work directories of other machines before running the cluster again")
def signal_handler(signal, frame):
- print('Cleaning up...')
+ info('Cleaning up...')
call(["nfd-stop"])
call(["sudo", "mn", "--clean"])
sys.exit(1)
@@ -516,15 +440,12 @@
# Checks that each program is in the system path
for program in dependencies:
if call(["which", program], stdout=devnull):
- print("{} is missing from the system path! Exiting...".format(program))
+ error("{} is missing from the system path! Exiting...".format(program))
sys.exit(1)
devnull.close()
if __name__ == '__main__':
- hosts_conf = []
- links_conf = []
-
signal.signal(signal.SIGQUIT, signal_handler)
options = parse_args()
@@ -535,7 +456,7 @@
try:
execute(options)
except Exception as e:
- print("Error: {}".format(e))
+ error("{}".format(e))
call(["nfd-stop"])
call(["sudo", "mn", "--clean"])
sys.exit(1)