class ExperimentControllerServer(BaseServer): def __init__(self, root_dir, log_level, experiment_xml, environment_setup, clean_root): super(ExperimentControllerServer, self).__init__(root_dir, log_level, environment_setup = environment_setup, clean_root = clean_root) self._experiment_xml = experiment_xml self._experiment = None def post_daemonize(self): from nepi.core.execute import ExperimentController self._experiment = ExperimentController(self._experiment_xml, root_dir = self._root_dir) @Marshalling.handles(GUIDS) @Marshalling.args() @Marshalling.retval( Marshalling.pickled_data ) def guids(self): return self._experiment.guids @Marshalling.handles(STARTED_TIME) @Marshalling.args() @Marshalling.retval( Marshalling.pickled_data ) def started_time(self): return self._experiment.started_time @Marshalling.handles(STOPPED_TIME) @Marshalling.args() @Marshalling.retval( Marshalling.pickled_data ) def stopped_time(self): return self._experiment.stopped_time @Marshalling.handles(XML) @Marshalling.args() @Marshalling.retval() def experiment_design_xml(self): return self._experiment.experiment_design_xml @Marshalling.handles(EXEC_XML) @Marshalling.args() @Marshalling.retval() def experiment_execute_xml(self): return self._experiment.experiment_execute_xml @Marshalling.handles(TRACE) @Marshalling.args(int, str, Marshalling.base64_data) @Marshalling.retval() def trace(self, guid, trace_id, attribute): return str(self._experiment.trace(guid, trace_id, attribute)) @Marshalling.handles(TRACES_INFO) @Marshalling.args() @Marshalling.retval( Marshalling.pickled_data ) def traces_info(self): return self._experiment.traces_info() @Marshalling.handles(FINISHED) @Marshalling.args(int) @Marshalling.retval(Marshalling.bool) def is_finished(self, guid): return self._experiment.is_finished(guid) @Marshalling.handles(STATUS) @Marshalling.args(int) @Marshalling.retval(int) def status(self, guid): return self._experiment.status(guid) @Marshalling.handles(GET) @Marshalling.args(int, Marshalling.base64_data, str) @Marshalling.retval( Marshalling.pickled_data ) def get(self, guid, name, time): return self._experiment.get(guid, name, time) @Marshalling.handles(SET) @Marshalling.args(int, Marshalling.base64_data, Marshalling.pickled_data, str) @Marshalling.retvoid def set(self, guid, name, value, time): self._experiment.set(guid, name, value, time) @Marshalling.handles(START) @Marshalling.args() @Marshalling.retvoid def start(self): self._experiment.start() @Marshalling.handles(STOP) @Marshalling.args() @Marshalling.retvoid def stop(self): self._experiment.stop() @Marshalling.handles(RECOVER) @Marshalling.args() @Marshalling.retvoid def recover(self): self._experiment.recover() @Marshalling.handles(SHUTDOWN) @Marshalling.args() @Marshalling.retvoid def shutdown(self): self._experiment.shutdown() @Marshalling.handles(GET_TESTBED_ID) @Marshalling.args(int) @Marshalling.retval() def get_testbed_id(self, guid): return self._experiment.get_testbed_id(guid) @Marshalling.handles(GET_FACTORY_ID) @Marshalling.args(int) @Marshalling.retval() def get_factory_id(self, guid): return self._experiment.get_factory_id(guid) @Marshalling.handles(GET_TESTBED_VERSION) @Marshalling.args(int) @Marshalling.retval() def get_testbed_version(self, guid): return self._experiment.get_testbed_version(guid)
def create_experiment_controller(xml, access_config = None): mode = None launch = True log_level = DC.ERROR_LEVEL if access_config: (mode, launch, root_dir, log_level, communication, user, host, port, key, agent, sudo, environment_setup, clean_root) \ = get_access_config_params(access_config) os.environ["NEPI_CONTROLLER_LOGLEVEL"] = log_level if not mode or mode == DC.MODE_SINGLE_PROCESS: from nepi.core.execute import ExperimentController if not access_config or not access_config.has_attribute(DC.ROOT_DIRECTORY): root_dir = TempDir() else: root_dir = PermDir(access_config.get_attribute_value(DC.ROOT_DIRECTORY)) controller = ExperimentController(xml, root_dir.path) # inject reference to temporary dir, so that it gets cleaned # up at destruction time. controller._tempdir = root_dir if not launch: # try to recover controller.recover() return controller elif mode == DC.MODE_DAEMON: try: return ExperimentControllerProxy(root_dir, log_level, experiment_xml = xml, communication = communication, host = host, port = port, user = user, ident_key = key, agent = agent, sudo = sudo, launch = launch, environment_setup = environment_setup, clean_root = clean_root) except: if not launch: # Maybe controller died, recover from persisted testbed information if possible controller = ExperimentControllerProxy(root_dir, log_level, experiment_xml = xml, communication = communication, host = host, port = port, user = user, ident_key = key, agent = agent, sudo = sudo, launch = True, environment_setup = environment_setup, clean_root = clean_root) controller.recover() return controller else: raise raise RuntimeError("Unsupported access configuration '%s'" % mode)
def _test_recover(self, daemonize_testbed, controller_access_configuration, environ=None, use_sfa=False): pl, exp = self.make_experiment_desc(use_sfa) pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) node1 = pl.create("Node") node2 = pl.create("Node") node1.set_attribute_value("hostname", self.host1) node2.set_attribute_value("hostname", self.host2) iface1 = pl.create("NodeInterface") iface2 = pl.create("NodeInterface") inet = pl.create("Internet") node1.connector("devs").connect(iface1.connector("node")) node2.connector("devs").connect(iface2.connector("node")) iface1.connector("inet").connect(inet.connector("devs")) iface2.connector("inet").connect(inet.connector("devs")) tap1 = pl.create("TapInterface") tap2 = pl.create("TapInterface") node1.connector("devs").connect(tap1.connector("node")) node2.connector("devs").connect(tap2.connector("node")) tap1.connector("udp").connect(tap2.connector("udp")) tap1ip = tap1.add_address() tap1ip.set_attribute_value("Address", "192.168.2.2") tap1ip.set_attribute_value("NetPrefix", 24) tap1ip.set_attribute_value("Broadcast", False) tap2ip = tap2.add_address() tap2ip.set_attribute_value("Address", "192.168.2.3") tap2ip.set_attribute_value("NetPrefix", 24) tap2ip.set_attribute_value("Broadcast", False) app = pl.create("Application") app.set_attribute_value("command", "ping -qc10 192.168.2.3") app.enable_trace("stdout") app.connector("node").connect(node1.connector("apps")) if daemonize_testbed: pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON) inst_root_dir = os.path.join(self.root_dir, "instance") os.mkdir(inst_root_dir) pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir) pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL) if environ: pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, environ) xml = exp.to_xml() if controller_access_configuration: controller = proxy.create_experiment_controller( xml, controller_access_configuration) else: controller = ExperimentController(xml, self.root_dir) try: controller.start() # purposedly break connection controller = None # recover if controller_access_configuration: controller_access_configuration.set_attribute_value( DC.RECOVER, True) controller = proxy.create_experiment_controller( None, controller_access_configuration) else: controller = ExperimentController(None, self.root_dir) controller.recover() while not controller.is_finished(app.guid): time.sleep(0.5) ping_result = controller.trace(app.guid, "stdout") comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time \d*ms.* """ self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result) finally: if controller is not None: try: controller.stop() except: import traceback traceback.print_exc() try: controller.shutdown() except: import traceback traceback.print_exc()
def _test_recover(self, daemonize_testbed, controller_access_configuration, environ=None, use_sfa=False): pl, exp = self.make_experiment_desc(use_sfa) pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) node1 = pl.create("Node") node2 = pl.create("Node") node1.set_attribute_value("hostname", self.host1) node2.set_attribute_value("hostname", self.host2) iface1 = pl.create("NodeInterface") iface2 = pl.create("NodeInterface") inet = pl.create("Internet") node1.connector("devs").connect(iface1.connector("node")) node2.connector("devs").connect(iface2.connector("node")) iface1.connector("inet").connect(inet.connector("devs")) iface2.connector("inet").connect(inet.connector("devs")) tap1 = pl.create("TapInterface") tap2 = pl.create("TapInterface") node1.connector("devs").connect(tap1.connector("node")) node2.connector("devs").connect(tap2.connector("node")) tap1.connector("udp").connect(tap2.connector("udp")) tap1ip = tap1.add_address() tap1ip.set_attribute_value("Address", "192.168.2.2") tap1ip.set_attribute_value("NetPrefix", 24) tap1ip.set_attribute_value("Broadcast", False) tap2ip = tap2.add_address() tap2ip.set_attribute_value("Address", "192.168.2.3") tap2ip.set_attribute_value("NetPrefix", 24) tap2ip.set_attribute_value("Broadcast", False) app = pl.create("Application") app.set_attribute_value("command", "ping -qc10 192.168.2.3") app.enable_trace("stdout") app.connector("node").connect(node1.connector("apps")) if daemonize_testbed: pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON) inst_root_dir = os.path.join(self.root_dir, "instance") os.mkdir(inst_root_dir) pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir) pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL) if environ: pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, environ) xml = exp.to_xml() if controller_access_configuration: controller = proxy.create_experiment_controller(xml, controller_access_configuration) else: controller = ExperimentController(xml, self.root_dir) try: controller.start() # purposedly break connection controller = None # recover if controller_access_configuration: controller_access_configuration.set_attribute_value(DC.RECOVER, True) controller = proxy.create_experiment_controller(None, controller_access_configuration) else: controller = ExperimentController(None, self.root_dir) controller.recover() while not controller.is_finished(app.guid): time.sleep(0.5) ping_result = controller.trace(app.guid, "stdout") comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time \d*ms.* """ self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result) finally: if controller is not None: try: controller.stop() except: import traceback traceback.print_exc() try: controller.shutdown() except: import traceback traceback.print_exc()
def _test_plpl_crossconnect(self, proto, recover=False): pl, pl2, exp = self.make_experiment_desc() if recover: pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) pl2.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) # Create PL node, ifaces, assign addresses node1, iface1, tap1, tap1ip, inet1 = self.make_pl_tapnode(pl, self.plcvnet1 + ".2", self.host1pl1, "node1") node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode(pl2, self.plcvnet2 + ".3", self.host1pl2, "node2") # Connect the two tap1.connector(proto).connect(tap2.connector(proto)) tap1.set_attribute_value("pointopoint", "{#[node2tap].addr[0].[Address]#}") tap2.set_attribute_value("pointopoint", "{#[node1tap].addr[0].[Address]#}") # Disable encryption for GRE if proto == "gre": tap1.set_attribute_value("tun_cipher", "PLAIN") tap2.set_attribute_value("tun_cipher", "PLAIN") # Create PlanetLab ping application, pinging the from one PL to another ping = pl.create("Application") ping.set_attribute_value("command", "ping -qc10 {#[node2tap].addr[0].[Address]#}") ping.enable_trace("stdout") ping.enable_trace("stderr") ping.connector("node").connect(node1.connector("apps")) comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time \d*ms.* """ xml = exp.to_xml() try: controller = ExperimentController(xml, self.root_dir) controller.start() if recover: controller = None controller = ExperimentController(None, self.root_dir) controller.recover() while not controller.is_finished(ping.guid): time.sleep(0.5) ping_result = controller.trace(ping.guid, "stdout") tap_trace = controller.trace(tap1.guid, "packets") tap2_trace = controller.trace(tap2.guid, "packets") finally: if controller is not None: try: controller.stop() except: import traceback traceback.print_exc() try: controller.shutdown() except: import traceback traceback.print_exc() # asserts at the end, to make sure there's proper cleanup self.assertTrue( re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n%s\nTap trace at origin:\n%s\nTap trace at destination:\n%s\n" % (ping_result, tap_trace, tap2_trace), )
def _test_plpl_crossconnect(self, proto, recover=False): pl, pl2, exp = self.make_experiment_desc() if recover: pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) pl2.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER) # Create PL node, ifaces, assign addresses node1, iface1, tap1, tap1ip, inet1 = self.make_pl_tapnode( pl, self.plcvnet1 + ".2", self.host1pl1, "node1") node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode( pl2, self.plcvnet2 + ".3", self.host1pl2, "node2") # Connect the two tap1.connector(proto).connect(tap2.connector(proto)) tap1.set_attribute_value("pointopoint", "{#[node2tap].addr[0].[Address]#}") tap2.set_attribute_value("pointopoint", "{#[node1tap].addr[0].[Address]#}") # Disable encryption for GRE if proto == "gre": tap1.set_attribute_value("tun_cipher", "PLAIN") tap2.set_attribute_value("tun_cipher", "PLAIN") # Create PlanetLab ping application, pinging the from one PL to another ping = pl.create("Application") ping.set_attribute_value( "command", "ping -qc10 {#[node2tap].addr[0].[Address]#}") ping.enable_trace("stdout") ping.enable_trace("stderr") ping.connector("node").connect(node1.connector("apps")) comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time \d*ms.* """ xml = exp.to_xml() try: controller = ExperimentController(xml, self.root_dir) controller.start() if recover: controller = None controller = ExperimentController(None, self.root_dir) controller.recover() while not controller.is_finished(ping.guid): time.sleep(0.5) ping_result = controller.trace(ping.guid, "stdout") tap_trace = controller.trace(tap1.guid, "packets") tap2_trace = controller.trace(tap2.guid, "packets") finally: if controller is not None: try: controller.stop() except: import traceback traceback.print_exc() try: controller.shutdown() except: import traceback traceback.print_exc() # asserts at the end, to make sure there's proper cleanup self.assertTrue( re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n%s\nTap trace at origin:\n%s\nTap trace at destination:\n%s\n" % (ping_result, tap_trace, tap2_trace))