released to pypi nepi-3.2-pypi
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Thu, 9 Apr 2015 10:29:10 +0000 (12:29 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Thu, 9 Apr 2015 10:29:10 +0000 (12:29 +0200)
Makefile
README [new file with mode: 0644]
VERSION [new file with mode: 0644]
setup.py
src/nepi/resources/linux/node.py

index 01a1d3b..118c778 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -64,3 +64,18 @@ dist: MANIFEST
        ./setup.py sdist
 
 .PHONY: all clean distclean dist test coverage install MANIFEST
+
+########## for uploading onto pypi
+# use pypitest instead for tests (both entries need to be defined in your .pypirc)
+PYPI_TARGET=pypi
+PYPI_TARBALL_HOST=root@build.onelab.eu
+PYPI_TARBALL_TOPDIR=/build/nepi
+
+VERSIONTAG=$(shell cat VERSION)
+
+# run this only once the sources are in on the right tag
+pypi: 
+       setup.py sdist upload -r $(PYPI_TARGET)
+       ssh $(PYPI_TARBALL_HOST) mkdir -p $(PYPI_TARBALL_TOPDIR)/$(VERSIONTAG)
+       rsync -av dist/nepi-$(VERSIONTAG).tar.gz $(PYPI_TARBALL_HOST):$(PYPI_TARBALL_TOPDIR)/
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..aede580
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+NEPI is a Python-based library to model and run network experiments on a variety of network evaluation platforms, including PlanetLab, OMF wireless testbeds, ns-3 simulators, and others. It allows to specify resources to use in an experiment, to define experiment workflow constraints and to automate deployment, resource control and result collection.       
diff --git a/VERSION b/VERSION
new file mode 100644 (file)
index 0000000..a3ec5a4
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+3.2
index 7037c19..988b4bc 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -3,41 +3,52 @@
 from distutils.core import setup
 import sys
 
+
+with open('VERSION') as f:
+    version_tag = f.read().strip()
+with open("COPYING") as f:
+    license = f.read()
+with open("README") as f:
+    long_description = f.read()
+
 setup(
-        name        = "nepi",
-        version     = "nepi-3-dev",
-        description = "Network Experiment Management Framework",
-        author      = "Alina Quereilhac, Julien Tribino, Lucia Guevgeozian",
-        url         = "http://nepi.inria.fr",
-        license     = "GPLv2",
-        platforms   = "Linux, OSX",
-        packages    = [
-            "nepi",
-            "nepi.execution",
-            "nepi.resources",
-            "nepi.resources.all",
-            "nepi.resources.linux",
-            "nepi.resources.linux.ccn",
-            "nepi.resources.linux.ns3",
-            "nepi.resources.linux.ns3.ccn",
-            "nepi.resources.linux.netns",
-            "nepi.resources.netns",
-            "nepi.resources.ns3",
-            "nepi.resources.ns3.classes",
-            "nepi.resources.omf",
-            "nepi.resources.planetlab",
-            "nepi.resources.planetlab.ns3",
-            "nepi.resources.planetlab.openvswitch",
-            "nepi.util",
-            "nepi.util.parsers",
-            "nepi.data",
-            "nepi.data.processing",
-            "nepi.data.processing.ccn",
-            "nepi.data.processing.ping"],
-        package_dir = {"": "src"},
-        package_data = {
-            "nepi.resources.planetlab" : [ "scripts/*.py" ],
-            "nepi.resources.linux" : [ "scripts/*.py" ],
-            "nepi.resources.linux.ns3" : [ "dependencies/*.tar.gz" ]
-            }
-    )
+    name             = "nepi",
+    version          = version_tag,
+    description      = "Network Experiment Management Framework",
+    long_description = long_description,
+    license          = license,
+    author           = "Alina Quereilhac",
+    author_email     = "alina.quereilhac@inria.fr",
+    download_url     = "http://build.onelab.eu/nepi/nepi-{v}.tar.gz".format(v=version_tag),
+    url              = "http://nepi.inria.fr/",
+    platforms        = "Linux, OSX",
+    package_dir      = {"": "src"},
+    packages         = [
+        "nepi",
+        "nepi.execution",
+        "nepi.resources",
+        "nepi.resources.all",
+        "nepi.resources.linux",
+        "nepi.resources.linux.ccn",
+        "nepi.resources.linux.ns3",
+        "nepi.resources.linux.ns3.ccn",
+        "nepi.resources.linux.netns",
+        "nepi.resources.netns",
+        "nepi.resources.ns3",
+        "nepi.resources.ns3.classes",
+        "nepi.resources.omf",
+        "nepi.resources.planetlab",
+        "nepi.resources.planetlab.ns3",
+        "nepi.resources.planetlab.openvswitch",
+        "nepi.util",
+        "nepi.util.parsers",
+        "nepi.data",
+        "nepi.data.processing",
+        "nepi.data.processing.ccn",
+        "nepi.data.processing.ping"],
+    package_data     = {
+        "nepi.resources.planetlab" : [ "scripts/*.py" ],
+        "nepi.resources.linux" : [ "scripts/*.py" ],
+        "nepi.resources.linux.ns3" : [ "dependencies/*.tar.gz" ]
+    }
+)
index b0d63c9..0abbf8f 100644 (file)
@@ -17,8 +17,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
+from nepi.execution.resource import (ResourceManager, clsinit_copy, 
+                                     ResourceState)
 from nepi.resources.linux import rpmfuncs, debfuncs 
 from nepi.util import sshfuncs, execfuncs
 from nepi.util.sshfuncs import ProcStatus
