发布于 2015-10-05 04:18:18 | 411 次阅读 | 评论: 0 | 来源: 网络整理
Context managers for use with the with
statement.
注解
When using Python 2.5, you will need to start your fabfile
with from __future__ import with_statement
in order to make use of
the with
statement (which is a regular, non __future__
feature of
Python 2.6+.)
注解
If you are using multiple directly nested with
statements, it can
be convenient to use multiple context expressions in one single with
statement. Instead of writing:
with cd('/path/to/app'):
with prefix('workon myvenv'):
run('./manage.py syncdb')
run('./manage.py loaddata myfixture')
you can write:
with cd('/path/to/app'), prefix('workon myvenv'):
run('./manage.py syncdb')
run('./manage.py loaddata myfixture')
Note that you need Python 2.7+ for this to work. On Python 2.5 or 2.6, you can do the following:
from contextlib import nested
with nested(cd('/path/to/app'), prefix('workon myvenv')):
...
Finally, note that settings
implements
nested
itself – see its API doc for details.
fabric.context_managers.
cd
(path)¶Context manager that keeps directory state when calling remote operations.
Any calls to run
, sudo
, get
, or put
within the wrapped block will
implicitly have a string similar to "cd <path> && "
prefixed in order
to give the sense that there is actually statefulness involved.
Because use of cd
affects all such invocations, any code making use of
those operations, such as much of the contrib
section, will also be
affected by use of cd
.
Like the actual ‘cd’ shell builtin, cd
may be called with relative paths
(keep in mind that your default starting directory is your remote user’s
$HOME
) and may be nested as well.
Below is a “normal” attempt at using the shell ‘cd’, which doesn’t work due
to how shell-less SSH connections are implemented – state is not kept
between invocations of run
or sudo
:
run('cd /var/www')
run('ls')
The above snippet will list the contents of the remote user’s $HOME
instead of /var/www
. With cd
, however, it will work as expected:
with cd('/var/www'):
run('ls') # Turns into "cd /var/www && ls"
Finally, a demonstration (see inline comments) of nesting:
with cd('/var/www'):
run('ls') # cd /var/www && ls
with cd('website1'):
run('ls') # cd /var/www/website1 && ls
注解
This context manager is currently implemented by appending to (and, as
always, restoring afterwards) the current value of an environment
variable, env.cwd
. However, this implementation may change in the
future, so we do not recommend manually altering env.cwd
– only
the behavior of cd
will have any guarantee of backwards
compatibility.
注解
Space characters will be escaped automatically to make dealing with such directory names easier.
在 1.0 版更改: Applies to get
and put
in addition to the command-running
operations.
参见
fabric.context_managers.
char_buffered
(*args, **kwds)¶Force local terminal pipe
be character, not line, buffered.
Only applies on Unix-based systems; on Windows this is a no-op.
fabric.context_managers.
hide
(*args, **kwds)¶Context manager for setting the given output groups
to False.
groups
must be one or more strings naming the output groups defined in
output
. The given groups will be set to False for the
duration of the enclosed block, and restored to their previous value
afterwards.
For example, to hide the “[hostname] run:” status lines, as well as
preventing printout of stdout and stderr, one might use hide
as follows:
def my_task():
with hide('running', 'stdout', 'stderr'):
run('ls /var/www')
fabric.context_managers.
lcd
(path)¶Context manager for updating local current working directory.
This context manager is identical to cd
, except
that it changes a different env var (lcwd
, instead of cwd
) and thus
only affects the invocation of local
and the local
arguments to get
/put
.
Relative path arguments are relative to the local user’s current working directory, which will vary depending on where Fabric (or Fabric-using code) was invoked. You can check what this is with os.getcwd. It may be useful to pin things relative to the location of the fabfile in use, which may be found in env.real_fabfile
1.0 新版功能.
fabric.context_managers.
path
(path, behavior='append')¶Append the given path
to the PATH used to execute any wrapped commands.
Any calls to run
or sudo
within the wrapped block will implicitly have
a string similar to "PATH=$PATH:<path> "
prepended before the given
command.
You may customize the behavior of path
by specifying the optional
behavior
keyword argument, as follows:
'append'
: append given path to the current $PATH
, e.g.
PATH=$PATH:<path>
. This is the default behavior.'prepend'
: prepend given path to the current $PATH
, e.g.
PATH=<path>:$PATH
.'replace'
: ignore previous value of $PATH
altogether, e.g.
PATH=<path>
.注解
This context manager is currently implemented by modifying (and, as
always, restoring afterwards) the current value of environment
variables, env.path
and env.path_behavior
. However, this
implementation may change in the future, so we do not recommend
manually altering them directly.
1.0 新版功能.
fabric.context_managers.
prefix
(command)¶Prefix all wrapped run
/sudo
commands with given command plus &&
.
This is nearly identical to cd
, except that nested
invocations append to a list of command strings instead of modifying a
single string.
Most of the time, you’ll want to be using this alongside a shell script which alters shell state, such as ones which export or alter shell environment variables.
For example, one of the most common uses of this tool is with the
workon
command from virtualenvwrapper:
with prefix('workon myvenv'):
run('./manage.py syncdb')
In the above snippet, the actual shell command run would be this:
$ workon myvenv && ./manage.py syncdb
This context manager is compatible with cd
, so
if your virtualenv doesn’t cd
in its postactivate
script, you could
do the following:
with cd('/path/to/app'):
with prefix('workon myvenv'):
run('./manage.py syncdb')
run('./manage.py loaddata myfixture')
Which would result in executions like so:
$ cd /path/to/app && workon myvenv && ./manage.py syncdb
$ cd /path/to/app && workon myvenv && ./manage.py loaddata myfixture
Finally, as alluded to near the beginning,
prefix
may be nested if desired, e.g.:
with prefix('workon myenv'):
run('ls')
with prefix('source /some/script'):
run('touch a_file')
The result:
$ workon myenv && ls
$ workon myenv && source /some/script && touch a_file
Contrived, but hopefully illustrative.
fabric.context_managers.
quiet
()¶Alias to settings(hide('everything'), warn_only=True)
.
Useful for wrapping remote interrogative commands which you expect to fail occasionally, and/or which you want to silence.
Example:
with quiet():
have_build_dir = run("test -e /tmp/build").succeeded
When used in a task, the above snippet will not produce any run: test -e
/tmp/build
line, nor will any stdout/stderr display, and command failure
is ignored.
参见
1.5 新版功能.
fabric.context_managers.
remote_tunnel
(*args, **kwds)¶Create a tunnel forwarding a locally-visible port to the remote target.
For example, you can let the remote host access a database that is installed on the client host:
# Map localhost:6379 on the server to localhost:6379 on the client,
# so that the remote 'redis-cli' program ends up speaking to the local
# redis-server.
with remote_tunnel(6379):
run("redis-cli -i")
The database might be installed on a client only reachable from the client host (as opposed to on the client itself):
# Map localhost:6379 on the server to redis.internal:6379 on the client
with remote_tunnel(6379, local_host="redis.internal")
run("redis-cli -i")
remote_tunnel
accepts up to four arguments:
remote_port
(mandatory) is the remote port to listen to.local_port
(optional) is the local port to connect to; the default is
the same port as the remote one.local_host
(optional) is the locally-reachable computer (DNS name or
IP address) to connect to; the default is localhost
(that is, the
same computer Fabric is running on).remote_bind_address
(optional) is the remote IP address to bind to
for listening, on the current target. It should be an IP address assigned
to an interface on the target (or a DNS name that resolves to such IP).
You can use “0.0.0.0” to bind to all interfaces.注解
By default, most SSH servers only allow remote tunnels to listen to the
localhost interface (127.0.0.1). In these cases, remote_bind_address
is ignored by the server, and the tunnel will listen only to 127.0.0.1.
fabric.context_managers.
settings
(*args, **kwargs)¶Nest context managers and/or override env
variables.
settings
serves two purposes:
Most usefully, it allows temporary overriding/updating of env
with
any provided keyword arguments, e.g. with settings(user='foo'):
.
Original values, if any, will be restored once the with
block closes.
- The keyword argument
clean_revert
has special meaning forsettings
itself (see below) and will be stripped out before execution.
In addition, it will use contextlib.nested to nest any given
non-keyword arguments, which should be other context managers, e.g.
with settings(hide('stderr'), show('stdout')):
.
These behaviors may be specified at the same time if desired. An example will hopefully illustrate why this is considered useful:
def my_task():
with settings(
hide('warnings', 'running', 'stdout', 'stderr'),
warn_only=True
):
if run('ls /etc/lsb-release'):
return 'Ubuntu'
elif run('ls /etc/redhat-release'):
return 'RedHat'
The above task executes a run
statement, but will warn instead of
aborting if the ls
fails, and all output – including the warning
itself – is prevented from printing to the user. The end result, in this
scenario, is a completely silent task that allows the caller to figure out
what type of system the remote host is, without incurring the handful of
output that would normally occur.
Thus, settings
may be used to set any combination of environment
variables in tandem with hiding (or showing) specific levels of output, or
in tandem with any other piece of Fabric functionality implemented as a
context manager.
If clean_revert
is set to True
, settings
will not revert
keys which are altered within the nested block, instead only reverting keys
whose values remain the same as those given. More examples will make this
clear; below is how settings
operates normally:
# Before the block, env.parallel defaults to False, host_string to None
with settings(parallel=True, host_string='myhost'):
# env.parallel is True
# env.host_string is 'myhost'
env.host_string = 'otherhost'
# env.host_string is now 'otherhost'
# Outside the block:
# * env.parallel is False again
# * env.host_string is None again
The internal modification of env.host_string
is nullified – not always
desirable. That’s where clean_revert
comes in:
# Before the block, env.parallel defaults to False, host_string to None
with settings(parallel=True, host_string='myhost', clean_revert=True):
# env.parallel is True
# env.host_string is 'myhost'
env.host_string = 'otherhost'
# env.host_string is now 'otherhost'
# Outside the block:
# * env.parallel is False again
# * env.host_string remains 'otherhost'
Brand new keys which did not exist in env
prior to using settings
are also preserved if clean_revert
is active. When False
, such keys
are removed when the block exits.
1.4.1 新版功能: The clean_revert
kwarg.
fabric.context_managers.
shell_env
(**kw)¶Set shell environment variables for wrapped commands.
For example, the below shows how you might set a ZeroMQ related environment variable when installing a Python ZMQ library:
with shell_env(ZMQ_DIR='/home/user/local'):
run('pip install pyzmq')
As with prefix
, this effectively turns the
run
command into:
$ export ZMQ_DIR='/home/user/local' && pip install pyzmq
Multiple key-value pairs may be given simultaneously.
注解
If used to affect the behavior of local
when
running from a Windows localhost, SET
commands will be used to
implement this feature.
fabric.context_managers.
show
(*args, **kwds)¶Context manager for setting the given output groups
to True.
groups
must be one or more strings naming the output groups defined in
output
. The given groups will be set to True for the
duration of the enclosed block, and restored to their previous value
afterwards.
For example, to turn on debug output (which is typically off by default):
def my_task():
with show('debug'):
run('ls /var/www')
As almost all output groups are displayed by default, show
is most useful
for turning on the normally-hidden debug
group, or when you know or
suspect that code calling your own code is trying to hide output with
hide
.
fabric.context_managers.
warn_only
()¶Alias to settings(warn_only=True)
.
参见