From edcd083571d40da9d03af8a462f0526e9f316af5 Mon Sep 17 00:00:00 2001
From: Michael Marsh <mmarsh@cs.umd.edu>
Date: Thu, 3 Jan 2019 09:27:42 -0500
Subject: [PATCH] updating to not always use docker

---
 README           | 19 +++++--------
 example.yml      |  1 +
 start_testbed.py | 72 +++++++++++++++++++++++++++++-------------------
 stop_testbed.py  | 17 ++++++++----
 4 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/README b/README
index b7f0006..7caa316 100644
--- a/README
+++ b/README
@@ -1,21 +1,16 @@
-This repository contains scripts to help you set up a docker-based
-testbed, with networking between the containers.
+This repository contains scripts to help you set up a simple
+namespace-based testbed, with networking between the namespaces.
+Optionally, you can start docker containers in the namespaces.
 
-Since the containers don't need to do much in order to demonstrate
-basic networking (you can change this to suit your needs), we're
-just going to run the command
+If we're using docker, the containers don't need to do much in order
+to demonstrate basic networking (you can change this to suit your
+needs), so we're just going to run the command
 
     tail -f /etc/issue
 
 This will never exit, while it waits for more output to be appended
 to the file.
 
-Before running start_testbed.py, you must run:
-
-    sudo mkdir -p /var/run/netns
-
-This only needs to be done once for your VM.
-
 To start the testbed, run
 
     ./start_testbed.py [-f <config file>]
@@ -25,5 +20,5 @@ To stop the testbed, run
     ./stop_testbed.py [-f <config file>]
 
 In both cases, if the config file isn't specified, it will use
-example.yml
+example.yml in the current directory.
 
diff --git a/example.yml b/example.yml
index c1b1ffe..b69f756 100644
--- a/example.yml
+++ b/example.yml
@@ -10,6 +10,7 @@ docker_opts: ""
 # center of the star. Containers will be named
 # <name>0 through <name><num-nodes - 1>.
 network:
+  docker: false
   name: test
   num_nodes: 4
   topology: mesh
diff --git a/start_testbed.py b/start_testbed.py
index 25fe39f..cd4ecbd 100755
--- a/start_testbed.py
+++ b/start_testbed.py
@@ -19,6 +19,7 @@ with open(args.file) as cfile:
     conf = yaml.load(cfile)
 
 ntwk = conf['network']
+use_docker = ntwk.get('docker', False)
 base_addr = reduce(
     lambda a,b : a*256+b,
     [ int(q) for q in ntwk['subnet_addr'].split('.') ]
@@ -27,7 +28,8 @@ subnet = ntwk['subnet_addr']+'/'+str(ntwk['subnet_len'])
 
 nodelist = list()
 
-retval = subprocess.call(['docker','pull',conf['image']])
+if use_docker:
+    retval = subprocess.call(['docker','pull',conf['image']])
 
 def make_ip(i):
     addr = base_addr + i
@@ -117,40 +119,52 @@ def start_node(base_name,i):
     global nodelist
     name = base_name + str(i)
 
-    # Start the container.
-    command = ['docker',
-               'run',
-               '-d',
-               '--name',
-               name
-              ]
-    if conf['docker_opts']:
-        command.extend(conf['docker_opts'].split())
-    command.append(conf['image'])
-    command.extend(conf['image_cmd'].split())
-    retval = subprocess.call(command)
+    if use_docker:
+        # Start the container.
+        command = ['docker',
+                   'run',
+                   '-d',
+                   '--name',
+                   name
+                  ]
+        if conf['docker_opts']:
+            command.extend(conf['docker_opts'].split())
+        command.append(conf['image'])
+        command.extend(conf['image_cmd'].split())
+        retval = subprocess.call(command)
 
     entry = dict()
     entry['name'] = name
     # Determine the IP address to use for this node.
     entry['addr'] = make_ip(i)
-    # Find the container's process ID.
-    entry['pid'] = subprocess.check_output([
-        'docker',
-        'inspect',
-        '-f',
-        '{{.State.Pid}}',
-        name
-        ]).strip()
+    if use_docker:
+        # Find the container's process ID.
+        entry['pid'] = subprocess.check_output([
+            'docker',
+            'inspect',
+            '-f',
+            '{{.State.Pid}}',
+            name
+            ]).strip()
  
-    # Set up a network namespace.
-    subprocess.call([
-        'sudo',
-        'ln',
-        '-s',
-        '/proc/{pid}/ns/net'.format(pid=entry['pid']),
-        '/var/run/netns/{name}'.format(name=name)
-       ])
+        # Set up a network namespace.
+        subprocess.call([
+            'sudo',
+            'ln',
+            '-s',
+            '/proc/{pid}/ns/net'.format(pid=entry['pid']),
+            '/var/run/netns/{name}'.format(name=name)
+           ])
+    else:
+        # Create the network namespace for the node, without docker.
+        subprocess.call([
+            'sudo',
+            'ip',
+            'netns',
+            'add',
+            name
+           ])
+        pass
 
     # Add the node's info to our list.
     nodelist.append(entry)
diff --git a/stop_testbed.py b/stop_testbed.py
index 7b02a02..aeff7b7 100755
--- a/stop_testbed.py
+++ b/stop_testbed.py
@@ -17,15 +17,20 @@ with open(args.file) as cfile:
     conf = yaml.load(cfile)
 
 ntwk = conf['network']
+use_docker = ntwk.get('docker', False)
 
 def stop_node(name,i):
     ctr_name = '{name}{i}'.format(name=name,i=i)
-    command = ['docker', 'kill', ctr_name ]
-    retval = subprocess.call(command)
-    command = ['docker', 'rm', ctr_name ]
-    retval = subprocess.call(command)
-    command = ['sudo', 'rm', '/var/run/netns/'+ctr_name]
-    retval = subprocess.call(command)
+    if use_docker:
+        command = ['docker', 'kill', ctr_name ]
+        retval = subprocess.call(command)
+        command = ['docker', 'rm', ctr_name ]
+        retval = subprocess.call(command)
+        command = ['sudo', 'rm', '/var/run/netns/'+ctr_name]
+        retval = subprocess.call(command)
+    else:
+        command = ['sudo', 'ip', 'netns', 'delete', ctr_name]
+        retval = subprocess.call(command)
 
 for i in range(ntwk['num_nodes']):
     stop_node(ntwk['name'],i)
-- 
GitLab