@@ -147,77 +147,81 @@ class LinuxNode(ResourceManager):
 
     @classmethod
     def _register_attributes(cls):
-        hostname = Attribute("hostname", "Hostname of the machine",
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "hostname", "Hostname of the machine",
+            flags = Flags.Design))
 
-        username = Attribute("username", "Local account username", 
-                flags = Flags.Credential)
+        cls._register_attribute(Attribute(
+            "username", "Local account username", 
+            flags = Flags.Credential))
 
-        port = Attribute("port", "SSH port", flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "port", "SSH port",
+            flags = Flags.Design))
         
-        home = Attribute("home",
-                "Experiment home directory to store all experiment related files",
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "home",
+            "Experiment home directory to store all experiment related files",
+            flags = Flags.Design))
         
-        identity = Attribute("identity", "SSH identity file",
-                flags = Flags.Credential)
+        cls._register_attribute(Attribute(
+            "identity", "SSH identity file",
+            flags = Flags.Credential))
         
-        server_key = Attribute("serverKey", "Server public key", 
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "serverKey", "Server public key", 
+            flags = Flags.Design))
         
-        clean_home = Attribute("cleanHome", "Remove all nepi files and directories "
-                " from node home folder before starting experiment", 
-                type = Types.Bool,
-                default = False,
-                flags = Flags.Design)
-
-        clean_experiment = Attribute("cleanExperiment", "Remove all files and directories " 
-                " from a previous same experiment, before the new experiment starts", 
-                type = Types.Bool,
-                default = False,
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "cleanHome",
+            "Remove all nepi files and directories "
+            " from node home folder before starting experiment", 
+            type = Types.Bool,
+            default = False,
+            flags = Flags.Design))
+
+        cls._register_attribute(Attribute(
+            "cleanExperiment", "Remove all files and directories " 
+            " from a previous same experiment, before the new experiment starts", 
+            type = Types.Bool,
+            default = False,
+            flags = Flags.Design))
         
-        clean_processes = Attribute("cleanProcesses", 
-                "Kill all running processes before starting experiment",
-                type = Types.Bool,
-                default = False,
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "cleanProcesses", 
+            "Kill all running processes before starting experiment",
+            type = Types.Bool,
+            default = False,
+            flags = Flags.Design))
         
-        clean_processes_after = Attribute("cleanProcessesAfter", 
-                """Kill all running processes after starting experiment
-This might be dangerous when using user root""",
-                type = Types.Bool,
-                default = True,
-                flags = Flags.Design)
+        cls._register_attribute(Attribute(
+            "cleanProcessesAfter", 
+            """Kill all running processes after starting experiment
+            This might be dangerous when using user root""",
+            type = Types.Bool,
+            default = True,
+            flags = Flags.Design))
         
