X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Flinux%2Fccn%2Ffibentry.py;h=4b7e9c48dd4d75de628e4d2ec31532062d081b09;hb=cb816db417dff4d0f985455c1d7cbd261fd40f9b;hp=3c82a0382f2fdcd8ef9f927ffdfe308c5198b30a;hpb=3ec952ecb376f66a3c083249c6deec2f19b82947;p=nepi.git diff --git a/src/nepi/resources/linux/ccn/fibentry.py b/src/nepi/resources/linux/ccn/fibentry.py index 3c82a038..4b7e9c48 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,132 +50,176 @@ 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", "Continuous ping to the peer end") + 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._traceroute = None + self._ccnd = None @property def ccnd(self): - ccnd = self.get_connected(LinuxCCND.rtype()) - if ccnd: return ccnd[0] - return None + if not self._ccnd: + ccnd = self.get_connected(LinuxCCND.get_rtype()) + if ccnd: + self._ccnd = ccnd[0] + + return self._ccnd + + @property + def ping(self): + if not self._ping: + from nepi.resources.linux.ping import LinuxPing + ping = self.get_connected(LinuxPing.get_rtype()) + if ping: + self._ping = ping[0] + + return self._ping + + @property + def traceroute(self): + if not self._traceroute: + from nepi.resources.linux.traceroute import LinuxTraceroute + traceroute = self.get_connected(LinuxTraceroute.get_rtype()) + if traceroute: + self._traceroute = traceroute[0] + + return self._traceroute @property def node(self): 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": + if not self.ping: + return None + return self.ec.trace(self.ping.guid, "stdout", attr, block, offset) + + if name == "traceroute": + if not self.traceroute: + return None + return self.ec.trace(self.traceroute.guid, "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: - try: - if not self.get("command"): - self.set("command", self._start_command) + if not self.get("ip"): + host = self.get("host") + ip = socket.gethostbyname(host) + self.set("ip", ip) - if not self.get("env"): - self.set("env", self._environment) + if not self.get("command"): + self.set("command", self._start_command) - command = self.get("command") + if not self.get("env"): + self.set("env", self._environment) - self.info("Deploying command '%s' " % command) + command = self.get("command") + + self.info("Deploying command '%s' " % command) - self.discover() - self.provision() - self.configure() - except: - self.fail() - raise - - 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") - if command: - # 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) - - (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 - + # 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 not self.trace_enabled("ping"): - return - - command = """ping %s""" % self.get("host") - (out, err), proc = self.node.run(command, self.run_home, - stdout = "ping", - stderr = "ping_stderr", - pidfile = "ping_pidfile") - - # Wait for pid file to be generated - pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile") - - # If the process is not running, check for error information - # on the remote machine - if not pid or not ppid: - (out, err), proc = self.node.check_errors(self.run_home, - stderr = "ping_pidfile") - - # Out is what was written in the stderr file - if err: - self.fail() - msg = " Failed to deploy ping trace command '%s' " % command - self.error(msg, out, err) - raise RuntimeError, msg - - def start(self): - if self._state in [ResourceState.READY, ResourceState.STARTED]: + if self.trace_enabled("ping") and not self.ping: + self.info("Configuring PING trace") + ping = self.ec.register_resource("LinuxPing") + self.ec.set(ping, "printTimestamp", True) + self.ec.set(ping, "target", self.get("host")) + self.ec.set(ping, "earlyStart", True) + self.ec.register_connection(ping, self.node.guid) + self.ec.register_connection(ping, self.guid) + # schedule ping deploy + self.ec.deploy(guids=[ping], group = self.deployment_group) + + if self.trace_enabled("traceroute") and not self.traceroute: + self.info("Configuring TRACEROUTE trace") + traceroute = self.ec.register_resource("LinuxTraceroute") + self.ec.set(traceroute, "printTimestamp", True) + self.ec.set(traceroute, "continuous", True) + self.ec.set(traceroute, "target", self.get("host")) + self.ec.set(traceroute, "earlyStart", True) + self.ec.register_connection(traceroute, self.node.guid) + self.ec.register_connection(traceroute, self.guid) + # schedule mtr deploy + self.ec.deploy(guids=[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') @@ -181,35 +227,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 - - # now stop the ping trace - if self.trace_enabled("ping"): - pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile") - (out, err), proc = self.node.kill(pid, ppid) + (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 }) @@ -217,14 +256,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 })