Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
    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()
Пример #4
0
    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()
Пример #5
0
    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),
        )
Пример #6
0
    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))