This changelog lists each bugfix, feature addition, etc in the order they were checked into Fabric’s source code repository. Published releases are bolded, dated and inserted at the appropriate points in the timeline.
To find out the changes included in a given release, simply look at the entries between that release and the previous one from the same release line (e.g. 1.1.4 down through 1.1.3 would be the effective changelog for the 1.1.4 release.)
Bugfixes to older release lines are always forward-ported to newer releases, and this is reflected in the changelog. Thus, the changelog for e.g. 1.2.2 might contain entries for the 1.1 and 1.0 lines as well, because those changes would have also been included in the 1.2 line.
The content below this section comes from older versions of Fabric which wrote out changelogs to individual, undated files. They have been concatenated and preserved here for historical reasons, and may not be in strict chronological order.
This page lists all changes made to Fabric in its 1.1.0 release.
This release also includes all applicable changes from the 1.0.2 release.
This release also includes all applicable changes from the 0.9.7 release.
This release also includes all applicable changes from the 0.9.5 release.
This page lists all changes made to Fabric in its 1.0.0 release.
The below changes are backwards incompatible and have the potential to break your 0.9.x based fabfiles!
The following changes were implemented in Fabric 0.9.7:
The following changes were implemented in Fabric 0.9.6:
The following changes were implemented in Fabric 0.9.5:
The following changes were implemented in Fabric 0.9.4:
The following changes were implemented in Fabric 0.9.3:
The following changes were implemented in Fabric 0.9.2:
The following changes were implemented in Fabric 0.9.1:
This document details the various backwards-incompatible changes made during Fabric’s rewrite between versions 0.1 and 0.9. The codebase has been almost completely rewritten and reorganized and an attempt has been made to remove “magical” behavior and make things more simple and Pythonic; the fab command-line component has also been redone to behave more like a typical Unix program.
You’ll want to at least skim the entire document, but the primary changes that will need to be made to one’s fabfiles are as follows:
You will need to explicitly import any and all methods or decorators used, at the top of your fabfile; they are no longer magically available. Here’s a sample fabfile that worked with 0.1 and earlier:
@hosts('a', 'b') def my_task(): run('ls /var/www') sudo('mkdir /var/www/newsite')
The above fabfile uses hosts, run and sudo, and so in Fabric 0.9 one simply needs to import those objects from the new API module fabric.api:
from fabric.api import hosts, run, sudo @hosts('a', 'b') def my_task(): run('ls /var/www') sudo('mkdir /var/www/newsite')
You may, if you wish, use from fabric.api import *, though this is technically not Python best practices; or you may import directly from the Fabric submodules (e.g. from fabric.decorators import hosts.) See Fabfile construction and use for more information.
Fabric started out Python 2.5-only, but became largely 2.4 compatible at one point during its lifetime. Fabric is once again only compatible with Python 2.5 or newer, in order to take advantage of the various new features and functions available in that version.
With this change we’re setting an official policy to support the two most recent stable releases of the Python 2.x line, which at time of writing is 2.5 and 2.6. We feel this is a decent compromise between new features and the reality of operating system packaging concerns. Given that most users use Fabric from their workstations, which are typically more up-to-date than servers, we’re hoping this doesn’t cut out too many folks.
Finally, note that while we will not officially support a 2.4-compatible version or fork, we may provide a link to such a project if one arises.
The config object previously used to access and set internal state (including Fabric config options) has been renamed to env, but otherwise remains mostly the same (it allows both dictionary and object-attribute style access to its data.) env resides in the state submodule and is importable via fabric.api, so where before one might have seen fabfiles like this:
def my_task(): config.foo = 'bar'
one will now be explicitly importing the object like so:
from fabric.api import env def my_task(): env.foo = 'bar'
Fabric’s default mode of use, in prior versions, was what we called “broad mode”: your tasks, as Python code, ran only once, and any calls to functions that made connections (such as run or sudo) would run once per host in the current host list. We also offered “deep mode”, in which your entire task function would run once per host.
In Fabric 0.9, this dichotomy has been removed, and “deep mode” is the method Fabric uses to perform all operations. This allows you to treat your Fabfiles much more like regular Python code, including the use of if statements and so forth, and allows operations like run to unambiguously return the output from the server.
Other modes of execution such as the old “broad mode” may return as Fabric’s internals are refactored and expanded, but for now we’ve simplified things, and deep mode made the most sense as the primary mode of use.
Because of how Fabric used to run in “broad mode” (see previous section) a special string formatting technique – the use of a bash-like dollar sign notation, e.g. "hostname: $(fab_host)" – had to be used to allow the current state of execution to be represented in one’s operations. This is no longer necessary and has been removed. Because your tasks are executed once per host, you may build strings normally (e.g. with the % operator) and refer to env.host_string, env.user and so forth.
For example, Fabric 0.1 had to insert the current username like so:
print("Your current username is $(fab_user)")
Fabric 0.9 and up simply reference env variables as normal:
print("Your current username is %s" % env.user)
As with the execution modes, a special string interpolation function or method that automatically makes use of env values may find its way back into Fabric at some point if a need becomes apparent.
In no particular order:
The Fabric config file location used to be ~/.fabric; in the interests of honoring Unix filename conventions, it’s now ~/.fabricrc.
The old config object (now env) had a getAny method which took one or more key strings as arguments, and returned the value attached to the first valid key. This method still exists but has been renamed to first.
Environment variables such as fab_host have been renamed to simply e.g. host. This looks cleaner and feels more natural, and requires less typing. Users will naturally need to be careful not to override these variables, but the same holds true for e.g. Python’s builtin methods and types already, so we felt it was worth the tradeoff.
Fabric’s version header is no longer printed every time the program runs; you should now use the standard --version/-V command-line options to print version and exit.
The old about command has been removed; other Unix programs don’t typically offer this. Users can always view the license and warranty info in their respective text files distributed with the software.
The old help command is now the typical Unix options -h/--help.
- Furthermore, there is no longer a listing of Fabric’s programming API available through the command line – those topics impact fabfile authors, not fab users (even though the former is a subset of the latter) and should stay in the documentation only.
prompt‘s primary function is now to return a value to the caller, although it may still optionally store the entered value in env as well.
prompt now considers the empty string to be valid input; this allows other functions to wrap prompt and handle “empty” input on their own terms.
In addition to the above changes, prompt has been updated to behave more obviously, as its previous behavior was confusing in a few ways:
- It will now overwrite pre-existing values in the environment dict, but will print a warning to the user if it does so.
- Additionally, (and this appeared to be undocumented) the default argument could take a callable as well as a string, and would simply set the default message to the return value if a callable was given. This seemed to add unnecessary complexity (given that users may call e.g. prompt(blah, msg, default=my_callable()) so it has been removed.
When connecting, Fabric used to use the undocumented fab_pkey env variable as a method of passing in a Paramiko PKey object to the SSH client’s connect method. This has been removed in favor of an ssh-like -i option, which allows one to specify a private key file to use; that should generally be enough for most users.
download is now get in order to match up with put (the name mismatch was due to get being the old method of getting env vars.)
The noshell argument to sudo (added late in its life to previous Fabric versions) has been renamed to shell (defaults to True, so the effective behavior remains the same) and has also been extended to the run operation.
- Additionally, the global sudo_noshell option has been renamed to use_shell and also applies to both run and sudo.
local_per_host has been removed, as it only applied to the now-removed “broad mode”.
load has been removed; Fabric is now “just Python”, so use Python’s import mechanisms in order to stitch multiple fabfiles together.
abort is no longer an “operation” per se and has been moved to fabric.utils. It is otherwise the same as before, taking a single string message, printing it to the user and then calling sys.exit(1).
rsyncproject and upload_project have been moved into fabric.contrib (specifically, fabric.contrib.project), which is intended to be a new tree of submodules for housing “extra” code which may build on top of the core Fabric operations.
invoke has been turned on its head, and is now the runs_once decorator (living in fabric.decorators). When used to decorate a function, that function will only execute one time during the lifetime of a fab run. Thus, where you might have used invoke multiple times to ensure a given command only runs once, you may now use runs_once to decorate the function and then call it multiple times in a normal fashion.
It looks like the regex behavior of the validate argument to prompt was never actually implemented. It now works as advertised.
Couldn’t think of a good reason for require to be a decorator and a function, and the function is more versatile in terms of where it may be used, so the decorator has been removed.
As things currently stand with the execution model, the depends decorator doesn’t make a lot of sense: instead, it’s safest/best to simply make “meta” commands that just call whatever chain of “real” commands you need performed for a given overarching task.
For example, instead of having command A say that it “depends on” command B, create a command C which calls A and B in the right order, e.g.:
def build(): local('make clean all') def upload(): put('app.tgz', '/tmp/app.tgz') run('tar xzf /tmp/app.tgz') def symlink(): run('ln -s /srv/media/photos /var/www/app/photos') def deploy(): build() upload() symlink()
The execution model is still subject to change as Fabric evolves. Please don’t hesitate to email the list or the developers if you have a use case that needs something Fabric doesn’t provide right now!
Removed the old fab shell functionality, since the move to “just Python” should make vanilla python/ipython usage of Fabric much easier.
- We may add it back in later as a convenient shortcut to what basically amounts to running ipython and performing a handful of from fabric.foo import bar calls.
The undocumented fab_quiet option has been replaced by a much more granular set of output controls. For more info, see Managing output.
The below list was generated by running git shortlog 0.9a1..0.9a2 and then manually sifting through and editing the resulting commit messages. This will probably occur for the rest of the alphas and betas; we hope to use Sphinx-specific methods of documenting changes once the final release is out the door.
This is closer to being a straight dump of the Git changelog than the previous sections; apologies for the overall change in tense.
As with the previous changelog, this is also mostly a dump of the Git log. We promise that future changelogs will be more verbose :)