1 # -*- coding: utf-8 -*-
3 from constants import TESTBED_ID, TESTBED_VERSION
4 from nepi.core import testbed_impl
5 from nepi.util.constants import TIME_NOW
10 class TestbedController(testbed_impl.TestbedController):
11 from nepi.util.tunchannel_impl import TunChannel
14 'TunChannel' : TunChannel,
17 LOCAL_TYPES = tuple(LOCAL_FACTORIES.values())
19 class HostLock(object):
20 # This class is used as a lock to prevent concurrency issues with more
21 # than one instance of netns running in the same machine. Both in
22 # different processes or different threads.
24 processcond = threading.Condition()
26 def __init__(self, lockfile):
27 processcond = self.__class__.processcond
32 while self.__class__.taken:
34 self.__class__.taken = True
38 self.lockfile = lockfile
39 fcntl.flock(self.lockfile, fcntl.LOCK_EX)
42 processcond = self.__class__.processcond
46 assert self.__class__.taken, "HostLock unlocked without being locked!"
48 fcntl.flock(self.lockfile, fcntl.LOCK_UN)
51 self.__class__.taken = False
57 super(TestbedController, self).__init__(TESTBED_ID, TESTBED_VERSION)
59 self._home_directory = None
61 self._netns_lock = open("/tmp/nepi-netns-lock","a")
64 return self.HostLock(self._netns_lock)
67 def home_directory(self):
68 return self._home_directory
75 self._home_directory = self._attributes.\
76 get_attribute_value("homeDirectory")
78 home = os.path.normpath(self.home_directory)
79 if not os.path.exists(home):
80 os.makedirs(home, 0755)
82 self._netns = self._load_netns_module()
83 super(TestbedController, self).do_setup()
87 super(TestbedController, self).do_create()
89 def set(self, guid, name, value, time = TIME_NOW):
90 super(TestbedController, self).set(guid, name, value, time)
91 # TODO: take on account schedule time for the task
92 factory_id = self._create[guid]
93 factory = self._factories[factory_id]
94 if factory_id not in self.LOCAL_FACTORIES and \
95 factory.box_attributes.is_attribute_metadata(name):
97 element = self._elements.get(guid)
99 setattr(element, name, value)
101 def get(self, guid, name, time = TIME_NOW):
102 value = super(TestbedController, self).get(guid, name, time)
103 # TODO: take on account schedule time for the task
104 factory_id = self._create[guid]
105 factory = self._factories[factory_id]
106 if factory_id not in self.LOCAL_FACTORIES and \
107 factory.box_attributes.is_attribute_metadata(name):
109 element = self._elements.get(guid)
111 return getattr(element, name)
112 except (KeyError, AttributeError):
115 def action(self, time, guid, action):
116 raise NotImplementedError
119 for guid, traces in self._traces.iteritems():
120 for trace_id, (trace, filename) in traces.iteritems():
121 if hasattr(trace, "close"):
123 for guid, element in self._elements.iteritems():
124 if isinstance(element, self.TunChannel):
127 factory_id = self._create[guid]
128 if factory_id == "Node":
130 self._elements.clear()
132 def trace_filepath(self, guid, trace_id, filename = None):
134 (trace, filename) = self._traces[guid][trace_id]
135 return os.path.join(self.home_directory, filename)
137 def trace_filename(self, guid, trace_id):
138 (trace, filename) = self._traces[guid][trace_id]
142 def follow_trace(self, guid, trace_id, trace, filename):
143 if not guid in self._traces:
144 self._traces[guid] = dict()
145 self._traces[guid][trace_id] = (trace, filename)
147 def _load_netns_module(self):
148 # TODO: Do something with the configuration!!!
151 netns_mod = sys.modules["netns"]
153 enable_debug = self._attributes.get_attribute_value("enableDebug")
155 netns_mod.environ.set_log_level(netns_mod.environ.LOG_DEBUG)