Coverage for ion/util/os_process : 90.00%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
|
#!/usr/bin/env python
@file ion/util/os_process.py @author Dave Foster <dfoster@asascience.com> @brief Operating System process wrapper for twisted. """
""" An exception class thrown when OSProcess spawning fails """
""" An operating system process wrapper for twisted.
OSProcess is a twisted safe wrapper for a process running on the operating system outside of a capability container. It can be used to spawn one shot tasks or long running daemons.
It is intended that you derive from this class to customize behavior, but this base works well for one shot commands like cp, mv, rm etc.
It is not safe to yield on the deferred returned by spawn unless you know the process will terminate. Call close in order to have a timeout protect you.
Example: @verbatim from ion.util.os_process import OSProcess def cb(res): print "\n".join(res['stdout'])
lsproc = OSProcess(binary="/bin/ls", spawnargs=["/var"]) lsproc.addCallback(cb) lsproc.spawn() @endverbatim
Tips for derived implementations: - The deferred returned by spawn only calls back when the process ends. For a daemon, you may want to return a different deferred in spawn to indicate when the daemon is ready, called back for example on receiving text on stdout indicating ready. - The _close_impl method is where you want to add your custom shutdown instructions, which may involve something like writing to the process' stdin or closing stdin for graceful shutdown.
""" """ @param binary The binary to run. @param spawnargs Arguments to give the binary. Does not need to have the binary as the first argument, as some other mechanisms may require. @param startdir The directory to run the binary from. If left unset, the process will run from the current directory. """
""" Spawns an OS process via twisted's reactor.
@returns A deferred that is called back on process ending. WARNING: it is not safe to yield on this deferred as the process may never terminate! Use the close method to safely close a process. You may yield on the deferred returned by that. """
raise RuntimeError("Already used this process protocol")
log.error("No binary specified") raise RuntimeError("No binary specified")
# arguments passed in here always take precedence. else: theargs.extend(args)
""" Default canceller for the process. Will call _close_impl with Force set to true. """ self._close_impl(True)
""" Adds a callback to be called when the process exits. You may call this method any time.
@param callback Method to be called when the process exits. This callback should take two arguments, a dict named result containing the status of the process (exitcode, outlines, errlines) and then a *args param for the callback args specified to this method.
This callback will be executed for any reason that the process ends - whether it ended on its own, ended as a result of close, or was killed abnormally. It is your responsibility to handle all these cases.
@param **kwargs Additional arguments to return to the callback. """ self.deferred_exited.addCallback(callback, kwargs)
""" Instructs the opened process to close down.
@param force If true, it severs all pipes and sends a KILL signal. At this point, twisted essentially forgets about the process.
@param timeout The amount of time allowed by the process to signal it has closed. Default is 5 seconds. If the process does not shut down within this time, close is called again with the force param set to True. """
self._close_impl(True)
# we have to save this so we can cancel the timeout in processEnded
# with the timeout in place, the processEnded will always be called, so its safe # to yield on this deferred now
""" Default implementation of close. Override this in your derived class. """ else:
""" Notice that the process has started. This base method provides logging notice only. """
""" Output on stdout has been received. Stores the output in a list. """
""" Output on stderr has been received. Stores the output in a list. """
""" Notice that the process has ended. Will callback the deferred returned by spawn with a dict containing the exit code, the lines produced on stdout, and the lines on stderr. If the exit code is non zero, the errback is raised. """
# if this was called as a result of a close() call, we need to cancel the timeout so # it won't try to kill again
# form a dict of status to be passed as the result 'outlines' : self.outlines, 'errlines' : self.errlines }
|