X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Futil%2Fexecfuncs.py;h=6b5f1a5bce3bd86b0e3b445e74fe3deee09c934e;hb=74bb6c4d720bab1e65a71db74525a1bf55cfcb2d;hp=bd3e68d25c846d7232fe2a115955b1a649d4e152;hpb=4896d77f40a611a22f9f1f8f2ae0e63e9008fee1;p=nepi.git diff --git a/src/nepi/util/execfuncs.py b/src/nepi/util/execfuncs.py index bd3e68d2..6b5f1a5b 100644 --- a/src/nepi/util/execfuncs.py +++ b/src/nepi/util/execfuncs.py @@ -1,30 +1,31 @@ -""" - NEPI, a framework to manage network experiments - Copyright (C) 2013 INRIA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -""" +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2013 INRIA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: Alina Quereilhac -from nepi.util.sshfuncs import RUNNING, FINISHED, NOT_STARTED, STDOUT +from nepi.util.sshfuncs import ProcStatus, STDOUT, log, shell_escape +import logging +import shlex import subprocess def lexec(command, user = None, sudo = False, - stdin = None, env = None): """ Executes a local command, returns ((stdout,stderr),process) @@ -37,15 +38,26 @@ def lexec(command, if sudo: command = "sudo %s" % command - elif user: - command = "su %s ; %s " % (user, command) + + # XXX: Doing 'su user' blocks waiting for a password on stdin + #elif user: + # command = "su %s ; %s " % (user, command) + + proc = subprocess.Popen(command, + shell = True, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE) - p = subprocess.Popen(command, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - stdin = stdin) + out = err = "" + log_msg = "lexec - command %s " % command + + try: + out, err = proc.communicate() + log(log_msg, logging.DEBUG, out, err) + except: + log(log_msg, logging.ERROR, out, err) + raise - out, err = p.communicate() return ((out, err), proc) def lcopy(source, dest, recursive = False): @@ -53,21 +65,35 @@ def lcopy(source, dest, recursive = False): Copies from/to localy. """ - if TRACE: - print "scp", source, dest - - command = ["cp"] + args = ["cp"] if recursive: - command.append("-R") - - command.append(src) - command.append(dst) - - p = subprocess.Popen(command, + args.append("-r") + + if isinstance(source, list): + args.extend(source) + else: + args.append(source) + + if isinstance(dest, list): + args.extend(dest) + else: + args.append(dest) + + proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = p.communicate() + out = err = "" + command = " ".join(args) + log_msg = " lcopy - command %s " % command + + try: + out, err = proc.communicate() + log(log_msg, logging.DEBUG, out, err) + except: + log(log_msg, logging.ERROR, out, err) + raise + return ((out, err), proc) def lspawn(command, pidfile, @@ -119,7 +145,7 @@ def lspawn(command, pidfile, 'stdin' : stdin, } - cmd = "%(create)s%(gohome)s rm -f %(pidfile)s ; %(sudo)s nohup bash -c %(command)s " % { + cmd = "%(create)s%(gohome)s rm -f %(pidfile)s ; %(sudo)s bash -c %(command)s " % { 'command' : shell_escape(daemon_command), 'sudo' : 'sudo -S' if sudo else '', 'pidfile' : shell_escape(pidfile), @@ -127,14 +153,14 @@ def lspawn(command, pidfile, 'create' : 'mkdir -p %s ; ' % (shell_escape(home),) if create_home else '', } - (out,err),proc = lexec(cmd) + (out,err), proc = lexec(cmd) if proc.wait(): raise RuntimeError, "Failed to set up application on host %s: %s %s" % (host, out,err,) - return (out,err),proc + return ((out,err), proc) -def lcheckpid(pidfile): +def lgetpid(pidfile): """ Check the pidfile of a process spawned with remote_spawn. @@ -147,7 +173,7 @@ def lcheckpid(pidfile): or None if the pidfile isn't valid yet (maybe the process is still starting). """ - (out,err),proc = lexec("cat %s" % pidfile ) + (out,err), proc = lexec("cat %s" % pidfile ) if proc.wait(): return None @@ -171,7 +197,7 @@ def lstatus(pid, ppid): One of NOT_STARTED, RUNNING, FINISHED """ - (out,err),proc = lexec( + (out,err), proc = lexec( # Check only by pid. pid+ppid does not always work (especially with sudo) " (( ps --pid %(pid)d -o pid | grep -c %(pid)d && echo 'wait') || echo 'done' ) | tail -n 1" % { 'ppid' : ppid, @@ -179,15 +205,15 @@ def lstatus(pid, ppid): }) if proc.wait(): - return NOT_STARTED + return ProcStatus.NOT_STARTED status = False if out: status = (out.strip() == 'wait') else: - return NOT_STARTED - return RUNNING if status else FINISHED - + return ProcStatus.NOT_STARTED + + return ProcStatus.RUNNING if status else ProcStatus.FINISHED def lkill(pid, ppid, sudo = False): """