modification to use cluster version
Change-Id: Iaf169507577deba20d548348532a2e0b91a03249
refs: #3652
diff --git a/bin/minindn b/bin/minindn
index 9eca39c..950dc05 100755
--- a/bin/minindn
+++ b/bin/minindn
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
-# Copyright (C) 2015-2016, The University of Memphis,
+# Copyright (C) 2015-2017, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -24,9 +24,9 @@
# This file incorporates work covered by the following copyright and
# permission notice:
#
-# Mininet 2.2.1 License
+# Mininet 2.3.0d1 License
#
-# Copyright (c) 2013-2015 Open Networking Laboratory
+# Copyright (c) 2013-2016 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
@@ -65,10 +65,15 @@
from mininet.link import TCLink
from mininet.util import ipStr, ipParse
+from mininet.examples.cluster import MininetCluster, RoundRobinPlacer, ClusterCleanup
+from mininet.examples.clustercli import ClusterCLI
from ndn import ExperimentManager
-from ndn.ndn_host import NdnHost, CpuLimitedNdnHost
+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
import os.path, time
import shutil
@@ -78,6 +83,9 @@
import sys
import signal
from subprocess import call
+import glob
+from functools import partial
+import re
from ndn.nlsr import Nlsr, NlsrConfigGenerator
from ndn.nfd import Nfd
@@ -112,6 +120,11 @@
self.workDir = "/tmp"
self.resultDir = None
self.pctTraffic = 1.0
+ self.cluster = None
+ self.servers = None
+ self.guided = None
+ self.placer = None
+ self.tunnelType = None
def createResultsDir(resultDir, faces, hr):
if faces == 0:
@@ -181,6 +194,19 @@
parser.add_argument('--version', '-V', action='version', version='%(prog)s ' + VERSION_NUMBER,
help='Displays version information')
+ parser.add_argument("--cluster", metavar='localhost,server2,...',
+ help="Run cluster edition")
+
+ parser.add_argument("--placement", default='guided',
+ choices=['roundRobin', 'guided'])
+
+ parser.add_argument("--place-list", dest="placeList",
+ help="""Provide corresponding number of nodes (comma separated) to put on
+ each node respectively of --cluster when guided placement is used""")
+
+ parser.add_argument("--tunnel-type", dest="tunnelType", default='ssh',
+ choices=['ssh', 'gre'])
+
args = parser.parse_args()
options = ProgramOptions()
@@ -197,6 +223,10 @@
options.workDir = args.workDir
options.resultDir = args.resultDir
options.pctTraffic = args.pctTraffic
+ options.cluster = args.cluster
+ options.placement = args.placement
+ options.tunnelType = args.tunnelType
+ options.placeList = args.placeList
if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
print("No experiment named %s" % options.experimentName)
@@ -205,6 +235,33 @@
if options.experimentName is not None and options.resultDir is None:
print("No results folder specified; experiment results will remain in the working directory")
+ if options.cluster is not None:
+ servers = options.cluster.split(',')
+ for server in servers:
+ ClusterCleanup.add(server)
+ options.servers = servers
+
+ if options.placement == "roundRobin":
+ 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!")
+ 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!")
+ sys.exit(1)
+
+ PopulatePlacement(options.placeList)
+ options.placement = GuidedPlacer
+
+ if options.tunnelType == "ssh":
+ options.tunnelType = RemoteNdnLink
+ else:
+ options.tunnelType = RemoteGRENdnLink
+
return options
class NdnTopo(Topo):
@@ -247,6 +304,17 @@
info('Template file cannot be found. Exiting...\n')
sys.exit(1)
+ if options.cluster is not None and options.placement == GuidedPlacer:
+ num_nodes = 0
+ with open(options.templateFile, 'r') as topo:
+ for line in topo:
+ if ': _' in line:
+ num_nodes += 1
+
+ if sum(options.placeList) != num_nodes:
+ print("Placement list sum is not equal to number of nodes!")
+ sys.exit(1)
+
# Use nfd.conf as default configuration for NFD, else use the sample
nfdConfFile = "%s/nfd.conf" % INSTALL_DIR
@@ -259,6 +327,17 @@
call(["sudo", "sed", "-i", 's|default_level [A-Z]*$|default_level $LOG_LEVEL|g', nfdConfFile])
+ # Copy nfd.conf to remote hosts - this assumes that NDN versions across
+ # the cluster are at least compatible if not the same
+ if options.cluster is not None:
+ for server in options.servers:
+ if server != "localhost":
+ login = "mininet@%s" % server
+ src = nfdConfFile
+ dst = "%s:/tmp/nfd.conf" % (login)
+ scp(src, dst)
+ ssh(login, "sudo cp /tmp/nfd.conf %s" % src)
+
if options.resultDir is not None:
options.resultDir = createResultsDir(options.resultDir, options.nFaces, options.hr)
@@ -269,11 +348,15 @@
if topo.isTCLink == True and topo.isLimited == True:
net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
elif topo.isTCLink == True and topo.isLimited == False:
- net = Mininet(topo,host=NdnHost,link=TCLink)
+ if options.cluster is not None:
+ mn = partial(MininetCluster, servers=options.servers, placement=options.placement)
+ net = mn(topo=topo, host=RemoteNdnHost, link=options.tunnelType)
+ else:
+ net = Mininet(topo, host=NdnHost, link=TCLink)
elif topo.isTCLink == False and topo.isLimited == True:
- net = Mininet(topo,host=CpuLimitedNdnHost)
+ net = Mininet(topo, host=CpuLimitedNdnHost)
else:
- net = Mininet(topo,host=NdnHost)
+ net = Mininet(topo, host=NdnHost)
t2 = datetime.datetime.now()
@@ -369,7 +452,16 @@
if options.resultDir is not None:
print("Moving results to %s" % options.resultDir)
- os.system("sudo mv /%s/* %s" % (options.workDir, options.resultDir))
+ for file in glob.glob('%s/*' % 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)
+ dst = options.resultDir
+ scp(src, dst)
+ print("Please clean work directories of other machines before running the cluster again")
def signal_handler(signal, frame):
print('Cleaning up...')