blob: 3d981bc75c4f097fa2db62eb242c1df174245e96 [file] [log] [blame]
Vince Lehmanb8b18062015-07-14 13:07:22 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Alexander Lane9944cf52018-05-17 12:16:50 -05003# Copyright (C) 2015-2018, The University of Memphis,
Vince Lehman5d5a5662015-12-02 12:33:12 -06004# Arizona Board of Regents,
5# Regents of the University of California.
Vince Lehmanb8b18062015-07-14 13:07:22 -05006#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
23#
24# This file incorporates work covered by the following copyright and
25# permission notice:
26#
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050027# Mininet 2.3.0d1 License
Vince Lehmanb8b18062015-07-14 13:07:22 -050028#
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050029# Copyright (c) 2013-2016 Open Networking Laboratory
Vince Lehmanb8b18062015-07-14 13:07:22 -050030# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
31# The Leland Stanford Junior University
32#
33# Original authors: Bob Lantz and Brandon Heller
34#
35# We are making Mininet available for public use and benefit with the
36# expectation that others will use, modify and enhance the Software and
37# contribute those enhancements back to the community. However, since we
38# would like to make the Software available for broadest use, with as few
39# restrictions as possible permission is hereby granted, free of charge, to
40# any person obtaining a copy of this Software to deal in the Software
41# under the copyrights without restriction, including without limitation
42# the rights to use, copy, modify, merge, publish, distribute, sublicense,
43# and/or sell copies of the Software, and to permit persons to whom the
44# Software is furnished to do so, subject to the following conditions:
45#
46# The above copyright notice and this permission notice shall be included
47# in all copies or substantial portions of the Software.
48#
49# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
50# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56#
57# The name and trademarks of copyright holder(s) may NOT be used in
58# advertising or publicity pertaining to the Software or any derivatives
59# without specific, written prior permission.
ashuef3490b2015-02-17 11:01:04 -060060
61from mininet.topo import Topo
62from mininet.net import Mininet
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050063from mininet.log import setLogLevel, output, info, error, warn
ashuef3490b2015-02-17 11:01:04 -060064from mininet.link import TCLink
ashu2ad32e22015-05-29 13:37:40 -050065from mininet.util import ipStr, ipParse
ashuef3490b2015-02-17 11:01:04 -060066
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050067from mininet.examples.cluster import MininetCluster, RoundRobinPlacer, ClusterCleanup
68from mininet.examples.clustercli import ClusterCLI
Vince Lehman3b8bc652015-06-18 15:01:47 -050069
70from ndn import ExperimentManager
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050071from ndn.experiments.experiment import Experiment
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050072from ndn.ndn_host import NdnHost, CpuLimitedNdnHost, RemoteNdnHost
Vince Lehmanfbd47c92015-10-14 16:00:06 -050073from ndn.conf_parser import parse_hosts, parse_switches, parse_links
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050074from ndn.remote_ndn_link import RemoteNdnLink, RemoteGRENdnLink
75from ndn.placer import GuidedPlacer, PopulatePlacement
Alexander Lane6f7a64f2018-05-17 15:01:14 -050076from ndn.nfd import Nfd
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050077from ndn.util import ssh, scp, MiniNDNCLI, ProgramOptions
ashuef3490b2015-02-17 11:01:04 -060078
79import os.path, time
Yucheng Zhang14aa5962016-04-05 17:10:15 -050080import shutil
Ashlesh Gawande044611d2016-12-21 14:24:49 -060081import argparse
ashuef3490b2015-02-17 11:01:04 -060082import datetime
ashu01b62f72015-03-12 15:16:11 -050083from os.path import expanduser
Vince Lehman3b8bc652015-06-18 15:01:47 -050084import sys
Ashlesh Gawande3807c1b2016-08-05 16:27:02 -050085import signal
Yucheng Zhang14aa5962016-04-05 17:10:15 -050086from subprocess import call
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050087import glob
88from functools import partial
89import re
ashuef3490b2015-02-17 11:01:04 -060090
Ashlesh Gawande212cb822017-02-07 10:42:13 -060091try:
92 import argcomplete
93except ImportError:
94 pass
95
Ashlesh Gawande670ff152018-06-08 12:26:39 -050096VERSION_NUMBER = "0.4.0"
Ashlesh Gawande044611d2016-12-21 14:24:49 -060097INSTALL_DIR='/usr/local/etc/mini-ndn/'
Vince Lehmane9f116d2015-07-15 10:40:21 -050098
Ashlesh Gawande044611d2016-12-21 14:24:49 -060099class PrintExperimentNames(argparse.Action):
100 def __init__(self, option_strings, dest, nargs=0, help=None):
101 super(PrintExperimentNames, self).__init__(option_strings=option_strings, dest=dest, nargs=nargs, help=help)
Vince Lehman3b8bc652015-06-18 15:01:47 -0500102
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600103 def __call__(self, parser, namespace, values, option_string=None):
104 experimentNames = ExperimentManager.getExperimentNames()
Vince Lehman3b8bc652015-06-18 15:01:47 -0500105
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600106 print("Mini-NDN experiments:")
107 for experiment in experimentNames:
Ashlesh Gawande501d4d62017-10-25 13:12:11 -0500108 print(" {}".format(experiment))
Vince Lehman194be242015-10-15 18:01:42 -0500109
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600110 sys.exit(0)
Vince Lehmane9f116d2015-07-15 10:40:21 -0500111
dmcoomes7adc7f72017-10-06 12:01:28 -0500112def createResultsDir(resultDir, faces, rType):
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500113 if faces == 0:
114 faces = "all"
115
dmcoomes7adc7f72017-10-06 12:01:28 -0500116 routingChoice = "/{}/".format(rType)
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500117
dmcoomes7adc7f72017-10-06 12:01:28 -0500118 resultDir = "{}/{}/faces-{}".format(resultDir, routingChoice, faces)
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500119 resultDir = os.path.abspath(resultDir)
120
121 if not os.path.isdir(resultDir):
122 os.makedirs(resultDir)
123 else:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500124 warn("Results directory ({}) already exists!".format(resultDir))
Ashlesh Gawande212cb822017-02-07 10:42:13 -0600125 sys.exit(1)
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500126
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500127 info("Results will be stored at: {}".format(resultDir))
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500128 return resultDir
Vince Lehman194be242015-10-15 18:01:42 -0500129
ashuef3490b2015-02-17 11:01:04 -0600130def parse_args():
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600131 parser = argparse.ArgumentParser(prog='minindn')
ashuef3490b2015-02-17 11:01:04 -0600132
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600133 # nargs='?' required here since optional argument
134 parser.add_argument('tempfile', nargs='?', default=INSTALL_DIR + 'default-topology.conf',
Ashlesh Gawande532302b2018-02-15 18:58:20 -0600135 help="If no template_file is given, topologies/default-topology.conf (given sample file) will be used.")
ashuef3490b2015-02-17 11:01:04 -0600136
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600137 parser.add_argument("--ctime", type=int, default=60,
138 help="Specify convergence time for the topology (Default: 60 seconds)")
ashuef3490b2015-02-17 11:01:04 -0600139
Ashlesh Gawande212cb822017-02-07 10:42:13 -0600140 parser.add_argument("--experiment", choices=[experiment for experiment in ExperimentManager.getExperimentNames()],
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600141 help="Runs the specified experiment")
Vince Lehman3b8bc652015-06-18 15:01:47 -0500142
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600143 parser.add_argument("--faces", type=int, default=3,
Ashlesh Gawande212cb822017-02-07 10:42:13 -0600144 help="Specify number of max faces per prefix for NLSR 0-60")
ashuef3490b2015-02-17 11:01:04 -0600145
dmcoomes7adc7f72017-10-06 12:01:28 -0500146 parser.add_argument("--routing", dest="routingType", default='link-state', choices=['link-state', 'hr', 'dry'],
147 help="""choices for routing are 'link-state' for link state, 'hr' for hyperbolic, and 'dry'
148 to test hyperbolic routing and compare with link state. Default is link-state.""")
Vince Lehman194be242015-10-15 18:01:42 -0500149
dmcoomesecf9c5a2017-10-11 10:17:46 -0500150 parser.add_argument("--no-nlsr", action="store_false", dest="isNlsrEnabled",
151 help="Run mini-ndn without NLSR routing")
152
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600153 parser.add_argument("--list-experiments", action=PrintExperimentNames,
154 help="Lists the names of all available experiments")
Vince Lehman194be242015-10-15 18:01:42 -0500155
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600156 parser.add_argument("--no-cli", action="store_false", dest="isCliEnabled",
157 help="Run experiments and exit without showing the command line interface")
Vince Lehman194be242015-10-15 18:01:42 -0500158
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600159 parser.add_argument("--nPings", type=int, default=300,
160 help="Number of pings to perform between each node in the experiment")
Vince Lehman194be242015-10-15 18:01:42 -0500161
dmcoomes7adc7f72017-10-06 12:01:28 -0500162 # store_true stores default value of False
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600163 parser.add_argument("--nlsr-security", action="store_true", dest="nlsrSecurity",
164 help="Enables NLSR security")
Vince Lehman5d5a5662015-12-02 12:33:12 -0600165
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600166 parser.add_argument("-t", "--testbed", action="store_true", dest="testbed",
167 help="Instantiates a snapshot of the NDN Testbed irrespective of the tempfile provided")
ashuef3490b2015-02-17 11:01:04 -0600168
dmcoomes80eeea12017-10-27 12:49:10 -0500169 parser.add_argument("--work-dir", action="store", dest="workDir", default="/tmp/minindn",
170 help="Specify the working directory; default is /tmp/minindn")
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500171
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600172 parser.add_argument("--result-dir", action="store", dest="resultDir", default=None,
173 help="Specify the full path destination folder where experiment results will be moved")
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500174
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600175 parser.add_argument("--pct-traffic", dest="pctTraffic", type=float, default=1.0,
176 help="Specify the percentage of nodes each node should ping")
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -0500177
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600178 parser.add_argument('--version', '-V', action='version', version='%(prog)s ' + VERSION_NUMBER,
179 help='Displays version information')
Vince Lehmane9f116d2015-07-15 10:40:21 -0500180
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500181 parser.add_argument("--cluster", metavar='localhost,server2,...',
182 help="Run cluster edition")
183
184 parser.add_argument("--placement", default='guided',
185 choices=['roundRobin', 'guided'])
186
187 parser.add_argument("--place-list", dest="placeList",
188 help="""Provide corresponding number of nodes (comma separated) to put on
189 each node respectively of --cluster when guided placement is used""")
190
191 parser.add_argument("--tunnel-type", dest="tunnelType", default='ssh',
192 choices=['ssh', 'gre'])
193
Ashlesh Gawande708fcca2017-06-23 14:04:12 -0500194 parser.add_argument("--face-type", dest='faceType', default='udp', choices=['udp', 'tcp'])
195
Ashlesh Gawande532302b2018-02-15 18:58:20 -0600196 parser.add_argument("--cs-size", dest='csSize', type=int, default=65536,
197 help="Set CS size in NFD's conf file")
198
Alexander Lane1bc9b472018-05-16 15:07:16 -0500199 ExperimentManager.addExperimentArgs(parser)
200
Ashlesh Gawande212cb822017-02-07 10:42:13 -0600201 if "argcomplete" in sys.modules:
202 argcomplete.autocomplete(parser)
203
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600204 args = parser.parse_args()
ashuef3490b2015-02-17 11:01:04 -0600205
Vince Lehman194be242015-10-15 18:01:42 -0500206 options = ProgramOptions()
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600207 options.templateFile = args.tempfile
Vince Lehman194be242015-10-15 18:01:42 -0500208 options.ctime = args.ctime
209 options.experimentName = args.experiment
210 options.nFaces = args.faces
dmcoomes7adc7f72017-10-06 12:01:28 -0500211 options.routingType = args.routingType
dmcoomesecf9c5a2017-10-11 10:17:46 -0500212 options.isNlsrEnabled = args.isNlsrEnabled
Vince Lehman194be242015-10-15 18:01:42 -0500213 options.isCliEnabled = args.isCliEnabled
Vince Lehman5d5a5662015-12-02 12:33:12 -0600214 options.nlsrSecurity = args.nlsrSecurity
Vince Lehman194be242015-10-15 18:01:42 -0500215 options.nPings = args.nPings
Vince Lehman5d5a5662015-12-02 12:33:12 -0600216
Vince Lehman194be242015-10-15 18:01:42 -0500217 options.testbed = args.testbed
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500218 options.workDir = args.workDir
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500219 options.resultDir = args.resultDir
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -0500220 options.pctTraffic = args.pctTraffic
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500221 options.cluster = args.cluster
222 options.placement = args.placement
223 options.tunnelType = args.tunnelType
224 options.placeList = args.placeList
Ashlesh Gawande708fcca2017-06-23 14:04:12 -0500225 options.faceType = args.faceType
Ashlesh Gawande532302b2018-02-15 18:58:20 -0600226 options.csSize = args.csSize
Alexander Lane1bc9b472018-05-16 15:07:16 -0500227 options.arguments = args
Ashlesh Gawande501d4d62017-10-25 13:12:11 -0500228
Vince Lehman194be242015-10-15 18:01:42 -0500229 if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500230 error("No experiment named {}".format(options.experimentName))
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600231 sys.exit(1)
Vince Lehman3b8bc652015-06-18 15:01:47 -0500232
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500233 if options.experimentName is not None and options.resultDir is None:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500234 warn("No results folder specified; experiment results will remain in the working directory")
ashuef3490b2015-02-17 11:01:04 -0600235
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500236 if options.cluster is not None:
237 servers = options.cluster.split(',')
238 for server in servers:
239 ClusterCleanup.add(server)
240 options.servers = servers
241
242 if options.placement == "roundRobin":
243 options.placement = RoundRobinPlacer
244 elif options.placement == "guided":
245 if options.placeList is None or not re.match("^[0-9,]+$", options.placeList):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500246 error("Please specify correctly how many nodes you want to place on each node!")
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500247 sys.exit(1)
248 else:
249 try:
250 options.placeList = map(int, options.placeList.split(","))
251 except ValueError:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500252 error("Please specify the nodes correctly, no comma at the beginning/end!")
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500253 sys.exit(1)
254
255 PopulatePlacement(options.placeList)
256 options.placement = GuidedPlacer
257
258 if options.tunnelType == "ssh":
259 options.tunnelType = RemoteNdnLink
260 else:
261 options.tunnelType = RemoteGRENdnLink
262
Vince Lehman194be242015-10-15 18:01:42 -0500263 return options
ashuef3490b2015-02-17 11:01:04 -0600264
265class NdnTopo(Topo):
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500266 def __init__(self, conf_arq, workDir, **opts):
ashuef3490b2015-02-17 11:01:04 -0600267 Topo.__init__(self, **opts)
268
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500269 self.hosts_conf = parse_hosts(conf_arq)
270 self.switches_conf = parse_switches(conf_arq)
271 self.links_conf = parse_links(conf_arq)
ashuef3490b2015-02-17 11:01:04 -0600272
273 self.isTCLink = False
274 self.isLimited = False
275
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500276 for host in self.hosts_conf:
ashuef3490b2015-02-17 11:01:04 -0600277 if host.cpu != None and self.isLimited != True:
278 self.isLimited = True
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500279 self.addHost(host.name, app=host.app, params=host.params, cpu=host.cpu,
dmcoomes74da84c2017-11-07 16:09:23 -0600280 cores=host.cores,cache=host.cache, workdir=workDir)
ashuef3490b2015-02-17 11:01:04 -0600281
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500282 for switch in self.switches_conf:
Vince Lehmanfbd47c92015-10-14 16:00:06 -0500283 self.addSwitch(switch.name)
284
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500285 for link in self.links_conf:
ashuef3490b2015-02-17 11:01:04 -0600286 if len(link.linkDict) == 0:
287 self.addLink(link.h1, link.h2)
288 else:
289 self.addLink(link.h1, link.h2, **link.linkDict)
290 self.isTCLink = True
291
292 info('Parse of ' + conf_arq + ' done.\n')
293
Vince Lehman194be242015-10-15 18:01:42 -0500294def execute(options):
ashuef3490b2015-02-17 11:01:04 -0600295 "Create a network based on template_file"
296
Vince Lehman194be242015-10-15 18:01:42 -0500297 if options.testbed:
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600298 options.templateFile = INSTALL_DIR + 'minindn.testbed.conf'
ashuef3490b2015-02-17 11:01:04 -0600299
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600300 if os.path.exists(options.templateFile) == False:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500301 error('Template file cannot be found. Exiting...\n')
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600302 sys.exit(1)
Ashlesh Gawande20f70762015-06-17 15:18:19 -0500303
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500304 if options.cluster is not None and options.placement == GuidedPlacer:
305 num_nodes = 0
306 with open(options.templateFile, 'r') as topo:
307 for line in topo:
308 if ': _' in line:
309 num_nodes += 1
310
311 if sum(options.placeList) != num_nodes:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500312 error("Placement list sum is not equal to number of nodes!")
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500313 sys.exit(1)
314
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500315 # Copy nfd.conf to remote hosts - this assumes that NDN versions across
316 # the cluster are at least compatible if not the same
317 if options.cluster is not None:
318 for server in options.servers:
319 if server != "localhost":
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500320 login = "mininet@{}".format(server)
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500321 src = nfdConfFile
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500322 dst = "{}:/tmp/nfd.conf".format(login)
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500323 scp(src, dst)
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500324 ssh(login, "sudo cp /tmp/nfd.conf {}".format(src))
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500325
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500326 if options.resultDir is not None:
dmcoomes7adc7f72017-10-06 12:01:28 -0500327 options.resultDir = createResultsDir(options.resultDir, options.nFaces, options.routingType)
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500328
Ashlesh Gawande044611d2016-12-21 14:24:49 -0600329 topo = NdnTopo(options.templateFile, options.workDir)
ashuef3490b2015-02-17 11:01:04 -0600330
ashuef3490b2015-02-17 11:01:04 -0600331 if topo.isTCLink == True and topo.isLimited == True:
332 net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
333 elif topo.isTCLink == True and topo.isLimited == False:
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500334 if options.cluster is not None:
335 mn = partial(MininetCluster, servers=options.servers, placement=options.placement)
336 net = mn(topo=topo, host=RemoteNdnHost, link=options.tunnelType)
337 else:
338 net = Mininet(topo, host=NdnHost, link=TCLink)
ashuef3490b2015-02-17 11:01:04 -0600339 elif topo.isTCLink == False and topo.isLimited == True:
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500340 net = Mininet(topo, host=CpuLimitedNdnHost)
ashuef3490b2015-02-17 11:01:04 -0600341 else:
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500342 net = Mininet(topo, host=NdnHost)
ashuef3490b2015-02-17 11:01:04 -0600343
ashuef3490b2015-02-17 11:01:04 -0600344 net.start()
345
ashu2ad32e22015-05-29 13:37:40 -0500346 # Giving proper IPs to intf so neighbor nodes can communicate
347 # This is one way of giving connectivity, another way could be
348 # to insert a switch between each pair of neighbors
349 ndnNetBase = "1.0.0.0"
350 interfaces = []
351 for host in net.hosts:
352 for intf in host.intfList():
353 link = intf.link
354 node1, node2 = link.intf1.node, link.intf2.node
Vince Lehmanfbd47c92015-10-14 16:00:06 -0500355
356 if node1 in net.switches or node2 in net.switches:
Vince Lehmanfbd47c92015-10-14 16:00:06 -0500357 continue
358
ashu2ad32e22015-05-29 13:37:40 -0500359 if link.intf1 not in interfaces and link.intf2 not in interfaces:
360 interfaces.append(link.intf1)
361 interfaces.append(link.intf2)
362 node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
363 node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
364 ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
365
Ashlesh Gawande532302b2018-02-15 18:58:20 -0600366 time.sleep(2)
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500367
Ashlesh Gawande532302b2018-02-15 18:58:20 -0600368 info('Starting NFD on nodes\n')
369 for host in net.hosts:
370 host.nfd = Nfd(host, options.csSize)
371 host.nfd.start()
372
ashuef3490b2015-02-17 11:01:04 -0600373 for host in net.hosts:
374 if 'app' in host.params:
Ashlesh Gawande557cb842015-07-01 15:39:44 -0500375 if host.params['app'] != '':
376 app = host.params['app']
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500377 info("Starting {} on node {}".format(app, host.name))
378 info(host.cmd(app))
ashuef3490b2015-02-17 11:01:04 -0600379
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500380 # Determine if each host is running NFD
Alexander Lane052aabb2018-05-14 14:48:29 -0500381 for host in net.hosts:
382 nfdStatus = host.cmd("ps -g -U root | grep 'nfd --config {}/[n]fd.conf'".format(host.homeFolder))
Alexander Lane052aabb2018-05-14 14:48:29 -0500383 if not host.nfd.isRunning or not nfdStatus:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500384 error("NFD on host {} is not running. Printing log file and exiting...".format(host.name))
385 info(host.cmd("tail {}/nfd.log".format(host.homeFolder)))
Alexander Lane052aabb2018-05-14 14:48:29 -0500386 net.stop()
387 sys.exit(1)
388
Vince Lehman3b8bc652015-06-18 15:01:47 -0500389 # Load experiment
Vince Lehman194be242015-10-15 18:01:42 -0500390 experimentName = options.experimentName
391
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500392 experimentArgs = {
393 "net": net,
394 "options": options
395 }
Vince Lehman3b8bc652015-06-18 15:01:47 -0500396
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500397 if experimentName is not None:
398 info("Loading experiment: {}".format(experimentName))
Vince Lehman3b8bc652015-06-18 15:01:47 -0500399
400 experiment = ExperimentManager.create(experimentName, experimentArgs)
401
402 if experiment is not None:
403 experiment.start()
404 else:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500405 error("Experiment '{}' does not exist".format(experimentName))
Vince Lehman3b8bc652015-06-18 15:01:47 -0500406 return
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500407 else:
408 experiment = Experiment(experimentArgs)
409 if options.isNlsrEnabled:
410 experiment.startNlsr(checkConvergence = False)
Vince Lehman3b8bc652015-06-18 15:01:47 -0500411
Vince Lehman194be242015-10-15 18:01:42 -0500412 if options.isCliEnabled is True:
Ashlesh Gawande95789cc2017-02-27 12:38:04 -0600413 MiniNDNCLI(net)
ashuef3490b2015-02-17 11:01:04 -0600414
415 net.stop()
416
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500417 if options.resultDir is not None:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500418 info("Moving results to {}".format(options.resultDir))
419 for file in glob.glob('{}/*'.format(options.workDir)):
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500420 shutil.move(file, options.resultDir)
421 if options.cluster is not None:
422 for server in options.servers:
423 if server != "localhost":
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500424 login = "mininet@{}".format(server)
425 src = "{}:{}/*".format(login, options.workDir)
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500426 dst = options.resultDir
427 scp(src, dst)
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500428 info("Please clean work directories of other machines before running the cluster again")
Ashlesh Gawanded829bfc2015-10-14 16:38:10 -0500429
Ashlesh Gawande3807c1b2016-08-05 16:27:02 -0500430def signal_handler(signal, frame):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500431 info('Cleaning up...')
Ashlesh Gawande3807c1b2016-08-05 16:27:02 -0500432 call(["nfd-stop"])
433 call(["sudo", "mn", "--clean"])
434 sys.exit(1)
435
Alexander Lane052aabb2018-05-14 14:48:29 -0500436def verify_dependencies():
437 "Prevent MiniNDN from running without necessary dependencies"
438 dependencies = ["nfd", "nlsr", "infoedit", "ndnping", "ndnpingserver"]
439 devnull = open("/dev/null", "w")
440 # Checks that each program is in the system path
441 for program in dependencies:
442 if call(["which", program], stdout=devnull):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500443 error("{} is missing from the system path! Exiting...".format(program))
Alexander Lane052aabb2018-05-14 14:48:29 -0500444 sys.exit(1)
445 devnull.close()
446
ashuef3490b2015-02-17 11:01:04 -0600447if __name__ == '__main__':
Vince Lehman3b8bc652015-06-18 15:01:47 -0500448
Ashlesh Gawande2763f192017-10-25 15:48:39 -0500449 signal.signal(signal.SIGQUIT, signal_handler)
Ashlesh Gawande3807c1b2016-08-05 16:27:02 -0500450
Vince Lehman194be242015-10-15 18:01:42 -0500451 options = parse_args()
ashuef3490b2015-02-17 11:01:04 -0600452
453 setLogLevel('info')
Alexander Lane052aabb2018-05-14 14:48:29 -0500454 verify_dependencies()
Alexander Lanee842cc22018-05-14 11:37:43 -0500455
Alexander Lanee842cc22018-05-14 11:37:43 -0500456 try:
457 execute(options)
458 except Exception as e:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500459 error("{}".format(e))
Alexander Lanee842cc22018-05-14 11:37:43 -0500460 call(["nfd-stop"])
461 call(["sudo", "mn", "--clean"])
Ashlesh Gawande670ff152018-06-08 12:26:39 -0500462 sys.exit(1)