Modified FailureManager to abort only when critical resources fail
[nepi.git] / src / nepi / resources / linux / udptunnel.py
index 349ddc2..1efe230 100644 (file)
@@ -18,8 +18,8 @@
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
 from nepi.execution.attribute import Attribute, Flags, Types
-from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
-        reschedule_delay
+from nepi.execution.resource import clsinit_copy, ResourceState, \
+        reschedule_delay, failtrap
 from nepi.resources.linux.application import LinuxApplication
 from nepi.util.sshfuncs import ProcStatus
 from nepi.util.timefuncs import tnow, tdiffsec
@@ -31,6 +31,9 @@ import time
 @clsinit_copy
 class UdpTunnel(LinuxApplication):
     _rtype = "UdpTunnel"
+    _help = "Constructs a tunnel between two Linux endpoints using a UDP connection "
+    _backend = "linux"
+
 
     @classmethod
     def _register_attributes(cls):
@@ -138,7 +141,6 @@ class UdpTunnel(LinuxApplication):
         msg = " Failed to connect endpoints "
         
         if proc.poll():
-            self.fail()
             self.error(msg, out, err)
             raise RuntimeError, msg
     
@@ -151,7 +153,6 @@ class UdpTunnel(LinuxApplication):
             (out, err), proc = endpoint.node.check_errors(self.run_home(endpoint))
             # Out is what was written in the stderr file
             if err:
-                self.fail()
                 msg = " Failed to start command '%s' " % command
                 self.error(msg, out, err)
                 raise RuntimeError, msg
@@ -160,6 +161,7 @@ class UdpTunnel(LinuxApplication):
         port = self.wait_local_port(endpoint)
         return (port, pid, ppid)
 
+    @failtrap
     def provision(self):
         # create run dir for tunnel on each node 
         self.endpoint1.node.mkdir(self.run_home(self.endpoint1))
@@ -187,46 +189,37 @@ class UdpTunnel(LinuxApplication):
        
         self.info("Provisioning finished")
  
-        self.debug("----- READY ---- ")
-        self._provision_time = tnow()
-        self._state = ResourceState.PROVISIONED
+        self.set_provisioned()
 
+    @failtrap
     def deploy(self):
         if (not self.endpoint1 or self.endpoint1.state < ResourceState.READY) or \
             (not self.endpoint2 or self.endpoint2.state < ResourceState.READY):
             self.ec.schedule(reschedule_delay, self.deploy)
         else:
-            try:
-                self.discover()
-                self.provision()
-            except:
-                self.fail()
-                raise
+            self.discover()
+            self.provision()
  
             self.debug("----- READY ---- ")
-            self._ready_time = tnow()
-            self._state = ResourceState.READY
+            self.set_ready()
 
+    @failtrap
     def start(self):
-        if self._state == ResourceState.READY:
+        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
 
-    # XXX: Leaves process unkilled!! 
-    #       Implement another mechanism to kill the tunnel!
+    @failtrap
     def stop(self):
         """ Stops application execution
         """
         if self.state == ResourceState.STARTED:
-            stopped = True
             self.info("Stopping tunnel")
     
             # Only try to kill the process if the pid and ppid
@@ -241,12 +234,9 @@ class UdpTunnel(LinuxApplication):
                     # check if execution errors occurred
                     msg = " Failed to STOP tunnel"
                     self.error(msg, err1, err2)
-                    self.fail()
-                    stopped = False
+                    raise RuntimeError, msg
 
-            if stopped:
-                self._stop_time = tnow()
-                self._state = ResourceState.STOPPED
+            self.set_stopped()
 
     @property
     def state(self):
@@ -280,7 +270,7 @@ class UdpTunnel(LinuxApplication):
                             self.error(msg, err1, err2)
                             self.fail()
                         else:
-                            self._state = ResourceState.FINISHED
+                            self.set_finished()
 
                 self._last_state_check = tnow()
 
@@ -288,11 +278,15 @@ class UdpTunnel(LinuxApplication):
 
     def wait_local_port(self, endpoint):
         """ Waits until the local_port file for the endpoint is generated, 
-            and returns the port number """
+        and returns the port number 
+        
+        """
         return self.wait_file(endpoint, "local_port")
 
     def wait_result(self, endpoint):
-        """ Waits until the return code file for the endpoint is generated """ 
+        """ Waits until the return code file for the endpoint is generated 
+        
+        """ 
         return self.wait_file(endpoint, "ret_file")
  
     def wait_file(self, endpoint, filename):
@@ -313,7 +307,6 @@ class UdpTunnel(LinuxApplication):
         else:
             msg = "Couldn't retrieve %s" % filename
             self.error(msg, out, err)
-            self.fail()
             raise RuntimeError, msg
 
         return result