configuration.
"""
- def _run(me, cmd, input = None):
+ def _run(me, cmd, input = None, state = None):
"""
This is the core of the remote service machinery. It issues a command
and parses the response. It will generate strings of informational
output from the command; error responses cause appropriate exceptions to
be raised.
- The command is determined by passing the CMD argument to the `_mkcmd'
- method, which a subclass must implement; it should return a list of
- command-line arguments suitable for `subprocess.Popen'. The INPUT is a
- string to make available on the command's stdin; if None, then no input
+ The command is determined by passing the CMD and STATE arguments to the
+ `_mkcmd' method, which a subclass must implement; it should return a list
+ of command-line arguments suitable for `subprocess.Popen'. The INPUT is
+ a string to make available on the command's stdin; if None, then no input
is provided to the command. The `_describe' method must provide a
description of the remote service for use in timeout messages.
## Run the command and collect its output and status.
with U.timeout(30, "waiting for remote service %s" % me._describe()):
- proc = SUB.Popen(me._mkcmd(cmd),
+ proc = SUB.Popen(me._mkcmd(cmd, state),
stdin = input is not None and SUB.PIPE or None,
stdout = SUB.PIPE, stderr = SUB.PIPE)
out, err = proc.communicate(input)
if not win:
raise U.ExpectedError, (500, 'No reply from remote service')
- def _run_noout(me, cmd, input = None):
+ def _run_noout(me, cmd, input = None, state = None):
"""Like `_run', but expect no output."""
- for _ in me._run(cmd, input):
+ for _ in me._run(cmd, input, state):
raise U.ExpectedError, (500, 'Unexpected output from remote service')
class SSHRemoteService (BasicRemoteService):
super(CommandRemoteService, me).__init__(*args, **kw)
me._set = set
me._clear = clear
- me._map = dict(u = user)
def _describe(me):
"""Description of the remote service."""
return "`%s' command service (%s)" % (me.name, ' '.join(me._default))
- def _subst(me, c):
+ def _subst(me, c, map):
"""Return the substitution for the placeholder `%C'."""
- return me._map.get(c, c)
+ return map.get(c, c)
- def _mkcmd(me, cmd):
+ def _mkcmd(me, cmd, map):
"""Construct the command to be executed, by substituting placeholders."""
- return [me.R_PAT.sub(lambda m: me._subst(m.group(1))) for arg in cmd]
+ return [me.R_PAT.sub(lambda m: me._subst(m.group(1), map), arg)
+ for arg in cmd]
def setpasswd(me, user, passwd):
"""Service protocol: set the USER's password to PASSWD."""
- me._run_noout(me._set, passwd + '\n')
+ me._run_noout(me._set, passwd + '\n', state = dict(u = user))
def clearpasswd(me, user):
"""Service protocol: clear the USER's password."""
- me._run_noout(me._clear)
+ me._run_noout(me._clear, state = dict(u = user))
CONF.export('CommandRemoteService')