X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Flinux%2Fccn%2Ffibentry.py;h=dca91c244c6a047e08a0c4ce96246e7f39d4d894;hb=e0447bc7e91d169d6d88498981421572d939b6fb;hp=2af3b2cfc579a9c4a887a7c9f4304d65c96d7e56;hpb=46da4690c5120b820385fd47b7fbf995c1bff2a0;p=nepi.git diff --git a/src/nepi/resources/linux/ccn/fibentry.py b/src/nepi/resources/linux/ccn/fibentry.py index 2af3b2cf..dca91c24 100644 --- a/src/nepi/resources/linux/ccn/fibentry.py +++ b/src/nepi/resources/linux/ccn/fibentry.py @@ -26,6 +26,8 @@ from nepi.resources.linux.ccn.ccnd import LinuxCCND from nepi.util.timefuncs import tnow import os +import socket +import time # TODO: Add rest of options for ccndc!!! @@ -40,7 +42,7 @@ class LinuxFIBEntry(LinuxApplication): uri = Attribute("uri", "URI prefix to match and route for this FIB entry", default = "ccnx:/", - flags = Flags.ExecReadOnly) + flags = Flags.Design) protocol = Attribute("protocol", "Transport protocol used in network connection to peer " @@ -48,29 +50,47 @@ class LinuxFIBEntry(LinuxApplication): type = Types.Enumerate, default = "udp", allowed = ["udp", "tcp"], - flags = Flags.ExecReadOnly) + flags = Flags.Design) host = Attribute("host", - "Peer host used in network connection for this FIB entry. ", - flags = Flags.ExecReadOnly) + "Peer hostname used in network connection for this FIB entry. ", + flags = Flags.Design) port = Attribute("port", "Peer port address used in network connection to peer " "for this FIB entry.", - flags = Flags.ExecReadOnly) + flags = Flags.Design) + + ip = Attribute("ip", + "Peer host public IP used in network connection for this FIB entry. ", + flags = Flags.Design) cls._register_attribute(uri) cls._register_attribute(protocol) cls._register_attribute(host) cls._register_attribute(port) + cls._register_attribute(ip) + + @classmethod + def _register_traces(cls): + ping = Trace("ping", "Ping to the peer end") + mtr = Trace("mtr", "Mtr to the peer end") + traceroute = Trace("traceroute", "Tracerout to the peer end") + + cls._register_trace(ping) + cls._register_trace(mtr) + cls._register_trace(traceroute) def __init__(self, ec, guid): super(LinuxFIBEntry, self).__init__(ec, guid) self._home = "fib-%s" % self.guid + self._ping = None + self._mtr = None + self._traceroute = None @property def ccnd(self): - ccnd = self.get_connected(LinuxCCND.rtype()) + ccnd = self.get_connected(LinuxCCND.get_rtype()) if ccnd: return ccnd[0] return None @@ -79,49 +99,108 @@ class LinuxFIBEntry(LinuxApplication): if self.ccnd: return self.ccnd.node return None - def deploy(self): + def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0): + if name == "ping": + return self.ec.trace(self._ping, "stdout", attr, block, offset) + if name == "mtr": + return self.ec.trace(self._mtr, "stdout", attr, block, offset) + if name == "traceroute": + return self.ec.trace(self._traceroute, "stdout", attr, block, offset) + + return super(LinuxFIBEntry, self).trace(name, attr, block, offset) + + def do_deploy(self): # Wait until associated ccnd is provisioned if not self.ccnd or self.ccnd.state < ResourceState.READY: # ccnr needs to wait until ccnd is deployed and running self.ec.schedule(reschedule_delay, self.deploy) else: - command = self._start_command - env = self._environment + if not self.get("ip"): + host = self.get("host") + ip = socket.gethostbyname(host) + self.set("ip", ip) + + if not self.get("command"): + self.set("command", self._start_command) - self.set("command", command) - self.set("env", env) + if not self.get("env"): + self.set("env", self._environment) + + command = self.get("command") self.info("Deploying command '%s' " % command) - - # create run dir for application - self.node.mkdir(self.run_home) - - (out, err), proc = self.execute_command(command, env) - - if proc.poll(): - self._state = ResourceState.FAILED - msg = "Failed to execute command" - self.error(msg, out, err) - raise RuntimeError, msg - self.debug("----- READY ---- ") - self._ready_time = tnow() - self._state = ResourceState.READY + self.do_discover() + self.do_provision() + self.configure() + + self.set_ready() + + def upload_start_command(self): + command = self.get("command") + env = self.get("env") - def start(self): - if self._state in [ResourceState.READY, ResourceState.STARTED]: + # We want to make sure the FIB entries are created + # before the experiment starts. + # Run the command as a bash script in the background, + # in the host ( but wait until the command has + # finished to continue ) + env = env and self.replace_paths(env) + command = self.replace_paths(command) + + # ccndc seems to return exitcode OK even if a (dns) error + # occurred, so we need to account for this case here. + (out, err), proc = self.execute_command(command, + env, blocking = True) + + if proc.poll(): + msg = "Failed to execute command" + self.error(msg, out, err) + raise RuntimeError, msg + + def configure(self): + if self.trace_enabled("ping"): + self.info("Configuring PING trace") + self._ping = self.ec.register_resource("LinuxPing") + self.ec.set(self._ping, "printTimestamp", True) + self.ec.set(self._ping, "target", self.get("host")) + self.ec.register_connection(self._ping, self.node.guid) + # schedule ping deploy + self.ec.deploy(guids=[self._ping], group = self.deployment_group) + + if self.trace_enabled("mtr"): + self.info("Configuring MTR trace") + self._mtr = self.ec.register_resource("LinuxMtr") + self.ec.set(self._mtr, "noDns", True) + self.ec.set(self._mtr, "printTimestamp", True) + self.ec.set(self._mtr, "continuous", True) + self.ec.set(self._mtr, "target", self.get("host")) + self.ec.register_connection(self._mtr, self.node.guid) + # schedule mtr deploy + self.ec.deploy(guids=[self._mtr], group = self.deployment_group) + + if self.trace_enabled("traceroute"): + self.info("Configuring TRACEROUTE trace") + self._traceroute = self.ec.register_resource("LinuxTraceroute") + self.ec.set(self._traceroute, "printTimestamp", True) + self.ec.set(self._traceroute, "continuous", True) + self.ec.set(self._traceroute, "target", self.get("host")) + self.ec.register_connection(self._traceroute, self.node.guid) + # schedule mtr deploy + self.ec.deploy(guids=[self._traceroute], group = self.deployment_group) + + def do_start(self): + if self.state == ResourceState.READY: command = self.get("command") self.info("Starting command '%s'" % command) - self._start_time = tnow() - self._state = ResourceState.STARTED + self.set_started() else: msg = " Failed to execute command '%s'" % command self.error(msg, out, err) - self._state = ResourceState.FAILED raise RuntimeError, msg - def stop(self): + def do_stop(self): command = self.get('command') env = self.get('env') @@ -129,30 +208,28 @@ class LinuxFIBEntry(LinuxApplication): self.info("Stopping command '%s'" % command) command = self._stop_command - (out, err), proc = self.execute_command(command, env) - - if proc.poll(): - pass + (out, err), proc = self.execute_command(command, env, + blocking = True) - self._stop_time = tnow() - self._state = ResourceState.STOPPED + self.set_stopped() - @property - def state(self): - return self._state + if err: + msg = " Failed to execute command '%s'" % command + self.error(msg, out, err) + raise RuntimeError, msg @property def _start_command(self): uri = self.get("uri") or "" protocol = self.get("protocol") or "" - host = self.get("host") or "" + ip = self.get("ip") or "" port = self.get("port") or "" # add ccnx:/example.com/ udp 224.0.0.204 52428 return "ccndc add %(uri)s %(protocol)s %(host)s %(port)s" % ({ "uri" : uri, "protocol": protocol, - "host": host, + "host": ip, "port": port }) @@ -160,14 +237,14 @@ class LinuxFIBEntry(LinuxApplication): def _stop_command(self): uri = self.get("uri") or "" protocol = self.get("protocol") or "" - host = self.get("host") or "" + ip = self.get("ip") or "" port = self.get("port") or "" # add ccnx:/example.com/ udp 224.0.0.204 52428 return "ccndc del %(uri)s %(protocol)s %(host)s %(port)s" % ({ "uri" : uri, "protocol": protocol, - "host": host, + "host": ip, "port": port }) @@ -175,13 +252,6 @@ class LinuxFIBEntry(LinuxApplication): def _environment(self): return self.ccnd.path - def execute_command(self, command, env): - environ = self.node.format_environment(env, inline = True) - command = environ + command - command = self.replace_paths(command) - - return self.node.execute(command) - def valid_connection(self, guid): # TODO: Validate! return True