linux/{node,application}
[nepi.git] / nepi / resources / linux / node.py
index 32b590e..168686c 100644 (file)
@@ -25,6 +25,7 @@ from nepi.util.sshfuncs import ProcStatus
 
 import collections
 import os
+import stat
 import random
 import re
 import tempfile
@@ -298,7 +299,7 @@ class LinuxNode(ResourceManager):
 
         if out.find("Debian") == 0: 
             self._os = OSType.DEBIAN
-        elif out.find("Ubuntu") ==0:
+        elif out.find("Ubuntu") == 0:
             self._os = OSType.UBUNTU
         elif out.find("Fedora release") == 0:
             self._os = OSType.FEDORA
@@ -334,7 +335,7 @@ class LinuxNode(ResourceManager):
 
     @property
     def use_deb(self):
-        return (self.os & (OSType.DEBIAN|OSType.UBUNTU))
+        return (self.os & (OSType.DEBIAN | OSType.UBUNTU))
 
     @property
     def use_rpm(self):
@@ -505,9 +506,10 @@ class LinuxNode(ResourceManager):
 
         (out, err), proc = self.execute(cmd, retry = 1, with_lock = True)
 
-    def search_for_child(self, pid, pids, ppid, family=[]):
+    def search_for_child(self, pid, pids, ppid, family=None):
         """ Recursive function to search for child. List A contains the pids and list B the parents (ppid)
         """
+        family = family if family is not None else []
         family.append(pid)
         for key, value in enumerate(ppid):
             if value == pid:
@@ -742,7 +744,7 @@ class LinuxNode(ResourceManager):
         return (out, err), proc
 
     def upload(self, src, dst, text = False, overwrite = True,
-               raise_on_error = True):
+               raise_on_error = True, executable = False):
         """ Copy content to destination
 
         src  string with the content to copy. Can be:
@@ -754,8 +756,9 @@ class LinuxNode(ResourceManager):
         dst  string with destination path on the remote host (remote is 
             always self.host)
 
-        text src is text input, it must be stored into a temp file before 
-        uploading
+        when src is text input, it gets stored into a temp file before 
+        uploading; in this case, and if executable is True, said temp file
+        is made executable, and thus uploaded file will be too
         """
         # If source is a string input 
         f = None
@@ -764,9 +767,15 @@ class LinuxNode(ResourceManager):
             # create a temporal file with the content to upload
             # in python3 we need to open in binary mode if str is bytes
             mode = 'w' if isinstance(src, str) else 'wb'
-            f = tempfile.NamedTemporaryFile(mode=mode, delete=False)
+            f = tempfile.NamedTemporaryFile(mode = mode, delete = False)
             f.write(src)
             f.close()
+            if executable:
+                # do something like chmod u+x
+                mode = os.stat(f.name).st_mode
+                mode |= stat.S_IXUSR
+                os.chmod(f.name, mode)
+                
             src = f.name
 
         # If dst files should not be overwritten, check that the files do not
@@ -907,18 +916,18 @@ class LinuxNode(ResourceManager):
         return self.execute(cmd, with_lock = True)
     
     def run_and_wait(self, command, home, 
-                     shfile="cmd.sh",
-                     env=None,
-                     overwrite=True,
-                     wait_run=True,
-                     pidfile="pidfile", 
-                     ecodefile="exitcode", 
-                     stdin=None, 
-                     stdout="stdout", 
-                     stderr="stderr", 
-                     sudo=False,
-                     tty=False,
-                     raise_on_error=True):
+                     shfile = "cmd.sh",
+                     env = None,
+                     overwrite = True,
+                     wait_run = True,
+                     pidfile = "pidfile", 
+                     ecodefile = "exitcode", 
+                     stdin = None, 
+                     stdout = "stdout", 
+                     stderr = "stderr", 
+                     sudo = False,
+                     tty = False,
+                     raise_on_error = True):
         """
         Uploads the 'command' to a bash script in the host.
         Then runs the script detached in background in the host, and
@@ -1000,10 +1009,10 @@ class LinuxNode(ResourceManager):
         return ExitCode.ERROR
 
     def upload_command(self, command, 
-                       shfile="cmd.sh",
-                       ecodefile="exitcode",
-                       overwrite=True,
-                       env=None):
+                       shfile = "cmd.sh",
+                       ecodefile = "exitcode",
+                       overwrite = True,
+                       env = None):
         """ Saves the command as a bash script file in the remote host, and
         forces to save the exit code of the command execution to the ecodefile
         """
@@ -1013,7 +1022,7 @@ class LinuxNode(ResourceManager):
             
         # The exit code of the command will be stored in ecodefile
         command = " {{ {command} }} ; echo $? > {ecodefile} ;"\
-                  .format(command=command, ecodefile=ecodefile)
+                  .format(command = command, ecodefile = ecodefile)
 
         # Export environment
         environ = self.format_environment(env)
@@ -1021,9 +1030,9 @@ class LinuxNode(ResourceManager):
         # Add environ to command
         command = environ + command
 
-        return self.upload(command, shfile, text=True, overwrite=overwrite)
+        return self.upload(command, shfile, text = True, overwrite = overwrite)
 
-    def format_environment(self, env, inline=False):
+    def format_environment(self, env, inline = False):
         """ Formats the environment variables for a command to be executed
         either as an inline command
         (i.e. export PYTHONPATH=src/..; export LALAL= ..;python script.py) or 
@@ -1176,7 +1185,7 @@ class LinuxNode(ResourceManager):
 
         command = []
         for d in dests:
-            command.append(" [ -f {dst} ] && echo '{dst}' ".format(dst=d) )
+            command.append(" [ -f {dst} ] && echo '{dst}' ".format(dst = d) )
 
         command = ";".join(command)