-        tear_down = Attribute("tearDown", "Bash script to be executed before " + \
-                "releasing the resource",
-                flags = Flags.Design)
-
-        gateway_user = Attribute("gatewayUser", "Gateway account username",
-                flags = Flags.Design)
-
-        gateway = Attribute("gateway", "Hostname of the gateway machine",
-                flags = Flags.Design)
-
-        ip = Attribute("ip", "Linux host public IP address. "
-                   "Must not be modified by the user unless hostname is 'localhost'",
-                    flags = Flags.Design)
-
-        cls._register_attribute(hostname)
-        cls._register_attribute(username)
-        cls._register_attribute(port)
-        cls._register_attribute(home)
-        cls._register_attribute(identity)
-        cls._register_attribute(server_key)
-        cls._register_attribute(clean_home)
-        cls._register_attribute(clean_experiment)
-        cls._register_attribute(clean_processes)
-        cls._register_attribute(clean_processes_after)
-        cls._register_attribute(tear_down)
-        cls._register_attribute(gateway_user)
-        cls._register_attribute(gateway)
-        cls._register_attribute(ip)
+        cls._register_attribute(Attribute(
+            "tearDown",
+            "Bash script to be executed before releasing the resource",
+            flags = Flags.Design))
+
+        cls._register_attribute(Attribute(
+            "gatewayUser",
+            "Gateway account username",
+            flags = Flags.Design))
+
+        cls._register_attribute(Attribute(
+            "gateway",
+            "Hostname of the gateway machine",
+            flags = Flags.Design))
+
+        cls._register_attribute(Attribute(
+            "ip",
+            "Linux host public IP address. "
+            "Must not be modified by the user unless hostname is 'localhost'",
+            flags = Flags.Design))
 
     def __init__(self, ec, guid):
         super(LinuxNode, self).__init__(ec, guid)
@@ -233,17 +237,17 @@ This might be dangerous when using user root""",
         # of a file or folder prior to its creation, and another 
         # application creating the same file or folder in between.
         self._node_lock = threading.Lock()
-    
+        
     def log_message(self, msg):
-        return " guid %d - host %s - %s " % (self.guid, 
-                self.get("hostname"), msg)
+        return " guid {} - host {} - {} "\
+            .format(self.guid, self.get("hostname"), msg)
 
     @property
     def home_dir(self):
         home = self.get("home") or ""
         if not home.startswith("/"):
-           home = os.path.join(self._home_dir, home) 
-        return home
+            home = os.path.join(self._home_dir, home) 
+            return home
 
     @property
     def nepi_home(self):
@@ -279,7 +283,7 @@ This might be dangerous when using user root""",
 
     @property
     def node_home(self):
-        return os.path.join(self.exp_home, "node-%d" % self.guid)
+        return os.path.join(self.exp_home, "node-{}".format(self.guid))
 
     @property
     def run_home(self):
@@ -312,7 +316,7 @@ This might be dangerous when using user root""",
         else:
             msg = "Unsupported OS"
             self.error(msg, out)
-            raise RuntimeError, "%s - %s " %( msg, out )
+            raise RuntimeError("{} - {} ".format(msg, out))
 
         return self._os
 
@@ -324,13 +328,13 @@ This might be dangerous when using user root""",
         out = ""
         try:
             (out, err), proc = self.execute("cat /etc/issue", 
-                    with_lock = True,
-                    blocking = True)
+                                            with_lock = True,
+                                            blocking = True)
         except:
             trace = traceback.format_exc()
-            msg = "Error detecting OS: %s " % trace
+            msg = "Error detecting OS: {} ".format(trace)
             self.error(msg, out, err)
-        
+    
         return out
 
     @property
@@ -348,7 +352,7 @@ This might be dangerous when using user root""",
     def do_provision(self):
         # check if host is alive
         if not self.is_alive():
-            msg = "Deploy failed. Unresponsive node %s" % self.get("hostname")
+            msg = "Deploy failed. Unresponsive node {}".format(self.get("hostname"))
             self.error(msg)
             raise RuntimeError, msg
 
@@ -359,16 +363,16 @@ This might be dangerous when using user root""",
 
         if self.get("cleanHome"):
             self.clean_home()
