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 WorkerPopen
37
38 ClusterShell worker for executing local commands.
39
40 Usage example:
41 >>> worker = WorkerPopen("/bin/uname", key="mykernel")
42 >>> task.schedule(worker) # schedule worker
43 >>> task.resume() # run task
44 >>> worker.retcode() # get return code
45 0
46 >>> worker.read() # read command output
47 'Linux'
48
49 """
50
51 import os
52 import signal
53
54 from ClusterShell.Worker.Worker import WorkerSimple, WorkerBadArgumentError
55
56
58 """
59 Implements the Popen Worker.
60 """
61
62 - def __init__(self, command, key=None, handler=None,
63 stderr=False, timeout=-1, autoclose=False):
64 """
65 Initialize Popen worker.
66 """
67 WorkerSimple.__init__(self, None, None, None, key, handler,
68 stderr, timeout, autoclose)
69
70 self.command = command
71 if not self.command:
72 raise WorkerBadArgumentError()
73
74 self.popen = None
75 self.rc = None
76
78 """
79 Start worker.
80 """
81 assert self.popen is None
82
83 self.popen = self._exec_nonblock(self.command, shell=True)
84 self.file_reader = self.popen.stdout
85 self.file_error = self.popen.stderr
86 self.file_writer = self.popen.stdin
87
88 if self.task.info("debug", False):
89 self.task.info("print_debug")(self.task, "POPEN: %s" % self.command)
90
91 self._invoke("ev_start")
92
93 return self
94
95 - def _close(self, force, timeout):
96 """
97 Close worker. Called by engine after worker has been
98 unregistered. This method should handle all termination types
99 (normal, forced or on timeout).
100 """
101 if not force and self._rbuf:
102
103
104 self.worker._on_msgline(self._rbuf)
105
106 rc = -1
107 if force or timeout:
108
109 prc = self.popen.poll()
110 if prc is None:
111
112 os.kill(self.popen.pid, signal.SIGKILL)
113 else:
114
115 prc = self.popen.wait()
116
117 if prc >= 0:
118
119 rc = prc
120 else:
121
122 rc = 128 + -prc
123
124 self.popen.stdin.close()
125 self.popen.stdout.close()
126
127 if rc >= 0:
128 self._on_rc(rc)
129 elif timeout:
130 self._on_timeout()
131
132 self._invoke("ev_close")
133
135 """
136 Set return code.
137 """
138 self.rc = rc
139 self.task._rc_set((self, self.key), rc)
140
141 self._invoke("ev_hup")
142
144 """
145 Return return code or None if command is still in progress.
146 """
147 return self.rc
148