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') ),
)
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()
+
TUNIFACE = "TunInterface"
TAPIFACE = "TapInterface"
APPLICATION = "Application"
+CCNXDAEMON = "CCNxDaemon"
DEPENDENCY = "Dependency"
NEPIDEPENDENCY = "NepiDependency"
NS3DEPENDENCY = "NS3Dependency"
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)
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)
### 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)
}),
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
}),
"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,
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,
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),
"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,