X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fplanetlab%2Ftap.py;h=6d1be501db703d046209fb94f441c7507960781f;hb=1e2eb157cb569e9c28a5b7888ed97076d27414cb;hp=9fdd5f08d0c8ff5008c692317750310c0cbf0e3a;hpb=8b192f1c0cc55e5bc847ce40436ab55ddce0585c;p=nepi.git diff --git a/src/nepi/resources/planetlab/tap.py b/src/nepi/resources/planetlab/tap.py index 9fdd5f08..6d1be501 100644 --- a/src/nepi/resources/planetlab/tap.py +++ b/src/nepi/resources/planetlab/tap.py @@ -18,7 +18,7 @@ # Author: Alina Quereilhac from nepi.execution.attribute import Attribute, Flags, Types -from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \ +from nepi.execution.resource import clsinit_copy, ResourceState, \ reschedule_delay from nepi.resources.linux.application import LinuxApplication from nepi.resources.planetlab.node import PlanetlabNode @@ -36,39 +36,41 @@ PYTHON_VSYS_VERSION = "1.0" @clsinit_copy class PlanetlabTap(LinuxApplication): _rtype = "PlanetlabTap" + _help = "Creates a TAP device on a PlanetLab host" + _backend = "planetlab" @classmethod def _register_attributes(cls): ip4 = Attribute("ip4", "IPv4 Address", - flags = Flags.ExecReadOnly) + flags = Flags.Design) mac = Attribute("mac", "MAC Address", - flags = Flags.ExecReadOnly) + flags = Flags.Design) prefix4 = Attribute("prefix4", "IPv4 network prefix", type = Types.Integer, - flags = Flags.ExecReadOnly) + flags = Flags.Design) mtu = Attribute("mtu", "Maximum transmition unit for device", type = Types.Integer) devname = Attribute("deviceName", "Name of the network interface (e.g. eth0, wlan0, etc)", - flags = Flags.ReadOnly) + flags = Flags.NoWrite) up = Attribute("up", "Link up", type = Types.Bool) snat = Attribute("snat", "Set SNAT=1", type = Types.Bool, - flags = Flags.ExecReadOnly) + flags = Flags.Design) pointopoint = Attribute("pointopoint", "Peer IP address", - flags = Flags.ExecReadOnly) + flags = Flags.Design) tear_down = Attribute("tearDown", "Bash script to be executed before " + \ "releasing the resource", - flags = Flags.ExecReadOnly) + flags = Flags.Design) cls._register_attribute(ip4) cls._register_attribute(mac) @@ -86,7 +88,7 @@ class PlanetlabTap(LinuxApplication): @property def node(self): - node = self.get_connected(PlanetlabNode.rtype()) + node = self.get_connected(PlanetlabNode.get_rtype()) if node: return node[0] return None @@ -127,11 +129,17 @@ class PlanetlabTap(LinuxApplication): stop_command = self.replace_paths(self._stop_command) self.node.upload(stop_command, os.path.join(self.app_home, "stop.sh"), - text = True, - overwrite = False) + text = True, + # Overwrite file every time. + # The stop.sh has the path to the socket, wich should change + # on every experiment run. + overwrite = True) def upload_start_command(self): - super(PlanetlabTap, self).upload_start_command() + # Overwrite file every time. + # The stop.sh has the path to the socket, wich should change + # on every experiment run. + super(PlanetlabTap, self).upload_start_command(overwrite = True) # We want to make sure the device is up and running # before the deploy finishes (so things will be ready @@ -142,10 +150,10 @@ class PlanetlabTap(LinuxApplication): self._run_in_background() # Retrive if_name - if_name = self._wait_if_name() + if_name = self.wait_if_name() self.set("deviceName", if_name) - def deploy(self): + def do_deploy(self): if not self.node or self.node.state < ResourceState.PROVISIONED: self.ec.schedule(reschedule_delay, self.deploy) else: @@ -158,43 +166,33 @@ class PlanetlabTap(LinuxApplication): if not self.get("install"): self.set("install", self._install) - try: - self.discover() - self.provision() - except: - self.fail() - raise - - self.debug("----- READY ---- ") - self._ready_time = tnow() - self._state = ResourceState.READY - - def start(self): - if self._state == ResourceState.READY: + self.do_discover() + self.do_provision() + + self.set_ready() + + 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') or '' - state = self.state - if state == ResourceState.STARTED: + if self.state == ResourceState.STARTED: self.info("Stopping command '%s'" % command) command = "bash %s" % os.path.join(self.app_home, "stop.sh") (out, err), proc = self.execute_command(command, blocking = True) - self._stop_time = tnow() - self._state = ResourceState.STOPPED + self.set_stopped() @property def state(self): @@ -208,19 +206,31 @@ class PlanetlabTap(LinuxApplication): if out.strip().find(self.get("deviceName")) == -1: # tap is not running is not running (socket not found) - self._state = ResourceState.FINISHED + self.set_stopped() self._last_state_check = tnow() return self._state - def _wait_if_name(self): + def do_release(self): + # Node needs to wait until all associated RMs are released + # to be released + from nepi.resources.linux.udptunnel import UdpTunnel + rms = self.get_connected(UdpTunnel.get_rtype()) + for rm in rms: + if rm.state < ResourceState.STOPPED: + self.ec.schedule(reschedule_delay, self.release) + return + + super(PlanetlabTap, self).do_release() + + def wait_if_name(self): """ Waits until the if_name file for the command is generated, and returns the if_name for the device """ if_name = None delay = 1.0 - for i in xrange(4): + for i in xrange(20): (out, err), proc = self.node.check_output(self.run_home, "if_name") if out: @@ -232,7 +242,6 @@ class PlanetlabTap(LinuxApplication): else: msg = "Couldn't retrieve if_name" self.error(msg, out, err) - self.fail() raise RuntimeError, msg return if_name