1 from nepi.util.sshfuncs import RUNNING, FINISHED, NOT_STARTED, STDOUT
11 Executes a local command, returns ((stdout,stderr),process)
15 for envkey, envval in env.iteritems():
16 export += '%s=%s ' % (envkey, envval)
17 command = "%s %s" % (export, command)
20 command = "sudo %s" % command
22 command = "su %s ; %s " % (user, command)
24 p = subprocess.Popen(command,
25 stdout = subprocess.PIPE,
26 stderr = subprocess.PIPE,
29 out, err = p.communicate()
30 return ((out, err), proc)
32 def lcopy(source, dest, recursive = False):
34 Copies from/to localy.
38 print "scp", source, dest
47 p = subprocess.Popen(command,
48 stdout=subprocess.PIPE,
49 stderr=subprocess.PIPE)
51 out, err = p.communicate()
52 return ((out, err), proc)
54 def lspawn(command, pidfile,
63 Spawn a local command such that it will continue working asynchronously.
66 command: the command to run - it should be a single line.
68 pidfile: path of a (ideally unique to this task) pidfile for tracking the process.
70 stdout: path of a file to redirect standard output to - must be a string.
72 stderr: path of a file to redirect standard error to - string or the special STDOUT value
73 to redirect to the same file stdout was redirected to. Defaults to STDOUT.
74 stdin: path of a file with input to be piped into the command's standard input
76 home: path of a folder to use as working directory - should exist, unless you specify create_home
78 create_home: if True, the home folder will be created first with mkdir -p
80 sudo: whether the command needs to be executed as root
83 (stdout, stderr), process
85 Of the spawning process, which only captures errors at spawning time.
86 Usually only useful for diagnostics.
88 # Start process in a "daemonized" way, using nohup and heavy
89 # stdin/out redirection to avoid connection issues
95 daemon_command = '{ { %(command)s > %(stdout)s 2>%(stderr)s < %(stdin)s & } ; echo $! 1 > %(pidfile)s ; }' % {
97 'pidfile' : shell_escape(pidfile),
103 cmd = "%(create)s%(gohome)s rm -f %(pidfile)s ; %(sudo)s nohup bash -c %(command)s " % {
104 'command' : shell_escape(daemon_command),
105 'sudo' : 'sudo -S' if sudo else '',
106 'pidfile' : shell_escape(pidfile),
107 'gohome' : 'cd %s ; ' % (shell_escape(home),) if home else '',
108 'create' : 'mkdir -p %s ; ' % (shell_escape(home),) if create_home else '',
111 (out,err),proc = lexec(cmd)
114 raise RuntimeError, "Failed to set up application on host %s: %s %s" % (host, out,err,)
116 return (out,err),proc
118 def lcheckpid(pidfile):
120 Check the pidfile of a process spawned with remote_spawn.
123 pidfile: the pidfile passed to remote_span
127 A (pid, ppid) tuple useful for calling remote_status and remote_kill,
128 or None if the pidfile isn't valid yet (maybe the process is still starting).
131 (out,err),proc = lexec("cat %s" % pidfile )
138 return map(int,out.strip().split(' ',1))
140 # Ignore, many ways to fail that don't matter that much
143 def lstatus(pid, ppid):
145 Check the status of a process spawned with remote_spawn.
148 pid/ppid: pid and parent-pid of the spawned process. See remote_check_pid
152 One of NOT_STARTED, RUNNING, FINISHED
155 (out,err),proc = lexec(
156 # Check only by pid. pid+ppid does not always work (especially with sudo)
157 " (( ps --pid %(pid)d -o pid | grep -c %(pid)d && echo 'wait') || echo 'done' ) | tail -n 1" % {
167 status = (out.strip() == 'wait')
170 return RUNNING if status else FINISHED
173 def lkill(pid, ppid, sudo = False):
175 Kill a process spawned with lspawn.
177 First tries a SIGTERM, and if the process does not end in 10 seconds,
181 pid/ppid: pid and parent-pid of the spawned process. See remote_check_pid
183 sudo: whether the command was run with sudo - careful killing like this.
187 Nothing, should have killed the process
190 subkill = "$(ps --ppid %(pid)d -o pid h)" % { 'pid' : pid }
192 SUBKILL="%(subkill)s" ;
193 %(sudo)s kill -- -%(pid)d $SUBKILL || /bin/true
194 %(sudo)s kill %(pid)d $SUBKILL || /bin/true
195 for x in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; do
197 if [ `ps --pid %(pid)d -o pid | grep -c %(pid)d` == '0' ]; then
200 %(sudo)s kill -- -%(pid)d $SUBKILL || /bin/true
201 %(sudo)s kill %(pid)d $SUBKILL || /bin/true
205 if [ `ps --pid %(pid)d -o pid | grep -c %(pid)d` != '0' ]; then
206 %(sudo)s kill -9 -- -%(pid)d $SUBKILL || /bin/true
207 %(sudo)s kill -9 %(pid)d $SUBKILL || /bin/true
211 cmd = "( %s ) >/dev/null 2>/dev/null </dev/null &" % (cmd,)
213 (out,err),proc = lexec(
217 'sudo' : 'sudo -S' if sudo else '',