+            
         if self.get("cleanExperiment"):
             self.clean_experiment()
-    
+            
         # Create shared directory structure and node home directory
         paths = [self.lib_dir, 
-            self.bin_dir, 
-            self.src_dir, 
-            self.share_dir, 
-            self.node_home]
+                 self.bin_dir, 
+                 self.src_dir, 
+                 self.share_dir, 
+                 self.node_home]
 
         self.mkdir(paths)
 
@@ -379,7 +383,7 @@ This might be dangerous when using user root""",
                 self.set("ip", ip)
             except:
                 if self.get("gateway") is None:
-                    msg = "Local DNS can not resolve hostname %s" % self.get("hostname") 
+                    msg = "Local DNS can not resolve hostname {}".format(self.get("hostname"))
                     self.error(msg)
 
         super(LinuxNode, self).do_provision()
@@ -431,8 +435,8 @@ This might be dangerous when using user root""",
         
         if self.get("username") != 'root':
             cmd = ("sudo -S killall tcpdump || /bin/true ; " +
-                "sudo -S kill -9 $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " +
-                "sudo -S killall -u %s || /bin/true ; " % self.get("username"))
+                   "sudo -S kill -9 $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " +
+                   "sudo -S killall -u {} || /bin/true ; ".format(self.get("username")))
         else:
             if self.state >= ResourceState.READY:
                 import pickle
@@ -448,14 +452,14 @@ This might be dangerous when using user root""",
                     kill_pids = ' '.join(dict(kill_pids).keys())
 
                     cmd = ("killall tcpdump || /bin/true ; " +
-                        "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " +
-                        "kill %s || /bin/true ; " % kill_pids)
+                           "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " +
+                           "kill {} || /bin/true ; ".format(kill_pids))
                 else:
                     cmd = ("killall tcpdump || /bin/true ; " +
-                        "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ")
+                           "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ")
             else:
                 cmd = ("killall tcpdump || /bin/true ; " +
-                    "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ")
+                       "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ")
 
         (out, err), proc = self.execute(cmd, retry = 1, with_lock = True)
 
@@ -464,8 +468,8 @@ This might be dangerous when using user root""",
         """
         self.info("Cleaning up home")
         
-        cmd = "cd %s ; find . -maxdepth 1 -name \.nepi -execdir rm -rf {} + " % (
-                self.home_dir )
+        cmd = "cd {} ; find . -maxdepth 1 -name \.nepi -execdir rm -rf {} + "\
+              .format(self.home_dir)
 
         return self.execute(cmd, with_lock = True)
 
@@ -476,33 +480,33 @@ This might be dangerous when using user root""",
         """
         self.info("Cleaning up experiment files")
         
-        cmd = "cd %s ; find . -maxdepth 1 -name '%s' -execdir rm -rf {} + " % (
-                self.exp_dir,
-                self.ec.exp_id )
-            
+        cmd = "cd {} ; find . -maxdepth 1 -name '{}' -execdir rm -rf {} + "\
+              .format(self.exp_dir, self.ec.exp_id)
+        
         return self.execute(cmd, with_lock = True)
 
     def execute(self, command,
-            sudo = False,
-            env = None,
-            tty = False,
-            forward_x11 = False,
-            retry = 3,
-            connect_timeout = 30,
-            strict_host_checking = False,
-            persistent = True,
-            blocking = True,
-            with_lock = False
-            ):
+                sudo = False,
+                env = None,
+                tty = False,
+                forward_x11 = False,
+                retry = 3,
+                connect_timeout = 30,
+                strict_host_checking = False,
+                persistent = True,
+                blocking = True,
+                with_lock = False
+    ):
         """ Notice that this invocation will block until the
         execution finishes. If this is not the desired behavior,
         use 'run' instead."""
 
         if self.localhost:
-            (out, err), proc = execfuncs.lexec(command, 
-                    user = self.get("username"), # still problem with localhost
-                    sudo = sudo,
-                    env = env)
+            (out, err), proc = execfuncs.lexec(
+                command, 
+                user = self.get("username"), # still problem with localhost
+                sudo = sudo,
+                env = env)
         else:
             if with_lock:
                 # If the execute command is blocking, we don't want to keep
@@ -529,7 +533,7 @@ This might be dangerous when using user root""",
                         persistent = persistent,
                         blocking = blocking, 
                         strict_host_checking = strict_host_checking
