Ns-3/linux tunnel experiments
[nepi.git] / src / nepi / resources / linux / application.py
index af6ae34..89a9cfb 100644 (file)
@@ -20,7 +20,7 @@
 from nepi.execution.attribute import Attribute, Flags, Types
 from nepi.execution.trace import Trace, TraceAttr
 from nepi.execution.resource import ResourceManager, clsinit_copy, \
-        ResourceState, reschedule_delay
+        ResourceState
 from nepi.resources.linux.node import LinuxNode
 from nepi.util.sshfuncs import ProcStatus
 from nepi.util.timefuncs import tnow, tdiffsec
@@ -81,9 +81,9 @@ class LinuxApplication(ResourceManager):
 
     """
 
-    _rtype = "LinuxApplication"
+    _rtype = "linux::Application"
     _help = "Runs an application on a Linux host with a BASH command "
-    _backend_type = "linux"
+    _platform = "linux"
 
     @classmethod
     def _register_attributes(cls):
@@ -173,7 +173,9 @@ class LinuxApplication(ResourceManager):
         super(LinuxApplication, self).__init__(ec, guid)
         self._pid = None
         self._ppid = None
+        self._node = None
         self._home = "app-%s" % self.guid
+
         # whether the command should run in foreground attached
         # to a terminal
         self._in_foreground = False
@@ -194,9 +196,16 @@ class LinuxApplication(ResourceManager):
 
     @property
     def node(self):
-        node = self.get_connected(LinuxNode.get_rtype())
-        if node: return node[0]
-        return None
+        if not self._node:
+            node = self.get_connected(LinuxNode.get_rtype())
+            if not node: 
+                msg = "Application %s guid %d NOT connected to Node" % (
+                        self._rtype, self.guid)
+                raise RuntimeError, msg
+
+            self._node = node[0]
+
+        return self._node
 
     @property
     def app_home(self):
@@ -360,6 +369,13 @@ class LinuxApplication(ResourceManager):
 
     def execute_deploy_command(self, command, prefix="deploy"):
         if command:
+            # replace application specific paths in the command
+            command = self.replace_paths(command)
+            
+            # replace application specific paths in the environment
+            env = self.get("env")
+            env = env and self.replace_paths(env)
+
             # Upload the command to a bash script and run it
             # in background ( but wait until the command has
             # finished to continue )
@@ -511,7 +527,7 @@ class LinuxApplication(ResourceManager):
         node = self.node
         if not node or node.state < ResourceState.READY:
             self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state )
-            self.ec.schedule(reschedule_delay, self.deploy)
+            self.ec.schedule(self.reschedule_delay, self.deploy)
         else:
             command = self.get("command") or ""
             self.info("Deploying command '%s' " % command)
@@ -628,11 +644,13 @@ class LinuxApplication(ResourceManager):
                     (out, err), proc = self.node.kill(self.pid, self.ppid,
                             sudo = self._sudo_kill)
 
+                    """
                     # TODO: check if execution errors occurred
                     if (proc and proc.poll()) or err:
                         msg = " Failed to STOP command '%s' " % self.get("command")
                         self.error(msg, out, err)
-        
+                    """
+
             super(LinuxApplication, self).do_stop()
 
     def do_release(self):
@@ -702,38 +720,49 @@ class LinuxApplication(ResourceManager):
         return self._state
 
     def execute_command(self, command, 
-            env = None,
-            sudo = False,
-            forward_x11 = False,
-            blocking = False):
+            env=None,
+            sudo=False,
+            tty=False,
+            forward_x11=False,
+            blocking=False):
 
         environ = ""
         if env:
-            environ = self.node.format_environment(env, inline = True)
+            environ = self.node.format_environment(env, inline=True)
         command = environ + command
         command = self.replace_paths(command)
 
         return self.node.execute(command,
-                sudo = sudo,
-                forward_x11 = forward_x11,
-                blocking = blocking)
+                sudo=sudo,
+                tty=tty,
+                forward_x11=forward_x11,
+                blocking=blocking)
 
-    def replace_paths(self, command):
+    def replace_paths(self, command, node=None, app_home=None, run_home=None):
         """
         Replace all special path tags with shell-escaped actual paths.
         """
+        if not node:
+            node=self.node
+
+        if not app_home:
+            app_home=self.app_home
+
+        if not run_home:
+            run_home = self.run_home
+
         return ( command
-            .replace("${USR}", self.node.usr_dir)
-            .replace("${LIB}", self.node.lib_dir)
-            .replace("${BIN}", self.node.bin_dir)
-            .replace("${SRC}", self.node.src_dir)
-            .replace("${SHARE}", self.node.share_dir)
-            .replace("${EXP}", self.node.exp_dir)
-            .replace("${EXP_HOME}", self.node.exp_home)
-            .replace("${APP_HOME}", self.app_home)
-            .replace("${RUN_HOME}", self.run_home)
-            .replace("${NODE_HOME}", self.node.node_home)
-            .replace("${HOME}", self.node.home_dir)
+            .replace("${USR}", node.usr_dir)
+            .replace("${LIB}", node.lib_dir)
+            .replace("${BIN}", node.bin_dir)
+            .replace("${SRC}", node.src_dir)
+            .replace("${SHARE}", node.share_dir)
+            .replace("${EXP}", node.exp_dir)
+            .replace("${EXP_HOME}", node.exp_home)
+            .replace("${APP_HOME}", app_home)
+            .replace("${RUN_HOME}", run_home)
+            .replace("${NODE_HOME}", node.node_home)
+            .replace("${HOME}", node.home_dir)
             )
 
     def valid_connection(self, guid):