| Home | Trees | Indices | Help |
|
|---|
|
|
1 #
2 # Copyright (C) 2008-2015 CEA/DAM
3 # Copyright (C) 2015 Stephane Thiell <sthiell@stanford.edu>
4 #
5 # This file is part of ClusterShell.
6 #
7 # ClusterShell is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # ClusterShell is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with ClusterShell; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 """
22 WorkerPopen
23
24 ClusterShell worker for executing local commands.
25
26 Usage example:
27 >>> worker = WorkerPopen("/bin/uname", key="mykernel")
28 >>> task.schedule(worker) # schedule worker
29 >>> task.resume() # run task
30 >>> worker.retcode() # get return code
31 0
32 >>> worker.read() # read command output
33 'Linux'
34
35 """
36
37 from ClusterShell.Worker.Worker import WorkerSimple, StreamClient
38
39
41
43 StreamClient.__init__(self, worker, key, stderr, timeout, autoclose)
44 self.popen = None
45 self.rc = None
46 # Declare writer stream to allow early buffering
47 self.streams.set_writer(worker.SNAME_STDIN, None, retain=False)
48
50 """Worker is starting."""
51 assert not self.worker.started
52 assert self.popen is None
53
54 self.popen = self._exec_nonblock(self.worker.command, shell=True)
55
56 task = self.worker.task
57 if task.info("debug", False):
58 task.info("print_debug")(task, "POPEN: %s" % self.worker.command)
59
60 self.worker._on_start(self.key)
61 return self
62
64 """
65 Close client. See EngineClient._close().
66 """
67 if abort:
68 # it's safer to call poll() first for long time completed processes
69 prc = self.popen.poll()
70 # if prc is None, process is still running
71 if prc is None:
72 try: # try to kill it
73 self.popen.kill()
74 except OSError:
75 pass
76 prc = self.popen.wait()
77
78 self.streams.clear()
79
80 if prc >= 0: # filter valid rc
81 self.rc = prc
82 self.worker._on_rc(self.key, prc)
83 elif timeout:
84 assert abort, "abort flag not set on timeout"
85 self.worker._on_timeout(self.key)
86 elif not abort:
87 # if process was signaled, return 128 + signum (bash-like)
88 self.rc = 128 + -prc
89 self.worker._on_rc(self.key, self.rc)
90
91 if self.worker.eh:
92 self.worker.eh.ev_close(self.worker)
93
94
96 """
97 Implements the Popen Worker.
98 """
99 - def __init__(self, command, key=None, handler=None,
100 stderr=False, timeout=-1, autoclose=False):
101 """Initialize Popen worker."""
102 WorkerSimple.__init__(self, None, None, None, key, handler, stderr,
103 timeout, autoclose, client_class=PopenClient)
104 self.command = command
105 if not self.command:
106 raise ValueError("missing command parameter in WorkerPopen "
107 "constructor")
108
112
113 WORKER_CLASS = WorkerPopen
114
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Wed Dec 21 14:07:57 2016 | http://epydoc.sourceforge.net |