-                        )
+                    )
             else:
                 (out, err), proc = sshfuncs.rexec(
                     command, 
@@ -550,7 +554,7 @@ This might be dangerous when using user root""",
                     persistent = persistent,
                     blocking = blocking, 
                     strict_host_checking = strict_host_checking
-                    )
+                )
 
         return (out, err), proc
 
@@ -564,16 +568,17 @@ This might be dangerous when using user root""",
             tty = False,
             strict_host_checking = False):
         
-        self.debug("Running command '%s'" % command)
+        self.debug("Running command '{}'".format(command))
         
         if self.localhost:
-            (out, err), proc = execfuncs.lspawn(command, pidfile,
-                    home = home, 
-                    create_home = create_home, 
-                    stdin = stdin or '/dev/null',
-                    stdout = stdout or '/dev/null',
-                    stderr = stderr or '/dev/null',
-                    sudo = sudo) 
+            (out, err), proc = execfuncs.lspawn(
+                command, pidfile,
+                home = home, 
+                create_home = create_home, 
+                stdin = stdin or '/dev/null',
+                stdout = stdout or '/dev/null',
+                stderr = stderr or '/dev/null',
+                sudo = sudo) 
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rspawn(
@@ -595,7 +600,7 @@ This might be dangerous when using user root""",
                     server_key = self.get("serverKey"),
                     tty = tty,
                     strict_host_checking = strict_host_checking
-                    )
+                )
 
         return (out, err), proc
 
@@ -615,7 +620,7 @@ This might be dangerous when using user root""",
                     identity = self.get("identity"),
                     server_key = self.get("serverKey"),
                     strict_host_checking = False
-                    )
+                )
         
         return pidtuple
 
@@ -625,17 +630,17 @@ This might be dangerous when using user root""",
         else:
             with self._node_lock:
                 status = sshfuncs.rstatus(
-                        pid, ppid,
-                        host = self.get("hostname"),
-                        user = self.get("username"),
-                        port = self.get("port"),
-                        gwuser = self.get("gatewayUser"),
-                        gw = self.get("gateway"),
-                        agent = True,
-                        identity = self.get("identity"),
-                        server_key = self.get("serverKey"),
-                        strict_host_checking = False
-                        )
+                    pid, ppid,
+                    host = self.get("hostname"),
+                    user = self.get("username"),
+                    port = self.get("port"),
+                    gwuser = self.get("gatewayUser"),
+                    gw = self.get("gateway"),
+                    agent = True,
+                    identity = self.get("identity"),
+                    server_key = self.get("serverKey"),
+                    strict_host_checking = False
+                )
            
         return status
     
@@ -661,14 +666,15 @@ This might be dangerous when using user root""",
                         identity = self.get("identity"),
                         server_key = self.get("serverKey"),
                         strict_host_checking = False
-                        )
+                    )
 
         return (out, err), proc
 
     def copy(self, src, dst):
         if self.localhost:
