2 # -*- coding: utf-8 -*-
4 from constants import TESTBED_ID, TESTBED_VERSION
5 from nepi.core import testbed_impl
6 from nepi.util.constants import TIME_NOW
11 class TestbedController(testbed_impl.TestbedController):
12 from nepi.util.tunchannel_impl import TunChannel
15 'ns3::Nepi::TunChannel' : TunChannel,
18 LOCAL_TYPES = tuple(LOCAL_FACTORIES.values())
20 class HostLock(object):
21 # This class is used as a lock to prevent concurrency issues with more
22 # than one instance of netns running in the same machine. Both in
23 # different processes or different threads.
25 processcond = threading.Condition()
27 def __init__(self, lockfile):
28 processcond = self.__class__.processcond
33 while self.__class__.taken:
35 self.__class__.taken = True
39 self.lockfile = lockfile
40 fcntl.flock(self.lockfile, fcntl.LOCK_EX)
43 processcond = self.__class__.processcond
47 assert self.__class__.taken, "HostLock unlocked without being locked!"
49 fcntl.flock(self.lockfile, fcntl.LOCK_UN)
52 self.__class__.taken = False
58 super(TestbedController, self).__init__(TESTBED_ID, TESTBED_VERSION)
60 self._home_directory = None
62 self._netns_lock = open("/tmp/nepi-netns-lock","a")
65 return self.HostLock(self._netns_lock)
68 def home_directory(self):
69 return self._home_directory
76 self._home_directory = self._attributes.\
77 get_attribute_value("homeDirectory")
79 home = os.path.normpath(self.home_directory)
80 if not os.path.exists(home):
81 os.makedirs(home, 0755)
83 self._netns = self._load_netns_module()
84 super(TestbedController, self).do_setup()
88 super(TestbedController, self).do_create()
90 def set(self, guid, name, value, time = TIME_NOW):
91 super(TestbedController, self).set(guid, name, value, time)
92 # TODO: take on account schedule time for the task
93 factory_id = self._create[guid]
94 factory = self._factories[factory_id]
95 if factory_id not in self.LOCAL_FACTORIES and \
96 factory.box_attributes.is_attribute_metadata(name):
98 element = self._elements.get(guid)
100 setattr(element, name, value)
102 def get(self, guid, name, time = TIME_NOW):
103 value = super(TestbedController, self).get(guid, name, time)
104 # TODO: take on account schedule time for the task
105 factory_id = self._create[guid]
106 factory = self._factories[factory_id]
107 if factory_id not in self.LOCAL_FACTORIES and \
108 factory.box_attributes.is_attribute_metadata(name):
110 element = self._elements.get(guid)
112 return getattr(element, name)
113 except (KeyError, AttributeError):
116 def action(self, time, guid, action):
117 raise NotImplementedError
120 for guid, traces in self._traces.iteritems():
121 for trace_id, (trace, filename) in traces.iteritems():
122 if hasattr(trace, "close"):
124 for guid, element in self._elements.iteritems():
125 if isinstance(element, self.TunChannel):
128 factory_id = self._create[guid]
129 if factory_id == "Node":
131 self._elements.clear()
133 def trace_filepath(self, guid, trace_id, filename = None):
135 (trace, filename) = self._traces[guid][trace_id]
136 return os.path.join(self.home_directory, filename)
138 def trace_filename(self, guid, trace_id):
139 (trace, filename) = self._traces[guid][trace_id]
143 def follow_trace(self, guid, trace_id, trace, filename):
144 if not guid in self._traces:
145 self._traces[guid] = dict()
146 self._traces[guid][trace_id] = (trace, filename)
148 def _load_netns_module(self):
149 # TODO: Do something with the configuration!!!
152 netns_mod = sys.modules["netns"]
154 enable_debug = self._attributes.get_attribute_value("enableDebug")
156 netns_mod.environ.set_log_level(netns_mod.environ.LOG_DEBUG)