forked from ianmiell/shutit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shutit_background.py
119 lines (102 loc) · 5.01 KB
/
shutit_background.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""Represents a ShutIt background command.
- options to:
- cancel command
- get status (running, suspended etc)
- check_timeout
state The state is given by a sequence of characters, for example, ``RWNA''. The first character indicates the run state of the process:
I Marks a process that is idle (sleeping for longer than about 20 seconds).
R Marks a runnable process.
S Marks a process that is sleeping for less than about 20 seconds.
T Marks a stopped process.
U Marks a process in uninterruptible wait.
Z Marks a dead process (a ``zombie'').
Additional characters after these, if any, indicate additional state information:
+ The process is in the foreground process group of its control terminal.
< The process has raised CPU scheduling priority.
> The process has specified a soft limit on memory requirements and is currently exceeding that limit; such a process is (necessarily) not swapped.
A the process has asked for random page replacement (VA_ANOM, from vadvise(2), for example, lisp(1) in a garbage collect).
E The process is trying to exit.
L The process has pages locked in core (for example, for raw I/O).
N The process has reduced CPU scheduling priority (see setpriority(2)).
S The process has asked for FIFO page replacement (VA_SEQL, from vadvise(2), for example, a large image processing program using virtual memory to sequentially
address voluminous data).
s The process is a session leader.
V The process is suspended during a vfork(2).
W The process is swapped out.
X The process is being traced or debugged.
ps -o stat= | sed 's/^\(.\)\(.*\)/\1/'
"""
import time
import logging
class ShutItBackgroundCommand(object):
"""Background command in ShutIt
"""
def __init__(self,
sendspec,
block_other_commands=True,
background=True):
# Stub this with a simple command for now
self.sendspec = sendspec
self.block_other_commands = block_other_commands
self.pid = None
self.return_value = None
self.start_time = None
self.run_state = 'N' # State as per ps man page, but 'C' == Complete, 'N' == not started
self.cwd = self.sendspec.shutit_pexpect_child.send_and_get_output(' command pwd')
def __str__(self):
string = ''
string += str(self.sendspec)
string += '\nblock_other_commands: ' + str(self.block_other_commands)
string += '\npid: ' + str(self.pid)
string += '\nreturn_value: ' + str(self.return_value)
string += '\nstart_time: ' + str(self.start_time)
string += '\nrun_state: ' + str(self.run_state)
string += '\ncwd: ' + str(self.cwd)
return string
def run_background_command(self):
shutit_pexpect_child = self.sendspec.shutit_pexpect_child
# Go to cwd
shutit_pexpect_child.quick_send(' command cd ' + self.cwd)
# record start time
self.start_time = time.localtime()
# run command
if self.sendspec.check_exit:
# Override - maybe log this TODO
self.sendspec.check_exit = False
#print 'sending: ' + self.sendspec.send
#print 'in: ' + str(shutit_pexpect_child)
shutit_pexpect_child.quick_send(self.sendspec.send)
self.sendspec.started = True
# Required to reset terminal after a background send.
shutit_pexpect_child.reset_terminal()
# record pid
self.pid = shutit_pexpect_child.send_and_get_output(" echo ${!}")
#print self.pid
return True
def check_background_command_state(self):
#print self
shutit_pexpect_child = self.sendspec.shutit_pexpect_child
#print('self.sendspec.send: ' + str(self.sendspec.send))
#print('self.sendspec.started: ' + str(self.sendspec.started))
#print('self.run_state: ' + str(self.run_state))
#print('self.pid: ' + str(self.pid))
#print('self.return_value: ' + str(self.return_value))
# Check the command has been started
if not self.sendspec.started:
#print 'not started?'
return self.run_state
self.run_state = shutit_pexpect_child.send_and_get_output(""" command ps -o stat """ + self.pid + """ | command sed '1d' """)
# If the job is complete, collect the return value
if self.run_state == '':
self.run_state = 'C'
# Stop this from blocking other commands from here.
self.block_other_commands = False
if isinstance(self.run_state,str) and self.run_state == 'C' and self.return_value is None:
shutit_pexpect_child.quick_send(' wait ' + self.pid)
self.return_value = shutit_pexpect_child.send_and_get_output(' echo $?')
if isinstance(self.run_state,str) and self.run_state == 'C' and self.return_value is not None:
# This job is complete, nothing to do.
pass
# TODO: honour sendspec.timeout
#print 'returning: ' + self.run_state
return self.run_state