-            (out, err), proc = execfuncs.lcopy(src, dst, 
-                    recursive = True)
+            (out, err), proc = execfuncs.lcopy(
+                src, dst, 
+                recursive = True)
         else:
             with self._node_lock:
                 (out, err), proc = sshfuncs.rcopy(
@@ -684,7 +690,7 @@ This might be dangerous when using user root""",
         return (out, err), proc
 
     def upload(self, src, dst, text = False, overwrite = True,
-            raise_on_error = True):
+               raise_on_error = True):
         """ Copy content to destination
 
         src  string with the content to copy. Can be:
@@ -721,7 +727,7 @@ This might be dangerous when using user root""",
 
         if not self.localhost:
             # Build destination as <user>@<server>:<path>
-            dst = "%s@%s:%s" % (self.get("username"), self.get("hostname"), dst)
+            dst = "{}@{}:{}".format(self.get("username"), self.get("hostname"), dst)
 
         ((out, err), proc) = self.copy(src, dst)
 
@@ -730,10 +736,10 @@ This might be dangerous when using user root""",
             os.remove(f.name)
 
         if err:
-            msg = " Failed to upload files - src: %s dst: %s" %  (";".join(src), dst) 
+            msg = " Failed to upload files - src: {} dst: {}".format(";".join(src), dst)
             self.error(msg, out, err)
             
-            msg = "%s out: %s err: %s" % (msg, out, err)
+            msg = "{} out: {} err: {}".format(msg, out, err)
             if raise_on_error:
                 raise RuntimeError, msg
 
@@ -742,12 +748,12 @@ This might be dangerous when using user root""",
     def download(self, src, dst, raise_on_error = True):
         if not self.localhost:
             # Build destination as <user>@<server>:<path>
-            src = "%s@%s:%s" % (self.get("username"), self.get("hostname"), src)
+            src = "{}@{}:{}".format(self.get("username"), self.get("hostname"), src)
 
         ((out, err), proc) = self.copy(src, dst)
 
         if err:
-            msg = " Failed to download files - src: %s dst: %s" %  (";".join(src), dst) 
+            msg = " Failed to download files - src: {} dst: {}".format(";".join(src), dst) 
             self.error(msg, out, err)
 
             if raise_on_error:
@@ -768,8 +774,9 @@ This might be dangerous when using user root""",
 
         return command
 
-    def install_packages(self, packages, home, run_home = None,
-            raise_on_error = True):
+    def install_packages(self, packages, home,
+                         run_home = None,
+                         raise_on_error = True):
         """ Install packages in the Linux host.
 
         'home' is the directory to upload the package installation script.
@@ -780,18 +787,18 @@ This might be dangerous when using user root""",
         run_home = run_home or home
 
         (out, err), proc = self.run_and_wait(command, run_home, 
-            shfile = os.path.join(home, "instpkg.sh"),
-            pidfile = "instpkg_pidfile",
-            ecodefile = "instpkg_exitcode",
-            stdout = "instpkg_stdout", 
-            stderr = "instpkg_stderr",
-            overwrite = False,
-            raise_on_error = raise_on_error)
+                                             shfile = os.path.join(home, "instpkg.sh"),
+                                             pidfile = "instpkg_pidfile",
+                                             ecodefile = "instpkg_exitcode",
+                                             stdout = "instpkg_stdout", 
+                                             stderr = "instpkg_stderr",
+                                             overwrite = False,
+                                             raise_on_error = raise_on_error)
 
         return (out, err), proc 
 
     def remove_packages(self, packages, home, run_home = None,
-            raise_on_error = True):
+                        raise_on_error = True):
         """ Uninstall packages from the Linux host.
 
         'home' is the directory to upload the package un-installation script.
@@ -809,14 +816,14 @@ This might be dangerous when using user root""",
         run_home = run_home or home
 
         (out, err), proc = self.run_and_wait(command, run_home, 
-            shfile = os.path.join(home, "rmpkg.sh"),
-            pidfile = "rmpkg_pidfile",
-            ecodefile = "rmpkg_exitcode",
-            stdout = "rmpkg_stdout", 
-            stderr = "rmpkg_stderr",
-            overwrite = False,
-            raise_on_error = raise_on_error)
-         
+                                             shfile = os.path.join(home, "rmpkg.sh"),
+                                             pidfile = "rmpkg_pidfile",
+                                             ecodefile = "rmpkg_exitcode",
+                                             stdout = "rmpkg_stdout", 
+                                             stderr = "rmpkg_stderr",
+                                             overwrite = False,
+                                             raise_on_error = raise_on_error)
+        
         return (out, err), proc 
 
     def mkdir(self, paths, clean = False):
