X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fcore%2Ftestbed_impl.py;h=d27588dcd1d2a15baacd7441ffd926aafb592a30;hb=1cf85539204432589217de408cd2eb37e3d68e6a;hp=f496f4a6fad705a77c65b76fc6788e6d9fed3549;hpb=7de95b1721fedbafccd70624cfbaa71755c5369c;p=nepi.git diff --git a/src/nepi/core/testbed_impl.py b/src/nepi/core/testbed_impl.py index f496f4a6..d27588dc 100644 --- a/src/nepi/core/testbed_impl.py +++ b/src/nepi/core/testbed_impl.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- from nepi.core import execute @@ -12,6 +11,7 @@ from nepi.util.parallel import ParallelRun import collections import copy +import logging class TestbedController(execute.TestbedController): def __init__(self, testbed_id, testbed_version): @@ -49,6 +49,9 @@ class TestbedController(execute.TestbedController): self._factories[factory.factory_id] = factory self._attributes = self._metadata.testbed_attributes() self._root_directory = None + + # Logging + self._logger = logging.getLogger("nepi.core.testbed_impl") @property def root_directory(self): @@ -147,12 +150,14 @@ class TestbedController(execute.TestbedController): self._add_address[guid] = list() self._add_address[guid].append((address, netprefix, broadcast)) - def defer_add_route(self, guid, destination, netprefix, nexthop, metric = 0): + def defer_add_route(self, guid, destination, netprefix, nexthop, + metric = 0, device = None): self._validate_guid(guid) self._validate_allow_routes(guid) if not guid in self._add_route: self._add_route[guid] = list() - self._add_route[guid].append((destination, netprefix, nexthop, metric)) + self._add_route[guid].append((destination, netprefix, nexthop, + metric, device)) def do_setup(self): self._root_directory = self._attributes.\ @@ -213,6 +218,8 @@ class TestbedController(execute.TestbedController): self._status = TS.STATUS_CONNECTED def _do_in_factory_order(self, action, order, postaction = None, poststep = None): + logger = self._logger + guids = collections.defaultdict(list) # order guids (elements) according to factory_id for guid, factory_id in self._create.iteritems(): @@ -232,28 +239,47 @@ class TestbedController(execute.TestbedController): # configure action factory = self._factories[factory_id] - if not getattr(factory, action): + if isinstance(action, basestring) and not getattr(factory, action): continue def perform_action(guid): - getattr(factory, action)(self, guid) + if isinstance(action, basestring): + getattr(factory, action)(self, guid) + else: + action(self, guid) if postaction: postaction(self, guid) # perform the action on all elements, in parallel if so requested if runner: + logger.debug("TestbedController: Starting parallel %s", action) runner.start() + for guid in guids[factory_id]: if runner: + logger.debug("TestbedController: Scheduling %s on %s", action, guid) runner.put(perform_action, guid) else: + logger.debug("TestbedController: Performing %s on %s", action, guid) perform_action(guid) + + # sync if runner: - runner.join() + runner.sync() # post hook if poststep: for guid in guids[factory_id]: - poststep(self, guid) + if runner: + logger.debug("TestbedController: Scheduling post-%s on %s", action, guid) + runner.put(poststep, self, guid) + else: + logger.debug("TestbedController: Performing post-%s on %s", action, guid) + poststep(self, guid) + + # sync + if runner: + runner.join() + logger.debug("TestbedController: Finished parallel %s", action) @staticmethod def do_poststep_preconfigure(self, guid): @@ -304,6 +330,14 @@ class TestbedController(execute.TestbedController): cross_connector_type_name, True) if connect_code: + if hasattr(connect_code, "func"): + func_name = connect_code.func.__name__ + elif hasattr(connect_code, "__name__"): + func_name = connect_code.__name__ + else: + func_name = repr(connect_code) + self._logger.debug("Cross-connect - guid: %d, connect_code: %s " % ( + guid, func_name)) elem_cross_data = cross_data[cross_testbed_guid][cross_guid] connect_code(self, guid, elem_cross_data) @@ -432,6 +466,9 @@ class TestbedController(execute.TestbedController): if status_function: return status_function(self, guid) return AS.STATUS_UNDETERMINED + + def testbed_status(self): + return self._status def trace(self, guid, trace_id, attribute='value'): if attribute == 'value': @@ -440,6 +477,8 @@ class TestbedController(execute.TestbedController): fd.close() elif attribute == 'path': content = self.trace_filepath(guid, trace_id) + elif attribute == 'filename': + content = self.trace_filename(guid, trace_id) else: content = None return content @@ -465,6 +504,13 @@ class TestbedController(execute.TestbedController): """ raise NotImplementedError + def trace_filename(self, guid, trace_id): + """ + Return a trace's file name, for TestbedController's default + implementation of trace() + """ + raise NotImplementedError + #shutdown: NotImplementedError def get_connected(self, guid, connector_type_name, @@ -531,7 +577,7 @@ class TestbedController(execute.TestbedController): def _validate_testbed_value(self, name, value): if not self._attributes.is_attribute_value_valid(name, value): - raise AttributeError("Invalid value %s for testbed attribute %s" % \ + raise AttributeError("Invalid value %r for testbed attribute %s" % \ (value, name)) def _validate_box_attribute(self, guid, name): @@ -543,7 +589,7 @@ class TestbedController(execute.TestbedController): def _validate_box_value(self, guid, name, value): factory = self._get_factory(guid) if not factory.box_attributes.is_attribute_value_valid(name, value): - raise AttributeError("Invalid value %s for attribute %s" % \ + raise AttributeError("Invalid value %r for attribute %s" % \ (value, name)) def _validate_factory_attribute(self, guid, name): @@ -555,7 +601,7 @@ class TestbedController(execute.TestbedController): def _validate_factory_value(self, guid, name, value): factory = self._get_factory(guid) if not factory.is_attribute_value_valid(name, value): - raise AttributeError("Invalid value %s for attribute %s" % \ + raise AttributeError("Invalid value %r for attribute %s" % \ (value, name)) def _validate_trace(self, guid, trace_name):