Operations¶
Functions to be used in fabfiles and other non-core code, such as run()/sudo().
-
fabric.operations.get(remote_path, local_path=None, use_sudo=False, temp_dir=None)¶ Download one or more files from a remote host.
getreturns an iterable containing the absolute paths to all local files downloaded, which will be empty iflocal_pathwas a StringIO object (see below for more on using StringIO). This object will also exhibit a.failedattribute containing any remote file paths which failed to download, and a.succeededattribute equivalent tonot .failed.remote_pathis the remote file or directory path to download, which may contain shell glob syntax, e.g."/var/log/apache2/*.log", and will have tildes replaced by the remote home directory. Relative paths will be considered relative to the remote user’s home directory, or the current remote working directory as manipulated bycd. If the remote path points to a directory, that directory will be downloaded recursively.local_pathis the local file path where the downloaded file or files will be stored. If relative, it will honor the local current working directory as manipulated bylcd. It may be interpolated, using standard Python dict-based interpolation, with the following variables:host: The value ofenv.host_string, egmyhostnameoruser@myhostname-222(the colon between hostname and port is turned into a dash to maximize filesystem compatibility)dirname: The directory part of the remote file path, e.g. thesrc/projectnameinsrc/projectname/utils.py.basename: The filename part of the remote file path, e.g. theutils.pyinsrc/projectname/utils.pypath: The full remote path, e.g.src/projectname/utils.py.
While the SFTP protocol (which
getuses) has no direct ability to download files from locations not owned by the connecting user, you may specifyuse_sudo=Trueto work around this. When set, this setting allowsgetto copy (using sudo) the remote files to a temporary location on the remote end (defaults to remote user’s$HOME; this may be overridden viatemp_dir), and then download them tolocal_path.Note
When
remote_pathis an absolute directory path, only the inner directories will be recreated locally and passed into the above variables. So for example,get('/var/log', '%(path)s')would start writing out files likeapache2/access.log,postgresql/8.4/postgresql.log, etc, in the local working directory. It would not write out e.g.var/log/apache2/access.log.Additionally, when downloading a single file,
%(dirname)sand%(path)sdo not make as much sense and will be empty and equivalent to%(basename)s, respectively. Thus a call likeget('/var/log/apache2/access.log', '%(path)s')will save a local file namedaccess.log, notvar/log/apache2/access.log.This behavior is intended to be consistent with the command-line
scpprogram (but sftp is always used for the transfer).If left blank,
local_pathdefaults to"%(host)s/%(path)s"in order to be safe for multi-host invocations.Warning
If your
local_pathargument does not contain%(host)sand yourgetcall runs against multiple hosts, your local files will be overwritten on each successive run!If
local_pathdoes not make use of the above variables (i.e. if it is a simple, explicit file path) it will act similar toscporcp, overwriting pre-existing files if necessary, downloading into a directory if given (e.g.get('/path/to/remote_file.txt', 'local_directory')will createlocal_directory/remote_file.txt) and so forth.local_pathmay alternately be a file-like object, such as the result ofopen('path', 'w')or aStringIOinstance.Note
Attempting to
geta directory into a file-like object is not valid and will result in an error.Note
This function will use
seekandtellto overwrite the entire contents of the file-like object, in order to be consistent with the behavior ofput(which also considers the entire file). However, unlikeput, the file pointer will not be restored to its previous location, as that doesn’t make as much sense here and/or may not even be possible.Note
If a file-like object such as StringIO has a
nameattribute, that will be used in Fabric’s printed output instead of the default<file obj>Changed in version 1.5: Allow a
nameattribute on file-like objects for log output
-
fabric.operations.local(command, capture=False, shell=None, pty=True, encoding='utf-8')¶ Run a command on the local system.
localis simply a convenience wrapper around the use of the builtin Pythonsubprocessmodule withshell=Trueactivated. If you need to do anything special, consider using thesubprocessmodule directly.shellis passed directly to subprocess.Popen’sexecuteargument (which determines the local shell to use.) As per the linked documentation, on Unix the default behavior is to use/bin/sh, so this option is useful for setting that value to e.g./bin/bash.If
ptyis changed toFalse, it redirects the subprocess stdin to an empty pipe to avoid it reading from the terminal, and creates a new “session id” for the subprocess.localis not currently capable of simultaneously printing and capturing output, asrun/sudodo. Thecapturekwarg allows you to switch between printing and capturing as necessary, and defaults toFalse.When
capture=False, the local subprocess’ stdout and stderr streams are hooked up directly to your terminal, though you may use the global output controlsoutput.stdoutandoutput.stderrto hide one or both if desired. In this mode, the return value’s stdout/stderr values are always empty.When
capture=True, you will not see any output from the subprocess in your terminal, but the return value will contain the captured stdout/stderr.encodingis used whencapture=Trueand running under Python-3, to decode stdout and stderr. The default is “utf-8”. The special value “binary” avoids decoding, leaving stdout and stderr asbytes.In either case, as with
runandsudo, this return value exhibits thereturn_code,stderr,failed,succeeded,commandandreal_commandattributes. Seerunfor details.localwill honor thelcdcontext manager, allowing you to control its current working directory independently of the remote end (which honorscd).New in version 1.9: The return value attributes
.commandand.real_command.New in version 1.15: The
ptyargument.New in version 1.19: The
encodingargument.
-
fabric.operations.open_shell(command=None)¶ Invoke a fully interactive shell on the remote end.
If
commandis given, it will be sent down the pipe before handing control over to the invoking user.This function is most useful for when you need to interact with a heavily shell-based command or series of commands, such as when debugging or when fully interactive recovery is required upon remote program failure.
It should be considered an easy way to work an interactive shell session into the middle of a Fabric script and is not a drop-in replacement for
run, which is also capable of interacting with the remote end (albeit only while its given command is executing) and has much stronger programmatic abilities such as error handling and stdout/stderr capture.Specifically,
open_shellprovides a better interactive experience thanrun, but use of a full remote shell prevents Fabric from determining whether programs run within the shell have failed, and pollutes the stdout/stderr stream with shell output such as login banners, prompts and echoed stdin.Thus, this function does not have a return value and will not trigger Fabric’s failure handling if any remote programs result in errors.
-
fabric.operations.prompt(text, key=None, default='', validate=None)¶ Prompt user with
textand return the input (likeraw_input).A single space character will be appended for convenience, but nothing else. Thus, you may want to end your prompt text with a question mark or a colon, e.g.
prompt("What hostname?").If
keyis given, the user’s input will be stored asenv.<key>in addition to being returned byprompt. If the key already existed inenv, its value will be overwritten and a warning printed to the user.If
defaultis given, it is displayed in square brackets and used if the user enters nothing (i.e. presses Enter without entering any text).defaultdefaults to the empty string. If non-empty, a space will be appended, so that a call such asprompt("What hostname?", default="foo")would result in a prompt ofWhat hostname? [foo](with a trailing space after the[foo].)The optional keyword argument
validatemay be a callable or a string:- If a callable, it is called with the user’s input, and should return the value to be stored on success. On failure, it should raise an exception with an exception message, which will be printed to the user.
- If a string, the value passed to
validateis used as a regular expression. It is thus recommended to use raw strings in this case. Note that the regular expression, if it is not fully matching (bounded by^and$) it will be made so. In other words, the input must fully match the regex.
Either way,
promptwill re-prompt until validation passes (or the user hitsCtrl-C).Note
prompthonors env.abort_on_prompts and will callabortinstead of prompting if that flag is set toTrue. If you want to block on user input regardless, try wrapping withsettings.Examples:
# Simplest form: environment = prompt('Please specify target environment: ') # With default, and storing as env.dish: prompt('Specify favorite dish: ', 'dish', default='spam & eggs') # With validation, i.e. requiring integer input: prompt('Please specify process nice level: ', key='nice', validate=int) # With validation against a regular expression: release = prompt('Please supply a release name', validate=r'^\w+-\d+(\.\d+)?$') # Prompt regardless of the global abort-on-prompts setting: with settings(abort_on_prompts=False): prompt('I seriously need an answer on this! ')
-
fabric.operations.put(local_path=None, remote_path=None, use_sudo=False, mirror_local_mode=False, mode=None, use_glob=True, temp_dir=None)¶ Upload one or more files to a remote host.
As with the OpenSSH
sftpprogram,putwill overwrite pre-existing remote files without requesting confirmation.putreturns an iterable containing the absolute file paths of all remote files uploaded. This iterable also exhibits a.failedattribute containing any local file paths which failed to upload (and may thus be used as a boolean test.) You may also check.succeededwhich is equivalent tonot .failed.local_pathmay be a relative or absolute local file or directory path, and may contain shell-style wildcards, as understood by the Pythonglobmodule (giveuse_glob=Falseto disable this behavior). Tilde expansion (as implemented byos.path.expanduser) is also performed.local_pathmay alternately be a file-like object, such as the result ofopen('path')or aStringIOinstance.Note
In this case,
putwill attempt to read the entire contents of the file-like object by rewinding it usingseek(and will usetellafterwards to preserve the previous file position).remote_pathmay also be a relative or absolute location, but applied to the remote host. Relative paths are relative to the remote user’s home directory, but tilde expansion (e.g.~/.ssh/) will also be performed if necessary.An empty string, in either path argument, will be replaced by the appropriate end’s current working directory.
While the SFTP protocol (which
putuses) has no direct ability to upload files to locations not owned by the connecting user, you may specifyuse_sudo=Trueto work around this. When set, this setting causesputto upload the local files to a temporary location on the remote end (defaults to remote user’s$HOME; this may be overridden viatemp_dir), and then usesudoto move them toremote_path.In some use cases, it is desirable to force a newly uploaded file to match the mode of its local counterpart (such as when uploading executable scripts). To do this, specify
mirror_local_mode=True.Alternately, you may use the
modekwarg to specify an exact mode, in the same vein asos.chmod, such as an exact octal number (0o755) or a string representing one ("0o755").putwill honorcd, so relative values inremote_pathwill be prepended by the current remote working directory, if applicable. Thus, for example, the below snippet would attempt to upload to/tmp/files/test.txtinstead of~/files/test.txt:with cd('/tmp'): put('/path/to/local/test.txt', 'files')
Use of
lcdwill affectlocal_pathin the same manner.Examples:
put('bin/project.zip', '/tmp/project.zip') put('*.py', 'cgi-bin/') put('index.html', 'index.html', mode=0o755)
Note
If a file-like object such as StringIO has a
nameattribute, that will be used in Fabric’s printed output instead of the default<file obj>Changed in version 1.5: Allow a
nameattribute on file-like objects for log outputChanged in version 1.7: Added
use_globoption to allow disabling of globbing.
-
fabric.operations.reboot(wait=120, command='reboot', use_sudo=True)¶ Reboot the remote system.
Will temporarily tweak Fabric’s reconnection settings (timeout and connection_attempts) to ensure that reconnection does not give up for at least
waitseconds.Note
Users who want greater control are encouraged to check out this function’s (6 lines long, well commented) source code and write their own adaptation using different timeout/attempt values or additional logic.
Changed in version 1.4: Changed the
waitkwarg to be optional, and refactored to leverage the new reconnection functionality; it may not actually have to wait forwaitseconds before reconnecting.Changed in version 1.11: Added
use_sudoas a kwarg. Maintained old functionality by setting the default value to True.
-
fabric.operations.require(*keys, **kwargs)¶ Check for given keys in the shared environment dict and abort if not found.
Positional arguments should be strings signifying what env vars should be checked for. If any of the given arguments do not exist, Fabric will abort execution and print the names of the missing keys.
The optional keyword argument
used_formay be a string, which will be printed in the error output to inform users why this requirement is in place.used_foris printed as part of a string similar to:"Th(is|ese) variable(s) (are|is) used for %s"
so format it appropriately.
The optional keyword argument
provided_bymay be a list of functions or function names or a single function or function name which the user should be able to execute in order to set the key or keys; it will be included in the error output if requirements are not met.Note: it is assumed that the keyword arguments apply to all given keys as a group. If you feel the need to specify more than one
used_for, for example, you should break your logic into multiple calls torequire().
-
fabric.operations.run(command, shell=True, pty=True, combine_stderr=None, quiet=False, warn_only=False, stdin=None, stdout=None, stderr=None, timeout=None, shell_escape=None, capture_buffer_size=None)¶ Run a shell command on a remote host.
If
shellis True (the default),runwill execute the given command string via a shell interpreter, the value of which may be controlled by settingenv.shell(defaulting to something similar to/bin/bash -l -c "<command>".) Any double-quote (") or dollar-sign ($) characters incommandwill be automatically escaped whenshellis True (unless disabled by settingshell_escape=False).When
shell=False, no shell wrapping or escaping will occur. (It’s possible to specifyshell=False, shell_escape=Trueif desired, which will still trigger escaping of dollar signs, etc but will not wrap with a shell program invocation).runwill return the result of the remote program’s stdout as a single (likely multiline) string. This string will exhibitfailedandsucceededboolean attributes specifying whether the command failed or succeeded, and will also include the return code as thereturn_codeattribute. Furthermore, it includes a copy of the requested & actual command strings executed, as.commandand.real_command, respectively.To lessen memory use when running extremely verbose programs (and, naturally, when having access to their full output afterwards is not necessary!) you may limit how much of the program’s stdout/err is stored by setting
capture_buffer_sizeto an integer value.Warning
Do not set
capture_buffer_sizeto any value smaller than the length ofenv.sudo_promptor you will likely break the functionality ofsudo! Ditto any user prompts stored inenv.prompts.Note
This value is used for each buffer independently, so e.g.
1024may result in storing a total of2048bytes if there’s data in both streams.)Any text entered in your local terminal will be forwarded to the remote program as it runs, thus allowing you to interact with password or other prompts naturally. For more on how this works, see Interaction with remote programs.
You may pass
pty=Falseto forego creation of a pseudo-terminal on the remote end in case the presence of one causes problems for the command in question. However, this will force Fabric itself to echo any and all input you type while the command is running, including sensitive passwords. (Withpty=True, the remote pseudo-terminal will echo for you, and will intelligently handle password-style prompts.) See Pseudo-terminals for details.Similarly, if you need to programmatically examine the stderr stream of the remote program (exhibited as the
stderrattribute on this function’s return value), you may setcombine_stderr=False. Doing so has a high chance of causing garbled output to appear on your terminal (though the resulting strings returned byrunwill be properly separated). For more info, please read Combining stdout and stderr.To ignore non-zero return codes, specify
warn_only=True. To both ignore non-zero return codes and force a command to run silently, specifyquiet=True.To override which local streams are used to display remote stdout and/or stderr, specify
stdoutorstderr. (By default, the regularsys.stdoutandsys.stderrPython stream objects are used.)For example,
run("command", stderr=sys.stdout)would print the remote standard error to the local standard out, while preserving it as its own distinct attribute on the return value (as per above.) Alternately, you could even provide your own stream objects or loggers, e.g.myout = StringIO(); run("command", stdout=myout).If you want an exception raised when the remote program takes too long to run, specify
timeout=NwhereNis an integer number of seconds, after which to time out. This will causerunto raise aCommandTimeoutexception.If you want to disable Fabric’s automatic attempts at escaping quotes, dollar signs etc., specify
shell_escape=False.Examples:
run("ls /var/www/") run("ls /home/myuser", shell=False) output = run('ls /var/www/site1') run("take_a_long_time", timeout=5)
New in version 1.5: The
quiet,warn_only,stdoutandstderrkwargs.New in version 1.5: The return value attributes
.commandand.real_command.New in version 1.6: The
timeoutargument.New in version 1.7: The
shell_escapeargument.New in version 1.11: The
capture_buffer_sizeargument.New in version 1.17: The
stdinargument.
-
fabric.operations.sudo(command, shell=True, pty=True, combine_stderr=None, user=None, quiet=False, warn_only=False, stdin=None, stdout=None, stderr=None, group=None, timeout=None, shell_escape=None, capture_buffer_size=None)¶ Run a shell command on a remote host, with superuser privileges.
sudois identical in every way torun, except that it will always wrap the givencommandin a call to thesudoprogram to provide superuser privileges.sudoaccepts additionaluserandgrouparguments, which are passed tosudoand allow you to run as some user and/or group other than root. On most systems, thesudoprogram can take a string username/group or an integer userid/groupid (uid/gid);userandgroupmay likewise be strings or integers.You may set env.sudo_user at module level or via
settingsif you want multiplesudocalls to have the sameuservalue. An explicituserargument will, of course, override this global setting.Examples:
sudo("~/install_script.py") sudo("mkdir /var/www/new_docroot", user="www-data") sudo("ls /home/jdoe", user=1001) result = sudo("ls /tmp/") with settings(sudo_user='mysql'): sudo("whoami") # prints 'mysql'
Changed in version 1.5: Now honors env.sudo_user.
New in version 1.5: The
quiet,warn_only,stdoutandstderrkwargs.New in version 1.5: The return value attributes
.commandand.real_command.New in version 1.7: The
shell_escapeargument.New in version 1.11: The
capture_buffer_sizeargument.New in version 1.17: The
stdinargument.