@@ -829,7 +836,7 @@ This might be dangerous when using user root""",
         if isinstance(paths, str):
             paths = [paths]
 
-        cmd = " ; ".join(map(lambda path: "mkdir -p %s" % path, paths))
+        cmd = " ; ".join(["mkdir -p {}".format(path) for path in paths])
 
         return self.execute(cmd, with_lock = True)
 
@@ -841,23 +848,23 @@ This might be dangerous when using user root""",
         if isinstance(paths, str):
             paths = [paths]
 
-        cmd = " ; ".join(map(lambda path: "rm -rf %s" % path, paths))
+        cmd = " ; ".join(map(lambda path: "rm -rf {}".format(path), paths))
 
         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
@@ -868,45 +875,45 @@ This might be dangerous when using user root""",
             shfile = os.path.join(home, shfile)
 
         self.upload_command(command, 
-            shfile = shfile, 
-            ecodefile = ecodefile, 
-            env = env,
-            overwrite = overwrite)
+                            shfile = shfile, 
+                            ecodefile = ecodefile, 
+                            env = env,
+                            overwrite = overwrite)
 
-        command = "bash %s" % shfile
+        command = "bash {}".format(shfile)
         # run command in background in remote host
         (out, err), proc = self.run(command, home, 
-                pidfile = pidfile,
-                stdin = stdin, 
-                stdout = stdout, 
-                stderr = stderr, 
-                sudo = sudo,
-                tty = tty)
+                                    pidfile = pidfile,
+                                    stdin = stdin, 
+                                    stdout = stdout, 
+                                    stderr = stderr, 
+                                    sudo = sudo,
+                                    tty = tty)
 
         # check no errors occurred
         if proc.poll():
-            msg = " Failed to run command '%s' " % command
+            msg = " Failed to run command '{}' ".format(command)
             self.error(msg, out, err)
             if raise_on_error:
                 raise RuntimeError, msg
 
         # Wait for pid file to be generated
         pid, ppid = self.wait_pid(
-                home = home, 
-                pidfile = pidfile, 
-                raise_on_error = raise_on_error)
+            home = home, 
+            pidfile = pidfile, 
+            raise_on_error = raise_on_error)
 
         if wait_run:
             # wait until command finishes to execute
             self.wait_run(pid, ppid)
-          
+            
             (eout, err), proc = self.check_errors(home,
-                ecodefile = ecodefile,
-                stderr = stderr)
+                                                  ecodefile = ecodefile,
+                                                  stderr = stderr)
 
             # Out is what was written in the stderr file
             if err:
-                msg = " Failed to run command '%s' " % command
+                msg = " Failed to run command '{}' ".format(command)
                 self.error(msg, eout, err)
 
                 if raise_on_error:
@@ -939,22 +946,20 @@ This might be dangerous when using user root""",
         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
         """
 
         if not (command.strip().endswith(";") or command.strip().endswith("&")):
             command += ";"
-      
+            
         # The exit code of the command will be stored in ecodefile
-        command = " { %(command)s } ; echo $? > %(ecodefile)s ;" % {
-                'command': command,
-                'ecodefile': ecodefile,
-                } 
+        command = " {{ {command} }} ; echo $? > {ecodefile} ;"\
+                  .format(command=command, ecodefile=ecodefile)
 
         # Export environment
         environ = self.format_environment(env)
@@ -976,11 +981,11 @@ This might be dangerous when using user root""",
         env = re.sub(r'\s+', ' ', env.strip())
 
         sep = ";" if inline else "\n"
-        return sep.join(map(lambda e: " export %s" % e, env.split(" "))) + sep 
+        return sep.join([" export {}".format(e) for e in env.split(" ")]) + sep 
 
     def check_errors(self, home, 
-            ecodefile = "exitcode", 
-            stderr = "stderr"):
+                     ecodefile = "exitcode", 
+                     stderr = "stderr"):
         """ Checks whether errors occurred while running a command.
         It first checks the exit code for the command, and only if the
         exit code is an error one it returns the error output.
@@ -993,7 +998,7 @@ This might be dangerous when using user root""",
         ecode = self.exitcode(home, ecodefile)
 
         if ecode in [ ExitCode.CORRUPTFILE, ExitCode.ERROR ]:
