From: Alina Quereilhac Date: Mon, 9 Apr 2012 15:06:30 +0000 (+0200) Subject: Added ccnxdaemon box to PlanetLab X-Git-Tag: nepi-3.0.0~163^2~23 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=ca623bb12ac6ed6e8260196cd4b59f710edddc0a;p=nepi.git Added ccnxdaemon box to PlanetLab --- diff --git a/src/nepi/testbeds/planetlab/application.py b/src/nepi/testbeds/planetlab/application.py index e198a5f6..32e21cff 100644 --- a/src/nepi/testbeds/planetlab/application.py +++ b/src/nepi/testbeds/planetlab/application.py @@ -206,10 +206,13 @@ class Dependency(object): raise RuntimeError, "Failed to set up application %s: %s %s" % (self.home_path, e.args[0], e.args[1],) if self.stdin: + stdin = self.stdin + if not os.path.isfile(stdin): + stdin = cStringIO.StringIO(self.stdin) + # Write program input try: - self._popen_scp( - cStringIO.StringIO(self.stdin), + self._popen_scp(stdin, '%s@%s:%s' % (self.node.slicename, self.node.hostname, os.path.join(self.home_path, 'stdin') ), ) @@ -1089,3 +1092,109 @@ class YumDependency(Dependency): r')', re.I) return badre.search(out) or badre.search(err) or self.node.check_bad_host(out,err) + + +class CCNxDaemon(Application): + """ + An application also has dependencies, but also a command to be ran and monitored. + + It adds the output of that command as traces. + """ + + def __init__(self, api=None): + super(CCNxDaemon,self).__init__(api) + + # Attributes + self.command = None + self.routes = None + + self.buildDepends = 'make gcc development-tools openssl-devel expat-devel libpcap-devel libxml2-devel' + + # We have to download the sources, untar, build... + ccnx_source_url = "http://www.ccnx.org/releases/ccnx-0.5.1.tar.gz" + + self.build = ( + " ( " + " cd .. && " + " test -d ccnx-src/build/bin " + " ) || ( " + # Not working, rebuild + "wget -q -c -O ccnx-src.tar.gz %(ccnx_source_url)s &&" + "mkdir -p ccnx-src && " + "tar xzf ccnx-src.tar.gz --strip-components=1 -C ccnx-src && " + "cd ccnx-src && " + "mkdir -p build/include &&" + "mkdir -p build/lib &&" + "mkdir -p build/bin &&" + "I=$PWD/build && " + "INSTALL_BASE=$I ./configure &&" + "make && make install" + " )" % dict( + ccnx_source_url = server.shell_escape(ccnx_source_url), + )) + + self.install = ( + " ( " + " cd .. && " + " test -d ${SOURCES}/bin " + " ) || ( " + " test -d ${BUILD}/ccnx-src/build/bin && " + " cp -r ${BUILD}/ccnx-src/build/bin ${SOURCES}" + " )" + ) + + self.env['PATH'] = "$PATH:${SOURCES}/bin" + + def start(self): + # Start will be invoked in prestart step + routes = "" + if self.ccnroutes: + routes = map(lambda route: "ccndc add ccnx:/ %s" % route, + self.ccnroutes.split("|")) + routes = " && " + " && ".join(routes) + self.command = "ccndstart %s" % routes + + super(CCNxDaemon, self).start() + + def kill(self): + self._logger.info("Killing %s", self) + + cmd = self._replace_paths("${SOURCES}/bin/ccndstop") + command = cStringIO.StringIO() + command.write(cmd) + command.seek(0) + + try: + self._popen_scp( + command, + '%s@%s:%s' % (self.node.slicename, self.node.hostname, + os.path.join(self.home_path, "kill.sh")) + ) + except RuntimeError, e: + raise RuntimeError, "Failed to kill ccndxdaemon: %s %s" \ + % (e.args[0], e.args[1],) + + + script = "bash ./kill.sh" + (out,err),proc = rspawn.remote_spawn( + script, + pidfile = 'kill-pid', + home = self.home_path, + stdin = '/dev/null', + stdout = 'killlog', + stderr = rspawn.STDOUT, + + host = self.node.hostname, + port = None, + user = self.node.slicename, + agent = None, + ident_key = self.node.ident_path, + server_key = self.node.server_key, + hostip = self.node.hostip, + ) + + if proc.wait(): + raise RuntimeError, "Failed to kill cnnxdaemon: %s %s" % (out,err,) + + super(CCNxDaemon, self).kill() + diff --git a/src/nepi/testbeds/planetlab/execute.py b/src/nepi/testbeds/planetlab/execute.py index a8151586..e1095ee4 100644 --- a/src/nepi/testbeds/planetlab/execute.py +++ b/src/nepi/testbeds/planetlab/execute.py @@ -684,6 +684,7 @@ class TestbedController(testbed_impl.TestbedController): Parallel(metadata.NS3DEPENDENCY), Parallel(metadata.DEPENDENCY), Parallel(metadata.APPLICATION), + Parallel(metadata.CCNXDAEMON), ]) # Tunnels are not harmed by configuration after @@ -754,8 +755,10 @@ class TestbedController(testbed_impl.TestbedController): def _make_internet(self, parameters): return self._make_generic(parameters, self._interfaces.Internet) - def _make_application(self, parameters): - return self._make_generic(parameters, self._app.Application) + def _make_application(self, parameters, clazz = None): + if not clazz: + clazz = self._app.Application + return self._make_generic(parameters, clazz) def _make_dependency(self, parameters): return self._make_generic(parameters, self._app.Dependency) diff --git a/src/nepi/testbeds/planetlab/metadata.py b/src/nepi/testbeds/planetlab/metadata.py index 09800a04..7b6e3f92 100644 --- a/src/nepi/testbeds/planetlab/metadata.py +++ b/src/nepi/testbeds/planetlab/metadata.py @@ -22,6 +22,7 @@ NODEIFACE = "NodeInterface" TUNIFACE = "TunInterface" TAPIFACE = "TapInterface" APPLICATION = "Application" +CCNXDAEMON = "CCNxDaemon" DEPENDENCY = "Dependency" NEPIDEPENDENCY = "NepiDependency" NS3DEPENDENCY = "NS3Dependency" @@ -202,7 +203,7 @@ def connect_dep(testbed_instance, node_guid, app_guid, node=None, app=None): if app.depends: node.required_packages.update(set( app.depends.split() )) - + if app.add_to_path: if app.home_path and app.home_path not in node.pythonpath: node.pythonpath.append(app.home_path) @@ -323,6 +324,16 @@ def create_application(testbed_instance, guid): testbed_instance.elements[guid] = element +def create_ccnxdaemon(testbed_instance, guid): + parameters = testbed_instance._get_parameters(guid) + element = testbed_instance._make_application(parameters, + clazz = testbed_instance._app.CCNxDaemon ) + + # Just inject configuration stuff + element.home_path = "nepi-ccnd-%s" % (guid,) + + testbed_instance.elements[guid] = element + def create_dependency(testbed_instance, guid): parameters = testbed_instance._get_parameters(guid) element = testbed_instance._make_dependency(parameters) @@ -389,6 +400,15 @@ def create_netpipe(testbed_instance, guid): ### Start/Stop functions ### +def prestart_ccnxdaemon(testbed_instance, guid): + # ccnx daemon needs to start before the rest of the + # ccn applications + start_application(testbed_instance, guid) + +def stop_ccndaemon(testbed_instance, guid): + app = testbed_instance.elements[guid] + app.kill() + def start_application(testbed_instance, guid): parameters = testbed_instance._get_parameters(guid) traces = testbed_instance._get_traces(guid) @@ -696,7 +716,7 @@ connections = [ }), dict({ "from": (TESTBED_ID, NODE, "apps"), - "to": (TESTBED_ID, (APPLICATION, MULTICASTANNOUNCER), "node"), + "to": (TESTBED_ID, (APPLICATION, CCNXDAEMON, MULTICASTANNOUNCER), "node"), "init_code": connect_dep, "can_cross": False }), @@ -1106,7 +1126,14 @@ attributes = dict({ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, "validation_function": validation.is_string }), - "sudo": dict({ + "ccnroutes": dict({ + "name": "ccnroutes", + "help": "Route can be static (e.g. udp ip) or multicast (e.g. udp 224.0.0.204 2869). To separate different route use '|' ", + "type": Attribute.STRING, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "validation_function": validation.is_string + }), + "sudo": dict({ "name": "sudo", "help": "Run with root privileges", "type": Attribute.BOOL, @@ -1313,14 +1340,15 @@ create_order = [ INTERNET, NODE, NODEIFACE, CLASSQUEUEFILTER, TOSQUEUEFILTER, MULTICASTANNOUNCER, MULTICASTFORWARDER, MULTICASTROUTER, TUNFILTER, TAPIFACE, TUNIFACE, NETPIPE, - NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, APPLICATION ] + NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, CCNXDAEMON, APPLICATION ] configure_order = [ INTERNET, Parallel(NODE), NODEIFACE, Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER), Parallel(TAPIFACE), Parallel(TUNIFACE), NETPIPE, - Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ] + Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON), + Parallel(APPLICATION)] # Start (and prestart) node after ifaces, because the node needs the ifaces in order to set up routes start_order = [ INTERNET, @@ -1328,11 +1356,13 @@ start_order = [ INTERNET, Parallel(TAPIFACE), Parallel(TUNIFACE), Parallel(NODE), NETPIPE, Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER), - Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ] + Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON), + Parallel(APPLICATION)] # cleanup order shutdown_order = [ Parallel(APPLICATION), + Parallel (CCNXDAEMON), Parallel(MULTICASTROUTER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTANNOUNCER), Parallel(TAPIFACE), Parallel(TUNIFACE), Parallel(NETPIPE), Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), @@ -1526,6 +1556,20 @@ factories_info = dict({ "traces": ["stdout", "stderr", "buildlog", "output"], "tags": [tags.APPLICATION], }), + + CCNXDAEMON: dict({ + "help": "CCNx daemon", + "category": FC.CATEGORY_APPLICATIONS, + "create_function": create_ccnxdaemon, + "prestart_function": prestart_ccnxdaemon, + "status_function": status_application, + "stop_function": stop_application, + "configure_function": configure_application, + "box_attributes": ["ccnroutes"], + "connector_types": ["node"], + "traces": ["stdout", "stderr", "buildlog", "output"], + "tags": [tags.APPLICATION], + }), DEPENDENCY: dict({ "help": "Requirement for package or application to be installed on some node", "category": FC.CATEGORY_APPLICATIONS,