-            err = "Error retrieving exit code status from file %s/%s" % (home, ecodefile)
+            err = "Error retrieving exit code status from file {}/{}".format(home, ecodefile)
         elif ecode > 0 or ecode == ExitCode.FILENOTFOUND:
             # The process returned an error code or didn't exist. 
             # Check standard error.
@@ -1004,9 +1009,9 @@ This might be dangerous when using user root""",
             # (cat returns 1 for error "No such file or directory")
             if ecode == ExitCode.FILENOTFOUND and proc.poll() == 1: 
                 err = "" 
-            
+                
         return ("", err), proc
+    
     def wait_pid(self, home, pidfile = "pidfile", raise_on_error = False):
         """ Waits until the pid file for the command is generated, 
             and returns the pid and ppid of the process """
@@ -1023,10 +1028,9 @@ This might be dangerous when using user root""",
                 time.sleep(delay)
                 delay = delay * 1.5
         else:
-            msg = " Failed to get pid for pidfile %s/%s " % (
-                    home, pidfile )
+            msg = " Failed to get pid for pidfile {}/{} ".format(home, pidfile )
             self.error(msg)
-            
+    
             if raise_on_error:
                 raise RuntimeError, msg
 
@@ -1054,8 +1058,8 @@ This might be dangerous when using user root""",
 
     def check_output(self, home, filename):
         """ Retrives content of file """
-        (out, err), proc = self.execute("cat %s" % 
-            os.path.join(home, filename), retry = 1, with_lock = True)
+        (out, err), proc = self.execute(
+            "cat {}".format(os.path.join(home, filename)), retry = 1, with_lock = True)
         return (out, err), proc
 
     def is_alive(self):
@@ -1073,20 +1077,21 @@ This might be dangerous when using user root""",
         # until the result is not empty string
         try:
             (out, err), proc = self.execute("echo 'ALIVE'",
-                    blocking = True,
-                    with_lock = True)
-    
+                                            blocking = True,
+                                            with_lock = True)
+            
             if out.find("ALIVE") > -1:
                 return True
         except:
             trace = traceback.format_exc()
-            msg = "Unresponsive host. Error reaching host: %s " % trace
+            msg = "Unresponsive host. Error reaching host: {} ".format(trace)
 
         self.error(msg, out, err)
         return False
 
     def find_home(self):
-        """ Retrieves host home directory
+        """ 
+        Retrieves host home directory
         """
         # The underlying SSH layer will sometimes return an empty
         # output (even if the command was executed without errors).
@@ -1095,14 +1100,14 @@ This might be dangerous when using user root""",
         msg = "Impossible to retrieve HOME directory"
         try:
             (out, err), proc = self.execute("echo ${HOME}",
-                    blocking = True,
-                    with_lock = True)
-    
+                                            blocking = True,
+                                            with_lock = True)
+            
             if out.strip() != "":
                 self._home_dir =  out.strip()
         except:
             trace = traceback.format_exc()
-            msg = "Impossible to retrieve HOME directory %s" % trace
+            msg = "Impossible to retrieve HOME directory {}".format(trace)
 
         if not self._home_dir:
             self.error(msg)
@@ -1112,17 +1117,17 @@ This might be dangerous when using user root""",
         """ Removes files that already exist in the Linux host from src list
         """
         # construct a dictionary with { dst: src }
-        dests = dict(map(lambda s: (os.path.join(dst, os.path.basename(s)), s), src)) \
-                    if len(src) > 1 else dict({dst: src[0]})
+        dests = { os.path.join(dst, os.path.basename(s)) : s for s in src } \
+                if len(src) > 1 else {dst: src[0]}
 
         command = []
         for d in dests.keys():
-            command.append(" [ -f %(dst)s ] && echo '%(dst)s' " % {'dst' : d} )
+            command.append(" [ -f {dst} ] && echo '{dst}' ".format(dst=d) )
 
         command = ";".join(command)
 
         (out, err), proc = self.execute(command, retry = 1, with_lock = True)
-    
+        
         for d in dests.keys():
             if out.find(d) > -1:
                 del dests[d]