diff -Nru fabric-1.8.2/AUTHORS fabric-1.10.0/AUTHORS --- fabric-1.8.2/AUTHORS 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/AUTHORS 2014-09-04 00:52:45.000000000 +0000 @@ -57,3 +57,4 @@ Rory Geoghegan Alexey Diyan Kamil Kisiel +Jonas Lundberg diff -Nru fabric-1.8.2/debian/changelog fabric-1.10.0/debian/changelog --- fabric-1.8.2/debian/changelog 2014-02-22 23:14:53.000000000 +0000 +++ fabric-1.10.0/debian/changelog 2014-10-05 00:35:23.000000000 +0000 @@ -1,3 +1,18 @@ +fabric (1.10.0-1) unstable; urgency=medium + + * New upstream release. (Closes: #760152) + * Update versioned depends on python-paramiko to >= 1.10. + Thanks David Banks for the suggestion. (Closes: #740930) + * Update Vcs-* fields. + * Packaging updates to generate the documentation: + - Add b-d on python-alabaster. + - Drop patch disable_sphinx_extension.patch. + - Update debian/rules accordingly. + - Update no_adsense patch to work with the new doc system. + * Update to Standards-Version 3.9.6, no changes required. + + -- Ana Beatriz Guerrero Lopez Sun, 05 Oct 2014 02:35:21 +0200 + fabric (1.8.2-1) unstable; urgency=medium * New upstream release. diff -Nru fabric-1.8.2/debian/control fabric-1.10.0/debian/control --- fabric-1.8.2/debian/control 2014-02-22 22:53:44.000000000 +0000 +++ fabric-1.10.0/debian/control 2014-10-05 00:33:57.000000000 +0000 @@ -3,15 +3,16 @@ Priority: optional Maintainer: Ana Beatriz Guerrero Lopez Build-Depends: debhelper (>= 7.0.50~), python-all (>= 2.6.6-3~) -Build-Depends-Indep: python-setuptools, python-sphinx, python-paramiko, python-fudge -Standards-Version: 3.9.5 -Vcs-Git: git://github.com/ana/pkg-fabric.git -Vcs-Browser: https://github.com/ana/pkg-fabric +Build-Depends-Indep: python-setuptools, python-sphinx, python-paramiko, + python-fudge, python-alabaster +Standards-Version: 3.9.6 +Vcs-Git: git://anonscm.debian.org/collab-maint/fabric.git +Vcs-Browser: http://anonscm.debian.org/cgit/collab-maint/fabric.git Homepage: http://fabfile.org/ Package: fabric Architecture: all -Depends: ${misc:Depends}, ${python:Depends}, python-paramiko (>= 1.6), python-pkg-resources, python-nose +Depends: ${misc:Depends}, ${python:Depends}, python-paramiko (>= 1.10), python-pkg-resources, python-nose Suggests: libjs-jquery Description: Simple Pythonic remote deployment tool Fabric is designed to upload files and run shell commands on a number of diff -Nru fabric-1.8.2/debian/docs fabric-1.10.0/debian/docs --- fabric-1.8.2/debian/docs 2014-02-22 21:09:35.000000000 +0000 +++ fabric-1.10.0/debian/docs 2014-10-04 23:10:26.000000000 +0000 @@ -1 +1 @@ -docs/_build/html +sites/docs/html diff -Nru fabric-1.8.2/debian/patches/disable_sphinx_extension.patch fabric-1.10.0/debian/patches/disable_sphinx_extension.patch --- fabric-1.8.2/debian/patches/disable_sphinx_extension.patch 2014-02-22 22:49:05.000000000 +0000 +++ fabric-1.10.0/debian/patches/disable_sphinx_extension.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- a/docs/conf.py -+++ b/docs/conf.py -@@ -26,7 +26,7 @@ from datetime import datetime - - # Add any Sphinx extension module names here, as strings. They can be extensions - # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. --extensions = ['sphinx.ext.autodoc', 'releases'] -+extensions = ['sphinx.ext.autodoc'] - - # 'releases' (changelog) settings - releases_issue_uri = "https://github.com/fabric/fabric/issues/%s" diff -Nru fabric-1.8.2/debian/patches/no_adsense.patch fabric-1.10.0/debian/patches/no_adsense.patch --- fabric-1.8.2/debian/patches/no_adsense.patch 2014-02-22 22:55:14.000000000 +0000 +++ fabric-1.10.0/debian/patches/no_adsense.patch 2014-10-05 00:31:32.000000000 +0000 @@ -1,21 +1,16 @@ ---- a/docs/_templates/layout.html -+++ b/docs/_templates/layout.html -@@ -2,18 +2,6 @@ - - {%- block extrahead %} - {{ super() }} -- - - {% endblock %} - +Description: remove Google adsense +--- +Forwarded: not-needed +Last-Update: 2014-10-05 + +--- fabric-1.10.0.orig/sites/shared_conf.py ++++ fabric-1.10.0/sites/shared_conf.py +@@ -19,7 +19,7 @@ html_theme_options = { + 'github_repo': 'fabric', + 'travis_button': True, + 'gittip_user': 'bitprophet', +- 'analytics_id': 'UA-18486793-1', ++# 'analytics_id': 'UA-18486793-1', + + 'link': '#3782BE', + 'link_hover': '#3782BE', diff -Nru fabric-1.8.2/debian/patches/series fabric-1.10.0/debian/patches/series --- fabric-1.8.2/debian/patches/series 2014-02-22 23:15:08.000000000 +0000 +++ fabric-1.10.0/debian/patches/series 2014-10-05 00:29:48.000000000 +0000 @@ -1,2 +1 @@ -disable_sphinx_extension.patch no_adsense.patch diff -Nru fabric-1.8.2/debian/rules fabric-1.10.0/debian/rules --- fabric-1.8.2/debian/rules 2014-02-22 21:09:35.000000000 +0000 +++ fabric-1.10.0/debian/rules 2014-10-05 00:24:59.000000000 +0000 @@ -5,19 +5,17 @@ override_dh_auto_build: dh_auto_build - $(MAKE) -C docs html + sphinx-build -b html -c sites/docs/ sites/docs/ sites/docs/html override_dh_auto_clean: - rm -rf paramiko/ + rm -rf sites/docs/html/ dh_auto_clean override_dh_auto_install: ln -sf /usr/share/javascript/jquery/jquery.js \ - docs/_build/html/_static/jquery.js + sites/docs/html/_static/jquery.js + rm -rf sites/docs/html/.doctrees dh_auto_install -override_dh_installchangelogs: - dh_installchangelogs --exclude=changes - override_dh_compress: - dh_compress -X.js -X.txt + dh_compress -X.js -X.txt -X.html diff -Nru fabric-1.8.2/docs/api/contrib/console.rst fabric-1.10.0/docs/api/contrib/console.rst --- fabric-1.8.2/docs/api/contrib/console.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/contrib/console.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Console Output Utilities -======================== - -.. automodule:: fabric.contrib.console - :members: diff -Nru fabric-1.8.2/docs/api/contrib/django.rst fabric-1.10.0/docs/api/contrib/django.rst --- fabric-1.8.2/docs/api/contrib/django.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/contrib/django.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -================== -Django Integration -================== - -.. automodule:: fabric.contrib.django - :members: diff -Nru fabric-1.8.2/docs/api/contrib/files.rst fabric-1.10.0/docs/api/contrib/files.rst --- fabric-1.8.2/docs/api/contrib/files.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/contrib/files.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -============================= -File and Directory Management -============================= - -.. automodule:: fabric.contrib.files - :members: diff -Nru fabric-1.8.2/docs/api/contrib/project.rst fabric-1.10.0/docs/api/contrib/project.rst --- fabric-1.8.2/docs/api/contrib/project.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/contrib/project.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -============= -Project Tools -============= - -.. automodule:: fabric.contrib.project - :members: diff -Nru fabric-1.8.2/docs/api/core/colors.rst fabric-1.10.0/docs/api/core/colors.rst --- fabric-1.8.2/docs/api/core/colors.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/colors.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -====================== -Color output functions -====================== - -.. automodule:: fabric.colors - :members: - :undoc-members: diff -Nru fabric-1.8.2/docs/api/core/context_managers.rst fabric-1.10.0/docs/api/core/context_managers.rst --- fabric-1.8.2/docs/api/core/context_managers.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/context_managers.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -================ -Context Managers -================ - -.. automodule:: fabric.context_managers - :members: diff -Nru fabric-1.8.2/docs/api/core/decorators.rst fabric-1.10.0/docs/api/core/decorators.rst --- fabric-1.8.2/docs/api/core/decorators.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/decorators.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -========== -Decorators -========== - -.. automodule:: fabric.decorators - :members: hosts, roles, runs_once, serial, parallel, task, with_settings diff -Nru fabric-1.8.2/docs/api/core/docs.rst fabric-1.10.0/docs/api/core/docs.rst --- fabric-1.8.2/docs/api/core/docs.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/docs.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -===================== -Documentation helpers -===================== - -.. automodule:: fabric.docs - :members: diff -Nru fabric-1.8.2/docs/api/core/network.rst fabric-1.10.0/docs/api/core/network.rst --- fabric-1.8.2/docs/api/core/network.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/network.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -======= -Network -======= - -.. automodule:: fabric.network - - .. autofunction:: disconnect_all diff -Nru fabric-1.8.2/docs/api/core/operations.rst fabric-1.10.0/docs/api/core/operations.rst --- fabric-1.8.2/docs/api/core/operations.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/operations.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -========== -Operations -========== - -.. automodule:: fabric.operations - :members: diff -Nru fabric-1.8.2/docs/api/core/tasks.rst fabric-1.10.0/docs/api/core/tasks.rst --- fabric-1.8.2/docs/api/core/tasks.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/tasks.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -===== -Tasks -===== - -.. automodule:: fabric.tasks - :members: Task, WrappedCallableTask, execute diff -Nru fabric-1.8.2/docs/api/core/utils.rst fabric-1.10.0/docs/api/core/utils.rst --- fabric-1.8.2/docs/api/core/utils.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/api/core/utils.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -===== -Utils -===== - -.. automodule:: fabric.utils - :members: diff -Nru fabric-1.8.2/docs/changelog.rst fabric-1.10.0/docs/changelog.rst --- fabric-1.8.2/docs/changelog.rst 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/docs/changelog.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,1556 +0,0 @@ -:orphan: - -========= -Changelog -========= - -* :release:`1.8.2 <2014-02-14>` -* :release:`1.7.2 <2014-02-14>` -* :bug:`955` Quote directories created as part of ``put``'s recursive directory - uploads when ``use_sudo=True`` so directories with shell meta-characters - (such as spaces) work correctly. Thanks to John Harris for the catch. -* :bug:`917` Correct an issue with ``put(use_sudo=True, mode=xxx)`` where the - ``chmod`` was trying to apply to the wrong location. Thanks to Remco - (``@nl5887``) for catch & patch. -* :bug:`1046` Fix typo preventing use of ProxyCommand in some situations. - Thanks to Keith Yang. -* :release:`1.8.1 <2013-12-24>` -* :release:`1.7.1 <2013-12-24>` -* :release:`1.6.4 <2013-12-24>` 956, 957 -* :release:`1.5.5 <2013-12-24>` 956, 957 -* :bug:`956` Fix pty size detection when running inside Emacs. Thanks to - `@akitada` for catch & patch. -* :bug:`957` Fix bug preventing use of :ref:`env.gateway ` with - targets requiring password authentication. Thanks to Daniel González, - `@Bengrunt` and `@adrianbn` for their bug reports. -* :bug:`948` Handle connection failures due to server load and try connecting - to hosts a number of times specified in :ref:`env.connection_attempts - `. -* :release:`1.8.0 <2013-09-20>` -* :feature:`931` Allow overriding of `.abort` behavior via a custom - exception-returning callable set as :ref:`env.abort_exception - `. Thanks to Chris Rose for the patch. -* :support:`984 backported` Make this changelog easier to read! Now with - per-release sections, generated automatically from the old timeline source - format. -* :feature:`910` Added a keyword argument to rsync_project to configure the - default options. Thanks to ``@moorepants`` for the patch. -* :release:`1.7.0 <2013-07-26>` -* :release:`1.6.2 <2013-07-26>` -* :feature:`925` Added `contrib.files.is_link <.is_link>`. Thanks to `@jtangas` - for the patch. -* :feature:`922` Task argument strings are now displayed when using - :option:`fab -d <-d>`. Thanks to Kevin Qiu for the patch. -* :bug:`912` Leaving ``template_dir`` un-specified when using - `.upload_template` in Jinja mode used to cause ``'NoneType' has no attribute - 'startswith'`` errors. This has been fixed. Thanks to Erick Yellott for catch - & to Erick Yellott + Kevin Williams for patches. -* :feature:`924` Add new env var option :ref:`colorize-errors` to enable - coloring errors and warnings. Thanks to Aaron Meurer for the patch. -* :bug:`593` Non-ASCII character sets in Jinja templates rendered within - `.upload_template` would cause ``UnicodeDecodeError`` when uploaded. This has - been addressed by encoding as ``utf-8`` prior to upload. Thanks to Sébastien - Fievet for the catch. -* :feature:`908` Support loading SSH keys from memory. Thanks to Caleb Groom - for the patch. -* :bug:`171` Added missing cross-references from ``env`` variables documentation - to corresponding command-line options. Thanks to Daniel D. Beck for the - contribution. -* :bug:`884` The password cache feature was not working correctly with - password-requiring SSH gateway connections. That's fixed now. Thanks to Marco - Nenciarini for the catch. -* :feature:`826` Enable sudo extraction of compressed archive via `use_sudo` - kwarg in `.upload_project`. Thanks to ``@abec`` for the patch. -* :bug:`694 major` Allow users to work around ownership issues in the default - remote login directory: add ``temp_dir`` kwarg for explicit specification of - which "bounce" folder to use when calling `.put` with ``use_sudo=True``. - Thanks to Devin Bayer for the report & Dieter Plaetinck / Jesse Myers for - suggesting the workaround. -* :bug:`882` Fix a `.get` bug regarding spaces in remote working directory - names. Thanks to Chris Rose for catch & patch. -* :release:`1.6.1 <2013-05-23>` -* :bug:`868` Substantial speedup of parallel tasks by removing an unnecessary - blocking timeout in the ``JobQueue`` loop. Thanks to Simo Kinnunen for the - patch. -* :bug:`328` `.lcd` was no longer being correctly applied to - `.upload_template`; this has been fixed. Thanks to Joseph Lawson for the - catch. -* :feature:`812` Add ``use_glob`` option to `.put` so users trying to upload - real filenames containing glob patterns (``*``, ``[`` etc) can disable the - default globbing behavior. Thanks to Michael McHugh for the patch. -* :bug:`864 major` Allow users to disable Fabric's auto-escaping in - `.run`/`.sudo`. Thanks to Christian Long and Michael McHugh for the patch. -* :bug:`870` Changes to shell env var escaping highlighted some extraneous and - now damaging whitespace in `with path(): <.path>`. This has been removed and - a regression test added. -* :bug:`871` Use of string mode values in `put(local, remote, mode="NNNN") - <.put>` would sometimes cause ``Unsupported operand`` errors. This has been - fixed. -* :bug:`84 major` Fixed problem with missing -r flag in Mac OS X sed version. - Thanks to Konrad Hałas for the patch. -* :bug:`861` Gracefully handle situations where users give a single string - literal to ``env.hosts``. Thanks to Bill Tucker for catch & patch. -* :bug:`367` Expand paths with tilde inside (``contrib.files``). Thanks to - Konrad Hałas for catch & patch. -* :feature:`845 backported` Downstream synchronization option implemented for - `~fabric.contrib.project.rsync_project`. Thanks to Antonio Barrero for the - patch. -* :release:`1.6.0 <2013-03-01>` -* :release:`1.5.4 <2013-03-01>` -* :bug:`844` Account for SSH config overhaul in Paramiko 1.10 by e.g. updating - treatment of ``IdentityFile`` to handle multiple values. **This and related - SSH config parsing changes are backwards incompatible**; we are including - them in this release because they do fix incorrect, off-spec behavior. -* :bug:`843` Ensure string ``pool_size`` values get run through ``int()`` - before deriving final result (stdlib ``min()`` has odd behavior here...). - Thanks to Chris Kastorff for the catch. -* :bug:`839` Fix bug in `~fabric.contrib.project.rsync_project` where IPv6 - address were not always correctly detected. Thanks to Antonio Barrero for - catch & patch. -* :bug:`587` Warn instead of aborting when :ref:`env.use_ssh_config - ` is True but the configured SSH conf file doesn't exist. - This allows multi-user fabfiles to enable SSH config without causing hard - stops for users lacking SSH configs. Thanks to Rodrigo Pimentel for the - report. -* :feature:`821` Add `~fabric.context_managers.remote_tunnel` to allow reverse - SSH tunneling (exposing locally-visible network ports to the remote end). - Thanks to Giovanni Bajo for the patch. -* :feature:`823` Add :ref:`env.remote_interrupt ` which - controls whether Ctrl-C is forwarded to the remote end or is captured locally - (previously, only the latter behavior was implemented). Thanks to Geert - Jansen for the patch. -* :release:`1.5.3 <2013-01-28>` -* :bug:`806` Force strings given to ``getpass`` during password prompts to be - ASCII, to prevent issues on some platforms when Unicode is encountered. - Thanks to Alex Louden for the patch. -* :bug:`805` Update `~fabric.context_managers.shell_env` to play nice with - Windows (7, at least) systems and `~fabric.operations.local`. Thanks to - Fernando Macedo for the patch. -* :bug:`654` Parallel runs whose sum total of returned data was large (e.g. - large return values from the task, or simply a large number of hosts in the - host list) were causing frustrating hangs. This has been fixed. -* :feature:`402` Attempt to detect stale SSH sessions and reconnect when they - arise. Thanks to `@webengineer` for the patch. -* :bug:`791` Cast `~fabric.operations.reboot`'s ``wait`` parameter to a numeric - type in case the caller submitted a string by mistake. Thanks to Thomas - Schreiber for the patch. -* :bug:`703 major` Add a ``shell`` kwarg to many methods in - `~fabric.contrib.files` to help avoid conflicts with - `~fabric.context_managers.cd` and similar. Thanks to `@mikek` for the patch. -* :feature:`730` Add :ref:`env.system_known_hosts/--system-known-hosts - ` to allow loading a user-specified system-level SSH - ``known_hosts`` file. Thanks to Roy Smith for the patch. -* :release:`1.5.2 <2013-01-15>` -* :feature:`818` Added :ref:`env.eagerly_disconnect ` - option to help prevent pile-up of many open connections. -* :feature:`706` Added :ref:`env.tasks `, returning list of tasks to - be executed by current ``fab`` command. -* :bug:`766` Use the variable name of a new-style ``fabric.tasks.Task`` - subclass object when the object name attribute is undefined. Thanks to - `@todddeluca` for the patch. -* :bug:`604` Fixed wrong treatment of backslashes in put operation when uploading - directory tree on Windows. Thanks to Jason Coombs for the catch and - `@diresys` & Oliver Janik for the patch. - for the patch. -* :bug:`792` The newish `~fabric.context_managers.shell_env` context manager - was incorrectly omitted from the ``fabric.api`` import endpoint. This has - been remedied. Thanks to Vishal Rana for the catch. -* :feature:`735` Add ``ok_ret_codes`` option to ``env`` to allow alternate - return codes to be treated os "ok". Thanks to Andy Kraut for the pull request. -* :bug:`775` Shell escaping was incorrectly applied to the value of ``$PATH`` - updates in our shell environment handling, causing (at the very least) - `~fabric.operations.local` binary paths to become inoperable in certain - situations. This has been fixed. -* :feature:`787` Utilize new Paramiko feature allowing us to skip the use of - temporary local files when using file-like objects in - `~fabric.operations.get`/`~fabric.operations.put`. -* :feature:`249` Allow specification of remote command timeout value by - setting :ref:`env.command_timeout `. Thanks to Paul - McMillan for suggestion & initial patch. -* Added current host string to prompt abort error messages. -* :release:`1.5.1 <2012-11-15>` -* :bug:`776` Fixed serious-but-non-obvious bug in direct-tcpip driven - gatewaying (e.g. that triggered by ``-g`` or ``env.gateway``.) Should work - correctly now. -* :bug:`771` Sphinx autodoc helper `~fabric.docs.unwrap_tasks` didn't play nice - with ``@task(name=xxx)`` in some situations. This has been fixed. -* :release:`1.5.0 <2012-11-06>` -* :release:`1.4.4 <2012-11-06>` -* :feature:`38` (also :issue:`698`) Implement both SSH-level and - ``ProxyCommand``-based gatewaying for SSH traffic. (This is distinct from - tunneling non-SSH traffic over the SSH connection, which is :issue:`78` and - not implemented yet.) - - * Thanks in no particular order to Erwin Bolwidt, Oskari Saarenmaa, Steven - Noonan, Vladimir Lazarenko, Lincoln de Sousa, Valentino Volonghi, Olle - Lundberg and Github user `@acrish` for providing the original patches to - both Fabric and Paramiko. - -* :feature:`684 backported` (also :issue:`569`) Update how - `~fabric.decorators.task` wraps task functions to preserve additional - metadata; this allows decorated functions to play nice with Sphinx autodoc. - Thanks to Jaka Hudoklin for catch & patch. -* :support:`103` (via :issue:`748`) Long standing Sphinx autodoc issue requiring - error-prone duplication of function signatures in our API docs has been - fixed. Thanks to Alex Morega for the patch. -* :bug:`767 major` Fix (and add test for) regression re: having linewise output - automatically activate when parallelism is in effect. Thanks to Alexander - Fortin and Dustin McQuay for the bug reports. -* :bug:`736 major` Ensure context managers that build env vars play nice with - ``contextlib.nested`` by deferring env var reference to entry time, not call - time. Thanks to Matthew Tretter for catch & patch. -* :feature:`763` Add :option:`--initial-password-prompt <-I>` to allow - prefilling the password cache at the start of a run. Great for sudo-powered - parallel runs. -* :feature:`665` (and #629) Update `~fabric.contrib.files.upload_template` to - have a more useful return value, namely that of its internal - `~fabric.operations.put` call. Thanks to Miquel Torres for the catch & - Rodrigue Alcazar for the patch. -* :feature:`578` Add ``name`` argument to `~fabric.decorators.task` (:ref:`docs - `) to allow overriding of the default "function - name is task name" behavior. Thanks to Daniel Simmons for catch & patch. -* :feature:`761` Allow advanced users to parameterize ``fabric.main.main()`` to - force loading of specific fabfiles. -* :bug:`749` Gracefully work around calls to ``fabric.version`` on systems - lacking ``/bin/sh`` (which causes an ``OSError`` in ``subprocess.Popen`` - calls.) -* :feature:`723` Add the ``group=`` argument to - `~fabric.operations.sudo`. Thanks to Antti Kaihola for the pull request. -* :feature:`725` Updated `~fabric.operations.local` to allow override - of which local shell is used. Thanks to Mustafa Khattab. -* :bug:`704 major` Fix up a bunch of Python 2.x style ``print`` statements to - be forwards compatible. Thanks to Francesco Del Degan for the patch. -* :feature:`491` (also :feature:`385`) IPv6 host string support. Thanks to Max - Arnold for the patch. -* :feature:`699` Allow `name` attribute on file-like objects for get/put. Thanks - to Peter Lyons for the pull request. -* :bug:`711 major` `~fabric.sftp.get` would fail when filenames had % in their - path. Thanks to John Begeman -* :bug:`702 major` `~fabric.operations.require` failed to test for "empty" - values in the env keys it checks (e.g. - ``require('a-key-whose-value-is-an-empty-list')`` would register a successful - result instead of alerting that the value was in fact empty. This has been - fixed, thanks to Rich Schumacher. -* :bug:`718` ``isinstance(foo, Bar)`` is used in `~fabric.main` instead - of ``type(foo) == Bar`` in order to fix some edge cases. - Thanks to Mikhail Korobov. -* :bug:`693` Fixed edge case where ``abort`` driven failures within parallel - tasks could result in a top level exception (a ``KeyError``) regarding error - handling. Thanks to Marcin Kuźmiński for the report. -* :support:`681 backported` Fixed outdated docstring for - `~fabric.decorators.runs_once` which claimed it would get run multiple times - in parallel mode. That behavior was fixed in an earlier release but the docs - were not updated. Thanks to Jan Brauer for the catch. -* :release:`1.4.3 <2012-07-06>` -* :release:`1.3.8 <2012-07-06>` -* :feature:`263` Shell environment variable support for - `~fabric.operations.run`/`~fabric.operations.sudo` added in the form of the - `~fabric.context_managers.shell_env` context manager. Thanks to Oliver - Tonnhofer for the original pull request, and to Kamil Kisiel for the final - implementation. -* :feature:`669` Updates to our Windows compatibility to rely more heavily on - cross-platform Python stdlib implementations. Thanks to Alexey Diyan for the - patch. -* :bug:`671` :ref:`reject-unknown-hosts` sometimes resulted in a password - prompt instead of an abort. This has been fixed. Thanks to Roy Smith for the - report. -* :bug:`659` Update docs to reflect that `~fabric.operations.local` currently - honors :ref:`env.path `. Thanks to `@floledermann - `_ for the catch. -* :bug:`652` Show available commands when aborting on invalid command names. -* :support:`651 backported` Added note about nesting ``with`` statements on - Python 2.6+. Thanks to Jens Rantil for the patch. -* :bug:`649` Don't swallow non-``abort``-driven exceptions in parallel mode. - Fabric correctly printed such exceptions, and returned them from - `~fabric.tasks.execute`, but did not actually cause the child or parent - processes to halt with a nonzero status. This has been fixed. - `~fabric.tasks.execute` now also honors :ref:`env.warn_only ` so - users may still opt to call it by hand and inspect the returned exceptions, - instead of encountering a hard stop. Thanks to Matt Robenolt for the catch. -* :feature:`241` Add the command executed as a ``.command`` attribute to the - return value of `~fabric.operations.run`/`~fabric.operations.sudo`. (Also - includes a second attribute containing the "real" command executed, including - the shell wrapper and any escaping.) -* :feature:`646` Allow specification of which local streams to use when - `~fabric.operations.run`/`~fabric.operations.sudo` print the remote - stdout/stderr, via e.g. ``run("command", stderr=sys.stdout)``. -* :support:`645 backported` Update Sphinx docs to work well when run out of a - source tarball as opposed to a Git checkout. Thanks again to `@Arfrever` for - the catch. -* :support:`640 backported` (also :issue:`644`) Update packaging manifest so - sdist tarballs include all necessary test & doc files. Thanks to Mike Gilbert - and `@Arfrever` for catch & patch. -* :feature:`627` Added convenient ``quiet`` and ``warn_only`` keyword arguments - to `~fabric.operations.run`/`~fabric.operations.sudo` which are aliases for - ``settings(hide('everything'), warn_only=True)`` and - ``settings(warn_only=True)``, respectively. (Also added corresponding - `context ` `managers - `.) Useful for remote program calls which - are expected to fail and/or whose output doesn't need to be shown to users. -* :feature:`633` Allow users to turn off host list deduping by setting - :ref:`env.dedupe_hosts ` to ``False``. This enables running the - same task multiple times on a single host, which was previously not possible. -* :support:`634 backported` Clarified that `~fabric.context_managers.lcd` does - no special handling re: the user's current working directory, and thus - relative paths given to it will be relative to ``os.getcwd()``. Thanks to - `@techtonik `_ for the catch. -* :release:`1.4.2 <2012-05-07>` -* :release:`1.3.7 <2012-05-07>` -* :bug:`562` Agent forwarding would error out or freeze when multiple uses of - the forwarded agent were used per remote invocation (e.g. a single - `~fabric.operations.run` command resulting in multiple Git or SVN checkouts.) - This has been fixed thanks to Steven McDonald and GitHub user `@lynxis`. -* :support:`626 backported` Clarity updates to the tutorial. Thanks to GitHub - user `m4z` for the patches. -* :bug:`625` `~fabric.context_managers.hide`/`~fabric.context_managers.show` - did not correctly restore prior display settings if an exception was raised - inside the block. This has been fixed. -* :bug:`624` Login password prompts did not always display the username being - authenticated for. This has been fixed. Thanks to Nick Zalutskiy for catch & - patch. -* :bug:`617` Fix the ``clean_revert`` behavior of - `~fabric.context_managers.settings` so it doesn't ``KeyError`` for newly - created settings keys. Thanks to Chris Streeter for the catch. -* :feature:`615` Updated `~fabric.operations.sudo` to honor the new setting - :ref:`env.sudo_user ` as a default for its ``user`` kwarg. -* :bug:`616` Add port number to the error message displayed upon connection - failures. -* :bug:`609` (and :issue:`564`) Document and clean up :ref:`env.sudo_prefix - ` so it can be more easily modified by users facing uncommon - use cases. Thanks to GitHub users `3point2` for the cleanup and `SirScott` - for the documentation catch. -* :bug:`610` Change detection of ``env.key_filename``'s type (added as part of - SSH config support in 1.4) so it supports arbitrary iterables. Thanks to - Brandon Rhodes for the catch. -* :release:`1.4.1 <2012-04-04>` -* :release:`1.3.6 <2012-04-04>` -* :bug:`608` Add ``capture`` kwarg to `~fabric.contrib.project.rsync_project` - to aid in debugging rsync problems. -* :bug:`607` Allow `~fabric.operations.local` to display stdout/stderr when it - warns/aborts, if it was capturing them. -* :bug:`395` Added :ref:`an FAQ entry ` detailing how to - handle init scripts which misbehave when a pseudo-tty is allocated. -* :bug:`568` `~fabric.tasks.execute` allowed too much of its internal state - changes (to variables such as ``env.host_string`` and ``env.parallel``) to - persist after execution completed; this caused a number of different - incorrect behaviors. `~fabric.tasks.execute` has been overhauled to clean up - its own state changes -- while preserving any state changes made by the task - being executed. -* :bug:`584` `~fabric.contrib.project.upload_project` did not take explicit - remote directory location into account when untarring, and now uses - `~fabric.context_managers.cd` to address this. Thanks to Ben Burry for the - patch. -* :bug:`458` `~fabric.decorators.with_settings` did not perfectly match - `~fabric.context_managers.settings`, re: ability to inline additional context - managers. This has been corrected. Thanks to Rory Geoghegan for the patch. -* :bug:`499` `contrib.files.first ` used an - outdated function signature in its wrapped `~fabric.contrib.files.exists` - call. This has been fixed. Thanks to Massimiliano Torromeo for catch & patch. -* :bug:`551` :option:`--list <-l>` output now detects terminal window size - and truncates (or doesn't truncate) accordingly. Thanks to Horacio G. de Oro - for the initial pull request. -* :bug:`572` Parallel task aborts (as oppposed to unhandled exceptions) now - correctly print their abort messages instead of tracebacks, and cause the - parent process to exit with the correct (nonzero) return code. Thanks to Ian - Langworth for the catch. -* :bug:`306` Remote paths now use posixpath for a separator. Thanks to Jason - Coombs for the patch. -* :release:`1.4.0 <2012-02-13>` -* :release:`1.3.5 <2012-02-13>` -* :release:`1.2.6 <2012-02-13>` -* :release:`1.1.8 <2012-02-13>` -* :bug:`495` Fixed documentation example showing how to subclass - `~fabric.tasks.Task`. Thanks to Brett Haydon for the catch and Mark Merritt - for the patch. -* :bug:`410` Fixed a bug where using the `~fabric.decorators.task` decorator - inside/under another decorator such as `~fabric.decorators.hosts` could cause - that task to become invalid when invoked by name (due to how old-style vs - new-style tasks are detected.) Thanks to Dan Colish for the initial patch. -* :feature:`559` `~fabric.contrib.project.rsync_project` now allows users to - append extra SSH-specific arguments to ``rsync``'s ``--rsh`` flag. -* :feature:`138` :ref:`env.port ` may now be written to at fabfile module - level to set a default nonstandard port number. Previously this value was - read-only. -* :feature:`3` Fabric can now load a subset of SSH config functionality - directly from your local ``~/.ssh/config`` if :ref:`env.use_ssh_config - ` is set to ``True``. See :ref:`ssh-config` for details. - Thanks to Kirill Pinchuk for the initial patch. -* :feature:`12` Added the ability to try connecting multiple times to - temporarily-down remote systems, instead of immediately failing. (Default - behavior is still to only try once.) See :ref:`env.timeout ` and - :ref:`env.connection_attempts ` for controlling both - connection timeouts and total number of attempts. `~fabric.operations.reboot` - has also been overhauled (but practically deprecated -- see its updated - docs.) -* :feature:`474` `~fabric.tasks.execute` now allows you to access the executed - task's return values, by itself returning a dictionary whose keys are the - host strings executed against. -* :bug:`487 major` Overhauled the regular expression escaping performed in - `~fabric.contrib.files.append` and `~fabric.contrib.files.contains` to try - and handle more corner cases. Thanks to Neilen Marais for the patch. -* :support:`532` Reorganized and cleaned up the output of ``fab --help``. -* :feature:`8` Added :option:`--skip-bad-hosts`/:ref:`env.skip_bad_hosts - ` option to allow skipping past temporarily down/unreachable - hosts. -* :feature:`13` Env vars may now be set at runtime via the new :option:`--set` - command-line flag. -* :feature:`506` A new :ref:`output alias `, ``commands``, has - been added, which allows hiding remote stdout and local "running command X" - output lines. -* :feature:`72` SSH agent forwarding support has made it into Fabric's SSH - library, and hooks for using it have been added (disabled by default; use - :option:`-A` or :ref:`env.forward_agent ` to enable.) Thanks - to Ben Davis for porting an existing Paramiko patch to `ssh` and providing - the necessary tweak to Fabric. -* :release:`1.3.4 <2012-01-12>` -* :bug:`492` `@parallel ` did not automatically - trigger :ref:`linewise output `, as was intended. This has - been fixed. Thanks to Brandon Huey for the catch. -* :bug:`510` Parallel mode is incompatible with user input, such as - password/hostname prompts, and was causing cryptic `Operation not supported - by device` errors when such prompts needed to be displayed. This behavior has - been updated to cleanly and obviously ``abort`` instead. -* :bug:`494` Fixed regression bug affecting some `env` values such as - `env.port` under parallel mode. Symptoms included - `~fabric.contrib.project.rsync_project` bailing out due to a None port value - when run under `@parallel `. Thanks to Rob - Terhaar for the report. -* :bug:`339` Don't show imported `~fabric.colors` members in :option:`--list - <-l>` output. Thanks to Nick Trew for the report. -* :release:`1.3.3 <2011-11-23>` -* :release:`1.2.5 <2011-11-23>` -* :release:`1.1.7 <2011-11-23>` -* :bug:`441` Specifying a task module as a task on the command line no longer - blows up but presents the usual "no task by that name" error message instead. - Thanks to Mitchell Hashimoto for the catch. -* :bug:`475` Allow escaping of equals signs in per-task args/kwargs. -* :bug:`450` Improve traceback display when handling ``ImportError`` for - dependencies. Thanks to David Wolever for the patches. -* :bug:`446` Add QNX to list of secondary-case `~fabric.contrib.files.sed` - targets. Thanks to Rodrigo Madruga for the tip. -* :bug:`443` `~fabric.contrib.files.exists` didn't expand tildes; now it does. - Thanks to Riccardo Magliocchetti for the patch. -* :bug:`437` `~fabric.decorators.with_settings` now correctly preserves the - wrapped function's docstring and other attributes. Thanks to Eric Buckley for - the catch and Luke Plant for the patch. -* :bug:`400` Handle corner case of systems where ``pwd.getpwuid`` raises - ``KeyError`` for the user's UID instead of returning a valid string. Thanks - to Dougal Matthews for the catch. -* :bug:`397` Some poorly behaved objects in third party modules triggered - exceptions during Fabric's "classic or new-style task?" test. A fix has been - added which tries to work around these. -* :bug:`341` `~fabric.contrib.files.append` incorrectly failed to detect that - the line(s) given already existed in files hidden to the remote user, and - continued appending every time it ran. This has been fixed. Thanks to - Dominique Peretti for the catch and Martin Vilcans for the patch. -* :bug:`342` Combining `~fabric.context_managers.cd` with - `~fabric.operations.put` and its ``use_sudo`` keyword caused an unrecoverable - error. This has been fixed. Thanks to Egor M for the report. -* :bug:`482` Parallel mode should imply linewise output; omission of this - behavior was an oversight. -* :bug:`230` Fix regression re: combo of no fabfile & arbitrary command use. - Thanks to Ali Saifee for the catch. -* :release:`1.3.2 <2011-11-07>` -* :release:`1.2.4 <2011-11-07>` -* :release:`1.1.6 <2011-11-07>` -* :support:`459 backported` Update our `setup.py` files to note that PyCrypto - released 2.4.1, which fixes the setuptools problems. -* :support:`467 backported` (also :issue:`468`, :issue:`469`) Handful of - documentation clarification tweaks. Thanks to Paul Hoffman for the patches. -* :release:`1.3.1 <2011-10-24>` -* :bug:`457` Ensured that Fabric fast-fails parallel tasks if any child - processes encountered errors. Previously, multi-task invocations would - continue to the 2nd, etc task when failures occurred, which does not fit with - how Fabric usually behaves. Thanks to Github user ``sdcooke`` for the report - and Morgan Goose for the fix. -* :release:`1.3.0 <2011-10-23>` -* :release:`1.2.3 <2011-10-23>` -* :release:`1.1.5 <2011-10-23>` -* :release:`1.0.5 <2011-10-23>` -* :support:`275` To support an edge use case of the features released in - :issue:`19`, and to lay the foundation for :issue:`275`, we have forked - Paramiko into the `Python 'ssh' library `_ - and changed our dependency to it for Fabric 1.3 and higher. This may have - implications for the more uncommon install use cases, and package - maintainers, but we hope to iron out any issues as they come up. -* :bug:`323` `~fabric.operations.put` forgot how to expand leading tildes in - the remote file path. This has been corrected. Thanks to Piet Delport for the - catch. -* :feature:`21` It is now possible, using the new `~fabric.tasks.execute` API - call, to execute task objects (by reference or by name) from within other - tasks or in library mode. `~fabric.tasks.execute` honors the other tasks' - `~fabric.decorators.hosts`/`~fabric.decorators.roles` decorators, and also - supports passing in explicit host and/or role arguments. -* :feature:`19` Tasks may now be optionally executed in parallel. Please see - the :doc:`parallel execution docs ` for details. Major - thanks to Morgan Goose for the initial implementation. -* :bug:`182` During display of remote stdout/stderr, Fabric occasionally - printed extraneous line prefixes (which in turn sometimes overwrote wrapped - text.) This has been fixed. -* :bug:`430` Tasks decorated with `~fabric.decorators.runs_once` printed - extraneous 'Executing...' status lines on subsequent invocations. This is - noisy at best and misleading at worst, and has been corrected. Thanks to - Jacob Kaplan-Moss for the report. -* :release:`1.2.2 <2011-09-01>` -* :release:`1.1.4 <2011-09-01>` -* :release:`1.0.4 <2011-09-01>` -* :bug:`252` `~fabric.context_managers.settings` would silently fail to set - ``env`` values for keys which did not exist outside the context manager - block. It now works as expected. Thanks to Will Maier for the catch and - suggested solution. -* :support:`393 backported` Fixed a typo in an example code snippet in the task - docs. Thanks to Hugo Garza for the catch. -* :bug:`396` :option:`--shortlist` broke after the addition of - :option:`--list-format <-F>` and no longer displayed the short list format - correctly. This has been fixed. -* :bug:`373` Re-added missing functionality preventing :ref:`host exclusion - ` from working correctly. -* :bug:`303` Updated terminal size detection to correctly skip over non-tty - stdout, such as when running ``fab taskname | other_command``. -* :release:`1.2.1 <2011-08-21>` -* :release:`1.1.3 <2011-08-21>` -* :release:`1.0.3 <2011-08-21>` -* :bug:`417` :ref:`abort-on-prompts` would incorrectly abort when set to True, - even if both password and host were defined. This has been fixed. Thanks to - Valerie Ishida for the report. -* :support:`416 backported` Updated documentation to reflect move from Redmine - to Github. -* :bug:`389` Fixed/improved error handling when Paramiko import fails. Thanks - to Brian Luft for the catch. -* :release:`1.2.0 <2011-07-12>` -* :feature:`22` Enhanced `@task ` to add :ref:`aliasing - `, :ref:`per-module default tasks `, and - :ref:`control over the wrapping task class `. - Thanks to Travis Swicegood for the initial work and collaboration. -* :bug:`380` Improved unicode support when testing objects for being - string-like. Thanks to Jiri Barton for catch & patch. -* :support:`382` Experimental overhaul of changelog formatting & process to - make supporting multiple lines of development less of a hassle. -* :release:`1.1.2 <2011-07-07>` -* :release:`1.0.2 <2011-06-24>` - - -Prehistory -========== - -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. - ----- - - -Changes in version 1.1.2 (2011-07-07) -===================================== - -Bugfixes --------- - -* :issue:`375`: The logic used to separate tasks from modules when running - ``fab --list`` incorrectly considered task classes implementing the mapping - interface to be modules, not individual tasks. This has been corrected. - Thanks to Vladimir Mihailenco for the catch. - - -Changes in version 1.1.1 (2011-06-29) -===================================== - -Bugfixes --------- - -* The public API for `~fabric.tasks.Task` mentioned use of the ``run()`` - method, but Fabric's main execution loop had not been updated to look for and - call it, forcing users who subclassed `~fabric.tasks.Task` to define - ``__call__()`` instead. This was an oversight and has been corrected. - - .. seealso:: :ref:`task-subclasses` - - -Changes in version 1.1 (2011-06-24) -=================================== - -This page lists all changes made to Fabric in its 1.1.0 release. - -.. note:: - This release also includes all applicable changes from the 1.0.2 release. - -Highlights ----------- - -* :issue:`76`: :ref:`New-style tasks ` have been added. With - the addition of the `~fabric.decorators.task` decorator and the - `~fabric.tasks.Task` class, you can now "opt-in" and explicitly mark task - functions as tasks, and Fabric will ignore the rest. The original behavior - (now referred to as :ref:`"classic" tasks `) will still take - effect if no new-style tasks are found. Major thanks to Travis Swicegood for - the original implementation. -* :issue:`56`: Namespacing is now possible: Fabric will crawl imported module - objects looking for new-style task objects and build a dotted hierarchy - (tasks named e.g. ``web.deploy`` or ``db.migrations.run``), allowing for - greater organization. See :ref:`namespaces` for details. Thanks again to - Travis Swicegood. - - -Feature additions ------------------ - -* :issue:`10`: `~fabric.contrib.upload_project` now allows control over the - local and remote directory paths, and has improved error handling. Thanks to - Rodrigue Alcazar for the patch. -* As part of :issue:`56` (highlighted above), added :option:`--list-format - <-F>` to allow specification of a nested output format from :option:`--list - <-l>`. -* :issue:`107`: `~fabric.operations.require`'s ``provided_by`` kwarg now - accepts iterables in addition to single values. Thanks to Thomas Ballinger - for the patch. -* :issue:`117`: `~fabric.contrib.files.upload_template` now supports the - `~fabric.operations.put` flags ``mirror_local_mode`` and ``mode``. Thanks to - Joe Stump for the suggestion and Thomas Ballinger for the patch. -* :issue:`154`: `~fabric.contrib.files.sed` now allows customized regex flags - to be specified via a new ``flags`` parameter. Thanks to Nick Trew for the - suggestion and Morgan Goose for initial implementation. -* :issue:`170`: Allow :ref:`exclusion ` of specific hosts from - the final run list. Thanks to Casey Banner for the suggestion and patch. -* :issue:`189`: Added :option:`--abort-on-prompts`/:ref:`env.abort_on_prompts - ` to allow a more non-interactive behavior, - aborting/exiting instead of trying to prompt the running user. Thanks to - Jeremy Avnet and Matt Chisholm for the initial patch. -* :issue:`273`: `~fabric.contrib.files.upload_template` now offers control over - whether it attempts to create backups of pre-existing destination files. - Thanks to Ales Zoulek for the suggestion and initial patch. -* :issue:`283`: Added the `~fabric.decorators.with_settings` decorator to allow - application of env var settings to an entire function, as an alternative to - using the `~fabric.context_managers.settings` context manager. Thanks to - Travis Swicegood for the patch. -* :issue:`353`: Added :option:`--keepalive`/:ref:`env.keepalive ` to - allow specification of an SSH keepalive parameter for troublesome network - connections. Thanks to Mark Merritt for catch & patch. - -Bugfixes --------- - -* :issue:`115`: An implementation detail causing host lists to lose order - when deduped by the ``fab`` execution loop, has been patched to preserve - order instead. So e.g. ``fab -H a,b,c`` (or setting ``env.hosts = ['a', 'b', - 'c']``) will now always run on ``a``, then ``b``, then ``c``. Previously, - there was a chance the order could get mixed up during deduplication. Thanks - to Rohit Aggarwal for the report. -* :issue:`345`: `~fabric.contrib.files.contains` returned the stdout of its - internal ``grep`` command instead of success/failure, causing incorrect - behavior when stderr exists and is combined with stdout. This has been - corrected. Thanks to Szymon Reichmann for catch and patch. - -Documentation updates ---------------------- - -* Documentation for task declaration has been moved from - :doc:`/usage/execution` into its own docs page, :doc:`/usage/tasks`, as a - result of the changes added in :issue:`76` and :issue:`56`. -* :issue:`184`: Make the usage of `~fabric.contrib.project.rsync_project`'s - ``local_dir`` argument more obvious, regarding its use in the ``rsync`` call. - (Specifically, so users know they can pass in multiple, space-joined - directory names instead of just one single directory.) - -Internals ---------- - -* :issue:`307`: A whole pile of minor PEP8 tweaks. Thanks to Markus Gattol for - highlighting the ``pep8`` tool and to Rick Harding for the patch. -* :issue:`314`: Test utility decorator improvements. Thanks to Rick Harding for - initial catch & patch. - - -Changes in version 1.0.2 (2011-06-24) -===================================== - -.. note:: - This release also includes all applicable changes from the 0.9.7 release. - -Bugfixes --------- - -* :issue:`258`: Bugfix to a previous, incorrectly applied fix regarding - `~fabric.operations.local` on Windows platforms. -* :issue:`324`: Update `~fabric.operations.run`/`~fabric.operations.sudo`'s - ``combine_stderr`` kwarg so that it correctly overrides the global setting in - all cases. This required changing its default value to ``None``, but the - default behavior (behaving as if the setting were ``True``) has not changed. - Thanks to Matthew Woodcraft and Connor Smith for the catch. -* :issue:`337`: Fix logic bug in `~fabric.operations.put` preventing use of - ``mirror_local_mode``. Thanks to Roman Imankulov for catch & patch. -* :issue:`352` (also :issue:`320`): Seemingly random issues with output lockup - and input problems (e.g. sudo prompts incorrectly rejecting passwords) appear - to have been caused by an I/O race condition. This has been fixed. Thanks to - Max Arnold and Paul Oswald for the detailed reports and to Max for the - diagnosis and patch. - - -Documentation -------------- - -* Updated the API documentation for `~fabric.context_managers.cd` to explicitly - point users to `~fabric.context_managers.lcd` for modifying local paths. -* Clarified the behavior of `~fabric.contrib.project.rsync_project` re: how - trailing slashes in ``local_dir`` affect ``remote_dir``. Thanks to Mark - Merritt for the catch. - - -Changes in version 1.0.1 (2011-03-27) -===================================== - -.. note:: - This release also includes all applicable changes from the 0.9.5 release. - -Bugfixes --------- - -* :issue:`301`: Fixed a bug in `~fabric.operations.local`'s behavior when - ``capture=False`` and ``output.stdout`` (or ``.stderr``) was also ``False``. - Thanks to Chris Rose for the catch. -* :issue:`310`: Update edge case in `~fabric.operations.put` where using the - ``mode`` kwarg alongside ``use_sudo=True`` runs a hidden - `~fabric.operations.sudo` command. The ``mode`` kwarg needs to be octal but - was being interpolated in the ``sudo`` call as a string/integer. Thanks to - Adam Ernst for the catch and suggested fix. -* :issue:`311`: `~fabric.contrib.files.append` was supposed to have its - ``partial`` kwarg's default flipped from ``True`` to ``False``. However, only - the documentation was altered. This has been fixed. Thanks to Adam Ernst for - bringing it to our attention. -* :issue:`312`: Tweak internal I/O related loops to prevent high CPU usage and - poor screen-printing behavior on some systems. Thanks to Kirill Pinchuk for - the initial patch. -* :issue:`320`: Some users reported problems with dropped input, particularly - while entering `~fabric.operations.sudo` passwords. This was fixed via the - same change as for :issue:`312`. - -Documentation -------------- - -* Added a missing entry for :ref:`env.path ` in the usage - documentation. - - -Changes in version 1.0 (2011-03-04) -=================================== - -This page lists all changes made to Fabric in its 1.0.0 release. - - -Highlights ----------- - -* :issue:`7`: `~fabric.operations.run`/`~fabric.operations.sudo` now allow full - interactivity with the remote end. You can interact with remote prompts and - similar interfaces, making certain tasks much easier, and freeing you from - the need to find noninteractive solutions if you don't want to. See - :doc:`/usage/interactivity` for more on these changes. -* `~fabric.operations.put` and `~fabric.operations.get` received many updates, - including but not limited to: recursion, globbing, inline ``sudo`` - capability, and increased control over local file paths. See the individual - ticket line-items below for details. Erich Heine (``sophacles`` on IRC) - played a large part in implementing and/or collecting these changes and - deserves much of the credit. -* Added functionality for loading fabfiles which are Python packages - (directories) instead of just modules (single files). This allows for easier - organization of nontrivial fabfiles and paves the way for task namespacing - in the near future. See :ref:`fabfile-discovery` for details. -* :issue:`185`: Mostly of interest to those contributing to Fabric itself, - Fabric now leverages Paramiko to provide a stub SSH and SFTP server for use - during runs of our test suite. This makes quick, configurable full-stack - testing of Fabric (and, to an extent, user fabfiles) possible. - - -Backwards-incompatible changes ------------------------------- - -The below changes are **backwards incompatible** and have the potential to -break your 0.9.x based fabfiles! - -* `~fabric.contrib.files.contains` and `~fabric.contrib.files.append` - previously had the ``filename`` argument in the second position, whereas all - other functions in the `contrib.files ` module had - ``filename`` as the first argument. These two functions have been brought in - line with the rest of the module. -* `~fabric.contrib.files.sed` now escapes single-quotes and parentheses in - addition to forward slashes, in its ``before`` and ``after`` kwargs. Related - to, but not entirely contained within, :issue:`159`. -* The ``user`` and ``pty`` kwargs in `~fabric.operations.sudo`'s signature have - had their order swapped around to more closely match - `~fabric.operations.run`. -* As part of the changes made in :issue:`7`, `~fabric.operations.run` and - `~fabric.operations.sudo` have had the default value of their ``pty`` kwargs - changed from ``False`` to ``True``. This, plus the addition of the - :ref:`combine-stderr` kwarg/env var, may result in significant behavioral - changes in remote programs which operate differently when attached to a tty. -* :issue:`61`: `~fabric.operations.put` and `~fabric.operations.get` now honor - the remote current-working-directory changes applied by - `~fabric.context_managers.cd`. Previously they would always treat relative - remote paths as being relative to the remote home directory. -* :issue:`79`: `~fabric.operations.get` now allows increased control over local - filenames when downloading single or multiple files. This is backwards - incompatible because the default path/filename for downloaded files has - changed. Thanks to Juha Mustonen, Erich Heine and Max Arnold for - brainstorming solutions. -* :issue:`88`: `~fabric.operations.local` has changed the default value of its - ``capture`` kwarg, from ``True`` to ``False``. This was changed in order to - be more intuitive, at the cost of no longer defaulting to the same rich - return value as in `~fabric.operations.run`/`~fabric.operations.sudo` (which - is still available by specifying ``capture=True``.) -* :issue:`121`: `~fabric.operations.put` will no longer automatically attempt - to mirror local file modes. Instead, you'll need to specify - ``mirror_local_mode=True`` to get this behavior. Thanks to Paul Smith for a - patch covering part of this change. -* :issue:`172`: `~fabric.contrib.files.append` has changed the default value of - its ``partial`` kwarg from ``True`` to ``False`` in order to be safer/more - intuitive. -* :issue:`221`: `~fabric.decorators.runs_once` now memoizes the wrapped task's - return value and returns that value on subsequent invocations, instead of - returning None. Thanks to Jacob Kaplan-Moss and Travis Swicegood for catch + - patch. - -Feature additions ------------------ - -* Prerelease versions of Fabric (starting with the 1.0 prereleases) will now - print the Git SHA1 hash of the current checkout, if the user is working off - of a Git clone of the Fabric source code repository. -* Added `~fabric.context_managers.path` context manager for modifying commands' - effective ``$PATH``. -* Added convenience ``.succeeded`` attribute to the return values of - `~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.local` - which is simply the opposite of the ``.failed`` attribute. (This addition has - also been backported to Fabric's 0.9 series.) -* Refactored SSH disconnection code out of the main ``fab`` loop into - `~fabric.network.disconnect_all`, allowing library users to avoid problems - with non-fabfile Python scripts hanging after execution finishes. -* :issue:`2`: Added ``use_sudo`` kwarg to `~fabric.operations.put` to allow - uploading of files to privileged locations. Thanks to Erich Heine and IRC - user ``npmap`` for suggestions and patches. -* :issue:`23`: Added `~fabric.context_managers.prefix` context manager for - easier management of persistent state across commands. -* :issue:`27`: Added environment variable (:ref:`always-use-pty`) and - command-line flag (:option:`--no-pty`) for global control over the - `~fabric.operations.run`/`~fabric.operations.sudo` ``pty`` argument. -* :issue:`28`: Allow shell-style globbing in `~fabric.operations.get`. Thanks - to Erich Heine and Max Arnold. -* :issue:`55`: `~fabric.operations.run`, `~fabric.operations.sudo` and - `~fabric.operations.local` now provide access to their standard error - (stderr) as an attribute on the return value, alongside e.g. ``.failed``. -* :issue:`148`: `~fabric.operations.local` now returns the same "rich" string - object as `~fabric.operations.run`/`~fabric.operations.sudo` do, so that it - is a string containing the command's stdout (if ``capture=True``) or the - empty string (if ``capture=False``) which exposes the ``.failed`` and - ``.return_code`` attributes, and so forth. -* :issue:`151`: Added a `~fabric.utils.puts` utility function, which allows - greater control over fabfile-generated (as opposed to Fabric-generated) - output. Also added `~fabric.utils.fastprint`, an alias to - `~fabric.utils.puts` allowing for convenient unbuffered, - non-newline-terminated printing. -* :issue:`192`: Added per-user/host password cache to assist in - multi-connection scenarios. -* :issue:`193`: When requesting a remote pseudo-terminal, use the invoking - terminal's dimensions instead of going with the default. -* :issue:`217`: `~fabric.operations.get`/`~fabric.operations.put` now accept - file-like objects as well as local file paths for their ``local_path`` - arguments. -* :issue:`245`: Added the `~fabric.context_managers.lcd` context manager for - controlling `~fabric.operations.local`'s current working directory and - `~fabric.operations.put`/`~fabric.operations.get`'s local working - directories. -* :issue:`274`: `~fabric.operations.put`/`~fabric.operations.get` now have - return values which may be iterated over to access the paths of files - uploaded remotely or downloaded locally, respectively. These return values - also allow access to ``.failed`` and ``.succeeded`` attributes, just like - `~fabric.operations.run` and friends. (In this case, ``.failed`` is actually - a list itself containing any paths which failed to transfer, which naturally - acts as a boolean as well.) - - -Documentation updates ---------------------- - -* API, tutorial and usage docs updated with the above new features. -* README now makes the Python 2.5+ requirement up front and explicit; some - folks were still assuming it would run on Python 2.4. -* Added a link to Python's documentation for string interpolation in - `~fabric.contrib.files.upload_template`'s docstring. - - -Changes in version 0.9.7 (2011-06-23) -===================================== - -The following changes were implemented in Fabric 0.9.7: - -Bugfixes --------- - -* :issue:`329`: `~fabric.operations.reboot` would have problems reconnecting post-reboot (resulting in a traceback) if ``env.host_string`` was not fully-formed (did not contain user and port specifiers.) This has been fixed. - - -Changes in version 0.9.6 (2011-04-29) -===================================== - -The following changes were implemented in Fabric 0.9.6: - -Bugfixes --------- - -* :issue:`347`: `~fabric.contrib.files.append` incorrectly tested for ``str`` - instead of ``types.StringTypes``, causing it to split up Unicode strings as - if they were one character per line. This has been fixed. - - -Changes in version 0.9.5 (2011-03-21) -===================================== - -The following changes were implemented in Fabric 0.9.5: - -Bugfixes --------- - -* :issue:`37`: Internal refactoring of a Paramiko call from ``_transport`` to - ``get_transport()``. -* :issue:`258`: Modify subprocess call on Windows platforms to avoid - space/quote problems in `~fabric.operations.local`. Thanks to Henrik - Heimbuerger and Raymond Cote for catch + suggested fixes. -* :issue:`261`: Fix bug in `~fabric.contrib.files.comment` which truncated - regexen ending with ``$``. Thanks to Antti Kaihola for the catch. -* :issue:`264`: Fix edge case in `~fabric.operations.reboot` by gracefully - clearing connection cache. Thanks to Jason Gerry for the report & - troubleshooting. -* :issue:`268`: Allow for ``@`` symbols in usernames, which is valid on some - systems. Fabric's host-string parser now splits username and hostname at the - last ``@`` found instead of the first. Thanks to Thadeus Burgess for the - report. -* :issue:`287`: Fix bug in password prompt causing occasional tracebacks. - Thanks to Antti Kaihola for the catch and Rick Harding for testing the - proposed solution. -* :issue:`288`: Use temporary files to work around the lack of a ``-i`` flag in - OpenBSD and NetBSD `~fabric.contrib.files.sed`. Thanks to Morgan Lefieux for - catch + patches. -* :issue:`305`: Strip whitespace from hostnames to help prevent user error. - Thanks to Michael Bravo for the report and Rick Harding for the patch. -* :issue:`316`: Use of `~fabric.context_managers.settings` with key names not - previously set in ``env`` no longer raises KeyErrors. Whoops. Thanks to Adam - Ernst for the catch. - -Documentation updates ---------------------- - -* :issue:`228`: Added description of the PyCrypto + pip + Python 2.5 problem to - the documentation and removed the Python 2.5 check from ``setup.py``. -* :issue:`291`: Updated the PyPM-related install docs re: recent changes in - PyPM and its download URLs. Thanks to Sridhar Ratnakumar for the patch. - - -Changes in version 0.9.4 (2011-02-18) -===================================== - -The following changes were implemented in Fabric 0.9.4: - -Feature additions ------------------ - -* Added :doc:`documentation ` for using Fabric as a library. -* Mentioned our `Twitter account `_ on the main - docs page. -* :issue:`290`: Added ``escape`` kwarg to `~fabric.contrib.files.append` to - allow control over previously automatic single-quote escaping. - - -Changes in version 0.9.3 (2010-11-12) -===================================== - -The following changes were implemented in Fabric 0.9.3: - -Feature additions ------------------ - -* :issue:`255`: Added ``stderr`` and ``succeeded`` attributes to - `~fabric.operations.local`. -* :issue:`254`: Backported the ``.stderr`` and ``.succeeded`` attributes on - `~fabric.operations.run`/`~fabric.operations.sudo` return values, from the - Git master/pre-1.0 branch. Please see those functions' API docs for details. - - -Bugfixes --------- - -* :issue:`228`: We discovered that the pip + PyCrypto installation problem was - limited to Python 2.5 only, and have updated our ``setup.py`` accordingly. -* :issue:`230`: Arbitrary or remainder commands (``fab -- ``) will no longer blow up when invoked with no fabfile present. Thanks - to IRC user ``orkaa`` for the report. -* :issue:`242`: Empty string values in task CLI args now parse correctly. - Thanks to Aaron Levy for the catch + patch. - - -Documentation updates ---------------------- - -* :issue:`239`: Fixed typo in execution usage docs. Thanks to Pradeep Gowda and - Turicas for the catch. - - -Changes in version 0.9.2 (2010-09-06) -===================================== - -The following changes were implemented in Fabric 0.9.2: - -Feature additions ------------------ - -* The `~fabric.operations.reboot` operation has been added, providing a way for - Fabric to issue a reboot command and then reconnect after the system has - restarted. -* ``python setup.py test`` now runs Fabric's test suite (provided you have all - the prerequisites from the ``requirements.txt`` installed). Thanks to Eric - Holscher for the patch. -* Added functionality for loading fabfiles which are Python packages - (directories) instead of just modules (single files.) See - :ref:`fabfile-discovery`. -* Added output lines informing the user of which tasks are being executed (e.g. - ``[myserver] Executing task 'foo'``.) -* Added support for lazy (callable) role definition values in ``env.roledefs``. -* Added `contrib.django ` module with basic Django - integration. -* :ref:`env.local_user ` was added, providing easy and permanent - access to the local system username, even if an alternate remote username has - been specified. -* :issue:`29`: Added support for arbitrary command-line-driven anonymous tasks - via ``fab [options] -- [shell command]``. See :ref:`arbitrary-commands`. -* :issue:`52`: Full tracebacks during aborts are now displayed if the user has - opted to see debug-level output. -* :issue:`101`: Added `~fabric.colors` module with basic color output support. - (:issue:`101` is still open: we plan to leverage the new module in Fabric's - own output in the future.) -* :issue:`137`: Commas used to separate per-task arguments may now be escaped - with a backslash. Thanks to Erich Heine for the patch. -* :issue:`144`: `~fabric.decorators.hosts` (and `~fabric.decorators.roles`) - will now expand a single, iterable argument instead of requiring one to use - e.g. ``@hosts(*iterable)``. -* :issue:`151`: Added a `~fabric.utils.puts` utility function, which allows - greater control over fabfile-generated (as opposed to Fabric-generated) - output. Also added `~fabric.utils.fastprint`, an alias to - `~fabric.utils.puts` allowing for convenient unbuffered, - non-newline-terminated printing. -* :issue:`208`: Users rolling their own shell completion or who otherwise find - themselves performing text manipulation on the output of :option:`--list - <-l>` may now use :option:`--shortlist` to get a plain, newline-separated - list of task names. - - -Bugfixes --------- - -* The interactive "what host to connect to?" prompt now correctly updates the - appropriate environment variables (hostname, username, port) based on user - input. -* Fixed a bug where Fabric's own internal fabfile would pre-empt the user's - fabfile due to a PYTHONPATH order issue. User fabfiles are now always loaded - at the front of the PYTHONPATH during import. -* Disabled some DeprecationWarnings thrown by Paramiko when that library is - imported into Fabric under Python 2.6. -* :issue:`44`, :issue:`63`: Modified `~fabric.contrib.project.rsync_project` to - honor the SSH port and identity file settings. Thanks to Mitch Matuson - and Morgan Goose. -* :issue:`123`: Removed Cygwin from the "are we on Windows" test; now, only - Python installs whose ``sys.platform`` says ``'win32'`` will use Windows-only - code paths (e.g. importing of ``pywin32``). - - -Documentation updates ---------------------- - -* Added a few new items to the :doc:`FAQ `. -* :issue:`173`: Simple but rather embarrassing typo fix in README. Thanks to - Ted Nyman for the catch. -* :issue:`194`: Added a note to :doc:`the install docs ` about a - possible edge case some Windows 64-bit Python users may encounter. -* :issue:`216`: Overhauled the :ref:`process backgrounding FAQ ` - to include additional techniques and be more holistic. - - -Packaging updates ------------------ - -* :issue:`86`, :issue:`158`: Removed the bundled Paramiko 1.7.4 and updated the - ``setup.py`` to require Paramiko >=1.7.6. This lets us skip the known-buggy - Paramiko 1.7.5 while getting some much needed bugfixes in Paramiko 1.7.6. - - -Changes in version 0.9.1 (2010-05-28) -===================================== - -The following changes were implemented in Fabric 0.9.1: - -Feature additions ------------------ - -* :issue:`82`: `~fabric.contrib.files.append` now offers a ``partial`` kwarg - allowing control over whether the "don't append if given text already exists" - test looks for exact matches or not. Thanks to Jonas Nockert for the catch - and discussion. -* :issue:`112`: ``fab --list`` now prints out the fabfile's module-level - docstring as a header, if there is one. -* :issue:`141`: Added some more CLI args/env vars to allow user configuration - of the Paramiko ``connect`` call -- specifically :ref:`no_agent` and - :ref:`no_keys`. - - -Bugfixes --------- - -* :issue:`75`: ``fab``, when called with no arguments or (useful) options, now - prints help, even when no fabfile can be found. Previously, calling ``fab`` - in a location with no fabfile would complain about the lack of fabfile - instead of displaying help. -* :issue:`130`: Context managers now correctly clean up ``env`` if they - encounter an exception. Thanks to Carl Meyer for catch + patch. -* :issue:`132`: `~fabric.operations.local` now calls ``strip`` on its stdout, - matching the behavior of `~fabric.operations.run`/`~fabric.operations.sudo`. - Thanks to Carl Meyer again on this one. -* :issue:`166`: `~fabric.context_managers.cd` now correctly overwrites - ``env.cwd`` when given an absolute path, instead of naively appending its - argument to ``env.cwd``'s previous value. - - -Documentation updates ---------------------- - -* A number of small to medium documentation tweaks were made which had no - specific Redmine ticket. The largest of these is the addition of :doc:`the - FAQ <../faq>` to the Sphinx documentation instead of storing it as a - source-only text file. (Said FAQ was also slightly expanded with new FAQs.) -* :issue:`17`: Added :ref:`note to FAQ ` re: use of ``dtach`` as - alternative to ``screen``. Thanks to Erich Heine for the tip. -* :issue:`64`: Updated :ref:`installation docs ` to clarify where - package maintainers should be downloading tarballs from. Thanks to James - Pearson for providing the necessary perspective. -* :issue:`95`: Added a link to a given version's changelog on the PyPI page - (technically, to the ``setup.py`` ``long_description`` field). -* :issue:`110`: Alphabetized :ref:`the CLI argument command reference - `. Thanks to Erich Heine. -* :issue:`120`: Tweaked documentation, help strings to make it more obvious - that fabfiles are simply Python modules. -* :issue:`127`: Added :ref:`note to install docs ` re: ActiveState's - PyPM. Thanks to Sridhar Ratnakumar for the tip. - - -Changes in version 0.9 (2009-11-08) -=================================== - -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. - - -Major changes -------------- - -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: - -Imports -~~~~~~~ - -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 :doc:`../usage/fabfiles` for more information. - -Python version -~~~~~~~~~~~~~~ - -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. - -Environment/config variables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``config`` object previously used to access and set internal state -(including Fabric config options) **has been renamed** to :data:`env`, but -otherwise remains mostly the same (it allows both dictionary and -object-attribute style access to its data.) :data:`env` resides in the -:mod:`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' - -Execution mode -~~~~~~~~~~~~~~ - -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. - -"Lazy" string interpolation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -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. - - -Other backwards-incompatible changes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -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 :data:`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 - :mod:`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 - :mod:`fabric.contrib` (specifically, :mod:`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 :mod:`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() - - .. note:: - - 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 :doc:`../usage/output_controls`. - - -Changes from alpha 1 to alpha 2 -------------------------------- - -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. - -* Various minor tweaks to the (still in-progress) documentation, including one - thanks to Curt Micol. - -* Added a number of TODO items based on user feedback (thanks!) - -* Host information now available in granular form (user, host, port) in the - env dict, alongside the full ``user@host:port`` host string. - -* Parsing of host strings is now more lenient when examining the username - (e.g. hyphens.) - -* User/host info no longer cleared out between commands. - -* Tweaked ``setup.py`` to use ``find_packages``. Thanks to Pat McNerthney. - -* Added 'capture' argument to `~fabric.operations.local` to allow local - interactive tasks. - -* Reversed default value of `~fabric.operations.local`'s ``show_stderr`` - kwarg; local stderr now prints by default instead of being hidden by - default. - -* Various internal fabfile tweaks. - - -Changes from alpha 2 to alpha 3 -------------------------------- - -* Lots of updates to the documentation and TODO - -* Added contrib.files with a handful of file-centric subroutines - -* Added contrib.console for console UI stuff (so far, just `confirm`) - -* Reworked config file mechanisms a bit, added CLI flag for setting it. - -* Output controls (including CLI args, documentation) have been added - -* Test coverage tweaked and grown a small amount (thanks in part to Peter - Ellis) - -* Roles overhauled/fixed (more like hosts now) - -* Changed ``--list`` linewrap behavior to truncate instead. - -* Make private key passphrase prompting more obvious to users. - -* Add ``pty`` option to `sudo`. Thanks to José Muanis for the tip-off re: get_pty() - -* Add CLI argument for setting the shell used in commands (thanks to Steve Steiner) - -* Only load host keys when ``env.reject_unknown_keys`` is True. Thanks to Pat - McNerthney. - -* And many, many additional bugfixes and behavioral tweaks too small to merit - cluttering up this list! Thanks as always to everyone who contributed - bugfixes, feedback and/or patches. - - -Changes from alpha 3 to beta 1 ------------------------------- - -This is closer to being a straight dump of the Git changelog than the previous -sections; apologies for the overall change in tense. - -* Add autodocs for fabric.contrib.console. - -* Minor cleanup to package init and setup.py. - -* Handle exceptions with strerror attributes that are None instead of strings. - -* contrib.files.append may now take a list of strings if desired. - -* Straighten out how prompt() deals with trailing whitespace - -* Add 'cd' context manager. - -* Update upload_template to correctly handle backing up target directories. - -* upload_template() can now use Jinja2 if it's installed and user asks for it. - -* Handle case where remote host SSH key doesn't match known_hosts. - -* Fix race condition in run/sudo. - -* Start fledgling FAQ; extended pty option to run(); related doc tweaks. - -* Bring local() in line with run()/sudo() in terms of .failed attribute. - -* Add dollar-sign backslash escaping to run/sudo. - -* Add FAQ question re: backgrounding processes. - -* Extend some of put()'s niceties to get(), plus docstring/comment updates - -* Add debug output of chosen fabfile for troubleshooting fabfile discovery. - -* Fix Python path bug which sometimes caused Fabric's internal fabfile to - pre-empt user's fabfile during load phase. - -* Gracefully handle "display" for tasks with no docstring. - -* Fix edge case that comes up during some auth/prompt situations. - -* Handle carriage returns in output_thread correctly. Thanks to Brian Rosner. - - -Changes from beta 1 to release candidate 1 ------------------------------------------- - -As with the previous changelog, this is also mostly a dump of the Git log. We -promise that future changelogs will be more verbose :) - -* Near-total overhaul and expansion of documentation (this is the big one!) - Other mentions of documentation in this list are items deserving their own - mention, e.g. FAQ updates. -* Add FAQ question re: passphrase/password prompt -* Vendorized Paramiko: it is now included in our distribution and is no longer - an external dependency, at least until upstream fixes a nasty 1.7.5 bug. -* Fix #34: switch upload_template to use mkstemp (also removes Python 2.5.2+ - dependency -- now works on 2.5.0 and up) -* Fix #62 by escaping backticks. -* Replace "ls" with "test" in exists() -* Fixes #50. Thanks to Alex Koshelev for the patch. -* ``local``'s return value now exhibits ``.return_code``. -* Abort on bad role names instead of blowing up. -* Turn off DeprecationWarning when importing paramiko. -* Attempted fix re #32 (dropped output) -* Update role/host initialization logic (was missing some edge cases) -* Add note to install docs re: PyCrypto on win32. -* Add FAQ item re: changing env.shell. -* Rest of TODO migrated to tickets. -* ``fab test`` (when in source tree) now uses doctests. -* Add note to compatibility page re: fab_quiet. -* Update local() to honor context_managers.cd() - -Changes from release candidate 1 to final release -------------------------------------------------- - -* Fixed the `~fabric.contrib.files.sed` docstring to accurately reflect which - ``sed`` options it uses. -* Various changes to internal fabfile, version mechanisms, and other - non-user-facing things. Binary files /tmp/N6trD1b267/fabric-1.8.2/docs/.changelog.rst.swp and /tmp/GW8FhdJcF_/fabric-1.10.0/docs/.changelog.rst.swp differ diff -Nru fabric-1.8.2/docs/conf.py fabric-1.10.0/docs/conf.py --- fabric-1.8.2/docs/conf.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/docs/conf.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Fabric documentation build configuration file, created by -# sphinx-quickstart on Sat Apr 25 14:53:36 2009. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -from __future__ import with_statement -import os -import sys -import types -from datetime import datetime - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'releases'] - -# 'releases' (changelog) settings -releases_issue_uri = "https://github.com/fabric/fabric/issues/%s" -releases_release_uri = "https://github.com/fabric/fabric/tree/%s" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Fabric' -year = datetime.now().year -copyright = u'%d, Christian Vest Hansen and Jeffrey E. Forcier' % year - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. - -# Add this checkout's local Fabric module to sys.path. Allows use of -# fabric.version in here, and ensures that the autodoc stuff also works. -sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), '..'))) -from fabric.version import get_version - -# Get version info -# -# Branch-only name -version = get_version('branch') -# The full human readable version, including alpha/beta/rc tags. -release = get_version('normal') - - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -default_role = 'obj' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' -html_style = 'rtd.css' -html_context = {} - -from fabric.api import local, hide, settings -with settings(hide('everything'), warn_only=True): - get_tags = 'git tag | sort -r | egrep "(1\.[^0]+)\.."' - tag_result = local(get_tags, True) - if tag_result.succeeded: - html_context['fabric_tags'] = tag_result.split() - - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Fabricdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Fabric.tex', u'Fabric Documentation', - u'Jeff Forcier', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True - - -# Restore decorated functions so that autodoc inspects the right arguments -def unwrap_decorated_functions(): - from fabric import operations, context_managers - for module in [context_managers, operations]: - for name, obj in vars(module).iteritems(): - if ( - # Only function objects - just in case some real object showed - # up that had .undecorated - isinstance(obj, types.FunctionType) - # Has our .undecorated 'cache' of the real object - and hasattr(obj, 'undecorated') - ): - setattr(module, name, obj.undecorated) - -unwrap_decorated_functions() diff -Nru fabric-1.8.2/docs/development.rst fabric-1.10.0/docs/development.rst --- fabric-1.8.2/docs/development.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/development.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -=========== -Development -=========== - -The Fabric development team is headed by `Jeff Forcier -`_, aka ``bitprophet``. However, dozens of other -developers pitch in by submitting patches and ideas via `GitHub issues and pull -requests `_, :ref:`IRC ` or the `mailing -list `_. - -Get the code -============ - -Please see the :ref:`source-code-checkouts` section of the :doc:`installation` -page for details on how to obtain Fabric's source code. - -Contributing -============ - -There are a number of ways to get involved with Fabric: - -* **Use Fabric and send us feedback!** This is both the easiest and arguably - the most important way to improve the project -- let us know how you - currently use Fabric and how you want to use it. (Please do try to search the - `ticket tracker `_ first, though, - when submitting feature ideas.) -* **Report bugs.** Pretty much a special case of the previous item: if you - think you've found a bug in Fabric, check on the `ticket tracker - `_ to see if anyone's reported it - yet, and if not -- file a bug! If possible, try to make sure you can - replicate it repeatedly, and let us know the circumstances (what version of - Fabric you're using, what platform you're on, and what exactly you were doing - when the bug cropped up.) -* **Submit patches or new features.** Make a `Github `_ - account, `create a fork `_ of `the main - Fabric repository `_, and `submit a pull - request `_. - -While we may not always reply promptly, we do try to make time eventually to -inspect all contributions and either incorporate them or explain why we don't -feel the change is a good fit. - -.. include:: ../CONTRIBUTING.rst - -Coding style ------------- - -Fabric tries hard to honor `PEP-8`_, especially (but not limited to!) the -following: - -* Keep all lines under 80 characters. This goes for the ReST documentation as - well as code itself. - - * Exceptions are made for situations where breaking a long string (such as a - string being ``print``-ed from source code, or an especially long URL link - in documentation) would be kind of a pain. - -* Typical Python 4-space (soft-tab) indents. No tabs! No 8 space indents! (No - 2- or 3-space indents, for that matter!) -* ``CamelCase`` class names, but ``lowercase_underscore_separated`` everything - else. - -.. _PEP-8: http://www.python.org/dev/peps/pep-0008/ - -Communication -------------- - -If a ticket-tracker ticket exists for a given issue, **please** keep all -communication in that ticket's comments -- for example, when submitting patches -via Github, it's easier for us if you leave a note in the ticket **instead of** -sending a Github pull request. - -The core devs receive emails for just about any ticket-tracker activity, so -additional notices via Github or other means only serve to slow things down. - -Branching/Repository Layout -=========================== - -While Fabric's development methodology isn't set in stone yet, the following -items detail how we currently organize the Git repository and expect to perform -merges and so forth. This will be chiefly of interest to those who wish to -follow a specific Git branch instead of released versions, or to any -contributors. - -* We use a combined 'release and feature branches' methodology, where every - minor release (e.g. 0.9, 1.0, 1.1, 1.2 etc; see :ref:`releases` below for - details on versioning) gets a release branch for bugfixes, and big feature - development is performed in a central ``master`` branch and/or in - feature-specific feature branches (e.g. a branch for reworking the internals - to be threadsafe, or one for overhauling task dependencies, etc.) -* Releases each get their own release branch, e.g. ``0.9``, ``1.0``, ``1.1`` - etc, and from these the actual releases are tagged, e.g. ``0.9.3`` or - ``1.0.0``. -* New feature work is typically done in feature branches, whose naming - convention is ``-``. For example, ticket - #61, which concerned adding ``cd`` support to ``get`` and ``put``, was - developed in a branch named ``61-add-cd-to-get-put``. - - * These branches are not intended for public use, and may be cleaned out of - the repositories periodically. Ideally, no one feature will be in - development long enough for its branch to become used in production! - -* Completed feature work is merged into the ``master`` branch, and once enough - new features are done, a new release branch is created and optionally used to - create prerelease versions for testing -- or simply released as-is. -* While we try our best not to commit broken code or change APIs without - warning, as with many other open-source projects we can only have a guarantee - of stability in the release branches. Only follow ``master`` (or, even worse, - feature branches!) if you're willing to deal with a little pain. -* Conversely, because we try to keep release branches relatively stable, you - may find it easier to use Fabric from a source checkout of a release branch - instead of manually upgrading to new released versions. This can provide a - decent middle ground between stability and the ability to get bugfixes or - backported features easily. -* The core developers will take care of performing merging/branching on the - official repositories. Since Git is Git, contributors may of course do - whatever they wish in their own clones/forks. -* Bugfixes are to be performed on release branches and then merged into - ``master`` so that ``master`` is always up-to-date (or nearly so; while it's - not mandatory to merge after every bugfix, doing so at least daily is a good - idea.) -* Feature branches should periodically merge in changes from - ``master`` so that when it comes time for them to merge back into ``master`` - things aren't quite as painful. - -.. _releases: - -Releases -======== - -Fabric tries to follow open-source standards and conventions in its release -tagging, including typical version numbers such as 2.0, 1.2.5, or -1.2b1. Each release will be marked as a tag in the Git repositories, and -are broken down as follows: - -Major ------ - -Major releases update the first number, e.g. going from 0.9 to 1.0, and -indicate that the software has reached some very large milestone. - -For example, the 1.0 release signified a commitment to a medium to long term -API and some significant backwards incompatible (compared to the 0.9 series) -features. Version 2.0 might indicate a rewrite using a new underlying network -technology or an overhaul to be more object-oriented. - -Major releases will often be backwards-incompatible with the previous line of -development, though this is not a requirement, just a usual happenstance. -Users should expect to have to make at least some changes to their fabfiles -when switching between major versions. - -Minor ------ - -Minor releases, such as moving from 1.0 to 1.1, typically mean that one or more -new, large features has been added. They are also sometimes used to mark off -the fact that a lot of bug fixes or small feature modifications have occurred -since the previous minor release. (And, naturally, some of them will involve -both at the same time.) - -These releases are guaranteed to be backwards-compatible with all other -releases containing the same major version number, so a fabfile that works -with 1.0 should also work fine with 1.1 or even 1.9. - -Bugfix/tertiary ---------------- - -The third and final part of version numbers, such as the '3' in 1.0.3, -generally indicate a release containing one or more bugfixes, although minor -feature modifications may (rarely) occur. - -This third number is sometimes omitted for the first major or minor release in -a series, e.g. 1.2 or 2.0, and in these cases it can be considered an implicit -zero (e.g. 2.0.0). - -.. note:: - - The 0.9 series of development included more significant feature work than - is typically found in tertiary releases; from 1.0 onwards a more - traditional approach, as per the above, is used. - - -Support of older releases -========================= - -Major and minor releases do not mark the end of the previous line or lines of -development: - -* The two most recent minor release branches will continue to receive critical - bugfixes. For example, if 1.1 were the latest minor release, it and 1.0 would - get bugfixes, but not 0.9 or earlier; and once 1.2 came out, this window - would then only extend back to 1.1. -* Depending on the nature of bugs found and the difficulty in backporting them, - older release lines may also continue to get bugfixes -- but there's no - longer a guarantee of any kind. Thus, if a bug were found in 1.1 that - affected 0.9 and could be easily applied, a new 0.9.x version *might* be - released. -* This policy may change in the future to accommodate more branches, depending - on development speed. - -We hope that this policy will allow us to have a rapid minor release cycle (and -thus keep new features coming out frequently) without causing users to feel too -much pressure to upgrade right away. At the same time, the backwards -compatibility guarantee means that users should still feel comfortable -upgrading to the next minor release in order to stay within this sliding -support window. diff -Nru fabric-1.8.2/docs/faq.rst fabric-1.10.0/docs/faq.rst --- fabric-1.8.2/docs/faq.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/faq.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ -================================ -Frequently Asked Questions (FAQ) -================================ - -These are some of the most commonly encountered problems or frequently asked -questions which we receive from users. They aren't intended as a substitute for -reading the rest of the documentation, especially the :ref:`usage docs -`, so please make sure you check those out if your question is not -answered here. - - -How do I dynamically set host lists? -==================================== - -See :ref:`dynamic-hosts`. - - -How can I run something after my task is done on all hosts? -=========================================================== - -See :ref:`leveraging-execute-return-value`. - - -.. _init-scripts-pty: - -Init scripts don't work! -======================== - -Init-style start/stop/restart scripts (e.g. ``/etc/init.d/apache2 start``) -sometimes don't like Fabric's allocation of a pseudo-tty, which is active by -default. In almost all cases, explicitly calling the command in question with -``pty=False`` works correctly:: - - sudo("/etc/init.d/apache2 restart", pty=False) - -If you have no need for interactive behavior and run into this problem -frequently, you may want to deactivate pty allocation globally by setting -:ref:`env.always_use_pty ` to ``False``. - -.. _one-shell-per-command: - -My (``cd``/``workon``/``export``/etc) calls don't seem to work! -=============================================================== - -While Fabric can be used for many shell-script-like tasks, there's a slightly -unintuitive catch: each `~fabric.operations.run` or `~fabric.operations.sudo` -call has its own distinct shell session. This is required in order for Fabric -to reliably figure out, after your command has run, what its standard out/error -and return codes were. - -Unfortunately, it means that code like the following doesn't behave as you -might assume:: - - def deploy(): - run("cd /path/to/application") - run("./update.sh") - -If that were a shell script, the second `~fabric.operations.run` call would -have executed with a current working directory of ``/path/to/application/`` -- -but because both commands are run in their own distinct session over SSH, it -actually tries to execute ``$HOME/update.sh`` instead (since your remote home -directory is the default working directory). - -A simple workaround is to make use of shell logic operations such as ``&&``, -which link multiple expressions together (provided the left hand side executed -without error) like so:: - - def deploy(): - run("cd /path/to/application && ./update.sh") - -Fabric provides a convenient shortcut for this specific use case, in fact: -`~fabric.context_managers.cd`. There is also `~fabric.context_managers.prefix` -for arbitrary prefix commands. - -.. note:: - You might also get away with an absolute path and skip directory changing - altogether:: - - def deploy(): - run("/path/to/application/update.sh") - - However, this requires that the command in question makes no assumptions - about your current working directory! - - -How do I use ``su`` to run commands as another user? -==================================================== - -This is a special case of :ref:`one-shell-per-command`. As that FAQ explains, -commands like ``su`` which are 'stateful' do not work well in Fabric, so -workarounds must be used. - -In the case of running commands as a user distinct from the login user, you -have two options: - -#. Use `~fabric.operations.sudo` with its ``user=`` kwarg, e.g. - ``sudo("command", user="otheruser")``. If you want to factor the ``user`` - part out of a bunch of commands, use `~fabric.context_managers.settings` to - set ``env.sudo_user``:: - - with settings(sudo_user="otheruser"): - sudo("command 1") - sudo("command 2") - ... - -#. If your target system cannot use ``sudo`` for some reason, you can still use - ``su``, but you need to invoke it in a non-interactive fashion by telling it - to run a specific command instead of opening a shell. Typically this is the - ``-c`` flag, e.g. ``su otheruser -c "command"``. - - To run multiple commands in the same ``su -c`` "wrapper", you could e.g. - write a wrapper function around `~fabric.operations.run`:: - - def run_su(command, user="otheruser"): - return run('su %s -c "%s"' % (user, command)) - - -Why do I sometimes see ``err: stdin: is not a tty``? -==================================================== - -This message is typically generated by programs such as ``biff`` or ``mesg`` -lurking within your remote user's ``.profile`` or ``.bashrc`` files (or any -other such files, including system-wide ones.) Fabric's default mode of -operation involves executing the Bash shell in "login mode", which causes these -files to be executed. - -Because Fabric also doesn't bother asking the remote end for a tty by default -(as it's not usually necessary) programs fired within your startup files, which -expect a tty to be present, will complain -- and thus, stderr output about -"stdin is not a tty" or similar. - -There are multiple ways to deal with this problem: - -* Find and remove or comment out the offending program call. If the program was - not added by you on purpose and is simply a legacy of the operating system, - this may be safe to do, and is the simplest approach. -* Override ``env.shell`` to remove the ``-l`` flag. This should tell Bash not - to load your startup files. If you don't depend on the contents of your - startup files (such as aliases or whatnot) this may be a good solution. -* Pass ``pty=True`` to `run` or `sudo`, which will force allocation of a - pseudo-tty on the remote end, and hopefully cause the offending program to be - less cranky. - - -.. _faq-daemonize: - -Why can't I run programs in the background with ``&``? It makes Fabric hang. -============================================================================ - -Because Fabric executes a shell on the remote end for each invocation of -``run`` or ``sudo`` (:ref:`see also `), backgrounding a -process via the shell will not work as expected. Backgrounded processes may -still prevent the calling shell from exiting until they stop running, and this -in turn prevents Fabric from continuing on with its own execution. - -The key to fixing this is to ensure that your process' standard pipes are all -disassociated from the calling shell, which may be done in a number of ways -(listed in order of robustness): - -* Use a pre-existing daemonization technique if one exists for the program at - hand -- for example, calling an init script instead of directly invoking a - server binary. - - * Or leverage a process manager such as ``supervisord``, ``upstart`` or - ``systemd`` - such tools let you define what it means to "run" one of - your background processes, then issue init-script-like - start/stop/restart/status commands. They offer many advantages over - classic init scripts as well. - -* Use ``tmux``, ``screen`` or ``dtach`` to fully detach the process from the - running shell; these tools have the benefit of allowing you to reattach to - the process later on if needed (though they are more ad-hoc than - ``supervisord``-like tools). -* Run the program under ``nohup`` or similar "in-shell" tools - note that this - approach has seen limited success for most users. - - -.. _faq-bash: - -My remote system doesn't have ``bash`` installed by default, do I need to install ``bash``? -=========================================================================================== - -While Fabric is written with ``bash`` in mind, it's not an absolute -requirement. Simply change :ref:`env.shell ` to call your desired shell, and -include an argument similar to ``bash``'s ``-c`` argument, which allows us to -build shell commands of the form:: - - /bin/bash -l -c "" - -where ``/bin/bash -l -c`` is the default value of :ref:`env.shell `. - -.. note:: - - The ``-l`` argument specifies a login shell and is not absolutely - required, merely convenient in many situations. Some shells lack the option - entirely and it may be safely omitted in such cases. - -A relatively safe baseline is to call ``/bin/sh``, which may call the original -``sh`` binary, or (on some systems) ``csh``, and give it the ``-c`` -argument, like so:: - - from fabric.api import env - - env.shell = "/bin/sh -c" - -This has been shown to work on FreeBSD and may work on other systems as well. - - -I'm sometimes incorrectly asked for a passphrase instead of a password. -======================================================================= - -Due to a bug of sorts in our SSH layer, it's not currently possible for Fabric -to always accurately detect the type of authentication needed. We have to try -and guess whether we're being asked for a private key passphrase or a remote -server password, and in some cases our guess ends up being wrong. - -The most common such situation is where you, the local user, appear to have an -SSH keychain agent running, but the remote server is not able to honor your SSH -key, e.g. you haven't yet transferred the public key over or are using an -incorrect username. In this situation, Fabric will prompt you with "Please -enter passphrase for private key", but the text you enter is actually being -sent to the remote end's password authentication. - -We hope to address this in future releases by modifying a fork of the -aforementioned SSH library. - - -Is Fabric thread-safe? -====================== - -Currently, no, it's not -- the present version of Fabric relies heavily on -shared state in order to keep the codebase simple. However, there are definite -plans to update its internals so that Fabric may be either threaded or -otherwise parallelized so your tasks can run on multiple servers concurrently. diff -Nru fabric-1.8.2/docs/index.rst fabric-1.10.0/docs/index.rst --- fabric-1.8.2/docs/index.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/index.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ -====== -Fabric -====== - -About -===== - -.. include:: ../README.rst - - -Installation -============ - -Stable releases of Fabric are best installed via ``pip`` or ``easy_install``; -or you may download TGZ or ZIP source archives from a couple of official -locations. Detailed instructions and links may be found on the -:doc:`installation` page. - -We recommend using the latest stable version of Fabric; releases are made often -to prevent any large gaps in functionality between the latest stable release -and the development version. - -However, if you want to live on the edge, you can pull down the source code -from our Git repository, or fork us on Github. The :doc:`installation` page has -details for how to access the source code. - -.. warning:: - - If you install Fabric from Git, you will need to install its dependency - Paramiko from Git as well. See :doc:`the installation docs ` - for details. - - -Development -=========== - -Any hackers interested in improving Fabric (or even users interested in how -Fabric is put together or released) please see the :doc:`development` page. It -contains comprehensive info on contributing, repository layout, our release -strategy, and more. - - -.. _documentation-index: - -Documentation -============= - -Please note that all documentation is currently written with Python 2.5 users -in mind, but with an eye for eventual Python 3.x compatibility. This leads to -the following patterns that may throw off readers used to Python 2.4 or who -have already upgraded to Python 2.6/2.7: - -* ``from __future__ import with_statement``: a "future import" required to - use the ``with`` statement in Python 2.5 -- a feature you'll be using - frequently. Python 2.6+ users don't need to do this. -* `` if else ``: Python's relatively new - ternary statement, available in 2.5 and newer. Python 2.4 and older used to - fake this with `` and or `` (which - isn't quite the same thing and has some logical loopholes.) -* ``print()`` instead of ``print ``: We use the - ``print`` statement's optional parentheses where possible, in order to be - more compatible with Python 3.x (in which ``print`` becomes a function.) - -.. toctree:: - :hidden: - - tutorial - installation - development - faq - troubleshooting - roadmap - -Tutorial --------- - -For new users, and/or for an overview of Fabric's basic functionality, please -see the :doc:`tutorial`. The rest of the documentation will assume you're -at least passingly familiar with the material contained within. - -.. _usage-docs: - -Usage documentation -------------------- - -The following list contains all major sections of Fabric's prose (non-API) -documentation, which expands upon the concepts outlined in the -:doc:`tutorial` and also covers advanced topics. - -.. toctree:: - :maxdepth: 2 - :glob: - - usage/* - -.. _faq: - -FAQ ---- - -Some frequently encountered questions, coupled with answers/solutions/excuses, -may be found on the :doc:`faq` page. - -Troubleshooting ---------------- - -Before asking for help or filing a bug, make sure you've read our -:doc:`document on troubleshooting `. - -.. _api_docs: - -API documentation ------------------ - -Fabric maintains two sets of API documentation, autogenerated from the source -code's docstrings (which are typically very thorough.) - -.. _core-api: - -Core API -~~~~~~~~ - -The **core** API is loosely defined as those functions, classes and methods -which form the basic building blocks of Fabric (such as -`~fabric.operations.run` and `~fabric.operations.sudo`) upon which everything -else (the below "contrib" section, and user fabfiles) builds. - -.. toctree:: - :maxdepth: 1 - :glob: - - api/core/* - -.. _contrib-api: - -Contrib API -~~~~~~~~~~~ - -Fabric's **contrib** package contains commonly useful tools (often merged in -from user fabfiles) for tasks such as user I/O, modifying remote files, and so -forth. While the core API is likely to remain small and relatively unchanged -over time, this contrib section will grow and evolve (while trying to remain -backwards-compatible) as more use-cases are solved and added. - -.. toctree:: - :maxdepth: 1 - :glob: - - api/contrib/* - - -Changelog ---------- - -Please see :doc:`the changelog `. - - -Roadmap -------- - -Please see :doc:`the roadmap `. - - -Getting help -============ - -If you've scoured the :ref:`prose ` and :ref:`API ` -documentation and still can't find an answer to your question, below are -various support resources that should help. We do request that you do at least -skim the documentation before posting tickets or mailing list questions, -however! - -Mailing list ------------- - -The best way to get help with using Fabric is via the `fab-user mailing list -`_ (currently hosted at -``nongnu.org``.) The Fabric developers do their best to reply promptly, and the -list contains an active community of other Fabric users and contributors as -well. - -Twitter -------- - -Fabric has an official Twitter account, `@pyfabric -`_, which is used for announcements and occasional -related news tidbits (e.g. "Hey, check out this neat article on Fabric!"). - -.. _bugs: - -Bugs/ticket tracker -------------------- - -To file new bugs or search existing ones, you may visit Fabric's `Github Issues -`_ page. This does require a (free, easy to set up) Github account. - -.. _irc: - -IRC ---- - -We maintain a semi-official IRC channel at ``#fabric`` on Freenode -(``irc://irc.freenode.net``) where the developers and other users may be found. -As always with IRC, we can't promise immediate responses, but some folks keep -logs of the channel and will try to get back to you when they can. diff -Nru fabric-1.8.2/docs/installation.rst fabric-1.10.0/docs/installation.rst --- fabric-1.8.2/docs/installation.rst 2014-02-14 18:36:36.000000000 +0000 +++ fabric-1.10.0/docs/installation.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -============ -Installation -============ - -Fabric is best installed via `pip `_ (highly -recommended) or `easy_install -`_ (older, but still works -fine), e.g.:: - - $ pip install fabric - -You may also opt to use your operating system's package manager; the package is -typically called ``fabric`` or ``python-fabric``. E.g.:: - - $ sudo apt-get install fabric - -Advanced users wanting to install a development version may use ``pip`` to grab -the latest master branch (as well as the dev version of the Paramiko -dependency):: - - $ pip install paramiko==dev - $ pip install fabric==dev - -Or, to install an editable version for debugging/hacking, execute ``pip install --e .`` (or ``python setup.py install``) inside a :ref:`downloaded ` -or :ref:`cloned ` copy of the source code. - -.. warning:: - - Any development installs of Fabric (whether via ``==dev`` or ``install - -e``) require the development version of Paramiko to be installed - beforehand, or Fabric's installation may fail. - - -Dependencies -============ - -In order for Fabric's installation to succeed, you will need four primary pieces of software: - -* the Python programming language; -* the ``setuptools`` packaging/installation library; -* the Python ``paramiko`` SSH2 library; -* and ``paramiko``'s dependency, the PyCrypto cryptography library. - -and, if using the :doc:`parallel execution mode `: - -* the `multiprocessing`_ library. - -Please read on for important details on each dependency -- there are a few -gotchas. - -Python ------- - -Fabric requires `Python `_ version 2.5 or 2.6. Some caveats -and notes about other Python versions: - -* We are not planning on supporting **Python 2.4** given its age and the number - of useful tools in Python 2.5 such as context managers and new modules. - That said, the actual amount of 2.5-specific functionality is not - prohibitively large, and we would link to -- but not support -- a third-party - 2.4-compatible fork. (No such fork exists at this time, to our knowledge.) -* Fabric has not yet been tested on **Python 3.x** and is thus likely to be - incompatible with that line of development. However, we try to be at least - somewhat forward-looking (e.g. using ``print()`` instead of ``print``) and - will definitely be porting to 3.x in the future once our dependencies do. - -setuptools ----------- - -`Setuptools`_ comes with some Python installations by default; if yours doesn't, -you'll need to grab it. In such situations it's typically packaged as -``python-setuptools``, ``py25-setuptools`` or similar. Fabric may drop its -setuptools dependency in the future, or include alternative support for the -`Distribute`_ project, but for now setuptools is required for installation. - -.. _setuptools: http://pypi.python.org/pypi/setuptools -.. _Distribute: http://pypi.python.org/pypi/distribute - -PyCrypto --------- - -`PyCrypto `_ provides the low-level -(C-based) encryption algorithms used to run SSH, and is thus required by our -SSH library. There are a couple gotchas associated with installing PyCrypto: -its compatibility with Python's package tools, and the fact that it is a -C-based extension. - -.. _pycrypto-and-pip: - -Package tools -~~~~~~~~~~~~~ - -We strongly recommend using ``pip`` to install Fabric as it is newer and -generally better than ``easy_install``. However, a combination of bugs in -specific versions of Python, ``pip`` and PyCrypto can prevent installation of -PyCrypto. Specifically: - -* Python = 2.5.x -* PyCrypto >= 2.1 (which is required to run Fabric >= 1.3) -* ``pip`` < 0.8.1 - -When all three criteria are met, you may encounter ``No such file or -directory`` IOErrors when trying to ``pip install Fabric`` or ``pip install -PyCrypto``. - -The fix is simply to make sure at least one of the above criteria is not met, -by doing the following (in order of preference): - -* Upgrade to ``pip`` 0.8.1 or above, e.g. by running ``pip install -U pip``. -* Upgrade to Python 2.6 or above. -* Downgrade to Fabric 1.2.x, which does not require PyCrypto >= 2.1, and - install PyCrypto 2.0.1 (the oldest version on PyPI which works with Fabric - 1.2.) - - -C extension -~~~~~~~~~~~ - -Unless you are installing from a precompiled source such as a Debian apt -repository or RedHat RPM, or using :ref:`pypm `, you will also need the -ability to build Python C-based modules from source in order to install -PyCrypto. Users on **Unix-based platforms** such as Ubuntu or Mac OS X will -need the traditional C build toolchain installed (e.g. Developer Tools / XCode -Tools on the Mac, or the ``build-essential`` package on Ubuntu or Debian Linux --- basically, anything with ``gcc``, ``make`` and so forth) as well as the -Python development libraries, often named ``python-dev`` or similar. - -For **Windows** users we recommend using :ref:`pypm`, installing a C -development environment such as `Cygwin `_ or obtaining a -precompiled Win32 PyCrypto package from `voidspace's Python modules page -`_. - -.. note:: - Some Windows users whose Python is 64-bit have found that the PyCrypto - dependency ``winrandom`` may not install properly, leading to ImportErrors. - In this scenario, you'll probably need to compile ``winrandom`` yourself - via e.g. MS Visual Studio. See :issue:`194` for info. - - -``multiprocessing`` -------------------- - -An optional dependency, the ``multiprocessing`` library is included in Python's -standard library in version 2.6 and higher. If you're using Python 2.5 and want -to make use of Fabric's :doc:`parallel execution features ` -you'll need to install it manually; the recommended route, as usual, is via -``pip``. Please see the `multiprocessing PyPI page -`_ for details. - - -.. warning:: - Early versions of Python 2.6 (in our testing, 2.6.0 through 2.6.2) ship - with a buggy ``multiprocessing`` module that appears to cause Fabric to - hang at the end of sessions involving large numbers of concurrent hosts. - If you encounter this problem, either use :ref:`env.pool_size / -z - ` to limit the amount of concurrency, or upgrade to Python - >=2.6.3. - - Python 2.5 is unaffected, as it requires the PyPI version of - ``multiprocessing``, which is newer than that shipped with Python <2.6.3. - -Development dependencies ------------------------- - -If you are interested in doing development work on Fabric (or even just running -the test suite), you may also need to install some or all of the following -packages: - -* `git `_ and `Mercurial`_, in order to obtain some of the - other dependencies below; -* `Nose `_ -* `Coverage `_ -* `PyLint `_ -* `Fudge `_ -* `Sphinx `_ - -For an up-to-date list of exact testing/development requirements, including -version numbers, please see the ``requirements.txt`` file included with the -source distribution. This file is intended to be used with ``pip``, e.g. ``pip -install -r requirements.txt``. - -.. _Mercurial: http://mercurial.selenic.com/wiki/ - - -.. _downloads: - -Downloads -========= - -To obtain a tar.gz or zip archive of the Fabric source code, you may visit -`Fabric's PyPI page `_, which offers manual -downloads in addition to being the entry point for ``pip`` and -``easy-install``. - - -.. _source-code-checkouts: - -Source code checkouts -===================== - -The Fabric developers manage the project's source code with the `Git -`_ DVCS. To follow Fabric's development via Git instead of -downloading official releases, you have the following options: - -* Clone the canonical repository straight from `the Fabric organization's - repository on Github `_, - ``git://github.com/fabric/fabric.git`` -* Make your own fork of the Github repository by making a Github account, - visiting `fabric/fabric `_ and clicking the - "fork" button. - -.. note:: - - If you've obtained the Fabric source via source control and plan on - updating your checkout in the future, we highly suggest using ``python - setup.py develop`` instead -- it will use symbolic links instead of file - copies, ensuring that imports of the library or use of the command-line - tool will always refer to your checkout. - -For information on the hows and whys of Fabric development, including which -branches may be of interest and how you can help out, please see the -:doc:`development` page. - - -.. _pypm: - -ActivePython and PyPM -===================== - -Windows users who already have ActiveState's `ActivePython -`_ distribution installed -may find Fabric is best installed with `its package manager, PyPM -`_. Below is example output from an -installation of Fabric via ``pypm``:: - - C:\> pypm install fabric - The following packages will be installed into "%APPDATA%\Python" (2.7): - paramiko-1.7.8 pycrypto-2.4 fabric-1.3.0 - Get: [pypm-free.activestate.com] fabric 1.3.0 - Get: [pypm-free.activestate.com] paramiko 1.7.8 - Get: [pypm-free.activestate.com] pycrypto 2.4 - Installing paramiko-1.7.8 - Installing pycrypto-2.4 - Installing fabric-1.3.0 - Fixing script %APPDATA%\Python\Scripts\fab-script.py - C:\> diff -Nru fabric-1.8.2/docs/Makefile fabric-1.10.0/docs/Makefile --- fabric-1.8.2/docs/Makefile 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf _build/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html - @echo - @echo "Build finished. The HTML pages are in _build/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml - @echo - @echo "Build finished. The HTML pages are in _build/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in _build/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in _build/qthelp, like this:" - @echo "# qcollectiongenerator _build/qthelp/Fabric.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile _build/qthelp/Fabric.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex - @echo - @echo "Build finished; the LaTeX files are in _build/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes - @echo - @echo "The overview file is in _build/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in _build/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in _build/doctest/output.txt." diff -Nru fabric-1.8.2/docs/roadmap.rst fabric-1.10.0/docs/roadmap.rst --- fabric-1.8.2/docs/roadmap.rst 2014-02-14 18:36:36.000000000 +0000 +++ fabric-1.10.0/docs/roadmap.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -=================== -Development roadmap -=================== - -This document outlines Fabric's intended development path. Please make sure -you're reading `the latest version -`_ of this document! - -.. warning:: - This information is subject to change without warning, and should not be - used as a basis for any life- or career-altering decisions! - -Fabric 1.x -========== - -Fabric 1.x, while not end-of-life'd, has reached a tipping point regarding -internal tech debt & ability to make significant improvements without harming -backwards compatibility. - -As such, future 1.x releases (**1.6** onwards) will emphasize small-to-medium -features (new features not requiring major overhauls of the internals) and -bugfixes. - -Invoke, Fabric 2.x and Patchwork -================================ - -While 1.x moves on as above, we are working on a reimagined 2.x version of the -tool, and plan to: - -* Finish and release `the Invoke tool/library - `_ (see also :issue:`565`), which is a - revamped and standalone version of Fabric's task running components. - - * Initially it will be basic, matching Fabric's current functionality, but - with a cleaner base to build on. - * Said cleaner base then gives us a jumping-off point for new task-oriented - features such as before/after hooks / call chains, task collections, - improved namespacing and so forth. - -* Start putting together Fabric 2.0, a partly/mostly rewritten Fabric core: - - * Leverage Invoke for task running, which will leave Fabric itself much - more library oriented. - * Implement object-oriented hosts/host lists and all the fun stuff that - provides (e.g. no more hacky host string and unintuitive env var - manipulation.) - * No (or optional & non-default) shared state. - * Any other core overhauls difficult to do in a backwards compatible - fashion. - * `Current issue list - `_ - -* Spin off ``fabric.contrib.*`` into a standalone "super-Fabric" (as in, "above Fabric") library, `Patchwork `_. - - * This lets core "execute commands on hosts" functionality iterate - separately from "commonly useful shortcuts using Fabric core". - * Lots of preliminary work & prior-art scanning has been done in - :issue:`461`. - * A public-but-alpha codebase for Patchwork exists as we think about the - API, and is currently based on Fabric 1.x. It will likely be Fabric 2.x - based by the time it is stable. diff -Nru fabric-1.8.2/docs/_static/rtd.css fabric-1.10.0/docs/_static/rtd.css --- fabric-1.8.2/docs/_static/rtd.css 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/_static/rtd.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,766 +0,0 @@ -/* - * rtd.css - * ~~~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- sphinxdoc theme. Originally created by - * Armin Ronacher for Werkzeug. - * - * Customized for ReadTheDocs by Eric Pierce & Eric Holscher - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* RTD colors - * light blue: #e8ecef - * medium blue: #8ca1af - * dark blue: #465158 - * dark grey: #444444 - * - * white hover: #d1d9df; - * medium blue hover: #697983; - * green highlight: #8ecc4c - * light blue (project bar): #e8ecef - */ - -@import url("basic.css"); - -/* PAGE LAYOUT -------------------------------------------------------------- */ - -body { - font: 100%/1.5 "ff-meta-web-pro-1","ff-meta-web-pro-2",Arial,"Helvetica Neue",sans-serif; - text-align: center; - color: black; - background-color: #465158; - padding: 0; - margin: 0; -} - -div.document { - text-align: left; - background-color: #e8ecef; -} - -div.bodywrapper { - background-color: #ffffff; - border-left: 1px solid #ccc; - border-bottom: 1px solid #ccc; - margin: 0 0 0 16em; -} - -div.body { - margin: 0; - padding: 0.5em 1.3em; - max-width: 55em; - min-width: 20em; -} - -div.related { - font-size: 1em; - background-color: #465158; -} - -div.documentwrapper { - float: left; - width: 100%; - background-color: #e8ecef; -} - - -/* HEADINGS --------------------------------------------------------------- */ - -h1 { - margin: 0; - padding: 0.7em 0 0.3em 0; - font-size: 1.5em; - line-height: 1.15; - color: #111; - clear: both; -} - -h2 { - margin: 2em 0 0.2em 0; - font-size: 1.35em; - padding: 0; - color: #465158; -} - -h3 { - margin: 1em 0 -0.3em 0; - font-size: 1.2em; - color: #6c818f; -} - -div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { - color: black; -} - -h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { - display: none; - margin: 0 0 0 0.3em; - padding: 0 0.2em 0 0.2em; - color: #aaa !important; -} - -h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, -h5:hover a.anchor, h6:hover a.anchor { - display: inline; -} - -h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, -h5 a.anchor:hover, h6 a.anchor:hover { - color: #777; - background-color: #eee; -} - - -/* LINKS ------------------------------------------------------------------ */ - -/* Normal links get a pseudo-underline */ -a { - color: #444; - text-decoration: none; - border-bottom: 1px solid #ccc; -} - -/* Links in sidebar, TOC, index trees and tables have no underline */ -.sphinxsidebar a, -.toctree-wrapper a, -.indextable a, -#indices-and-tables a { - color: #444; - text-decoration: none; - border-bottom: none; -} - -/* Most links get an underline-effect when hovered */ -a:hover, -div.toctree-wrapper a:hover, -.indextable a:hover, -#indices-and-tables a:hover { - color: #111; - text-decoration: none; - border-bottom: 1px solid #111; -} - -/* Footer links */ -div.footer a { - color: #86989B; - text-decoration: none; - border: none; -} -div.footer a:hover { - color: #a6b8bb; - text-decoration: underline; - border: none; -} - -/* Permalink anchor (subtle grey with a red hover) */ -div.body a.headerlink { - color: #ccc; - font-size: 1em; - margin-left: 6px; - padding: 0 4px 0 4px; - text-decoration: none; - border: none; -} -div.body a.headerlink:hover { - color: #c60f0f; - border: none; -} - - -/* NAVIGATION BAR --------------------------------------------------------- */ - -div.related ul { - height: 2.5em; -} - -div.related ul li { - margin: 0; - padding: 0.65em 0; - float: left; - display: block; - color: white; /* For the >> separators */ - font-size: 0.8em; -} - -div.related ul li.right { - float: right; - margin-right: 5px; - color: transparent; /* Hide the | separators */ -} - -/* "Breadcrumb" links in nav bar */ -div.related ul li a { - order: none; - background-color: inherit; - font-weight: bold; - margin: 6px 0 6px 4px; - line-height: 1.75em; - color: #ffffff; - padding: 0.4em 0.8em; - border: none; - border-radius: 3px; -} -/* previous / next / modules / index links look more like buttons */ -div.related ul li.right a { - margin: 0.375em 0; - background-color: #697983; - text-shadow: 0 1px rgba(0, 0, 0, 0.5); - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; -} -/* All navbar links light up as buttons when hovered */ -div.related ul li a:hover { - background-color: #8ca1af; - color: #ffffff; - text-decoration: none; - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; -} -/* Take extra precautions for tt within links */ -a tt, -div.related ul li a tt { - background: inherit !important; - color: inherit !important; -} - - -/* SIDEBAR ---------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 0; -} - -div.sphinxsidebar { - margin: 0; - margin-left: -100%; - float: left; - top: 3em; - left: 0; - padding: 0 1em; - width: 14em; - font-size: 1em; - text-align: left; - background-color: #e8ecef; -} - -div.sphinxsidebar img { - max-width: 12em; -} - -div.sphinxsidebar h3, div.sphinxsidebar h4 { - margin: 1.2em 0 0.3em 0; - font-size: 1em; - padding: 0; - color: #222222; - font-family: "ff-meta-web-pro-1", "ff-meta-web-pro-2", "Arial", "Helvetica Neue", sans-serif; -} - -div.sphinxsidebar h3 a { - color: #444444; -} - -div.sphinxsidebar ul, -div.sphinxsidebar p { - margin-top: 0; - padding-left: 0; - line-height: 130%; - background-color: #e8ecef; -} - -/* No bullets for nested lists, but a little extra indentation */ -div.sphinxsidebar ul ul { - list-style-type: none; - margin-left: 1.5em; - padding: 0; -} - -/* A little top/bottom padding to prevent adjacent links' borders - * from overlapping each other */ -div.sphinxsidebar ul li { - padding: 1px 0; -} - -/* A little left-padding to make these align with the ULs */ -div.sphinxsidebar p.topless { - padding-left: 0 0 0 1em; -} - -/* Make these into hidden one-liners */ -div.sphinxsidebar ul li, -div.sphinxsidebar p.topless { - white-space: nowrap; - overflow: hidden; -} -/* ...which become visible when hovered */ -div.sphinxsidebar ul li:hover, -div.sphinxsidebar p.topless:hover { - overflow: visible; -} - -/* Search text box and "Go" button */ -#searchbox { - margin-top: 2em; - margin-bottom: 1em; - background: #ddd; - padding: 0.5em; - border-radius: 6px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; -} -#searchbox h3 { - margin-top: 0; -} - -/* Make search box and button abut and have a border */ -input, -div.sphinxsidebar input { - border: 1px solid #999; - float: left; -} - -/* Search textbox */ -input[type="text"] { - margin: 0; - padding: 0 3px; - height: 20px; - width: 144px; - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; - -moz-border-radius-topleft: 3px; - -moz-border-radius-bottomleft: 3px; - -webkit-border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; -} -/* Search button */ -input[type="submit"] { - margin: 0 0 0 -1px; /* -1px prevents a double-border with textbox */ - height: 22px; - color: #444; - background-color: #e8ecef; - padding: 1px 4px; - font-weight: bold; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - -moz-border-radius-topright: 3px; - -moz-border-radius-bottomright: 3px; - -webkit-border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; -} -input[type="submit"]:hover { - color: #ffffff; - background-color: #8ecc4c; -} - -div.sphinxsidebar p.searchtip { - clear: both; - padding: 0.5em 0 0 0; - background: #ddd; - color: #666; - font-size: 0.9em; -} - -/* Sidebar links are unusual */ -div.sphinxsidebar li a, -div.sphinxsidebar p a { - background: #e8ecef; /* In case links overlap main content */ - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border: 1px solid transparent; /* To prevent things jumping around on hover */ - padding: 0 5px 0 5px; -} -div.sphinxsidebar li a:hover, -div.sphinxsidebar p a:hover { - color: #111; - text-decoration: none; - border: 1px solid #888; -} - -/* Tweak any link appearing in a heading */ -div.sphinxsidebar h3 a { -} - - - - -/* OTHER STUFF ------------------------------------------------------------ */ - -cite, code, tt { - font-family: 'Consolas', 'Deja Vu Sans Mono', - 'Bitstream Vera Sans Mono', monospace; - font-size: 0.95em; - letter-spacing: 0.01em; -} - -tt { - background-color: #f2f2f2; - color: #444; -} - -tt.descname, tt.descclassname, tt.xref { - border: 0; -} - -hr { - border: 1px solid #abc; - margin: 2em; -} - -pre, #_fontwidthtest { - font-family: 'Consolas', 'Deja Vu Sans Mono', - 'Bitstream Vera Sans Mono', monospace; - margin: 1em 2em; - font-size: 0.95em; - letter-spacing: 0.015em; - line-height: 120%; - padding: 0.5em; - border: 1px solid #ccc; - background-color: #eee; - border-radius: 6px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; -} - -pre a { - color: inherit; - text-decoration: underline; -} - -td.linenos pre { - padding: 0.5em 0; -} - -div.quotebar { - background-color: #f8f8f8; - max-width: 250px; - float: right; - padding: 2px 7px; - border: 1px solid #ccc; -} - -div.topic { - background-color: #f8f8f8; -} - -table { - border-collapse: collapse; - margin: 0 -0.5em 0 -0.5em; -} - -table td, table th { - padding: 0.2em 0.5em 0.2em 0.5em; -} - - -/* ADMONITIONS AND WARNINGS ------------------------------------------------- */ - -/* Shared by admonitions and warnings */ -div.admonition, div.warning { - font-size: 0.9em; - margin: 2em; - padding: 0; - /* - border-radius: 6px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; - */ -} -div.admonition p, div.warning p { - margin: 0.5em 1em 0.5em 1em; - padding: 0; -} -div.admonition pre, div.warning pre { - margin: 0.4em 1em 0.4em 1em; -} -div.admonition p.admonition-title, -div.warning p.admonition-title { - margin: 0; - padding: 0.1em 0 0.1em 0.5em; - color: white; - font-weight: bold; - font-size: 1.1em; - text-shadow: 0 1px rgba(0, 0, 0, 0.5); -} -div.admonition ul, div.admonition ol, -div.warning ul, div.warning ol { - margin: 0.1em 0.5em 0.5em 3em; - padding: 0; -} - - -/* Admonitions only */ -div.admonition { - border: 1px solid #609060; - background-color: #e9ffe9; -} -div.admonition p.admonition-title { - background-color: #70A070; - border-bottom: 1px solid #609060; -} - - -/* Warnings only */ -div.warning { - border: 1px solid #900000; - background-color: #ffe9e9; -} -div.warning p.admonition-title { - background-color: #b04040; - border-bottom: 1px solid #900000; -} - - - -div.versioninfo { - margin: 1em 0 0 0; - border: 1px solid #ccc; - background-color: #DDEAF0; - padding: 8px; - line-height: 1.3em; - font-size: 0.9em; -} - -.viewcode-back { - font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', - 'Verdana', sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -dl { - margin: 1em 0 2.5em 0; -} - -/* Highlight target when you click an internal link */ -dt:target { - background: #ffe080; -} -/* Don't highlight whole divs */ -div.highlight { - background: transparent; -} -/* But do highlight spans (so search results can be highlighted) */ -span.highlight { - background: #ffe080; -} - -div.footer { - background-color: #465158; - color: #eeeeee; - padding: 0 2em 2em 2em; - clear: both; - font-size: 0.8em; - text-align: center; -} - -p { - margin: 0.8em 0 0.5em 0; -} - -.section p img { - margin: 1em 2em; -} - - -/* MOBILE LAYOUT -------------------------------------------------------------- */ - -@media screen and (max-width: 600px) { - - h1, h2, h3, h4, h5 { - position: relative; - } - - ul { - padding-left: 1.75em; - } - - div.bodywrapper a.headerlink, #indices-and-tables h1 a { - color: #e6e6e6; - font-size: 80%; - float: right; - line-height: 1.8; - position: absolute; - right: -0.7em; - visibility: inherit; - } - - div.bodywrapper h1 a.headerlink, #indices-and-tables h1 a { - line-height: 1.5; - } - - pre { - font-size: 0.7em; - overflow: auto; - word-wrap: break-word; - white-space: pre-wrap; - } - - div.related ul { - height: 2.5em; - padding: 0; - text-align: left; - } - - div.related ul li { - clear: both; - color: #465158; - padding: 0.2em 0; - } - - div.related ul li:last-child { - border-bottom: 1px dotted #8ca1af; - padding-bottom: 0.4em; - margin-bottom: 1em; - width: 100%; - } - - div.related ul li a { - color: #465158; - padding-right: 0; - } - - div.related ul li a:hover { - background: inherit; - color: inherit; - } - - div.related ul li.right { - clear: none; - padding: 0.65em 0; - margin-bottom: 0.5em; - } - - div.related ul li.right a { - color: #fff; - padding-right: 0.8em; - } - - div.related ul li.right a:hover { - background-color: #8ca1af; - } - - div.body { - clear: both; - min-width: 0; - word-wrap: break-word; - } - - div.bodywrapper { - margin: 0 0 0 0; - } - - div.sphinxsidebar { - float: none; - margin: 0; - width: auto; - } - - div.sphinxsidebar input[type="text"] { - height: 2em; - line-height: 2em; - width: 70%; - } - - div.sphinxsidebar input[type="submit"] { - height: 2em; - margin-left: 0.5em; - width: 20%; - } - - div.sphinxsidebar p.searchtip { - background: inherit; - margin-bottom: 1em; - } - - div.sphinxsidebar ul li, div.sphinxsidebar p.topless { - white-space: normal; - } - - .bodywrapper img { - display: block; - margin-left: auto; - margin-right: auto; - max-width: 100%; - } - - div.documentwrapper { - float: none; - } - - div.admonition, div.warning, pre, blockquote { - margin-left: 0em; - margin-right: 0em; - } - - .body p img { - margin: 0; - } - - #searchbox { - background: transparent; - } - - .related:not(:first-child) li { - display: none; - } - - .related:not(:first-child) li.right { - display: block; - } - - div.footer { - padding: 1em; - } - - .rtd_doc_footer .badge { - float: none; - margin: 1em auto; - position: static; - } - - .rtd_doc_footer .badge.revsys-inline { - margin-right: auto; - margin-bottom: 2em; - } - - table.indextable { - display: block; - width: auto; - } - - .indextable tr { - display: block; - } - - .indextable td { - display: block; - padding: 0; - width: auto !important; - } - - .indextable td dt { - margin: 1em 0; - } - - ul.search { - margin-left: 0.25em; - } - - ul.search li div.context { - font-size: 90%; - line-height: 1.1; - margin-bottom: 1; - margin-left: 0; - } - -} diff -Nru fabric-1.8.2/docs/_templates/layout.html fabric-1.10.0/docs/_templates/layout.html --- fabric-1.8.2/docs/_templates/layout.html 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/_templates/layout.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -{% extends "!layout.html" %} - -{%- block extrahead %} -{{ super() }} - - -{% endblock %} - - -{% block sidebarlogo %} -{{ super() }} -{% if fabric_tags %} -

Project Versions

- -{% endif %} -{% endblock %} diff -Nru fabric-1.8.2/docs/troubleshooting.rst fabric-1.10.0/docs/troubleshooting.rst --- fabric-1.8.2/docs/troubleshooting.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/troubleshooting.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -=============== -Troubleshooting -=============== - -Stuck? Having a problem? Here are the steps to try before you submit a bug -report. - -* **Make sure you're on the latest version.** If you're not on the most recent - version, your problem may have been solved already! Upgrading is always the - best first step. -* **Try older versions.** If you're already *on* the latest Fabric, try rolling - back a few minor versions (e.g. if on 1.7, try Fabric 1.5 or 1.6) and see if - the problem goes away. This will help the devs narrow down when the problem - first arose in the commit log. -* **Try switching up your Paramiko.** Fabric relies heavily on the Paramiko - library for its SSH functionality, so try applying the above two steps to - your Paramiko install as well. - - .. note:: - Fabric versions sometimes have different Paramiko dependencies - so to - try older Paramikos you may need to downgrade Fabric as well. - -* **Make sure Fabric is really the problem.** If your problem is in the - behavior or output of a remote command, try recreating it without Fabric - involved: - - * Run Fabric with ``--show=debug`` and look for the ``run:`` or ``sudo:`` - line about the command in question. Try running that exact command, - including any ``/bin/bash`` wrapper, remotely and see what happens. This - may find problems related to the bash or sudo wrappers. - * Execute the command (both the normal version, and the 'unwrapped' version - seen via ``--show=debug``) from your local workstation using ``ssh``, - e.g.:: - - $ ssh -t mytarget "my command" - - The ``-t`` flag matches Fabric's default behavior of enabling a PTY - remotely. This helps identify apps that behave poorly when run in a - non-shell-spawned PTY. - -* **Enable Paramiko-level debug logging.** If your issue is in the lower level - Paramiko library, it can help us to see the debug output Paramiko prints. At - top level in your fabfile, add the following:: - - import logging - logging.basicConfig(level=logging.DEBUG) - - This should start printing Paramiko's debug statements to your standard error - stream. (Feel free to add more logging kwargs to ``basicConfig()`` such as - ``filename='/path/to/a/file'`` if you like.) - - Then submit this info to anybody helping you on IRC or in your bug report. diff -Nru fabric-1.8.2/docs/tutorial.rst fabric-1.10.0/docs/tutorial.rst --- fabric-1.8.2/docs/tutorial.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/tutorial.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,468 +0,0 @@ -===================== -Overview and Tutorial -===================== - -Welcome to Fabric! - -This document is a whirlwind tour of Fabric's features and a quick guide to its -use. Additional documentation (which is linked to throughout) can be found in -the :ref:`usage documentation ` -- please make sure to check it out. - - -What is Fabric? -=============== - -As the ``README`` says: - - .. include:: ../README.rst - :end-before: It provides - -More specifically, Fabric is: - -* A tool that lets you execute **arbitrary Python functions** via the **command - line**; -* A library of subroutines (built on top of a lower-level library) to make - executing shell commands over SSH **easy** and **Pythonic**. - -Naturally, most users combine these two things, using Fabric to write and -execute Python functions, or **tasks**, to automate interactions with remote -servers. Let's take a look. - - -Hello, ``fab`` -============== - -This wouldn't be a proper tutorial without "the usual":: - - def hello(): - print("Hello world!") - -Placed in a Python module file named ``fabfile.py`` in your current working -directory, that ``hello`` function can be executed with the ``fab`` tool -(installed as part of Fabric) and does just what you'd expect:: - - $ fab hello - Hello world! - - Done. - -That's all there is to it. This functionality allows Fabric to be used as a -(very) basic build tool even without importing any of its API. - -.. note:: - - The ``fab`` tool simply imports your fabfile and executes the function or - functions you instruct it to. There's nothing magic about it -- anything - you can do in a normal Python script can be done in a fabfile! - -.. seealso:: :ref:`execution-strategy`, :doc:`/usage/tasks`, :doc:`/usage/fab` - - -Task arguments -============== - -It's often useful to pass runtime parameters into your tasks, just as you might -during regular Python programming. Fabric has basic support for this using a -shell-compatible notation: ``:,=,...``. It's -contrived, but let's extend the above example to say hello to you personally:: - - def hello(name="world"): - print("Hello %s!" % name) - -By default, calling ``fab hello`` will still behave as it did before; but now -we can personalize it:: - - $ fab hello:name=Jeff - Hello Jeff! - - Done. - -Those already used to programming in Python might have guessed that this -invocation behaves exactly the same way:: - - $ fab hello:Jeff - Hello Jeff! - - Done. - -For the time being, your argument values will always show up in Python as -strings and may require a bit of string manipulation for complex types such -as lists. Future versions may add a typecasting system to make this easier. - -.. seealso:: :ref:`task-arguments` - -Local commands -============== - -As used above, ``fab`` only really saves a couple lines of -``if __name__ == "__main__"`` boilerplate. It's mostly designed for use with -Fabric's API, which contains functions (or **operations**) for executing shell -commands, transferring files, and so forth. - -Let's build a hypothetical Web application fabfile. This example scenario is -as follows: The Web application is managed via Git on a remote host -``vcshost``. On ``localhost``, we have a local clone of said Web application. -When we push changes back to ``vcshost``, we want to be able to immediately -install these changes on a remote host ``my_server`` in an automated fashion. -We will do this by automating the local and remote Git commands. - -Fabfiles usually work best at the root of a project:: - - . - |-- __init__.py - |-- app.wsgi - |-- fabfile.py <-- our fabfile! - |-- manage.py - `-- my_app - |-- __init__.py - |-- models.py - |-- templates - | `-- index.html - |-- tests.py - |-- urls.py - `-- views.py - -.. note:: - - We're using a Django application here, but only as an example -- Fabric is - not tied to any external codebase, save for its SSH library. - -For starters, perhaps we want to run our tests and commit to our VCS so we're -ready for a deploy:: - - from fabric.api import local - - def prepare_deploy(): - local("./manage.py test my_app") - local("git add -p && git commit") - local("git push") - -The output of which might look a bit like this:: - - $ fab prepare_deploy - [localhost] run: ./manage.py test my_app - Creating test database... - Creating tables - Creating indexes - .......................................... - ---------------------------------------------------------------------- - Ran 42 tests in 9.138s - - OK - Destroying test database... - - [localhost] run: git add -p && git commit - - - - [localhost] run: git push - - - - Done. - -The code itself is straightforward: import a Fabric API function, -`~fabric.operations.local`, and use it to run and interact with local shell -commands. The rest of Fabric's API is similar -- it's all just Python. - -.. seealso:: :doc:`api/core/operations`, :ref:`fabfile-discovery` - - -Organize it your way -==================== - -Because Fabric is "just Python" you're free to organize your fabfile any way -you want. For example, it's often useful to start splitting things up into -subtasks:: - - from fabric.api import local - - def test(): - local("./manage.py test my_app") - - def commit(): - local("git add -p && git commit") - - def push(): - local("git push") - - def prepare_deploy(): - test() - commit() - push() - -The ``prepare_deploy`` task can be called just as before, but now you can make -a more granular call to one of the sub-tasks, if desired. - - -Failure -======= - -Our base case works fine now, but what happens if our tests fail? Chances are -we want to put on the brakes and fix them before deploying. - -Fabric checks the return value of programs called via operations and will abort -if they didn't exit cleanly. Let's see what happens if one of our tests -encounters an error:: - - $ fab prepare_deploy - [localhost] run: ./manage.py test my_app - Creating test database... - Creating tables - Creating indexes - .............E............................ - ====================================================================== - ERROR: testSomething (my_project.my_app.tests.MainTests) - ---------------------------------------------------------------------- - Traceback (most recent call last): - [...] - - ---------------------------------------------------------------------- - Ran 42 tests in 9.138s - - FAILED (errors=1) - Destroying test database... - - Fatal error: local() encountered an error (return code 2) while executing './manage.py test my_app' - - Aborting. - -Great! We didn't have to do anything ourselves: Fabric detected the failure and -aborted, never running the ``commit`` task. - -.. seealso:: :ref:`Failure handling (usage documentation) ` - -Failure handling ----------------- - -But what if we wanted to be flexible and give the user a choice? A setting -(or **environment variable**, usually shortened to **env var**) called -:ref:`warn_only` lets you turn aborts into warnings, allowing flexible error -handling to occur. - -Let's flip this setting on for our ``test`` function, and then inspect the -result of the `~fabric.operations.local` call ourselves:: - - from __future__ import with_statement - from fabric.api import local, settings, abort - from fabric.contrib.console import confirm - - def test(): - with settings(warn_only=True): - result = local('./manage.py test my_app', capture=True) - if result.failed and not confirm("Tests failed. Continue anyway?"): - abort("Aborting at user request.") - - [...] - -In adding this new feature we've introduced a number of new things: - -* The ``__future__`` import required to use ``with:`` in Python 2.5; -* Fabric's `contrib.console ` submodule, containing the - `~fabric.contrib.console.confirm` function, used for simple yes/no prompts; -* The `~fabric.context_managers.settings` context manager, used to apply - settings to a specific block of code; -* Command-running operations like `~fabric.operations.local` can return objects - containing info about their result (such as ``.failed``, or - ``.return_code``); -* And the `~fabric.utils.abort` function, used to manually abort execution. - -However, despite the additional complexity, it's still pretty easy to follow, -and is now much more flexible. - -.. seealso:: :doc:`api/core/context_managers`, :ref:`env-vars` - - -Making connections -================== - -Let's start wrapping up our fabfile by putting in the keystone: a ``deploy`` -task that is destined to run on one or more remote server(s), and ensures the -code is up to date:: - - def deploy(): - code_dir = '/srv/django/myproject' - with cd(code_dir): - run("git pull") - run("touch app.wsgi") - -Here again, we introduce a handful of new concepts: - -* Fabric is just Python -- so we can make liberal use of regular Python code - constructs such as variables and string interpolation; -* `~fabric.context_managers.cd`, an easy way of prefixing commands with a ``cd - /to/some/directory`` call. This is similar to `~fabric.context_managers.lcd` - which does the same locally. -* `~fabric.operations.run`, which is similar to `~fabric.operations.local` but - runs **remotely** instead of locally. - -We also need to make sure we import the new functions at the top of our file:: - - from __future__ import with_statement - from fabric.api import local, settings, abort, run, cd - from fabric.contrib.console import confirm - -With these changes in place, let's deploy:: - - $ fab deploy - No hosts found. Please specify (single) host string for connection: my_server - [my_server] run: git pull - [my_server] out: Already up-to-date. - [my_server] out: - [my_server] run: touch app.wsgi - - Done. - -We never specified any connection info in our fabfile, so Fabric doesn't know -on which host(s) the remote command should be executed. When this happens, -Fabric prompts us at runtime. Connection definitions use SSH-like "host -strings" (e.g. ``user@host:port``) and will use your local username as a -default -- so in this example, we just had to specify the hostname, -``my_server``. - - -Remote interactivity --------------------- - -``git pull`` works fine if you've already got a checkout of your source code -- -but what if this is the first deploy? It'd be nice to handle that case too and -do the initial ``git clone``:: - - def deploy(): - code_dir = '/srv/django/myproject' - with settings(warn_only=True): - if run("test -d %s" % code_dir).failed: - run("git clone user@vcshost:/path/to/repo/.git %s" % code_dir) - with cd(code_dir): - run("git pull") - run("touch app.wsgi") - -As with our calls to `~fabric.operations.local` above, `~fabric.operations.run` -also lets us construct clean Python-level logic based on executed shell -commands. However, the interesting part here is the ``git clone`` call: since -we're using Git's SSH method of accessing the repository on our Git server, -this means our remote `~fabric.operations.run` call will need to authenticate -itself. - -Older versions of Fabric (and similar high level SSH libraries) run remote -programs in limbo, unable to be touched from the local end. This is -problematic when you have a serious need to enter passwords or otherwise -interact with the remote program. - -Fabric 1.0 and later breaks down this wall and ensures you can always talk to -the other side. Let's see what happens when we run our updated ``deploy`` task -on a new server with no Git checkout:: - - $ fab deploy - No hosts found. Please specify (single) host string for connection: my_server - [my_server] run: test -d /srv/django/myproject - - Warning: run() encountered an error (return code 1) while executing 'test -d /srv/django/myproject' - - [my_server] run: git clone user@vcshost:/path/to/repo/.git /srv/django/myproject - [my_server] out: Cloning into /srv/django/myproject... - [my_server] out: Password: - [my_server] out: remote: Counting objects: 6698, done. - [my_server] out: remote: Compressing objects: 100% (2237/2237), done. - [my_server] out: remote: Total 6698 (delta 4633), reused 6414 (delta 4412) - [my_server] out: Receiving objects: 100% (6698/6698), 1.28 MiB, done. - [my_server] out: Resolving deltas: 100% (4633/4633), done. - [my_server] out: - [my_server] run: git pull - [my_server] out: Already up-to-date. - [my_server] out: - [my_server] run: touch app.wsgi - - Done. - -Notice the ``Password:`` prompt -- that was our remote ``git`` call on our Web server, asking for the password to the Git server. We were able to type it in and the clone continued normally. - -.. seealso:: :doc:`/usage/interactivity` - - -.. _defining-connections: - -Defining connections beforehand -------------------------------- - -Specifying connection info at runtime gets old real fast, so Fabric provides a -handful of ways to do it in your fabfile or on the command line. We won't cover -all of them here, but we will show you the most common one: setting the global -host list, :ref:`env.hosts `. - -:doc:`env ` is a global dictionary-like object driving many of -Fabric's settings, and can be written to with attributes as well (in fact, -`~fabric.context_managers.settings`, seen above, is simply a wrapper for this.) -Thus, we can modify it at module level near the top of our fabfile like so:: - - from __future__ import with_statement - from fabric.api import * - from fabric.contrib.console import confirm - - env.hosts = ['my_server'] - - def test(): - do_test_stuff() - -When ``fab`` loads up our fabfile, our modification of ``env`` will execute, -storing our settings change. The end result is exactly as above: our ``deploy`` -task will run against the ``my_server`` server. - -This is also how you can tell Fabric to run on multiple remote systems at once: -because ``env.hosts`` is a list, ``fab`` iterates over it, calling the given -task once for each connection. - -.. seealso:: :doc:`usage/env`, :ref:`host-lists` - - -Conclusion -========== - -Our completed fabfile is still pretty short, as such things go. Here it is in -its entirety:: - - from __future__ import with_statement - from fabric.api import * - from fabric.contrib.console import confirm - - env.hosts = ['my_server'] - - def test(): - with settings(warn_only=True): - result = local('./manage.py test my_app', capture=True) - if result.failed and not confirm("Tests failed. Continue anyway?"): - abort("Aborting at user request.") - - def commit(): - local("git add -p && git commit") - - def push(): - local("git push") - - def prepare_deploy(): - test() - commit() - push() - - def deploy(): - code_dir = '/srv/django/myproject' - with settings(warn_only=True): - if run("test -d %s" % code_dir).failed: - run("git clone user@vcshost:/path/to/repo/.git %s" % code_dir) - with cd(code_dir): - run("git pull") - run("touch app.wsgi") - -This fabfile makes use of a large portion of Fabric's feature set: - -* defining fabfile tasks and running them with :doc:`fab `; -* calling local shell commands with `~fabric.operations.local`; -* modifying env vars with `~fabric.context_managers.settings`; -* handling command failures, prompting the user, and manually aborting; -* and defining host lists and `~fabric.operations.run`-ning remote commands. - -However, there's still a lot more we haven't covered here! Please make sure you -follow the various "see also" links, and check out the documentation table of -contents on :ref:`the main index page `. - -Thanks for reading! diff -Nru fabric-1.8.2/docs/usage/env.rst fabric-1.10.0/docs/usage/env.rst --- fabric-1.8.2/docs/usage/env.rst 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/docs/usage/env.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,866 +0,0 @@ -=================================== -The environment dictionary, ``env`` -=================================== - -A simple but integral aspect of Fabric is what is known as the "environment": a -Python dictionary subclass, which is used as a combination settings registry and -shared inter-task data namespace. - -The environment dict is currently implemented as a global singleton, -``fabric.state.env``, and is included in ``fabric.api`` for convenience. Keys -in ``env`` are sometimes referred to as "env variables". - -Environment as configuration -============================ - -Most of Fabric's behavior is controllable by modifying ``env`` variables, such -as ``env.hosts`` (as seen in :ref:`the tutorial `). Other -commonly-modified env vars include: - -* ``user``: Fabric defaults to your local username when making SSH connections, - but you can use ``env.user`` to override this if necessary. The :doc:`execution` - documentation also has info on how to specify usernames on a per-host basis. -* ``password``: Used to explicitly set your default connection or sudo password - if desired. Fabric will prompt you when necessary if this isn't set or - doesn't appear to be valid. -* ``warn_only``: a Boolean setting determining whether Fabric exits when - detecting errors on the remote end. See :doc:`execution` for more on this - behavior. - -There are a number of other env variables; for the full list, see -:ref:`env-vars` at the bottom of this document. - -The `~fabric.context_managers.settings` context manager -------------------------------------------------------- - -In many situations, it's useful to only temporarily modify ``env`` vars so that -a given settings change only applies to a block of code. Fabric provides a -`~fabric.context_managers.settings` context manager, which takes any number of -key/value pairs and will use them to modify ``env`` within its wrapped block. - -For example, there are many situations where setting ``warn_only`` (see below) -is useful. To apply it to a few lines of code, use -``settings(warn_only=True)``, as seen in this simplified version of the -``contrib`` `~fabric.contrib.files.exists` function:: - - from fabric.api import settings, run - - def exists(path): - with settings(warn_only=True): - return run('test -e %s' % path) - -See the :doc:`../api/core/context_managers` API documentation for details on -`~fabric.context_managers.settings` and other, similar tools. - -Environment as shared state -=========================== - -As mentioned, the ``env`` object is simply a dictionary subclass, so your own -fabfile code may store information in it as well. This is sometimes useful for -keeping state between multiple tasks within a single execution run. - -.. note:: - - This aspect of ``env`` is largely historical: in the past, fabfiles were - not pure Python and thus the environment was the only way to communicate - between tasks. Nowadays, you may call other tasks or subroutines directly, - and even keep module-level shared state if you wish. - - In future versions, Fabric will become threadsafe, at which point ``env`` - may be the only easy/safe way to keep global state. - -Other considerations -==================== - -While it subclasses ``dict``, Fabric's ``env`` has been modified so that its -values may be read/written by way of attribute access, as seen in some of the -above material. In other words, ``env.host_string`` and ``env['host_string']`` -are functionally identical. We feel that attribute access can often save a bit -of typing and makes the code more readable, so it's the recommended way to -interact with ``env``. - -The fact that it's a dictionary can be useful in other ways, such as with -Python's ``dict``-based string interpolation, which is especially handy if you -need to insert multiple env vars into a single string. Using "normal" string -interpolation might look like this:: - - print("Executing on %s as %s" % (env.host, env.user)) - -Using dict-style interpolation is more readable and slightly shorter:: - - print("Executing on %(host)s as %(user)s" % env) - -.. _env-vars: - -Full list of env vars -===================== - -Below is a list of all predefined (or defined by Fabric itself during -execution) environment variables. While many of them may be manipulated -directly, it's often best to use `~fabric.context_managers`, either generally -via `~fabric.context_managers.settings` or via specific context managers such -as `~fabric.context_managers.cd`. - -Note that many of these may be set via ``fab``'s command-line switches -- see -:doc:`fab` for details. Cross-references are provided where appropriate. - -.. seealso:: :option:`--set` - -.. _abort-exception: - -``abort_exception`` -------------------- - -**Default:** ``None`` - -Fabric normally handles aborting by printing an error message to stderr and -calling ``sys.exit(1)``. This setting allows you to override that behavior -(which is what happens when ``env.abort_exception`` is ``None``.) - -Give it a callable which takes a string (the error message that would have been -printed) and returns an exception instance. That exception object is then -raised instead of ``SystemExit`` (which is what ``sys.exit`` does.) - -Much of the time you'll want to simply set this to an exception class, as those -fit the above description perfectly (callable, take a string, return an -exception instance.) E.g. ``env.abort_exception = MyExceptionClass``. - -.. _abort-on-prompts: - -``abort_on_prompts`` --------------------- - -**Default:** ``False`` - -When ``True``, Fabric will run in a non-interactive mode, calling -`~fabric.utils.abort` anytime it would normally prompt the user for input (such -as password prompts, "What host to connect to?" prompts, fabfile invocation of -`~fabric.operations.prompt`, and so forth.) This allows users to ensure a Fabric -session will always terminate cleanly instead of blocking on user input forever -when unforeseen circumstances arise. - -.. versionadded:: 1.1 -.. seealso:: :option:`--abort-on-prompts` - - -``all_hosts`` -------------- - -**Default:** ``None`` - -Set by ``fab`` to the full host list for the currently executing command. For -informational purposes only. - -.. seealso:: :doc:`execution` - -.. _always-use-pty: - -``always_use_pty`` ------------------- - -**Default:** ``True`` - -When set to ``False``, causes `~fabric.operations.run`/`~fabric.operations.sudo` -to act as if they have been called with ``pty=False``. - -.. seealso:: :option:`--no-pty` -.. versionadded:: 1.0 - -.. _colorize-errors: - -``colorize_errors`` -------------------- - -**Default** ``False`` - -When set to ``True``, error output to the terminal is colored red and warnings -are colored magenta to make them easier to see. - -.. versionadded:: 1.7 - -.. _combine-stderr: - -``combine_stderr`` ------------------- - -**Default**: ``True`` - -Causes the SSH layer to merge a remote program's stdout and stderr streams to -avoid becoming meshed together when printed. See :ref:`combine_streams` for -details on why this is needed and what its effects are. - -.. versionadded:: 1.0 - -``command`` ------------ - -**Default:** ``None`` - -Set by ``fab`` to the currently executing command name (e.g., when executed as -``$ fab task1 task2``, ``env.command`` will be set to ``"task1"`` while -``task1`` is executing, and then to ``"task2"``.) For informational purposes -only. - -.. seealso:: :doc:`execution` - -``command_prefixes`` --------------------- - -**Default:** ``[]`` - -Modified by `~fabric.context_managers.prefix`, and prepended to commands -executed by `~fabric.operations.run`/`~fabric.operations.sudo`. - -.. versionadded:: 1.0 - -.. _command-timeout: - -``command_timeout`` -------------------- - -**Default:** ``None`` - -Remote command timeout, in seconds. - -.. versionadded:: 1.6 -.. seealso:: :option:`--command-timeout` - -.. _connection-attempts: - -``connection_attempts`` ------------------------ - -**Default:** ``1`` - -Number of times Fabric will attempt to connect when connecting to a new server. For backwards compatibility reasons, it defaults to only one connection attempt. - -.. versionadded:: 1.4 -.. seealso:: :option:`--connection-attempts`, :ref:`timeout` - -``cwd`` -------- - -**Default:** ``''`` - -Current working directory. Used to keep state for the -`~fabric.context_managers.cd` context manager. - -.. _dedupe_hosts: - -``dedupe_hosts`` ----------------- - -**Default:** ``True`` - -Deduplicate merged host lists so any given host string is only represented once -(e.g. when using combinations of ``@hosts`` + ``@roles``, or ``-H`` and -``-R``.) - -When set to ``False``, this option relaxes the deduplication, allowing users -who explicitly want to run a task multiple times on the same host (say, in -parallel, though it works fine serially too) to do so. - -.. versionadded:: 1.5 - -.. _disable-known-hosts: - -``disable_known_hosts`` ------------------------ - -**Default:** ``False`` - -If ``True``, the SSH layer will skip loading the user's known-hosts file. -Useful for avoiding exceptions in situations where a "known host" changing its -host key is actually valid (e.g. cloud servers such as EC2.) - -.. seealso:: :option:`--disable-known-hosts <-D>`, :doc:`ssh` - - -.. _eagerly-disconnect: - -``eagerly_disconnect`` ----------------------- - -**Default:** ``False`` - -If ``True``, causes ``fab`` to close connections after each individual task -execution, instead of at the end of the run. This helps prevent a lot of -typically-unused network sessions from piling up and causing problems with -limits on per-process open files, or network hardware. - -.. note:: - When active, this setting will result in the disconnect messages appearing - throughout your output, instead of at the end. This may be improved in - future releases. - - -.. _exclude-hosts: - -``exclude_hosts`` ------------------ - -**Default:** ``[]`` - -Specifies a list of host strings to be :ref:`skipped over ` -during ``fab`` execution. Typically set via :option:`--exclude-hosts/-x <-x>`. - -.. versionadded:: 1.1 - - -``fabfile`` ------------ - -**Default:** ``fabfile.py`` - -Filename pattern which ``fab`` searches for when loading fabfiles. -To indicate a specific file, use the full path to the file. Obviously, it -doesn't make sense to set this in a fabfile, but it may be specified in a -``.fabricrc`` file or on the command line. - -.. seealso:: :option:`--fabfile <-f>`, :doc:`fab` - - -.. _gateway: - -``gateway`` ------------ - -**Default:** ``None`` - -Enables SSH-driven gatewaying through the indicated host. The value should be a -normal Fabric host string as used in e.g. :ref:`env.host_string `. -When this is set, newly created connections will be set to route their SSH -traffic through the remote SSH daemon to the final destination. - -.. versionadded:: 1.5 - -.. seealso:: :option:`--gateway <-g>` - - -.. _host_string: - -``host_string`` ---------------- - -**Default:** ``None`` - -Defines the current user/host/port which Fabric will connect to when executing -`~fabric.operations.run`, `~fabric.operations.put` and so forth. This is set by -``fab`` when iterating over a previously set host list, and may also be -manually set when using Fabric as a library. - -.. seealso:: :doc:`execution` - - -.. _forward-agent: - -``forward_agent`` --------------------- - -**Default:** ``False`` - -If ``True``, enables forwarding of your local SSH agent to the remote end. - -.. versionadded:: 1.4 - -.. seealso:: :option:`--forward-agent <-A>` - - -``host`` --------- - -**Default:** ``None`` - -Set to the hostname part of ``env.host_string`` by ``fab``. For informational -purposes only. - -.. _hosts: - -``hosts`` ---------- - -**Default:** ``[]`` - -The global host list used when composing per-task host lists. - -.. seealso:: :option:`--hosts <-H>`, :doc:`execution` - -.. _keepalive: - -``keepalive`` -------------- - -**Default:** ``0`` (i.e. no keepalive) - -An integer specifying an SSH keepalive interval to use; basically maps to the -SSH config option ``ClientAliveInterval``. Useful if you find connections are -timing out due to meddlesome network hardware or what have you. - -.. seealso:: :option:`--keepalive` -.. versionadded:: 1.1 - - -.. _key: - -``key`` ----------------- - -**Default:** ``None`` - -A string, or file-like object, containing an SSH key; used during connection -authentication. - -.. note:: - The most common method for using SSH keys is to set :ref:`key-filename`. - -.. versionadded:: 1.7 - - -.. _key-filename: - -``key_filename`` ----------------- - -**Default:** ``None`` - -May be a string or list of strings, referencing file paths to SSH key files to -try when connecting. Passed through directly to the SSH layer. May be -set/appended to with :option:`-i`. - -.. seealso:: `Paramiko's documentation for SSHClient.connect() `_ - -.. _env-linewise: - -``linewise`` ------------- - -**Default:** ``False`` - -Forces buffering by line instead of by character/byte, typically when running -in parallel mode. May be activated via :option:`--linewise`. This option is -implied by :ref:`env.parallel ` -- even if ``linewise`` is False, -if ``parallel`` is True then linewise behavior will occur. - -.. seealso:: :ref:`linewise-output` - -.. versionadded:: 1.3 - - -.. _local-user: - -``local_user`` --------------- - -A read-only value containing the local system username. This is the same value -as :ref:`user`'s initial value, but whereas :ref:`user` may be altered by CLI -arguments, Python code or specific host strings, :ref:`local-user` will always -contain the same value. - -.. _no_agent: - -``no_agent`` ------------- - -**Default:** ``False`` - -If ``True``, will tell the SSH layer not to seek out running SSH agents when -using key-based authentication. - -.. versionadded:: 0.9.1 -.. seealso:: :option:`--no_agent <-a>` - -.. _no_keys: - -``no_keys`` ------------------- - -**Default:** ``False`` - -If ``True``, will tell the SSH layer not to load any private key files from -one's ``$HOME/.ssh/`` folder. (Key files explicitly loaded via ``fab -i`` will -still be used, of course.) - -.. versionadded:: 0.9.1 -.. seealso:: :option:`-k` - -.. _env-parallel: - -``parallel`` -------------------- - -**Default:** ``False`` - -When ``True``, forces all tasks to run in parallel. Implies :ref:`env.linewise -`. - -.. versionadded:: 1.3 -.. seealso:: :option:`--parallel <-P>`, :doc:`parallel` - -.. _password: - -``password`` ------------- - -**Default:** ``None`` - -The default password used by the SSH layer when connecting to remote hosts, -**and/or** when answering `~fabric.operations.sudo` prompts. - -.. seealso:: :option:`--initial-password-prompt <-I>`, :ref:`env.passwords `, :ref:`password-management` - -.. _passwords: - -``passwords`` -------------- - -**Default:** ``{}`` - -This dictionary is largely for internal use, and is filled automatically as a -per-host-string password cache. Keys are full :ref:`host strings -` and values are passwords (strings). - -.. seealso:: :ref:`password-management` - -.. versionadded:: 1.0 - - -.. _env-path: - -``path`` --------- - -**Default:** ``''`` - -Used to set the ``$PATH`` shell environment variable when executing commands in -`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.local`. -It is recommended to use the `~fabric.context_managers.path` context manager -for managing this value instead of setting it directly. - -.. versionadded:: 1.0 - - -.. _pool-size: - -``pool_size`` -------------- - -**Default:** ``0`` - -Sets the number of concurrent processes to use when executing tasks in parallel. - -.. versionadded:: 1.3 -.. seealso:: :option:`--pool-size <-z>`, :doc:`parallel` - -.. _port: - -``port`` --------- - -**Default:** ``None`` - -Set to the port part of ``env.host_string`` by ``fab`` when iterating over a -host list. May also be used to specify a default port. - -.. _real-fabfile: - -``real_fabfile`` ----------------- - -**Default:** ``None`` - -Set by ``fab`` with the path to the fabfile it has loaded up, if it got that -far. For informational purposes only. - -.. seealso:: :doc:`fab` - - -.. _remote-interrupt: - -``remote_interrupt`` --------------------- - -**Default:** ``None`` - -Controls whether Ctrl-C triggers an interrupt remotely or is captured locally, -as follows: - -* ``None`` (the default): only `~fabric.operations.open_shell` will exhibit - remote interrupt behavior, and - `~fabric.operations.run`/`~fabric.operations.sudo` will capture interrupts - locally. -* ``False``: even `~fabric.operations.open_shell` captures locally. -* ``True``: all functions will send the interrupt to the remote end. - -.. versionadded:: 1.6 - - -.. _rcfile: - -``rcfile`` ----------- - -**Default:** ``$HOME/.fabricrc`` - -Path used when loading Fabric's local settings file. - -.. seealso:: :option:`--config <-c>`, :doc:`fab` - -.. _reject-unknown-hosts: - -``reject_unknown_hosts`` ------------------------- - -**Default:** ``False`` - -If ``True``, the SSH layer will raise an exception when connecting to hosts not -listed in the user's known-hosts file. - -.. seealso:: :option:`--reject-unknown-hosts <-r>`, :doc:`ssh` - -.. _system-known-hosts: - -``system_known_hosts`` ------------------------- - -**Default:** ``None`` - -If set, should be the path to a :file:`known_hosts` file. The SSH layer will -read this file before reading the user's known-hosts file. - -.. seealso:: :doc:`ssh` - -``roledefs`` ------------- - -**Default:** ``{}`` - -Dictionary defining role name to host list mappings. - -.. seealso:: :doc:`execution` - -.. _roles: - -``roles`` ---------- - -**Default:** ``[]`` - -The global role list used when composing per-task host lists. - -.. seealso:: :option:`--roles <-R>`, :doc:`execution` - -.. _shell: - -``shell`` ---------- - -**Default:** ``/bin/bash -l -c`` - -Value used as shell wrapper when executing commands with e.g. -`~fabric.operations.run`. Must be able to exist in the form `` -""`` -- e.g. the default uses Bash's ``-c`` option which -takes a command string as its value. - -.. seealso:: :option:`--shell <-s>`, - :ref:`FAQ on bash as default shell `, :doc:`execution` - -.. _skip-bad-hosts: - -``skip_bad_hosts`` ------------------- - -**Default:** ``False`` - -If ``True``, causes ``fab`` (or non-``fab`` use of `~fabric.tasks.execute`) to skip over hosts it can't connect to. - -.. versionadded:: 1.4 -.. seealso:: - :option:`--skip-bad-hosts`, :ref:`excluding-hosts`, :doc:`execution` - - -.. _ssh-config-path: - -``ssh_config_path`` -------------------- - -**Default:** ``$HOME/.ssh/config`` - -Allows specification of an alternate SSH configuration file path. - -.. versionadded:: 1.4 -.. seealso:: :option:`--ssh-config-path`, :ref:`ssh-config` - -``ok_ret_codes`` ------------------------- - -**Default:** ``[0]`` - -Return codes in this list are used to determine whether calls to -`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.sudo` -are considered successful. - -.. versionadded:: 1.6 - -.. _sudo_prefix: - -``sudo_prefix`` ---------------- - -**Default:** ``"sudo -S -p '%(sudo_prompt)s' " % env`` - -The actual ``sudo`` command prefixed onto `~fabric.operations.sudo` calls' -command strings. Users who do not have ``sudo`` on their default remote -``$PATH``, or who need to make other changes (such as removing the ``-p`` when -passwordless sudo is in effect) may find changing this useful. - -.. seealso:: - - The `~fabric.operations.sudo` operation; :ref:`env.sudo_prompt - ` - -.. _sudo_prompt: - -``sudo_prompt`` ---------------- - -**Default:** ``"sudo password:"`` - -Passed to the ``sudo`` program on remote systems so that Fabric may correctly -identify its password prompt. - -.. seealso:: - - The `~fabric.operations.sudo` operation; :ref:`env.sudo_prefix - ` - -.. _sudo_user: - -``sudo_user`` -------------- - -**Default:** ``None`` - -Used as a fallback value for `~fabric.operations.sudo`'s ``user`` argument if -none is given. Useful in combination with `~fabric.context_managers.settings`. - -.. seealso:: `~fabric.operations.sudo` - -.. _env-tasks: - -``tasks`` -------------- - -**Default:** ``[]`` - -Set by ``fab`` to the full tasks list to be executed for the currently -executing command. For informational purposes only. - -.. seealso:: :doc:`execution` - -.. _timeout: - -``timeout`` ------------ - -**Default:** ``10`` - -Network connection timeout, in seconds. - -.. versionadded:: 1.4 -.. seealso:: :option:`--timeout`, :ref:`connection-attempts` - -``use_shell`` -------------- - -**Default:** ``True`` - -Global setting which acts like the ``use_shell`` argument to -`~fabric.operations.run`/`~fabric.operations.sudo`: if it is set to ``False``, -operations will not wrap executed commands in ``env.shell``. - - -.. _use-ssh-config: - -``use_ssh_config`` ------------------- - -**Default:** ``False`` - -Set to ``True`` to cause Fabric to load your local SSH config file. - -.. versionadded:: 1.4 -.. seealso:: :ref:`ssh-config` - - -.. _user: - -``user`` --------- - -**Default:** User's local username - -The username used by the SSH layer when connecting to remote hosts. May be set -globally, and will be used when not otherwise explicitly set in host strings. -However, when explicitly given in such a manner, this variable will be -temporarily overwritten with the current value -- i.e. it will always display -the user currently being connected as. - -To illustrate this, a fabfile:: - - from fabric.api import env, run - - env.user = 'implicit_user' - env.hosts = ['host1', 'explicit_user@host2', 'host3'] - - def print_user(): - with hide('running'): - run('echo "%(user)s"' % env) - -and its use:: - - $ fab print_user - - [host1] out: implicit_user - [explicit_user@host2] out: explicit_user - [host3] out: implicit_user - - Done. - Disconnecting from host1... done. - Disconnecting from host2... done. - Disconnecting from host3... done. - -As you can see, during execution on ``host2``, ``env.user`` was set to -``"explicit_user"``, but was restored to its previous value -(``"implicit_user"``) afterwards. - -.. note:: - - ``env.user`` is currently somewhat confusing (it's used for configuration - **and** informational purposes) so expect this to change in the future -- - the informational aspect will likely be broken out into a separate env - variable. - -.. seealso:: :doc:`execution`, :option:`--user <-u>` - -``version`` ------------ - -**Default:** current Fabric version string - -Mostly for informational purposes. Modification is not recommended, but -probably won't break anything either. - -.. seealso:: :option:`--version <-V>` - -.. _warn_only: - -``warn_only`` -------------- - -**Default:** ``False`` - -Specifies whether or not to warn, instead of abort, when -`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.local` -encounter error conditions. - -.. seealso:: :option:`--warn-only <-w>`, :doc:`execution` diff -Nru fabric-1.8.2/docs/usage/execution.rst fabric-1.10.0/docs/usage/execution.rst --- fabric-1.8.2/docs/usage/execution.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/execution.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,845 +0,0 @@ -=============== -Execution model -=============== - -If you've read the :doc:`../tutorial`, you should already be familiar with how -Fabric operates in the base case (a single task on a single host.) However, in -many situations you'll find yourself wanting to execute multiple tasks and/or -on multiple hosts. Perhaps you want to split a big task into smaller reusable -parts, or crawl a collection of servers looking for an old user to remove. Such -a scenario requires specific rules for when and how tasks are executed. - -This document explores Fabric's execution model, including the main execution -loop, how to define host lists, how connections are made, and so forth. - - -.. _execution-strategy: - -Execution strategy -================== - -Fabric defaults to a single, serial execution method, though there is an -alternative parallel mode available as of Fabric 1.3 (see -:doc:`/usage/parallel`). This default behavior is as follows: - -* A list of tasks is created. Currently this list is simply the arguments given - to :doc:`fab `, preserving the order given. -* For each task, a task-specific host list is generated from various - sources (see :ref:`host-lists` below for details.) -* The task list is walked through in order, and each task is run once per host - in its host list. -* Tasks with no hosts in their host list are considered local-only, and will - always run once and only once. - -Thus, given the following fabfile:: - - from fabric.api import run, env - - env.hosts = ['host1', 'host2'] - - def taskA(): - run('ls') - - def taskB(): - run('whoami') - -and the following invocation:: - - $ fab taskA taskB - -you will see that Fabric performs the following: - -* ``taskA`` executed on ``host1`` -* ``taskA`` executed on ``host2`` -* ``taskB`` executed on ``host1`` -* ``taskB`` executed on ``host2`` - -While this approach is simplistic, it allows for a straightforward composition -of task functions, and (unlike tools which push the multi-host functionality -down to the individual function calls) enables shell script-like logic where -you may introspect the output or return code of a given command and decide what -to do next. - - -Defining tasks -============== - -For details on what constitutes a Fabric task and how to organize them, please see :doc:`/usage/tasks`. - - -Defining host lists -=================== - -Unless you're using Fabric as a simple build system (which is possible, but not -the primary use-case) having tasks won't do you any good without the ability to -specify remote hosts on which to execute them. There are a number of ways to do -so, with scopes varying from global to per-task, and it's possible mix and -match as needed. - -.. _host-strings: - -Hosts ------ - -Hosts, in this context, refer to what are also called "host strings": Python -strings specifying a username, hostname and port combination, in the form of -``username@hostname:port``. User and/or port (and the associated ``@`` or -``:``) may be omitted, and will be filled by the executing user's local -username, and/or port 22, respectively. Thus, ``admin@foo.com:222``, -``deploy@website`` and ``nameserver1`` could all be valid host strings. - -IPv6 address notation is also supported, for example ``::1``, ``[::1]:1222``, -``user@2001:db8::1`` or ``user@[2001:db8::1]:1222``. Square brackets -are necessary only to separate the address from the port number. If no -port number is used, the brackets are optional. Also if host string is -specified via command-line argument, it may be necessary to escape -brackets in some shells. - -.. note:: - The user/hostname split occurs at the last ``@`` found, so e.g. email - address usernames are valid and will be parsed correctly. - -During execution, Fabric normalizes the host strings given and then stores each -part (username/hostname/port) in the environment dictionary, for both its use -and for tasks to reference if the need arises. See :doc:`env` for details. - -.. _execution-roles: - -Roles ------ - -Host strings map to single hosts, but sometimes it's useful to arrange hosts in -groups. Perhaps you have a number of Web servers behind a load balancer and -want to update all of them, or want to run a task on "all client servers". -Roles provide a way of defining strings which correspond to lists of host -strings, and can then be specified instead of writing out the entire list every -time. - -This mapping is defined as a dictionary, ``env.roledefs``, which must be -modified by a fabfile in order to be used. A simple example:: - - from fabric.api import env - - env.roledefs['webservers'] = ['www1', 'www2', 'www3'] - -Since ``env.roledefs`` is naturally empty by default, you may also opt to -re-assign to it without fear of losing any information (provided you aren't -loading other fabfiles which also modify it, of course):: - - from fabric.api import env - - env.roledefs = { - 'web': ['www1', 'www2', 'www3'], - 'dns': ['ns1', 'ns2'] - } - -In addition to list/iterable object types, the values in ``env.roledefs`` may -be callables, and will thus be called when looked up when tasks are run instead -of at module load time. (For example, you could connect to remote servers -to obtain role definitions, and not worry about causing delays at fabfile load -time when calling e.g. ``fab --list``.) - -Use of roles is not required in any way -- it's simply a convenience in -situations where you have common groupings of servers. - -.. versionchanged:: 0.9.2 - Added ability to use callables as ``roledefs`` values. - -.. _host-lists: - -How host lists are constructed ------------------------------- - -There are a number of ways to specify host lists, either globally or per-task, -and generally these methods override one another instead of merging together -(though this may change in future releases.) Each such method is typically -split into two parts, one for hosts and one for roles. - -Globally, via ``env`` -~~~~~~~~~~~~~~~~~~~~~ - -The most common method of setting hosts or roles is by modifying two key-value -pairs in the environment dictionary, :doc:`env `: ``hosts`` and ``roles``. -The value of these variables is checked at runtime, while constructing each -tasks's host list. - -Thus, they may be set at module level, which will take effect when the fabfile -is imported:: - - from fabric.api import env, run - - env.hosts = ['host1', 'host2'] - - def mytask(): - run('ls /var/www') - -Such a fabfile, run simply as ``fab mytask``, will run ``mytask`` on ``host1`` -followed by ``host2``. - -Since the env vars are checked for *each* task, this means that if you have the -need, you can actually modify ``env`` in one task and it will affect all -following tasks:: - - from fabric.api import env, run - - def set_hosts(): - env.hosts = ['host1', 'host2'] - - def mytask(): - run('ls /var/www') - -When run as ``fab set_hosts mytask``, ``set_hosts`` is a "local" task -- its -own host list is empty -- but ``mytask`` will again run on the two hosts given. - -.. note:: - - This technique used to be a common way of creating fake "roles", but is - less necessary now that roles are fully implemented. It may still be useful - in some situations, however. - -Alongside ``env.hosts`` is ``env.roles`` (not to be confused with -``env.roledefs``!) which, if given, will be taken as a list of role names to -look up in ``env.roledefs``. - -Globally, via the command line -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In addition to modifying ``env.hosts``, ``env.roles``, and -``env.exclude_hosts`` at the module level, you may define them by passing -comma-separated string arguments to the command-line switches -:option:`--hosts/-H <-H>` and :option:`--roles/-R <-R>`, e.g.:: - - $ fab -H host1,host2 mytask - -Such an invocation is directly equivalent to ``env.hosts = ['host1', 'host2']`` --- the argument parser knows to look for these arguments and will modify -``env`` at parse time. - -.. note:: - - It's possible, and in fact common, to use these switches to set only a - single host or role. Fabric simply calls ``string.split(',')`` on the given - string, so a string with no commas turns into a single-item list. - -It is important to know that these command-line switches are interpreted -**before** your fabfile is loaded: any reassignment to ``env.hosts`` or -``env.roles`` in your fabfile will overwrite them. - -If you wish to nondestructively merge the command-line hosts with your -fabfile-defined ones, make sure your fabfile uses ``env.hosts.extend()`` -instead:: - - from fabric.api import env, run - - env.hosts.extend(['host3', 'host4']) - - def mytask(): - run('ls /var/www') - -When this fabfile is run as ``fab -H host1,host2 mytask``, ``env.hosts`` will -then contain ``['host1', 'host2', 'host3', 'host4']`` at the time that -``mytask`` is executed. - -.. note:: - - ``env.hosts`` is simply a Python list object -- so you may use - ``env.hosts.append()`` or any other such method you wish. - -.. _hosts-per-task-cli: - -Per-task, via the command line -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Globally setting host lists only works if you want all your tasks to run on the -same host list all the time. This isn't always true, so Fabric provides a few -ways to be more granular and specify host lists which apply to a single task -only. The first of these uses task arguments. - -As outlined in :doc:`fab`, it's possible to specify per-task arguments via a -special command-line syntax. In addition to naming actual arguments to your -task function, this may be used to set the ``host``, ``hosts``, ``role`` or -``roles`` "arguments", which are interpreted by Fabric when building host lists -(and removed from the arguments passed to the task itself.) - -.. note:: - - Since commas are already used to separate task arguments from one another, - semicolons must be used in the ``hosts`` or ``roles`` arguments to - delineate individual host strings or role names. Furthermore, the argument - must be quoted to prevent your shell from interpreting the semicolons. - -Take the below fabfile, which is the same one we've been using, but which -doesn't define any host info at all:: - - from fabric.api import run - - def mytask(): - run('ls /var/www') - -To specify per-task hosts for ``mytask``, execute it like so:: - - $ fab mytask:hosts="host1;host2" - -This will override any other host list and ensure ``mytask`` always runs on -just those two hosts. - -Per-task, via decorators -~~~~~~~~~~~~~~~~~~~~~~~~ - -If a given task should always run on a predetermined host list, you may wish to -specify this in your fabfile itself. This can be done by decorating a task -function with the `~fabric.decorators.hosts` or `~fabric.decorators.roles` -decorators. These decorators take a variable argument list, like so:: - - from fabric.api import hosts, run - - @hosts('host1', 'host2') - def mytask(): - run('ls /var/www') - -They will also take an single iterable argument, e.g.:: - - my_hosts = ('host1', 'host2') - @hosts(my_hosts) - def mytask(): - # ... - -When used, these decorators override any checks of ``env`` for that particular -task's host list (though ``env`` is not modified in any way -- it is simply -ignored.) Thus, even if the above fabfile had defined ``env.hosts`` or the call -to :doc:`fab ` uses :option:`--hosts/-H <-H>`, ``mytask`` would still run -on a host list of ``['host1', 'host2']``. - -However, decorator host lists do **not** override per-task command-line -arguments, as given in the previous section. - -Order of precedence -~~~~~~~~~~~~~~~~~~~ - -We've been pointing out which methods of setting host lists trump the others, -as we've gone along. However, to make things clearer, here's a quick breakdown: - -* Per-task, command-line host lists (``fab mytask:host=host1``) override - absolutely everything else. -* Per-task, decorator-specified host lists (``@hosts('host1')``) override the - ``env`` variables. -* Globally specified host lists set in the fabfile (``env.hosts = ['host1']``) - *can* override such lists set on the command-line, but only if you're not - careful (or want them to.) -* Globally specified host lists set on the command-line (``--hosts=host1``) - will initialize the ``env`` variables, but that's it. - -This logic may change slightly in the future to be more consistent (e.g. -having :option:`--hosts <-H>` somehow take precedence over ``env.hosts`` in the -same way that command-line per-task lists trump in-code ones) but only in a -backwards-incompatible release. - -.. _combining-host-lists: - -Combining host lists --------------------- - -There is no "unionizing" of hosts between the various sources mentioned in -:ref:`host-lists`. If ``env.hosts`` is set to ``['host1', 'host2', 'host3']``, -and a per-function (e.g. via `~fabric.decorators.hosts`) host list is set to -just ``['host2', 'host3']``, that function will **not** execute on ``host1``, -because the per-task decorator host list takes precedence. - -However, for each given source, if both roles **and** hosts are specified, they -will be merged together into a single host list. Take, for example, this -fabfile where both of the decorators are used:: - - from fabric.api import env, hosts, roles, run - - env.roledefs = {'role1': ['b', 'c']} - - @hosts('a', 'b') - @roles('role1') - def mytask(): - run('ls /var/www') - -Assuming no command-line hosts or roles are given when ``mytask`` is executed, -this fabfile will call ``mytask`` on a host list of ``['a', 'b', 'c']`` -- the -union of ``role1`` and the contents of the `~fabric.decorators.hosts` call. - - -.. _deduplication: - -Host list deduplication ------------------------ - -By default, to support :ref:`combining-host-lists`, Fabric deduplicates the -final host list so any given host string is only present once. However, this -prevents explicit/intentional running of a task multiple times on the same -target host, which is sometimes useful. - -To turn off deduplication, set :ref:`env.dedupe_hosts ` to -``False``. - - -.. _excluding-hosts: - -Excluding specific hosts ------------------------- - -At times, it is useful to exclude one or more specific hosts, e.g. to override -a few bad or otherwise undesirable hosts which are pulled in from a role or an -autogenerated host list. - -.. note:: - As of Fabric 1.4, you may wish to use :ref:`skip-bad-hosts` instead, which - automatically skips over any unreachable hosts. - -Host exclusion may be accomplished globally with :option:`--exclude-hosts/-x -<-x>`:: - - $ fab -R myrole -x host2,host5 mytask - -If ``myrole`` was defined as ``['host1', 'host2', ..., 'host15']``, the above -invocation would run with an effective host list of ``['host1', 'host3', -'host4', 'host6', ..., 'host15']``. - - .. note:: - Using this option does not modify ``env.hosts`` -- it only causes the - main execution loop to skip the requested hosts. - -Exclusions may be specified per-task by using an extra ``exclude_hosts`` kwarg, -which is implemented similarly to the abovementioned ``hosts`` and ``roles`` -per-task kwargs, in that it is stripped from the actual task invocation. This -example would have the same result as the global exclude above:: - - $ fab mytask:roles=myrole,exclude_hosts="host2;host5" - -Note that the host list is semicolon-separated, just as with the ``hosts`` -per-task argument. - -Combining exclusions -~~~~~~~~~~~~~~~~~~~~ - -Host exclusion lists, like host lists themselves, are not merged together -across the different "levels" they can be declared in. For example, a global -``-x`` option will not affect a per-task host list set with a decorator or -keyword argument, nor will per-task ``exclude_hosts`` keyword arguments affect -a global ``-H`` list. - -There is one minor exception to this rule, namely that CLI-level keyword -arguments (``mytask:exclude_hosts=x,y``) **will** be taken into account when -examining host lists set via ``@hosts`` or ``@roles``. Thus a task function -decorated with ``@hosts('host1', 'host2')`` executed as ``fab -taskname:exclude_hosts=host2`` will only run on ``host1``. - -As with the host list merging, this functionality is currently limited (partly -to keep the implementation simple) and may be expanded in future releases. - - -.. _execute: - -Intelligently executing tasks with ``execute`` -============================================== - -.. versionadded:: 1.3 - -Most of the information here involves "top level" tasks executed via :doc:`fab -`, such as the first example where we called ``fab taskA taskB``. -However, it's often convenient to wrap up multi-task invocations like this into -their own, "meta" tasks. - -Prior to Fabric 1.3, this had to be done by hand, as outlined in -:doc:`/usage/library`. Fabric's design eschews magical behavior, so simply -*calling* a task function does **not** take into account decorators such as -`~fabric.decorators.roles`. - -New in Fabric 1.3 is the `~fabric.tasks.execute` helper function, which takes a -task object or name as its first argument. Using it is effectively the same as -calling the given task from the command line: all the rules given above in -:ref:`host-lists` apply. (The ``hosts`` and ``roles`` keyword arguments to -`~fabric.tasks.execute` are analogous to :ref:`CLI per-task arguments -`, including how they override all other host/role-setting -methods.) - -As an example, here's a fabfile defining two stand-alone tasks for deploying a -Web application:: - - from fabric.api import run, roles - - env.roledefs = { - 'db': ['db1', 'db2'], - 'web': ['web1', 'web2', 'web3'], - } - - @roles('db') - def migrate(): - # Database stuff here. - pass - - @roles('web') - def update(): - # Code updates here. - pass - -In Fabric <=1.2, the only way to ensure that ``migrate`` runs on the DB servers -and that ``update`` runs on the Web servers (short of manual -``env.host_string`` manipulation) was to call both as top level tasks:: - - $ fab migrate update - -Fabric >=1.3 can use `~fabric.tasks.execute` to set up a meta-task. Update the -``import`` line like so:: - - from fabric.api import run, roles, execute - -and append this to the bottom of the file:: - - def deploy(): - execute(migrate) - execute(update) - -That's all there is to it; the `~fabric.decorators.roles` decorators will be honored as expected, resulting in the following execution sequence: - -* `migrate` on `db1` -* `migrate` on `db2` -* `update` on `web1` -* `update` on `web2` -* `update` on `web3` - -.. warning:: - This technique works because tasks that themselves have no host list (this - includes the global host list settings) only run one time. If used inside a - "regular" task that is going to run on multiple hosts, calls to - `~fabric.tasks.execute` will also run multiple times, resulting in - multiplicative numbers of subtask calls -- be careful! - - If you would like your `execute` calls to only be called once, you - may use the `~fabric.decorators.runs_once` decorator. - -.. seealso:: `~fabric.tasks.execute`, `~fabric.decorators.runs_once` - - -.. _leveraging-execute-return-value: - -Leveraging ``execute`` to access multi-host results ---------------------------------------------------- - -In nontrivial Fabric runs, especially parallel ones, you may want to gather up -a bunch of per-host result values at the end - e.g. to present a summary table, -perform calculations, etc. - -It's not possible to do this in Fabric's default "naive" mode (one where you -rely on Fabric looping over host lists on your behalf), but with `.execute` -it's pretty easy. Simply switch from calling the actual work-bearing task, to -calling a "meta" task which takes control of execution with `.execute`:: - - from fabric.api import task, execute, run, runs_once - - @task - def workhorse(): - return run("get my infos") - - @task - @runs_once - def go(): - results = execute(workhorse) - print results - -In the above, ``workhorse`` can do any Fabric stuff at all -- it's literally -your old "naive" task -- except that it needs to return something useful. - -``go`` is your new entry point (to be invoked as ``fab go``, or whatnot) and -its job is to take the ``results`` dictionary from the `.execute` call and do -whatever you need with it. Check the API docs for details on the structure of -that return value. - - -.. _dynamic-hosts: - -Using ``execute`` with dynamically-set host lists -------------------------------------------------- - -A common intermediate-to-advanced use case for Fabric is to parameterize lookup -of one's target host list at runtime (when use of :ref:`execution-roles` does not -suffice). ``execute`` can make this extremely simple, like so:: - - from fabric.api import run, execute, task - - # For example, code talking to an HTTP API, or a database, or ... - from mylib import external_datastore - - # This is the actual algorithm involved. It does not care about host - # lists at all. - def do_work(): - run("something interesting on a host") - - # This is the user-facing task invoked on the command line. - @task - def deploy(lookup_param): - # This is the magic you don't get with @hosts or @roles. - # Even lazy-loading roles require you to declare available roles - # beforehand. Here, the sky is the limit. - host_list = external_datastore.query(lookup_param) - # Put this dynamically generated host list together with the work to be - # done. - execute(do_work, hosts=host_list) - -For example, if ``external_datastore`` was a simplistic "look up hosts by tag -in a database" service, and you wanted to run a task on all hosts tagged as -being related to your application stack, you might call the above like this:: - - $ fab deploy:app - -But wait! A data migration has gone awry on the DB servers. Let's fix up our -migration code in our source repo, and deploy just the DB boxes again:: - - $ fab deploy:db - -This use case looks similar to Fabric's roles, but has much more potential, and -is by no means limited to a single argument. Define the task however you wish, -query your external data store in whatever way you need -- it's just Python. - -The alternate approach -~~~~~~~~~~~~~~~~~~~~~~ - -Similar to the above, but using ``fab``'s ability to call multiple tasks in -succession instead of an explicit ``execute`` call, is to mutate -:ref:`env.hosts ` in a host-list lookup task and then call ``do_work`` -in the same session:: - - from fabric.api import run, task - - from mylib import external_datastore - - # Marked as a publicly visible task, but otherwise unchanged: still just - # "do the work, let somebody else worry about what hosts to run on". - @task - def do_work(): - run("something interesting on a host") - - @task - def set_hosts(lookup_param): - # Update env.hosts instead of calling execute() - env.hosts = external_datastore.query(lookup_param) - -Then invoke like so:: - - $ fab set_hosts:app do_work - -One benefit of this approach over the previous one is that you can replace -``do_work`` with any other "workhorse" task:: - - $ fab set_hosts:db snapshot - $ fab set_hosts:cassandra,cluster2 repair_ring - $ fab set_hosts:redis,environ=prod status - - -.. _failures: - -Failure handling -================ - -Once the task list has been constructed, Fabric will start executing them as -outlined in :ref:`execution-strategy`, until all tasks have been run on the -entirety of their host lists. However, Fabric defaults to a "fail-fast" -behavior pattern: if anything goes wrong, such as a remote program returning a -nonzero return value or your fabfile's Python code encountering an exception, -execution will halt immediately. - -This is typically the desired behavior, but there are many exceptions to the -rule, so Fabric provides ``env.warn_only``, a Boolean setting. It defaults to -``False``, meaning an error condition will result in the program aborting -immediately. However, if ``env.warn_only`` is set to ``True`` at the time of -failure -- with, say, the `~fabric.context_managers.settings` context -manager -- Fabric will emit a warning message but continue executing. - - -.. _connections: - -Connections -=========== - -``fab`` itself doesn't actually make any connections to remote hosts. Instead, -it simply ensures that for each distinct run of a task on one of its hosts, the -env var ``env.host_string`` is set to the right value. Users wanting to -leverage Fabric as a library may do so manually to achieve similar effects -(though as of Fabric 1.3, using `~fabric.tasks.execute` is preferred and more -powerful.) - -``env.host_string`` is (as the name implies) the "current" host string, and is -what Fabric uses to determine what connections to make (or re-use) when -network-aware functions are run. Operations like `~fabric.operations.run` or -`~fabric.operations.put` use ``env.host_string`` as a lookup key in a shared -dictionary which maps host strings to SSH connection objects. - -.. note:: - - The connections dictionary (currently located at - ``fabric.state.connections``) acts as a cache, opting to return previously - created connections if possible in order to save some overhead, and - creating new ones otherwise. - -Lazy connections ----------------- - -Because connections are driven by the individual operations, Fabric will not -actually make connections until they're necessary. Take for example this task -which does some local housekeeping prior to interacting with the remote -server:: - - from fabric.api import * - - @hosts('host1') - def clean_and_upload(): - local('find assets/ -name "*.DS_Store" -exec rm '{}' \;') - local('tar czf /tmp/assets.tgz assets/') - put('/tmp/assets.tgz', '/tmp/assets.tgz') - with cd('/var/www/myapp/'): - run('tar xzf /tmp/assets.tgz') - -What happens, connection-wise, is as follows: - -#. The two `~fabric.operations.local` calls will run without making any network - connections whatsoever; -#. `~fabric.operations.put` asks the connection cache for a connection to - ``host1``; -#. The connection cache fails to find an existing connection for that host - string, and so creates a new SSH connection, returning it to - `~fabric.operations.put`; -#. `~fabric.operations.put` uploads the file through that connection; -#. Finally, the `~fabric.operations.run` call asks the cache for a connection - to that same host string, and is given the existing, cached connection for - its own use. - -Extrapolating from this, you can also see that tasks which don't use any -network-borne operations will never actually initiate any connections (though -they will still be run once for each host in their host list, if any.) - -Closing connections -------------------- - -Fabric's connection cache never closes connections itself -- it leaves this up -to whatever is using it. The :doc:`fab ` tool does this bookkeeping for -you: it iterates over all open connections and closes them just before it exits -(regardless of whether the tasks failed or not.) - -Library users will need to ensure they explicitly close all open connections -before their program exits. This can be accomplished by calling -`~fabric.network.disconnect_all` at the end of your script. - -.. note:: - `~fabric.network.disconnect_all` may be moved to a more public location in - the future; we're still working on making the library aspects of Fabric - more solidified and organized. - -Multiple connection attempts and skipping bad hosts ---------------------------------------------------- - -As of Fabric 1.4, multiple attempts may be made to connect to remote servers -before aborting with an error: Fabric will try connecting -:ref:`env.connection_attempts ` times before giving up, -with a timeout of :ref:`env.timeout ` seconds each time. (These -currently default to 1 try and 10 seconds, to match previous behavior, but they -may be safely changed to whatever you need.) - -Furthermore, even total failure to connect to a server is no longer an absolute -hard stop: set :ref:`env.skip_bad_hosts ` to ``True`` and in -most situations (typically initial connections) Fabric will simply warn and -continue, instead of aborting. - -.. versionadded:: 1.4 - -.. _password-management: - -Password management -=================== - -Fabric maintains an in-memory, two-tier password cache to help remember your -login and sudo passwords in certain situations; this helps avoid tedious -re-entry when multiple systems share the same password [#]_, or if a remote -system's ``sudo`` configuration doesn't do its own caching. - -The first layer is a simple default or fallback password cache, -:ref:`env.password ` (which may also be set at the command line via -:option:`--password <-p>` or :option:`--initial-password-prompt <-I>`). This -env var stores a single password which (if non-empty) will be tried in the -event that the host-specific cache (see below) has no entry for the current -:ref:`host string `. - -:ref:`env.passwords ` (plural!) serves as a per-user/per-host cache, -storing the most recently entered password for every unique user/host/port -combination. Due to this cache, connections to multiple different users and/or -hosts in the same session will only require a single password entry for each. -(Previous versions of Fabric used only the single, default password cache and -thus required password re-entry every time the previously entered password -became invalid.) - -Depending on your configuration and the number of hosts your session will -connect to, you may find setting either or both of these env vars to be useful. -However, Fabric will automatically fill them in as necessary without any -additional configuration. - -Specifically, each time a password prompt is presented to the user, the value -entered is used to update both the single default password cache, and the cache -value for the current value of ``env.host_string``. - -.. [#] We highly recommend the use of SSH `key-based access - `_ instead of relying on - homogeneous password setups, as it's significantly more secure. - - -.. _ssh-config: - -Leveraging native SSH config files -================================== - -Command-line SSH clients (such as the one provided by `OpenSSH -`_) make use of a specific configuration format typically -known as ``ssh_config``, and will read from a file in the platform-specific -location ``$HOME/.ssh/config`` (or an arbitrary path given to -:option:`--ssh-config-path`/:ref:`env.ssh_config_path `.) This -file allows specification of various SSH options such as default or per-host -usernames, hostname aliases, and toggling other settings (such as whether to -use :ref:`agent forwarding `.) - -Fabric's SSH implementation allows loading a subset of these options from one's -actual SSH config file, should it exist. This behavior is not enabled by -default (in order to be backwards compatible) but may be turned on by setting -:ref:`env.use_ssh_config ` to ``True`` at the top of your -fabfile. - -If enabled, the following SSH config directives will be loaded and honored by Fabric: - -* ``User`` and ``Port`` will be used to fill in the appropriate connection - parameters when not otherwise specified, in the following fashion: - - * Globally specified ``User``/``Port`` will be used in place of the current - defaults (local username and 22, respectively) if the appropriate env vars - are not set. - * However, if :ref:`env.user `/:ref:`env.port ` *are* set, they - override global ``User``/``Port`` values. - * User/port values in the host string itself (e.g. ``hostname:222``) will - override everything, including any ``ssh_config`` values. -* ``HostName`` can be used to replace the given hostname, just like with - regular ``ssh``. So a ``Host foo`` entry specifying ``HostName example.com`` - will allow you to give Fabric the hostname ``'foo'`` and have that expanded - into ``'example.com'`` at connection time. -* ``IdentityFile`` will extend (not replace) :ref:`env.key_filename - `. -* ``ForwardAgent`` will augment :ref:`env.forward_agent ` in an - "OR" manner: if either is set to a positive value, agent forwarding will be - enabled. -* ``ProxyCommand`` will trigger use of a proxy command for host connections, - just as with regular ``ssh``. - - .. note:: - If all you want to do is bounce SSH traffic off a gateway, you may find - :ref:`env.gateway ` to be a more efficient connection method - (which will also honor more Fabric-level settings) than the typical ``ssh - gatewayhost nc %h %p`` method of using ``ProxyCommand`` as a gateway. - - .. note:: - If your SSH config file contains ``ProxyCommand`` directives *and* you have - set :ref:`env.gateway ` to a non-``None`` value, ``env.gateway`` - will take precedence and the ``ProxyCommand`` will be ignored. - - If one has a pre-created SSH config file, rationale states it will be - easier for you to modify ``env.gateway`` (e.g. via - `~fabric.context_managers.settings`) than to work around your conf file's - contents entirely. diff -Nru fabric-1.8.2/docs/usage/fabfiles.rst fabric-1.10.0/docs/usage/fabfiles.rst --- fabric-1.8.2/docs/usage/fabfiles.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/usage/fabfiles.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -============================ -Fabfile construction and use -============================ - -This document contains miscellaneous sections about fabfiles, both how to best -write them, and how to use them once written. - -.. _fabfile-discovery: - -Fabfile discovery -================= - -Fabric is capable of loading Python modules (e.g. ``fabfile.py``) or packages -(e.g. a ``fabfile/`` directory containing an ``__init__.py``). By default, it -looks for something named (to Python's import machinery) ``fabfile`` - so -either ``fabfile/`` or ``fabfile.py``. - -The fabfile discovery algorithm searches in the invoking user's current working -directory or any parent directories. Thus, it is oriented around "project" use, -where one keeps e.g. a ``fabfile.py`` at the root of a source code tree. Such a -fabfile will then be discovered no matter where in the tree the user invokes -``fab``. - -The specific name to be searched for may be overridden on the command-line with -the :option:`-f` option, or by adding a :ref:`fabricrc ` line which -sets the value of ``fabfile``. For example, if you wanted to name your fabfile -``fab_tasks.py``, you could create such a file and then call ``fab -f -fab_tasks.py ``, or add ``fabfile = fab_tasks.py`` to -``~/.fabricrc``. - -If the given fabfile name contains path elements other than a filename (e.g. -``../fabfile.py`` or ``/dir1/dir2/custom_fabfile``) it will be treated as a -file path and directly checked for existence without any sort of searching. -When in this mode, tilde-expansion will be applied, so one may refer to e.g. -``~/personal_fabfile.py``. - -.. note:: - - Fabric does a normal ``import`` (actually an ``__import__``) of your - fabfile in order to access its contents -- it does not do any ``eval``-ing - or similar. In order for this to work, Fabric temporarily adds the found - fabfile's containing folder to the Python load path (and removes it - immediately afterwards.) - -.. versionchanged:: 0.9.2 - The ability to load package fabfiles. - - -.. _importing-the-api: - -Importing Fabric -================ - -Because Fabric is just Python, you *can* import its components any way you -want. However, for the purposes of encapsulation and convenience (and to make -life easier for Fabric's packaging script) Fabric's public API is maintained in -the ``fabric.api`` module. - -All of Fabric's :doc:`../api/core/operations`, -:doc:`../api/core/context_managers`, :doc:`../api/core/decorators` and -:doc:`../api/core/utils` are included in this module as a single, flat -namespace. This enables a very simple and consistent interface to Fabric within -your fabfiles:: - - from fabric.api import * - - # call run(), sudo(), etc etc - -This is not technically best practices (for `a -number of reasons`_) and if you're only using a couple of -Fab API calls, it *is* probably a good idea to explicitly ``from fabric.api -import env, run`` or similar. However, in most nontrivial fabfiles, you'll be -using all or most of the API, and the star import:: - - from fabric.api import * - -will be a lot easier to write and read than:: - - from fabric.api import abort, cd, env, get, hide, hosts, local, prompt, \ - put, require, roles, run, runs_once, settings, show, sudo, warn - -so in this case we feel pragmatism overrides best practices. - -.. _a number of reasons: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#importing - - -Defining tasks and importing callables -====================================== - -For important information on what exactly Fabric will consider as a task when -it loads your fabfile, as well as notes on how best to import other code, -please see :doc:`/usage/tasks` in the :doc:`execution` documentation. diff -Nru fabric-1.8.2/docs/usage/fab.rst fabric-1.10.0/docs/usage/fab.rst --- fabric-1.8.2/docs/usage/fab.rst 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/docs/usage/fab.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,482 +0,0 @@ -============================= -``fab`` options and arguments -============================= - -The most common method for utilizing Fabric is via its command-line tool, -``fab``, which should have been placed on your shell's executable path when -Fabric was installed. ``fab`` tries hard to be a good Unix citizen, using a -standard style of command-line switches, help output, and so forth. - - -Basic use -========= - -In its most simple form, ``fab`` may be called with no options at all, and -with one or more arguments, which should be task names, e.g.:: - - $ fab task1 task2 - -As detailed in :doc:`../tutorial` and :doc:`execution`, this will run ``task1`` -followed by ``task2``, assuming that Fabric was able to find a fabfile nearby -containing Python functions with those names. - -However, it's possible to expand this simple usage into something more -flexible, by using the provided options and/or passing arguments to individual -tasks. - - -.. _arbitrary-commands: - -Arbitrary remote shell commands -=============================== - -.. versionadded:: 0.9.2 - -Fabric leverages a lesser-known command line convention and may be called in -the following manner:: - - $ fab [options] -- [shell command] - -where everything after the ``--`` is turned into a temporary -`~fabric.operations.run` call, and is not parsed for ``fab`` options. If you've -defined a host list at the module level or on the command line, this usage will -act like a one-line anonymous task. - -For example, let's say you just wanted to get the kernel info for a bunch of -systems; you could do this:: - - $ fab -H system1,system2,system3 -- uname -a - -which would be literally equivalent to the following fabfile:: - - from fabric.api import run - - def anonymous(): - run("uname -a") - -as if it were executed thusly:: - - $ fab -H system1,system2,system3 anonymous - -Most of the time you will want to just write out the task in your fabfile -(anything you use once, you're likely to use again) but this feature provides a -handy, fast way to quickly dash off an SSH-borne command while leveraging your -fabfile's connection settings. - - -.. _command-line-options: - -Command-line options -==================== - -A quick overview of all possible command line options can be found via ``fab ---help``. If you're looking for details on a specific option, we go into detail -below. - -.. note:: - - ``fab`` uses Python's `optparse`_ library, meaning that it honors typical - Linux or GNU style short and long options, as well as freely mixing options - and arguments. E.g. ``fab task1 -H hostname task2 -i path/to/keyfile`` is - just as valid as the more straightforward ``fab -H hostname -i - path/to/keyfile task1 task2``. - -.. _optparse: http://docs.python.org/library/optparse.html - -.. cmdoption:: -a, --no_agent - - Sets :ref:`env.no_agent ` to ``True``, forcing our SSH layer not - to talk to the SSH agent when trying to unlock private key files. - - .. versionadded:: 0.9.1 - -.. cmdoption:: -A, --forward-agent - - Sets :ref:`env.forward_agent ` to ``True``, enabling agent - forwarding. - - .. versionadded:: 1.4 - -.. cmdoption:: --abort-on-prompts - - Sets :ref:`env.abort_on_prompts ` to ``True``, forcing - Fabric to abort whenever it would prompt for input. - - .. versionadded:: 1.1 - -.. cmdoption:: -c RCFILE, --config=RCFILE - - Sets :ref:`env.rcfile ` to the given file path, which Fabric will - try to load on startup and use to update environment variables. - -.. cmdoption:: -d COMMAND, --display=COMMAND - - Prints the entire docstring for the given task, if there is one. Does not - currently print out the task's function signature, so descriptive - docstrings are a good idea. (They're *always* a good idea, of course -- - just moreso here.) - -.. cmdoption:: --connection-attempts=M, -n M - - Set number of times to attempt connections. Sets - :ref:`env.connection_attempts `. - - .. seealso:: - :ref:`env.connection_attempts `, - :ref:`env.timeout ` - .. versionadded:: 1.4 - -.. cmdoption:: -D, --disable-known-hosts - - Sets :ref:`env.disable_known_hosts ` to ``True``, - preventing Fabric from loading the user's SSH :file:`known_hosts` file. - -.. cmdoption:: -f FABFILE, --fabfile=FABFILE - - The fabfile name pattern to search for (defaults to ``fabfile.py``), or - alternately an explicit file path to load as the fabfile (e.g. - ``/path/to/my/fabfile.py``.) - - .. seealso:: :doc:`fabfiles` - -.. cmdoption:: -F LIST_FORMAT, --list-format=LIST_FORMAT - - Allows control over the output format of :option:`--list <-l>`. ``short`` is - equivalent to :option:`--shortlist`, ``normal`` is the same as simply - omitting this option entirely (i.e. the default), and ``nested`` prints out - a nested namespace tree. - - .. versionadded:: 1.1 - .. seealso:: :option:`--shortlist`, :option:`--list <-l>` - -.. cmdoption:: -g HOST, --gateway=HOST - - Sets :ref:`env.gateway ` to ``HOST`` host string. - - .. versionadded:: 1.5 - -.. cmdoption:: -h, --help - - Displays a standard help message, with all possible options and a brief - overview of what they do, then exits. - -.. cmdoption:: --hide=LEVELS - - A comma-separated list of :doc:`output levels ` to hide by - default. - - -.. cmdoption:: -H HOSTS, --hosts=HOSTS - - Sets :ref:`env.hosts ` to the given comma-delimited list of host - strings. - -.. cmdoption:: -x HOSTS, --exclude-hosts=HOSTS - - Sets :ref:`env.exclude_hosts ` to the given comma-delimited - list of host strings to then keep out of the final host list. - - .. versionadded:: 1.1 - -.. cmdoption:: -i KEY_FILENAME - - When set to a file path, will load the given file as an SSH identity file - (usually a private key.) This option may be repeated multiple times. Sets - (or appends to) :ref:`env.key_filename `. - -.. cmdoption:: -I, --initial-password-prompt - - Forces a password prompt at the start of the session (after fabfile load - and option parsing, but before executing any tasks) in order to pre-fill - :ref:`env.password `. - - This is useful for fire-and-forget runs (especially parallel sessions, in - which runtime input is not possible) when setting the password via - :option:`--password <-p>` or by setting :ref:`env.password ` in - your fabfile, is undesirable. - - .. note:: The value entered into this prompt will *overwrite* anything - supplied via :ref:`env.password ` at module level, or via - :option:`--password <-p>`. - - .. seealso:: :ref:`password-management` - -.. cmdoption:: -k - - Sets :ref:`env.no_keys ` to ``True``, forcing the SSH layer to not - look for SSH private key files in one's home directory. - - .. versionadded:: 0.9.1 - -.. cmdoption:: --keepalive=KEEPALIVE - - Sets :ref:`env.keepalive ` to the given (integer) value, specifying an SSH keepalive interval. - - .. versionadded:: 1.1 - -.. cmdoption:: --linewise - - Forces output to be buffered line-by-line instead of byte-by-byte. Often useful or required for :ref:`parallel execution `. - - .. versionadded:: 1.3 - -.. cmdoption:: -l, --list - - Imports a fabfile as normal, but then prints a list of all discovered tasks - and exits. Will also print the first line of each task's docstring, if it - has one, next to it (truncating if necessary.) - - .. versionchanged:: 0.9.1 - Added docstring to output. - .. seealso:: :option:`--shortlist`, :option:`--list-format <-F>` - -.. cmdoption:: -p PASSWORD, --password=PASSWORD - - Sets :ref:`env.password ` to the given string; it will then be - used as the default password when making SSH connections or calling the - ``sudo`` program. - - .. seealso:: :option:`--initial-password-prompt <-I>` - -.. cmdoption:: -P, --parallel - - Sets :ref:`env.parallel ` to ``True``, causing - tasks to run in parallel. - - .. versionadded:: 1.3 - .. seealso:: :doc:`/usage/parallel` - -.. cmdoption:: --no-pty - - Sets :ref:`env.always_use_pty ` to ``False``, causing all - `~fabric.operations.run`/`~fabric.operations.sudo` calls to behave as if - one had specified ``pty=False``. - - .. versionadded:: 1.0 - -.. cmdoption:: -r, --reject-unknown-hosts - - Sets :ref:`env.reject_unknown_hosts ` to ``True``, - causing Fabric to abort when connecting to hosts not found in the user's SSH - :file:`known_hosts` file. - -.. cmdoption:: -R ROLES, --roles=ROLES - - Sets :ref:`env.roles ` to the given comma-separated list of role - names. - -.. cmdoption:: --set KEY=VALUE,... - - Allows you to set default values for arbitrary Fabric env vars. Values set - this way have a low precedence -- they will not override more specific env - vars which are also specified on the command line. E.g.:: - - fab --set password=foo --password=bar - - will result in ``env.password = 'bar'``, not ``'foo'`` - - Multiple ``KEY=VALUE`` pairs may be comma-separated, e.g. ``fab --set - var1=val1,var2=val2``. - - Other than basic string values, you may also set env vars to True by - omitting the ``=VALUE`` (e.g. ``fab --set KEY``), and you may set values to - the empty string (and thus a False-equivalent value) by keeping the equals - sign, but omitting ``VALUE`` (e.g. ``fab --set KEY=``.) - - .. versionadded:: 1.4 - -.. cmdoption:: -s SHELL, --shell=SHELL - - Sets :ref:`env.shell ` to the given string, overriding the default - shell wrapper used to execute remote commands. - -.. cmdoption:: --shortlist - - Similar to :option:`--list <-l>`, but without any embellishment, just task - names separated by newlines with no indentation or docstrings. - - .. versionadded:: 0.9.2 - .. seealso:: :option:`--list <-l>` - -.. cmdoption:: --show=LEVELS - - A comma-separated list of :doc:`output levels ` to - be added to those that are shown by - default. - - .. seealso:: `~fabric.operations.run`, `~fabric.operations.sudo` - -.. cmdoption:: --ssh-config-path - - Sets :ref:`env.ssh_config_path `. - - .. versionadded:: 1.4 - .. seealso:: :ref:`ssh-config` - -.. cmdoption:: --skip-bad-hosts - - Sets :ref:`env.skip_bad_hosts `, causing Fabric to skip - unavailable hosts. - - .. versionadded:: 1.4 - -.. cmdoption:: --timeout=N, -t N - - Set connection timeout in seconds. Sets :ref:`env.timeout `. - - .. seealso:: - :ref:`env.timeout `, - :ref:`env.connection_attempts ` - .. versionadded:: 1.4 - -.. cmdoption:: --command-timeout=N, -T N - - Set remote command timeout in seconds. Sets - :ref:`env.command_timeout `. - - .. seealso:: - :ref:`env.command_timeout `, - - .. versionadded:: 1.6 - -.. cmdoption:: -u USER, --user=USER - - Sets :ref:`env.user ` to the given string; it will then be used as the - default username when making SSH connections. - -.. cmdoption:: -V, --version - - Displays Fabric's version number, then exits. - -.. cmdoption:: -w, --warn-only - - Sets :ref:`env.warn_only ` to ``True``, causing Fabric to - continue execution even when commands encounter error conditions. - -.. cmdoption:: -z, --pool-size - - Sets :ref:`env.pool_size `, which specifies how many processes - to run concurrently during parallel execution. - - .. versionadded:: 1.3 - .. seealso:: :doc:`/usage/parallel` - - -.. _task-arguments: - -Per-task arguments -================== - -The options given in :ref:`command-line-options` apply to the invocation of -``fab`` as a whole; even if the order is mixed around, options still apply to -all given tasks equally. Additionally, since tasks are just Python functions, -it's often desirable to pass in arguments to them at runtime. - -Answering both these needs is the concept of "per-task arguments", which is a -special syntax you can tack onto the end of any task name: - -* Use a colon (``:``) to separate the task name from its arguments; -* Use commas (``,``) to separate arguments from one another (may be escaped - by using a backslash, i.e. ``\,``); -* Use equals signs (``=``) for keyword arguments, or omit them for positional - arguments. May also be escaped with backslashes. - -Additionally, since this process involves string parsing, all values will end -up as Python strings, so plan accordingly. (We hope to improve upon this in -future versions of Fabric, provided an intuitive syntax can be found.) - -For example, a "create a new user" task might be defined like so (omitting most -of the actual logic for brevity):: - - def new_user(username, admin='no', comment="No comment provided"): - log_action("New User (%s): %s" % (username, comment)) - pass - -You can specify just the username:: - - $ fab new_user:myusername - -Or treat it as an explicit keyword argument:: - - $ fab new_user:username=myusername - -If both args are given, you can again give them as positional args:: - - $ fab new_user:myusername,yes - -Or mix and match, just like in Python:: - - $ fab new_user:myusername,admin=yes - -The ``log_action`` call above is useful for illustrating escaped commas, like -so:: - - $ fab new_user:myusername,admin=no,comment='Gary\, new developer (starts Monday)' - -.. note:: - Quoting the backslash-escaped comma is required, as not doing so will cause - shell syntax errors. Quotes are also needed whenever an argument involves - other shell-related characters such as spaces. - -All of the above are translated into the expected Python function calls. For -example, the last call above would become:: - - >>> new_user('myusername', admin='yes', comment='Gary, new developer (starts Monday)') - -Roles and hosts ---------------- - -As mentioned in :ref:`the section on task execution `, -there are a handful of per-task keyword arguments (``host``, ``hosts``, -``role`` and ``roles``) which do not actually map to the task functions -themselves, but are used for setting per-task host and/or role lists. - -These special kwargs are **removed** from the args/kwargs sent to the task -function itself; this is so that you don't run into TypeErrors if your task -doesn't define the kwargs in question. (It also means that if you **do** define -arguments with these names, you won't be able to specify them in this manner -- -a regrettable but necessary sacrifice.) - -.. note:: - - If both the plural and singular forms of these kwargs are given, the value - of the plural will win out and the singular will be discarded. - -When using the plural form of these arguments, one must use semicolons (``;``) -since commas are already being used to separate arguments from one another. -Furthermore, since your shell is likely to consider semicolons a special -character, you'll want to quote the host list string to prevent shell -interpretation, e.g.:: - - $ fab new_user:myusername,hosts="host1;host2" - -Again, since the ``hosts`` kwarg is removed from the argument list sent to the -``new_user`` task function, the actual Python invocation would be -``new_user('myusername')``, and the function would be executed on a host list -of ``['host1', 'host2']``. - -.. _fabricrc: - -Settings files -============== - -Fabric currently honors a simple user settings file, or ``fabricrc`` (think -``bashrc`` but for ``fab``) which should contain one or more key-value pairs, -one per line. These lines will be subject to ``string.split('=')``, and thus -can currently only be used to specify string settings. Any such key-value pairs -will be used to update :doc:`env ` when ``fab`` runs, and is loaded prior -to the loading of any fabfile. - -By default, Fabric looks for ``~/.fabricrc``, and this may be overridden by -specifying the :option:`-c` flag to ``fab``. - -For example, if your typical SSH login username differs from your workstation -username, and you don't want to modify ``env.user`` in a project's fabfile -(possibly because you expect others to use it as well) you could write a -``fabricrc`` file like so:: - - user = ssh_user_name - -Then, when running ``fab``, your fabfile would load up with ``env.user`` set to -``'ssh_user_name'``. Other users of that fabfile could do the same, allowing -the fabfile itself to be cleanly agnostic regarding the default username. diff -Nru fabric-1.8.2/docs/usage/interactivity.rst fabric-1.10.0/docs/usage/interactivity.rst --- fabric-1.8.2/docs/usage/interactivity.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/interactivity.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -================================ -Interaction with remote programs -================================ - -Fabric's primary operations, `~fabric.operations.run` and -`~fabric.operations.sudo`, are capable of sending local input to the remote -end, in a manner nearly identical to the ``ssh`` program. For example, programs -which display password prompts (e.g. a database dump utility, or changing a -user's password) will behave just as if you were interacting with them -directly. - -However, as with ``ssh`` itself, Fabric's implementation of this feature is -subject to a handful of limitations which are not always intuitive. This -document discusses such issues in detail. - -.. note:: - Readers unfamiliar with the basics of Unix stdout and stderr pipes, and/or - terminal devices, may wish to visit the Wikipedia pages for `Unix pipelines - `_ and `Pseudo terminals - `_ respectively. - - -.. _combine_streams: - -Combining stdout and stderr -=========================== - -The first issue to be aware of is that of the stdout and stderr streams, and -why they are separated or combined as needed. - -Buffering ---------- - -Fabric 0.9.x and earlier, and Python itself, buffer output on a line-by-line -basis: text is not printed to the user until a newline character is found. -This works fine in most situations but becomes problematic when one needs to -deal with partial-line output such as prompts. - -.. note:: - Line-buffered output can make programs appear to halt or freeze for no - reason, as prompts print out text without a newline, waiting for the user - to enter their input and press Return. - -Newer Fabric versions buffer both input and output on a character-by-character -basis in order to make interaction with prompts possible. This has the -convenient side effect of enabling interaction with complex programs utilizing -the "curses" libraries or which otherwise redraw the screen (think ``top``). - -Crossing the streams --------------------- - -Unfortunately, printing to stderr and stdout simultaneously (as many programs -do) means that when the two streams are printed independently one byte at a -time, they can become garbled or meshed together. While this can sometimes be -mitigated by line-buffering one of the streams and not the other, it's still a -serious issue. - -To solve this problem, Fabric uses a setting in our SSH layer which merges the -two streams at a low level and causes output to appear more naturally. This -setting is represented in Fabric as the :ref:`combine-stderr` env var and -keyword argument, and is ``True`` by default. - -Due to this default setting, output will appear correctly, but at the -cost of an empty ``.stderr`` attribute on the return values of -`~fabric.operations.run`/`~fabric.operations.sudo`, as all output will appear -to be stdout. - -Conversely, users requiring a distinct stderr stream at the Python level and -who aren't bothered by garbled user-facing output (or who are hiding stdout and -stderr from the command in question) may opt to set this to ``False`` as -needed. - - -.. _pseudottys: - -Pseudo-terminals -================ - -The other main issue to consider when presenting interactive prompts to users -is that of echoing the user's own input. - -Echoes ------- - -Typical terminal applications or bona fide text terminals (e.g. when using a -Unix system without a running GUI) present programs with a terminal device -called a tty or pty (for pseudo-terminal). These automatically echo all text -typed into them back out to the user (via stdout), as interaction without -seeing what you had just typed would be difficult. Terminal devices are also -able to conditionally turn off echoing, allowing secure password prompts. - -However, it's possible for programs to be run without a tty or pty present at -all (consider cron jobs, for example) and in this situation, any stdin data -being fed to the program won't be echoed. This is desirable for programs being -run without any humans around, and it's also Fabric's old default mode of -operation. - -Fabric's approach ------------------ - -Unfortunately, in the context of executing commands via Fabric, when no pty is -present to echo a user's stdin, Fabric must echo it for them. This is -sufficient for many applications, but it presents problems for password -prompts, which become insecure. - -In the interests of security and meeting the principle of least surprise -(insofar as users are typically expecting things to behave as they would when -run in a terminal emulator), Fabric 1.0 and greater force a pty by default. -With a pty enabled, Fabric simply allows the remote end to handle echoing or -hiding of stdin and does not echo anything itself. - -.. note:: - In addition to allowing normal echo behavior, a pty also means programs - that behave differently when attached to a terminal device will then do so. - For example, programs that colorize output on terminals but not when run in - the background will print colored output. Be wary of this if you inspect - the return value of `~fabric.operations.run` or `~fabric.operations.sudo`! - -For situations requiring the pty behavior turned off, the :option:`--no-pty` -command-line argument and :ref:`always-use-pty` env var may be used. - - -Combining the two -================= - -As a final note, keep in mind that use of pseudo-terminals effectively implies -combining stdout and stderr -- in much the same way as the :ref:`combine_stderr -` setting does. This is because a terminal device naturally -sends both stdout and stderr to the same place -- the user's display -- thus -making it impossible to differentiate between them. - -However, at the Fabric level, the two groups of settings are distinct from one -another and may be combined in various ways. The default is for both to be set -to ``True``; the other combinations are as follows: - -* ``run("cmd", pty=False, combine_stderr=True)``: will cause Fabric to echo all - stdin itself, including passwords, as well as potentially altering ``cmd``'s - behavior. Useful if ``cmd`` behaves undesirably when run under a pty and - you're not concerned about password prompts. -* ``run("cmd", pty=False, combine_stderr=False)``: with both settings - ``False``, Fabric will echo stdin and won't issue a pty -- and this is highly - likely to result in undesired behavior for all but the simplest commands. - However, it is also the only way to access a distinct stderr stream, which is - occasionally useful. -* ``run("cmd", pty=True, combine_stderr=False)``: valid, but won't really make - much of a difference, as ``pty=True`` will still result in merged streams. - May be useful for avoiding any edge case problems in ``combine_stderr`` (none - are presently known). diff -Nru fabric-1.8.2/docs/usage/library.rst fabric-1.10.0/docs/usage/library.rst --- fabric-1.8.2/docs/usage/library.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/library.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -=========== -Library Use -=========== - -Fabric's primary use case is via fabfiles and the :doc:`fab ` tool, -and this is reflected in much of the documentation. However, Fabric's internals -are written in such a manner as to be easily used without ``fab`` or fabfiles -at all -- this document will show you how. - -There's really only a couple of considerations one must keep in mind, when -compared to writing a fabfile and using ``fab`` to run it: how connections are -really made, and how disconnections occur. - -Connections -=========== - -We've documented how Fabric really connects to its hosts before, but it's -currently somewhat buried in the middle of the overall :doc:`execution docs -`. Specifically, you'll want to skip over to the -:ref:`connections` section and read it real quick. (You should really give that -entire document a once-over, but it's not absolutely required.) - -As that section mentions, the key is simply that `~fabric.operations.run`, -`~fabric.operations.sudo` and the other operations only look in one place when -connecting: :ref:`env.host_string `. All of the other mechanisms -for setting hosts are interpreted by the ``fab`` tool when it runs, and don't -matter when running as a library. - -That said, most use cases where you want to marry a given task ``X`` and a given list of hosts ``Y`` can, as of Fabric 1.3, be handled with the `~fabric.tasks.execute` function via ``execute(X, hosts=Y)``. Please see `~fabric.tasks.execute`'s documentation for details -- manual host string manipulation should be rarely necessary. - -Disconnecting -============= - -The other main thing that ``fab`` does for you is to disconnect from all hosts -at the end of a session; otherwise, Python will sit around forever waiting for -those network resources to be released. - -Fabric 0.9.4 and newer have a function you can use to do this easily: -`~fabric.network.disconnect_all`. Simply make sure your code calls this when it -terminates (typically in the ``finally`` clause of an outer ``try: finally`` -statement -- lest errors in your code prevent disconnections from happening!) -and things ought to work pretty well. - -If you're on Fabric 0.9.3 or older, you can simply do this (``disconnect_all`` -just adds a bit of nice output to this logic):: - - from fabric.state import connections - - for key in connections.keys(): - connections[key].close() - del connections[key] - - -Final note -========== - -This document is an early draft, and may not cover absolutely every difference -between ``fab`` use and library use. However, the above should highlight the -largest stumbling blocks. When in doubt, note that in the Fabric source code, -``fabric/main.py`` contains the bulk of the extra work done by ``fab``, and may -serve as a useful reference. diff -Nru fabric-1.8.2/docs/usage/output_controls.rst fabric-1.10.0/docs/usage/output_controls.rst --- fabric-1.8.2/docs/usage/output_controls.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/output_controls.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -=============== -Managing output -=============== - -The ``fab`` tool is very verbose by default and prints out almost everything it -can, including the remote end's stderr and stdout streams, the command strings -being executed, and so forth. While this is necessary in many cases in order to -know just what's going on, any nontrivial Fabric task will quickly become -difficult to follow as it runs. - - -Output levels -============= - -To aid in organizing task output, Fabric output is grouped into a number of -non-overlapping levels or groups, each of which may be turned on or off -independently. This provides flexible control over what is displayed to the -user. - -.. note:: - - All levels, save for ``debug``, are on by default. - -Standard output levels ----------------------- - -The standard, atomic output levels/groups are as follows: - -* **status**: Status messages, i.e. noting when Fabric is done running, if - the user used a keyboard interrupt, or when servers are disconnected from. - These messages are almost always relevant and rarely verbose. - -* **aborts**: Abort messages. Like status messages, these should really only be - turned off when using Fabric as a library, and possibly not even then. Note - that even if this output group is turned off, aborts will still occur -- - there just won't be any output about why Fabric aborted! - -* **warnings**: Warning messages. These are often turned off when one expects a - given operation to fail, such as when using ``grep`` to test existence of - text in a file. If paired with setting ``env.warn_only`` to True, this - can result in fully silent warnings when remote programs fail. As with - ``aborts``, this setting does not control actual warning behavior, only - whether warning messages are printed or hidden. - -* **running**: Printouts of commands being executed or files transferred, e.g. - ``[myserver] run: ls /var/www``. Also controls printing of tasks being run, - e.g. ``[myserver] Executing task 'foo'``. - -* **stdout**: Local, or remote, stdout, i.e. non-error output from commands. - -* **stderr**: Local, or remote, stderr, i.e. error-related output from commands. - -* **user**: User-generated output, i.e. local output printed by fabfile code - via use of the `~fabric.utils.fastprint` or `~fabric.utils.puts` functions. - -.. versionchanged:: 0.9.2 - Added "Executing task" lines to the ``running`` output level. - -.. versionchanged:: 0.9.2 - Added the ``user`` output level. - -Debug output ------------- - -There is a final atomic output level, ``debug``, which behaves slightly -differently from the rest: - -* **debug**: Turn on debugging (which is off by default.) Currently, this is - largely used to view the "full" commands being run; take for example this - `~fabric.operations.run` call:: - - run('ls "/home/username/Folder Name With Spaces/"') - - Normally, the ``running`` line will show exactly what is passed into - `~fabric.operations.run`, like so:: - - [hostname] run: ls "/home/username/Folder Name With Spaces/" - - With ``debug`` on, and assuming you've left :ref:`shell` set to ``True``, you - will see the literal, full string as passed to the remote server:: - - [hostname] run: /bin/bash -l -c "ls \"/home/username/Folder Name With Spaces\"" - - Enabling ``debug`` output will also display full Python tracebacks during - aborts. - - .. note:: - - Where modifying other pieces of output (such as in the above example - where it modifies the 'running' line to show the shell and any escape - characters), this setting takes precedence over the others; so if - ``running`` is False but ``debug`` is True, you will still be shown the - 'running' line in its debugging form. - -.. versionchanged:: 1.0 - Debug output now includes full Python tracebacks during aborts. - -.. _output-aliases: - -Output level aliases --------------------- - -In addition to the atomic/standalone levels above, Fabric also provides a -couple of convenience aliases which map to multiple other levels. These may be -referenced anywhere the other levels are referenced, and will effectively -toggle all of the levels they are mapped to. - -* **output**: Maps to both ``stdout`` and ``stderr``. Useful for when you only - care to see the 'running' lines and your own print statements (and warnings). - -* **everything**: Includes ``warnings``, ``running``, ``user`` and ``output`` - (see above.) Thus, when turning off ``everything``, you will only see a bare - minimum of output (just ``status`` and ``debug`` if it's on), along with your - own print statements. - -* **commands**: Includes ``stdout`` and ``running``. Good for hiding - non-erroring commands entirely, while still displaying any stderr output. - -.. versionchanged:: 1.4 - Added the ``commands`` output alias. - - -Hiding and/or showing output levels -=================================== - -You may toggle any of Fabric's output levels in a number of ways; for examples, -please see the API docs linked in each bullet point: - -* **Direct modification of fabric.state.output**: `fabric.state.output` is a - dictionary subclass (similar to :doc:`env `) whose keys are the output - level names, and whose values are either True (show that particular type of - output) or False (hide it.) - - `fabric.state.output` is the lowest-level implementation of output levels and - is what Fabric's internals reference when deciding whether or not to print - their output. - -* **Context managers**: `~fabric.context_managers.hide` and - `~fabric.context_managers.show` are twin context managers that take one or - more output level names as strings, and either hide or show them within the - wrapped block. As with Fabric's other context managers, the prior values are - restored when the block exits. - - .. seealso:: - - `~fabric.context_managers.settings`, which can nest calls to - `~fabric.context_managers.hide` and/or `~fabric.context_managers.show` - inside itself. - -* **Command-line arguments**: You may use the :option:`--hide` and/or - :option:`--show` arguments to :doc:`fab`, which behave exactly like the - context managers of the same names (but are, naturally, globally applied) and - take comma-separated strings as input. diff -Nru fabric-1.8.2/docs/usage/parallel.rst fabric-1.10.0/docs/usage/parallel.rst --- fabric-1.8.2/docs/usage/parallel.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/parallel.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -================== -Parallel execution -================== - -.. versionadded:: 1.3 - -By default, Fabric executes all specified tasks **serially** (see -:ref:`execution-strategy` for details.) This document describes Fabric's -options for running tasks on multiple hosts in **parallel**, via per-task -decorators and/or global command-line switches. - - -What it does -============ - -Because Fabric 1.x is not fully threadsafe (and because in general use, task -functions do not typically interact with one another) this functionality is -implemented via the Python `multiprocessing -`_ module. It creates one -new process for each host and task combination, optionally using a -(configurable) sliding window to prevent too many processes from running at the -same time. - -For example, imagine a scenario where you want to update Web application code -on a number of Web servers, and then reload the servers once the code has been -distributed everywhere (to allow for easier rollback if code updates fail.) One -could implement this with the following fabfile:: - - from fabric.api import * - - def update(): - with cd("/srv/django/myapp"): - run("git pull") - - def reload(): - sudo("service apache2 reload") - -and execute it on a set of 3 servers, in serial, like so:: - - $ fab -H web1,web2,web3 update reload - -Normally, without any parallel execution options activated, Fabric would run -in order: - -#. ``update`` on ``web1`` -#. ``update`` on ``web2`` -#. ``update`` on ``web3`` -#. ``reload`` on ``web1`` -#. ``reload`` on ``web2`` -#. ``reload`` on ``web3`` - -With parallel execution activated (via :option:`-P` -- see below for details), -this turns into: - -#. ``update`` on ``web1``, ``web2``, and ``web3`` -#. ``reload`` on ``web1``, ``web2``, and ``web3`` - -Hopefully the benefits of this are obvious -- if ``update`` took 5 seconds to -run and ``reload`` took 2 seconds, serial execution takes (5+2)*3 = 21 seconds -to run, while parallel execution takes only a third of the time, (5+2) = 7 -seconds on average. - - -How to use it -============= - -Decorators ----------- - -Since the minimum "unit" that parallel execution affects is a task, the -functionality may be enabled or disabled on a task-by-task basis using the -`~fabric.decorators.parallel` and `~fabric.decorators.serial` decorators. For -example, this fabfile:: - - from fabric.api import * - - @parallel - def runs_in_parallel(): - pass - - def runs_serially(): - pass - -when run in this manner:: - - $ fab -H host1,host2,host3 runs_in_parallel runs_serially - -will result in the following execution sequence: - -#. ``runs_in_parallel`` on ``host1``, ``host2``, and ``host3`` -#. ``runs_serially`` on ``host1`` -#. ``runs_serially`` on ``host2`` -#. ``runs_serially`` on ``host3`` - -Command-line flags ------------------- - -One may also force all tasks to run in parallel by using the command-line flag -:option:`-P` or the env variable :ref:`env.parallel `. However, -any task specifically wrapped with `~fabric.decorators.serial` will ignore this -setting and continue to run serially. - -For example, the following fabfile will result in the same execution sequence -as the one above:: - - from fabric.api import * - - def runs_in_parallel(): - pass - - @serial - def runs_serially(): - pass - -when invoked like so:: - - $ fab -H host1,host2,host3 -P runs_in_parallel runs_serially - -As before, ``runs_in_parallel`` will run in parallel, and ``runs_serially`` in -sequence. - - -Bubble size -=========== - -With large host lists, a user's local machine can get overwhelmed by running -too many concurrent Fabric processes. Because of this, you may opt to use a -moving bubble approach that limits Fabric to a specific number of concurrently -active processes. - -By default, no bubble is used and all hosts are run in one concurrent pool. You -can override this on a per-task level by specifying the ``pool_size`` keyword -argument to `~fabric.decorators.parallel`, or globally via :option:`-z`. - -For example, to run on 5 hosts at a time:: - - from fabric.api import * - - @parallel(pool_size=5) - def heavy_task(): - # lots of heavy local lifting or lots of IO here - -Or skip the ``pool_size`` kwarg and instead:: - - $ fab -P -z 5 heavy_task - -.. _linewise-output: - -Linewise vs bytewise output -=========================== - -Fabric's default mode of printing to the terminal is byte-by-byte, in order to -support :doc:`/usage/interactivity`. This often gives poor results when running -in parallel mode, as the multiple processes may write to your terminal's -standard out stream simultaneously. - -To help offset this problem, Fabric's option for linewise output is -automatically enabled whenever parallelism is active. This will cause you to -lose most of the benefits outlined in the above link Fabric's remote -interactivity features, but as those do not map well to parallel invocations, -it's typically a fair trade. - -There's no way to avoid the multiple processes mixing up on a line-by-line -basis, but you will at least be able to tell them apart by the host-string line -prefix. - -.. note:: - Future versions will add improved logging support to make troubleshooting - parallel runs easier. diff -Nru fabric-1.8.2/docs/usage/ssh.rst fabric-1.10.0/docs/usage/ssh.rst --- fabric-1.8.2/docs/usage/ssh.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/ssh.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -============ -SSH behavior -============ - -Fabric currently makes use of a pure-Python SSH re-implementation for managing -connections, meaning that there are occasionally spots where it is limited by -that library's capabilities. Below are areas of note where Fabric will exhibit -behavior that isn't consistent with, or as flexible as, the behavior of the -``ssh`` command-line program. - - -Unknown hosts -============= - -SSH's host key tracking mechanism keeps tabs on all the hosts you attempt to -connect to, and maintains a ``~/.ssh/known_hosts`` file with mappings between -identifiers (IP address, sometimes with a hostname as well) and SSH keys. (For -details on how this works, please see the `OpenSSH documentation -`_.) - -The ``paramiko`` library is capable of loading up your ``known_hosts`` file, -and will then compare any host it connects to, with that mapping. Settings are -available to determine what happens when an unknown host (a host whose username -or IP is not found in ``known_hosts``) is seen: - -* **Reject**: the host key is rejected and the connection is not made. This - results in a Python exception, which will terminate your Fabric session with a - message that the host is unknown. -* **Add**: the new host key is added to the in-memory list of known hosts, the - connection is made, and things continue normally. Note that this does **not** - modify your on-disk ``known_hosts`` file! -* **Ask**: not yet implemented at the Fabric level, this is a ``paramiko`` - library option which would result in the user being prompted about the - unknown key and whether to accept it. - -Whether to reject or add hosts, as above, is controlled in Fabric via the -:ref:`env.reject_unknown_hosts ` option, which is False -by default for convenience's sake. We feel this is a valid tradeoff between -convenience and security; anyone who feels otherwise can easily modify their -fabfiles at module level to set ``env.reject_unknown_hosts = True``. - - -Known hosts with changed keys -============================= - -The point of SSH's key/fingerprint tracking is so that man-in-the-middle -attacks can be detected: if an attacker redirects your SSH traffic to a -computer under his control, and pretends to be your original destination -server, the host keys will not match. Thus, the default behavior of SSH (and -its Python implementation) is to immediately abort the connection when a host -previously recorded in ``known_hosts`` suddenly starts sending us a different -host key. - -In some edge cases such as some EC2 deployments, you may want to ignore this -potential problem. Our SSH layer, at the time of writing, doesn't give us -control over this exact behavior, but we can sidestep it by simply skipping the -loading of ``known_hosts`` -- if the host list being compared to is empty, then -there's no problem. Set :ref:`env.disable_known_hosts ` to -True when you want this behavior; it is False by default, in order to preserve -default SSH behavior. - -.. warning:: - Enabling :ref:`env.disable_known_hosts ` will leave - you wide open to man-in-the-middle attacks! Please use with caution. diff -Nru fabric-1.8.2/docs/usage/tasks.rst fabric-1.10.0/docs/usage/tasks.rst --- fabric-1.8.2/docs/usage/tasks.rst 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/docs/usage/tasks.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,540 +0,0 @@ -============== -Defining tasks -============== - -As of Fabric 1.1, there are two distinct methods you may use in order to define -which objects in your fabfile show up as tasks: - -* The "new" method starting in 1.1 considers instances of `~fabric.tasks.Task` - or its subclasses, and also descends into imported modules to allow building - nested namespaces. -* The "classic" method from 1.0 and earlier considers all public callable - objects (functions, classes etc) and only considers the objects in the - fabfile itself with no recursing into imported module. - -.. note:: - These two methods are **mutually exclusive**: if Fabric finds *any* - new-style task objects in your fabfile or in modules it imports, it will - assume you've committed to this method of task declaration and won't - consider any non-`~fabric.tasks.Task` callables. If *no* new-style tasks - are found, it reverts to the classic behavior. - -The rest of this document explores these two methods in detail. - -.. note:: - - To see exactly what tasks in your fabfile may be executed via ``fab``, use - :option:`fab --list <-l>`. - -.. _new-style-tasks: - -New-style tasks -=============== - -Fabric 1.1 introduced the `~fabric.tasks.Task` class to facilitate new features -and enable some programming best practices, specifically: - -* **Object-oriented tasks**. Inheritance and all that comes with it can make - for much more sensible code reuse than passing around simple function - objects. The classic style of task declaration didn't entirely rule this - out, but it also didn't make it terribly easy. -* **Namespaces**. Having an explicit method of declaring tasks makes it easier - to set up recursive namespaces without e.g. polluting your task list with the - contents of Python's ``os`` module (which would show up as valid "tasks" - under the classic methodology.) - -With the introduction of `~fabric.tasks.Task`, there are two ways to set up new -tasks: - -* Decorate a regular module level function with `@task - `, which transparently wraps the function in a - `~fabric.tasks.Task` subclass. The function name will be used as the task - name when invoking. -* Subclass `~fabric.tasks.Task` (`~fabric.tasks.Task` itself is intended to be - abstract), define a ``run`` method, and instantiate your subclass at module - level. Instances' ``name`` attributes are used as the task name; if omitted - the instance's variable name will be used instead. - -Use of new-style tasks also allows you to set up :ref:`namespaces -`. - - -.. _task-decorator: - -The ``@task`` decorator ------------------------ - -The quickest way to make use of new-style task features is to wrap basic task functions with `@task `:: - - from fabric.api import task, run - - @task - def mytask(): - run("a command") - - -When this decorator is used, it signals to Fabric that *only* functions wrapped in the decorator are to be loaded up as valid tasks. (When not present, :ref:`classic-style task ` behavior kicks in.) - -.. _task-decorator-arguments: - -Arguments -~~~~~~~~~ - -`@task ` may also be called with arguments to -customize its behavior. Any arguments not documented below are passed into the -constructor of the ``task_class`` being used, with the function itself as the -first argument (see :ref:`task-decorator-and-classes` for details.) - -* ``task_class``: The `~fabric.tasks.Task` subclass used to wrap the decorated - function. Defaults to `~fabric.tasks.WrappedCallableTask`. -* ``aliases``: An iterable of string names which will be used as aliases for - the wrapped function. See :ref:`task-aliases` for details. -* ``alias``: Like ``aliases`` but taking a single string argument instead of an - iterable. If both ``alias`` and ``aliases`` are specified, ``aliases`` will - take precedence. -* ``default``: A boolean value determining whether the decorated task also - stands in for its containing module as a task name. See :ref:`default-tasks`. -* ``name``: A string setting the name this task appears as to the command-line - interface. Useful for task names that would otherwise shadow Python builtins - (which is technically legal but frowned upon and bug-prone.) - -.. _task-aliases: - -Aliases -~~~~~~~ - -Here's a quick example of using the ``alias`` keyword argument to facilitate -use of both a longer human-readable task name, and a shorter name which is -quicker to type:: - - from fabric.api import task - - @task(alias='dwm') - def deploy_with_migrations(): - pass - -Calling :option:`--list <-l>` on this fabfile would show both the original -``deploy_with_migrations`` and its alias ``dwm``:: - - $ fab --list - Available commands: - - deploy_with_migrations - dwm - -When more than one alias for the same function is needed, simply swap in the -``aliases`` kwarg, which takes an iterable of strings instead of a single -string. - -.. _default-tasks: - -Default tasks -~~~~~~~~~~~~~ - -In a similar manner to :ref:`aliases `, it's sometimes useful to -designate a given task within a module as the "default" task, which may be -called by referencing *just* the module name. This can save typing and/or -allow for neater organization when there's a single "main" task and a number -of related tasks or subroutines. - -For example, a ``deploy`` submodule might contain tasks for provisioning new -servers, pushing code, migrating databases, and so forth -- but it'd be very -convenient to highlight a task as the default "just deploy" action. Such a -``deploy.py`` module might look like this:: - - from fabric.api import task - - @task - def migrate(): - pass - - @task - def push(): - pass - - @task - def provision(): - pass - - @task - def full_deploy(): - if not provisioned: - provision() - push() - migrate() - -With the following task list (assuming a simple top level ``fabfile.py`` that just imports ``deploy``):: - - $ fab --list - Available commands: - - deploy.full_deploy - deploy.migrate - deploy.provision - deploy.push - -Calling ``deploy.full_deploy`` on every deploy could get kind of old, or somebody new to the team might not be sure if that's really the right task to run. - -Using the ``default`` kwarg to `@task `, we can tag -e.g. ``full_deploy`` as the default task:: - - @task(default=True) - def full_deploy(): - pass - -Doing so updates the task list like so:: - - $ fab --list - Available commands: - - deploy - deploy.full_deploy - deploy.migrate - deploy.provision - deploy.push - -Note that ``full_deploy`` still exists as its own explicit task -- but now -``deploy`` shows up as a sort of top level alias for ``full_deploy``. - -If multiple tasks within a module have ``default=True`` set, the last one to -be loaded (typically the one lowest down in the file) will take precedence. - -Top-level default tasks -~~~~~~~~~~~~~~~~~~~~~~~ - -Using ``@task(default=True)`` in the top level fabfile will cause the denoted -task to execute when a user invokes ``fab`` without any task names (similar to -e.g. ``make``.) When using this shortcut, it is not possible to specify -arguments to the task itself -- use a regular invocation of the task if this -is necessary. - -.. _task-subclasses: - -``Task`` subclasses -------------------- - -If you're used to :ref:`classic-style tasks `, an easy way to -think about `~fabric.tasks.Task` subclasses is that their ``run`` method is -directly equivalent to a classic task; its arguments are the task arguments -(other than ``self``) and its body is what gets executed. - -For example, this new-style task:: - - class MyTask(Task): - name = "deploy" - def run(self, environment, domain="whatever.com"): - run("git clone foo") - sudo("service apache2 restart") - - instance = MyTask() - -is exactly equivalent to this function-based task:: - - @task - def deploy(environment, domain="whatever.com"): - run("git clone foo") - sudo("service apache2 restart") - -Note how we had to instantiate an instance of our class; that's simply normal -Python object-oriented programming at work. While it's a small bit of -boilerplate right now -- for example, Fabric doesn't care about the name you -give the instantiation, only the instance's ``name`` attribute -- it's well -worth the benefit of having the power of classes available. - -We plan to extend the API in the future to make this experience a bit smoother. - -.. _task-decorator-and-classes: - -Using custom subclasses with ``@task`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It's possible to marry custom `~fabric.tasks.Task` subclasses with `@task -`. This may be useful in cases where your core -execution logic doesn't do anything class/object-specific, but you want to -take advantage of class metaprogramming or similar techniques. - -Specifically, any `~fabric.tasks.Task` subclass which is designed to take in a -callable as its first constructor argument (as the built-in -`~fabric.tasks.WrappedCallableTask` does) may be specified as the -``task_class`` argument to `@task `. - -Fabric will automatically instantiate a copy of the given class, passing in -the wrapped function as the first argument. All other args/kwargs given to the -decorator (besides the "special" arguments documented in -:ref:`task-decorator-arguments`) are added afterwards. - -Here's a brief and somewhat contrived example to make this obvious:: - - from fabric.api import task - from fabric.tasks import Task - - class CustomTask(Task): - def __init__(self, func, myarg, *args, **kwargs): - super(CustomTask, self).__init__(*args, **kwargs) - self.func = func - self.myarg = myarg - - def run(self, *args, **kwargs): - return self.func(*args, **kwargs) - - @task(task_class=CustomTask, myarg='value', alias='at') - def actual_task(): - pass - -When this fabfile is loaded, a copy of ``CustomTask`` is instantiated, effectively calling:: - - task_obj = CustomTask(actual_task, myarg='value') - -Note how the ``alias`` kwarg is stripped out by the decorator itself and never -reaches the class instantiation; this is identical in function to how -:ref:`command-line task arguments ` work. - -.. _namespaces: - -Namespaces ----------- - -With :ref:`classic tasks `, fabfiles were limited to a single, -flat set of task names with no real way to organize them. In Fabric 1.1 and -newer, if you declare tasks the new way (via `@task ` -or your own `~fabric.tasks.Task` subclass instances) you may take advantage -of **namespacing**: - -* Any module objects imported into your fabfile will be recursed into, looking - for additional task objects. -* Within submodules, you may control which objects are "exported" by using the - standard Python ``__all__`` module-level variable name (thought they should - still be valid new-style task objects.) -* These tasks will be given new dotted-notation names based on the modules they - came from, similar to Python's own import syntax. - -Let's build up a fabfile package from simple to complex and see how this works. - -Basic -~~~~~ - -We start with a single `__init__.py` containing a few tasks (the Fabric API -import omitted for brevity):: - - @task - def deploy(): - ... - - @task - def compress(): - ... - -The output of ``fab --list`` would look something like this:: - - deploy - compress - -There's just one namespace here: the "root" or global namespace. Looks simple -now, but in a real-world fabfile with dozens of tasks, it can get difficult to -manage. - -Importing a submodule -~~~~~~~~~~~~~~~~~~~~~ - -As mentioned above, Fabric will examine any imported module objects for tasks, -regardless of where that module exists on your Python import path. For now we -just want to include our own, "nearby" tasks, so we'll make a new submodule in -our package for dealing with, say, load balancers -- ``lb.py``:: - - @task - def add_backend(): - ... - -And we'll add this to the top of ``__init__.py``:: - - import lb - -Now ``fab --list`` shows us:: - - deploy - compress - lb.add_backend - -Again, with only one task in its own submodule, it looks kind of silly, but the -benefits should be pretty obvious. - -Going deeper -~~~~~~~~~~~~ - -Namespacing isn't limited to just one level. Let's say we had a larger setup -and wanted a namespace for database related tasks, with additional -differentiation inside that. We make a sub-package named ``db/`` and inside it, -a ``migrations.py`` module:: - - @task - def list(): - ... - - @task - def run(): - ... - -We need to make sure that this module is visible to anybody importing ``db``, -so we add it to the sub-package's ``__init__.py``:: - - import migrations - -As a final step, we import the sub-package into our root-level ``__init__.py``, -so now its first few lines look like this:: - - import lb - import db - -After all that, our file tree looks like this:: - - . - ├── __init__.py - ├── db - │   ├── __init__.py - │   └── migrations.py - └── lb.py - -and ``fab --list`` shows:: - - deploy - compress - lb.add_backend - db.migrations.list - db.migrations.run - -We could also have specified (or imported) tasks directly into -``db/__init__.py``, and they would show up as ``db.`` as you might -expect. - -Limiting with ``__all__`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -You may limit what Fabric "sees" when it examines imported modules, by using -the Python convention of a module level ``__all__`` variable (a list of -variable names.) If we didn't want the ``db.migrations.run`` task to show up by -default for some reason, we could add this to the top of ``db/migrations.py``:: - - __all__ = ['list'] - -Note the lack of ``'run'`` there. You could, if needed, import ``run`` directly -into some other part of the hierarchy, but otherwise it'll remain hidden. - -Switching it up -~~~~~~~~~~~~~~~ - -We've been keeping our fabfile package neatly organized and importing it in a -straightforward manner, but the filesystem layout doesn't actually matter here. -All Fabric's loader cares about is the names the modules are given when they're -imported. - -For example, if we changed the top of our root ``__init__.py`` to look like -this:: - - import db as database - -Our task list would change thusly:: - - deploy - compress - lb.add_backend - database.migrations.list - database.migrations.run - -This applies to any other import -- you could import third party modules into -your own task hierarchy, or grab a deeply nested module and make it appear near -the top level. - -Nested list output -~~~~~~~~~~~~~~~~~~ - -As a final note, we've been using the default Fabric :option:`--list <-l>` -output during this section -- it makes it more obvious what the actual task -names are. However, you can get a more nested or tree-like view by passing -``nested`` to the :option:`--list-format <-F>` option:: - - $ fab --list-format=nested --list - Available commands (remember to call as module.[...].task): - - deploy - compress - lb: - add_backend - database: - migrations: - list - run - -While it slightly obfuscates the "real" task names, this view provides a handy -way of noting the organization of tasks in large namespaces. - - -.. _classic-tasks: - -Classic tasks -============= - -When no new-style `~fabric.tasks.Task`-based tasks are found, Fabric will -consider any callable object found in your fabfile, **except** the following: - -* Callables whose name starts with an underscore (``_``). In other words, - Python's usual "private" convention holds true here. -* Callables defined within Fabric itself. Fabric's own functions such as - `~fabric.operations.run` and `~fabric.operations.sudo` will not show up in - your task list. - - -Imports -------- - -Python's ``import`` statement effectively includes the imported objects in your -module's namespace. Since Fabric's fabfiles are just Python modules, this means -that imports are also considered as possible classic-style tasks, alongside -anything defined in the fabfile itself. - - .. note:: - This only applies to imported *callable objects* -- not modules. - Imported modules only come into play if they contain :ref:`new-style - tasks `, at which point this section no longer - applies. - -Because of this, we strongly recommend that you use the ``import module`` form -of importing, followed by ``module.callable()``, which will result in a cleaner -fabfile API than doing ``from module import callable``. - -For example, here's a sample fabfile which uses ``urllib.urlopen`` to get some -data out of a webservice:: - - from urllib import urlopen - - from fabric.api import run - - def webservice_read(): - objects = urlopen('http://my/web/service/?foo=bar').read().split() - print(objects) - -This looks simple enough, and will run without error. However, look what -happens if we run :option:`fab --list <-l>` on this fabfile:: - - $ fab --list - Available commands: - - webservice_read List some directories. - urlopen urlopen(url [, data]) -> open file-like object - -Our fabfile of only one task is showing two "tasks", which is bad enough, and -an unsuspecting user might accidentally try to call ``fab urlopen``, which -probably won't work very well. Imagine any real-world fabfile, which is likely -to be much more complex, and hopefully you can see how this could get messy -fast. - -For reference, here's the recommended way to do it:: - - import urllib - - from fabric.api import run - - def webservice_read(): - objects = urllib.urlopen('http://my/web/service/?foo=bar').read().split() - print(objects) - -It's a simple change, but it'll make anyone using your fabfile a bit happier. diff -Nru fabric-1.8.2/fabfile/docs.py fabric-1.10.0/fabfile/docs.py --- fabric-1.8.2/fabfile/docs.py 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/fabfile/docs.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -from __future__ import with_statement - -from fabric.api import lcd, local, task - - -@task(default=True) -def build(clean='no', browse_='no'): - """ - Generate the Sphinx documentation. - """ - c = "" - if clean.lower() in ['yes', 'y']: - c = "clean " - b = "" - with lcd('docs'): - local('make %shtml%s' % (c, b)) - if browse_.lower() in ['yes', 'y']: - browse() - - -@task -def browse(): - """ - Open the current dev docs in a browser tab. - """ - local("open docs/_build/html/index.html") diff -Nru fabric-1.8.2/fabfile/__init__.py fabric-1.10.0/fabfile/__init__.py --- fabric-1.8.2/fabfile/__init__.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/fabfile/__init__.py 2014-09-04 00:43:57.000000000 +0000 @@ -8,7 +8,6 @@ from fabric.api import abort, local, task -import docs import tag from utils import msg @@ -20,7 +19,10 @@ Specify string argument ``args`` for additional args to ``nosetests``. """ - default_args = "-sv --with-doctest --nologcapture --with-color" + # Default to explicitly targeting the 'tests' folder, but only if nothing + # is being overridden. + tests = "" if args else " tests" + default_args = "-sv --with-doctest --nologcapture --with-color %s" % tests default_args += (" " + args) if args else "" nose.core.run_exit(argv=[''] + default_args.split()) diff -Nru fabric-1.8.2/fabric/context_managers.py fabric-1.10.0/fabric/context_managers.py --- fabric-1.8.2/fabric/context_managers.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/fabric/context_managers.py 2014-09-03 20:20:44.000000000 +0000 @@ -329,7 +329,7 @@ def _change_cwd(which, path): path = path.replace(' ', '\ ') - if state.env.get(which) and not path.startswith('/'): + if state.env.get(which) and not path.startswith('/') and not path.startswith('~'): new_cwd = state.env.get(which) + '/' + path else: new_cwd = path diff -Nru fabric-1.8.2/fabric/contrib/files.py fabric-1.10.0/fabric/contrib/files.py --- fabric-1.8.2/fabric/contrib/files.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/fabric/contrib/files.py 2014-09-03 22:51:54.000000000 +0000 @@ -9,6 +9,7 @@ import re import os from StringIO import StringIO +from functools import partial from fabric.api import * from fabric.utils import apply_lcwd @@ -42,13 +43,14 @@ If ``use_sudo`` is True, will use `.sudo` instead of `.run`. - `.is_link` will, by default, hide all output. Give ``verbose=True`` to change this. + `.is_link` will, by default, hide all output. Give ``verbose=True`` to + change this. """ func = sudo if use_sudo else run cmd = 'test -L "$(echo %s)"' % path args, kwargs = [], {'warn_only': True} if not verbose: - opts = [hide('everything')] + args = [hide('everything')] with settings(*args, **kwargs): return func(cmd).succeeded @@ -56,7 +58,8 @@ def first(*args, **kwargs): """ Given one or more file paths, returns first one found, or None if none - exist. May specify ``use_sudo`` and ``verbose`` which are passed to `exists`. + exist. May specify ``use_sudo`` and ``verbose`` which are passed to + `exists`. """ for directory in args: if exists(directory, **kwargs): @@ -65,7 +68,7 @@ def upload_template(filename, destination, context=None, use_jinja=False, template_dir=None, use_sudo=False, backup=True, mirror_local_mode=False, - mode=None): + mode=None, pty=None): """ Render and upload a template text file to a remote host. @@ -93,10 +96,18 @@ internal `~fabric.operations.put` call; please see its documentation for details on these two options. + The ``pty`` kwarg will be passed verbatim to any internal + `~fabric.operations.run`/`~fabric.operations.sudo` calls, such as those + used for testing directory-ness, making backups, etc. + .. versionchanged:: 1.1 Added the ``backup``, ``mirror_local_mode`` and ``mode`` kwargs. + .. versionchanged:: 1.9 + Added the ``pty`` kwarg. """ func = use_sudo and sudo or run + if pty is not None: + func = partial(func, pty=pty) # Normalize destination to be an actual filename, due to using StringIO with settings(hide('everything'), warn_only=True): if func('test -d %s' % _expand_path(destination)).succeeded: @@ -106,7 +117,7 @@ # Use mode kwarg to implement mirror_local_mode, again due to using # StringIO if mirror_local_mode and mode is None: - mode = os.stat(filename).st_mode + mode = os.stat(apply_lcwd(filename, env)).st_mode # To prevent put() from trying to do this # logic itself mirror_local_mode = False @@ -129,6 +140,8 @@ tb = traceback.format_exc() abort(tb + "\nUnable to import Jinja2 -- see above.") else: + if template_dir: + filename = os.path.join(template_dir, filename) filename = apply_lcwd(filename, env) with open(os.path.expanduser(filename)) as inputfile: text = inputfile.read() diff -Nru fabric-1.8.2/fabric/io.py fabric-1.10.0/fabric/io.py --- fabric-1.8.2/fabric/io.py 2014-02-14 18:36:36.000000000 +0000 +++ fabric-1.10.0/fabric/io.py 2014-09-03 22:51:54.000000000 +0000 @@ -13,6 +13,7 @@ from fabric.utils import RingBuffer from fabric.exceptions import CommandTimeout + if win32: import msvcrt @@ -50,7 +51,11 @@ def _flush(self, text): self.stream.write(text) - self.stream.flush() + # Actually only flush if not in linewise mode. + # When linewise is set (e.g. in parallel mode) flushing makes + # doubling-up of line prefixes, and other mixed output, more likely. + if not env.linewise: + self.stream.flush() self.write_buffer.extend(text) def loop(self): @@ -148,13 +153,18 @@ # Store in internal buffer _buffer += fragment # Handle prompts - prompt = _endswith(self.capture, env.sudo_prompt) - try_again = (_endswith(self.capture, env.again_prompt + '\n') - or _endswith(self.capture, env.again_prompt + '\r\n')) - if prompt: - self.prompt() - elif try_again: - self.try_again() + expected, response = self._get_prompt_response() + if expected: + del self.capture[-1 * len(expected):] + self.chan.sendall(str(response) + '\n') + else: + prompt = _endswith(self.capture, env.sudo_prompt) + try_again = (_endswith(self.capture, env.again_prompt + '\n') + or _endswith(self.capture, env.again_prompt + '\r\n')) + if prompt: + self.prompt() + elif try_again: + self.try_again() # Print trailing new line if the last thing we printed was our line # prefix. @@ -195,13 +205,23 @@ self.reprompt = False # Send current password down the pipe self.chan.sendall(password + '\n') - + def try_again(self): # Remove text from capture buffer self.capture = self.capture[:len(env.again_prompt)] # Set state so we re-prompt the user at the next prompt. self.reprompt = True + def _get_prompt_response(self): + """ + Iterate through the request prompts dict and return the response and + original request if we find a match + """ + for tup in env.prompts.iteritems(): + if _endswith(self.capture, tup[0]): + return tup + return None, None + def input_loop(chan, using_pty): while not chan.exit_status_ready(): diff -Nru fabric-1.8.2/fabric/__main__.py fabric-1.10.0/fabric/__main__.py --- fabric-1.8.2/fabric/__main__.py 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/fabric/__main__.py 2014-09-04 00:52:45.000000000 +0000 @@ -0,0 +1,2 @@ +import fabric.main +fabric.main.main() diff -Nru fabric-1.8.2/fabric/main.py fabric-1.10.0/fabric/main.py --- fabric-1.8.2/fabric/main.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/fabric/main.py 2014-09-04 00:52:45.000000000 +0000 @@ -59,7 +59,7 @@ """ Take given file path and return dictionary of any key=value pairs found. - Usage docs are in docs/usage/fab.rst, in "Settings files." + Usage docs are in sites/docs/usage/fab.rst, in "Settings files." """ if os.path.exists(path): comments = lambda s: s and not s.startswith("#") @@ -84,7 +84,7 @@ """ Attempt to locate a fabfile, either explicitly or by searching parent dirs. - Usage docs are in docs/usage/fabfiles.rst, in "Fabfile discovery." + Usage docs are in sites/docs/usage/fabfiles.rst, in "Fabfile discovery." """ # Obtain env value if not given specifically if names is None: @@ -519,7 +519,7 @@ """ Parse string list into list of tuples: command, args, kwargs, hosts, roles. - See docs/usage/fab.rst, section on "per-task arguments" for details. + See sites/docs/usage/fab.rst, section on "per-task arguments" for details. """ cmds = [] for cmd in arguments: @@ -709,7 +709,7 @@ unknown_commands.append(tup[0]) # Abort if any unknown commands were specified - if unknown_commands: + if unknown_commands and not state.env.get('skip_unknown_tasks', False): warn("Command(s) not found:\n%s" \ % indent(unknown_commands)) show_commands(None, options.list_format, 1) diff -Nru fabric-1.8.2/fabric/network.py fabric-1.10.0/fabric/network.py --- fabric-1.8.2/fabric/network.py 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/fabric/network.py 2014-09-03 22:51:54.000000000 +0000 @@ -33,7 +33,8 @@ sys.exit(1) -ipv6_regex = re.compile('^\[?(?P[0-9A-Fa-f:]+)\]?(:(?P\d+))?$') +ipv6_regex = re.compile( + '^\[?(?P[0-9A-Fa-f:]+(?:%[a-z]+\d+)?)\]?(:(?P\d+))?$') def direct_tcpip(client, host, port): @@ -138,9 +139,16 @@ """ Force a new connection to ``key`` host string. """ + from fabric.state import env + user, host, port = normalize(key) key = normalize_to_string(key) - self[key] = connect(user, host, port, cache=self) + seek_gateway = True + # break the loop when the host is gateway itself + if env.gateway: + seek_gateway = normalize_to_string(env.gateway) != key + self[key] = connect( + user, host, port, cache=self, seek_gateway=seek_gateway) def __getitem__(self, key): """ diff -Nru fabric-1.8.2/fabric/operations.py fabric-1.10.0/fabric/operations.py --- fabric-1.8.2/fabric/operations.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/fabric/operations.py 2014-09-04 00:55:15.000000000 +0000 @@ -411,7 +411,7 @@ @needs_host -def get(remote_path, local_path=None): +def get(remote_path, local_path=None, use_sudo=False, temp_dir=""): """ Download one or more files from a remote host. @@ -445,6 +445,13 @@ ``utils.py`` in ``src/projectname/utils.py`` * ``path``: The full remote path, e.g. ``src/projectname/utils.py``. + While the SFTP protocol (which `get` uses) has no direct ability to download + files from locations not owned by the connecting user, you may specify + ``use_sudo=True`` to work around this. When set, this setting allows `get` + to copy (using sudo) the remote files to a temporary location on the remote end + (defaults to remote user's ``$HOME``; this may be overridden via ``temp_dir``), + and then download them to ``local_path``. + .. note:: When ``remote_path`` is an absolute directory path, only the inner directories will be recreated locally and passed into the above @@ -562,14 +569,13 @@ for remote_path in names: if ftp.isdir(remote_path): - result = ftp.get_dir(remote_path, local_path) + result = ftp.get_dir(remote_path, local_path, use_sudo, temp_dir) local_files.extend(result) else: # Perform actual get. If getting to real local file path, # add result (will be true final path value) to # local_files. File-like objects are omitted. - result = ftp.get(remote_path, local_path, local_is_path, - os.path.basename(remote_path)) + result = ftp.get(remote_path, local_path, use_sudo, local_is_path, os.path.basename(remote_path), temp_dir) if local_is_path: local_files.append(result) @@ -1127,7 +1133,8 @@ In either case, as with `~fabric.operations.run` and `~fabric.operations.sudo`, this return value exhibits the ``return_code``, - ``stderr``, ``failed`` and ``succeeded`` attributes. See `run` for details. + ``stderr``, ``failed``, ``succeeded``, ``command`` and ``real_command`` + attributes. See `run` for details. `~fabric.operations.local` will honor the `~fabric.context_managers.lcd` context manager, allowing you to control its current working directory @@ -1140,6 +1147,8 @@ Now honors the `~fabric.context_managers.lcd` context manager. .. versionchanged:: 1.0 Changed the default value of ``capture`` from ``True`` to ``False``. + .. versionadded:: 1.9 + The return value attributes ``.command`` and ``.real_command``. """ given_command = command # Apply cd(), path() etc @@ -1162,12 +1171,9 @@ err_stream = None if output.stderr else dev_null try: cmd_arg = wrapped_command if win32 else [wrapped_command] - if shell is not None: - p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, - stderr=err_stream, executable=shell) - else: - p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, - stderr=err_stream) + p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, + stderr=err_stream, executable=shell, + close_fds=(not win32)) (stdout, stderr) = p.communicate() finally: if dev_null is not None: @@ -1175,6 +1181,8 @@ # Handle error condition (deal with stdout being None, too) out = _AttributeString(stdout.strip() if stdout else "") err = _AttributeString(stderr.strip() if stderr else "") + out.command = given_command + out.real_command = wrapped_command out.failed = False out.return_code = p.returncode out.stderr = err @@ -1188,7 +1196,7 @@ @needs_host -def reboot(wait=120): +def reboot(wait=120, command='reboot'): """ Reboot the remote system. @@ -1225,7 +1233,7 @@ timeout=timeout, connection_attempts=attempts ): - sudo('reboot') + sudo(command) # Try to make sure we don't slip in before pre-reboot lockdown time.sleep(5) # This is actually an internal-ish API call, but users can simply drop diff -Nru fabric-1.8.2/fabric/sftp.py fabric-1.10.0/fabric/sftp.py --- fabric-1.8.2/fabric/sftp.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/fabric/sftp.py 2014-09-04 00:52:45.000000000 +0000 @@ -36,7 +36,7 @@ def isdir(self, path): try: - return stat.S_ISDIR(self.ftp.lstat(path).st_mode) + return stat.S_ISDIR(self.ftp.stat(path).st_mode) except IOError: return False @@ -110,7 +110,9 @@ else: self.ftp.mkdir(path) - def get(self, remote_path, local_path, local_is_path, rremote=None): + def get(self, remote_path, local_path, use_sudo, local_is_path, rremote=None, temp_dir=""): + from fabric.api import sudo, hide + # rremote => relative remote path, so get(/var/log) would result in # this function being called with # remote_path=/var/log/apache2/access.log and @@ -123,6 +125,7 @@ 'dirname': os.path.dirname(rremote), 'path': rremote } + if local_is_path: # Naive fix to issue #711 escaped_path = re.sub(r'(%[^()]*\w)', r'%\1', local_path) @@ -135,6 +138,7 @@ os.makedirs(dirpath) if os.path.isdir(local_path): local_path = os.path.join(local_path, path_vars['basename']) + if output.running: print("[%s] download: %s <- %s" % ( env.host_string, @@ -145,18 +149,43 @@ if local_is_path and os.path.exists(local_path): msg = "Local file %s already exists and is being overwritten." warn(msg % local_path) - # File-like objects: reset to file seek 0 (to ensure full overwrite) - # and then use Paramiko's getfo() directly - getter = self.ftp.get - if not local_is_path: - local_path.seek(0) - getter = self.ftp.getfo - getter(remote_path, local_path) + + # When using sudo, "bounce" the file through a guaranteed-unique file + # path in the default remote CWD (which, typically, the login user will + # have write permissions on) in order to sudo(cp) it. + if use_sudo: + target_path = remote_path + hasher = hashlib.sha1() + hasher.update(env.host_string) + hasher.update(target_path) + target_path = posixpath.join(temp_dir, hasher.hexdigest()) + # Temporarily nuke 'cwd' so sudo() doesn't "cd" its mv command. + # (The target path has already been cwd-ified elsewhere.) + with settings(hide('everything'), cwd=""): + sudo('cp -p "%s" "%s"' % (remote_path, target_path)) + # Only root and the user has the right to read the file + sudo('chmod %o "%s"' % (0404, target_path)) + remote_path = target_path + + try: + # File-like objects: reset to file seek 0 (to ensure full overwrite) + # and then use Paramiko's getfo() directly + getter = self.ftp.get + if not local_is_path: + local_path.seek(0) + getter = self.ftp.getfo + getter(remote_path, local_path) + finally: + # try to remove the temporary file after the download + if use_sudo: + with settings(hide('everything'), cwd=""): + sudo('rm -f "%s"' % remote_path) + # Return local_path object for posterity. (If mutated, caller will want # to know.) return local_path - def get_dir(self, remote_path, local_path): + def get_dir(self, remote_path, local_path, use_sudo, temp_dir): # Decide what needs to be stripped from remote paths so they're all # relative to the given remote_path if os.path.basename(remote_path): @@ -192,11 +221,12 @@ lpath = local_path # Now we can make a call to self.get() with specific file paths # on both ends. - result.append(self.get(rpath, lpath, True, rremote)) + result.append(self.get(rpath, lpath, use_sudo, True, rremote, temp_dir)) return result def put(self, local_path, remote_path, use_sudo, mirror_local_mode, mode, local_is_path, temp_dir): + from fabric.api import sudo, hide pre = self.ftp.getcwd() pre = pre if pre else '' diff -Nru fabric-1.8.2/fabric/state.py fabric-1.10.0/fabric/state.py --- fabric-1.8.2/fabric/state.py 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/fabric/state.py 2014-09-04 00:52:45.000000000 +0000 @@ -83,7 +83,7 @@ # optparse.NO_DEFAULT (currently a two-tuple)! In general, None is a better # default than ''. # -# User-facing documentation for these are kept in docs/env.rst. +# User-facing documentation for these are kept in sites/docs/env.rst. env_options = [ make_option('-a', '--no_agent', @@ -243,6 +243,12 @@ help="skip over hosts that can't be reached" ), + make_option('--skip-unknown-tasks', + action="store_true", + default=False, + help="skip over unknown tasks" + ), + make_option('--ssh-config-path', default=default_ssh_config_path, metavar='PATH', @@ -315,6 +321,7 @@ 'default_port': default_port, 'eagerly_disconnect': False, 'echo_stdin': True, + 'effective_roles': [], 'exclude_hosts': [], 'gateway': None, 'host': None, @@ -332,6 +339,7 @@ 'roledefs': {}, 'shell_env': {}, 'skip_bad_hosts': False, + 'skip_unknown_tasks': False, 'ssh_config_path': default_ssh_config_path, 'ok_ret_codes': [0], # a list of return codes that indicate success # -S so sudo accepts passwd via stdin, -p with our known-value prompt for @@ -340,6 +348,7 @@ 'sudo_prompt': 'sudo password:', 'sudo_user': None, 'tasks': [], + 'prompts': {}, 'use_exceptions_for': {'network': False}, 'use_shell': True, 'use_ssh_config': False, diff -Nru fabric-1.8.2/fabric/tasks.py fabric-1.10.0/fabric/tasks.py --- fabric-1.8.2/fabric/tasks.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/fabric/tasks.py 2014-09-04 00:52:45.000000000 +0000 @@ -98,30 +98,33 @@ def run(self): raise NotImplementedError - def get_hosts(self, arg_hosts, arg_roles, arg_exclude_hosts, env=None): + def get_hosts_and_effective_roles(self, arg_hosts, arg_roles, arg_exclude_hosts, env=None): """ - Return the host list the given task should be using. + Return a tuple containing the host list the given task should be using + and the roles being used. See :ref:`host-lists` for detailed documentation on how host lists are set. + + .. versionchanged:: 1.9 """ env = env or {'hosts': [], 'roles': [], 'exclude_hosts': []} roledefs = env.get('roledefs', {}) # Command line per-task takes precedence over anything else. if arg_hosts or arg_roles: - return merge(arg_hosts, arg_roles, arg_exclude_hosts, roledefs) + return merge(arg_hosts, arg_roles, arg_exclude_hosts, roledefs), arg_roles # Decorator-specific hosts/roles go next func_hosts = getattr(self, 'hosts', []) func_roles = getattr(self, 'roles', []) if func_hosts or func_roles: - return merge(func_hosts, func_roles, arg_exclude_hosts, roledefs) + return merge(func_hosts, func_roles, arg_exclude_hosts, roledefs), func_roles # Finally, the env is checked (which might contain globally set lists # from the CLI or from module-level code). This will be the empty list # if these have not been set -- which is fine, this method should # return an empty list if no hosts have been set anywhere. env_vars = map(_get_list(env), "hosts roles exclude_hosts".split()) env_vars.append(roledefs) - return merge(*env_vars) + return merge(*env_vars), env.get('roles', []) def get_pool_size(self, hosts, default): # Default parallel pool size (calculate per-task in case variables @@ -200,6 +203,10 @@ )) +def _is_network_error_ignored(): + return not state.env.use_exceptions_for['network'] and state.env.skip_bad_hosts + + def _execute(task, host, my_env, args, kwargs, jobs, queue, multiprocessing): """ Primary single-host work body of execute() @@ -228,8 +235,7 @@ def submit(result): queue.put({'name': name, 'result': result}) try: - key = normalize_to_string(state.env.host_string) - state.connections.pop(key, "") + state.connections.clear() submit(task.run(*args, **kwargs)) except BaseException, e: # We really do want to capture everything # SystemExit implies use of abort(), which prints its own @@ -238,12 +244,16 @@ # clear what host encountered the exception that will # print. if e.__class__ is not SystemExit: - sys.stderr.write("!!! Parallel execution exception under host %r:\n" % name) + if not (isinstance(e, NetworkError) and + _is_network_error_ignored()): + sys.stderr.write("!!! Parallel execution exception under host %r:\n" % name) submit(e) # Here, anything -- unexpected exceptions, or abort() # driven SystemExits -- will bubble up and terminate the # child process. - raise + if not (isinstance(e, NetworkError) and + _is_network_error_ignored()): + raise # Stuff into Process wrapper kwarg_dict = { @@ -320,7 +330,12 @@ my_env['command'] = task task = crawl(task, state.commands) if task is None: - abort("%r is not callable or a valid task name" % (task,)) + msg = "%r is not callable or a valid task name" % (my_env['command'],) + if state.env.get('skip_unknown_tasks', False): + warn(msg) + return + else: + abort(msg) # Set env.command if we were given a real function or callable task obj else: dunder_name = getattr(task, '__name__', None) @@ -331,7 +346,8 @@ # Filter out hosts/roles kwargs new_kwargs, hosts, roles, exclude_hosts = parse_kwargs(kwargs) # Set up host list - my_env['all_hosts'] = task.get_hosts(hosts, roles, exclude_hosts, state.env) + my_env['all_hosts'], my_env['effective_roles'] = task.get_hosts_and_effective_roles(hosts, roles, + exclude_hosts, state.env) parallel = requires_parallel(task) if parallel: @@ -393,7 +409,10 @@ ran_jobs = jobs.run() for name, d in ran_jobs.iteritems(): if d['exit_code'] != 0: - if isinstance(d['results'], BaseException): + if isinstance(d['results'], NetworkError) and \ + _is_network_error_ignored(): + error(d['results'].message, func=warn, exception=d['results'].wrapped) + elif isinstance(d['results'], BaseException): error(err, exception=d['results']) else: error(err) diff -Nru fabric-1.8.2/fabric/task_utils.py fabric-1.10.0/fabric/task_utils.py --- fabric-1.8.2/fabric/task_utils.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/fabric/task_utils.py 2014-09-04 00:52:45.000000000 +0000 @@ -52,6 +52,9 @@ role_hosts = [] for role in roles: value = roledefs[role] + # Handle dict style roledefs + if isinstance(value, dict): + value = value['hosts'] # Handle "lazy" roles (callables) if callable(value): value = value() diff -Nru fabric-1.8.2/fabric/utils.py fabric-1.10.0/fabric/utils.py --- fabric-1.8.2/fabric/utils.py 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/fabric/utils.py 2014-09-03 22:51:54.000000000 +0000 @@ -7,6 +7,14 @@ import textwrap from traceback import format_exc + +def _encode(msg, stream): + if isinstance(msg, unicode) and hasattr(stream, 'encoding'): + return msg.encode(stream.encoding) + else: + return str(msg) + + def abort(msg): """ Abort execution, print ``msg`` to stderr and exit with error status (1.) @@ -25,7 +33,7 @@ from colors import red if output.aborts: - sys.stderr.write(red("\nFatal error: %s\n" % str(msg))) + sys.stderr.write(red("\nFatal error: %s\n" % _encode(msg, sys.stderr))) sys.stderr.write(red("\nAborting.\n")) if env.abort_exception: @@ -51,6 +59,7 @@ from colors import magenta if output.warnings: + msg = _encode(msg, sys.stderr) sys.stderr.write(magenta("\nWarning: %s\n\n" % msg)) @@ -110,7 +119,7 @@ prefix = "" if env.host_string and show_prefix: prefix = "[%s] " % env.host_string - sys.stdout.write(prefix + str(text) + end) + sys.stdout.write(prefix + _encode(text, sys.stdout) + end) if flush: sys.stdout.flush() diff -Nru fabric-1.8.2/fabric/version.py fabric-1.10.0/fabric/version.py --- fabric-1.8.2/fabric/version.py 2014-02-14 18:41:06.000000000 +0000 +++ fabric-1.10.0/fabric/version.py 2014-09-04 16:47:33.000000000 +0000 @@ -9,7 +9,7 @@ from os.path import abspath, dirname -VERSION = (1, 8, 2, 'final', 0) +VERSION = (1, 10, 0, 'final', 0) def git_sha(): diff -Nru fabric-1.8.2/Fabric.egg-info/PKG-INFO fabric-1.10.0/Fabric.egg-info/PKG-INFO --- fabric-1.8.2/Fabric.egg-info/PKG-INFO 2014-02-14 18:41:08.000000000 +0000 +++ fabric-1.10.0/Fabric.egg-info/PKG-INFO 2014-09-04 16:48:50.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: Fabric -Version: 1.8.2 +Version: 1.10.0 Summary: Fabric is a simple, Pythonic tool for remote execution and deployment. Home-page: http://fabfile.org Author: Jeff Forcier @@ -8,7 +8,7 @@ License: UNKNOWN Description: To find out what's new in this version of Fabric, please see `the changelog - `_. + `_. You can also install the `in-development version `_ using @@ -16,10 +16,7 @@ ---- - .. image:: https://secure.travis-ci.org/fabric/fabric.png?branch=master - :target: https://travis-ci.org/fabric/fabric - - Fabric is a Python (2.5 or higher) library and command-line tool for + Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks. diff -Nru fabric-1.8.2/Fabric.egg-info/requires.txt fabric-1.10.0/Fabric.egg-info/requires.txt --- fabric-1.8.2/Fabric.egg-info/requires.txt 2014-02-14 18:41:08.000000000 +0000 +++ fabric-1.10.0/Fabric.egg-info/requires.txt 2014-09-04 16:48:50.000000000 +0000 @@ -1 +1 @@ -paramiko>=1.10.0 \ No newline at end of file +paramiko>=1.10,<1.13 \ No newline at end of file diff -Nru fabric-1.8.2/Fabric.egg-info/SOURCES.txt fabric-1.10.0/Fabric.egg-info/SOURCES.txt --- fabric-1.8.2/Fabric.egg-info/SOURCES.txt 2014-02-14 18:41:08.000000000 +0000 +++ fabric-1.10.0/Fabric.egg-info/SOURCES.txt 2014-09-04 16:48:50.000000000 +0000 @@ -11,46 +11,11 @@ Fabric.egg-info/entry_points.txt Fabric.egg-info/requires.txt Fabric.egg-info/top_level.txt -docs/.changelog.rst.swp -docs/Makefile -docs/changelog.rst -docs/conf.py -docs/development.rst -docs/faq.rst -docs/index.rst -docs/installation.rst -docs/roadmap.rst -docs/troubleshooting.rst -docs/tutorial.rst -docs/_static/rtd.css -docs/_templates/layout.html -docs/api/contrib/console.rst -docs/api/contrib/django.rst -docs/api/contrib/files.rst -docs/api/contrib/project.rst -docs/api/core/colors.rst -docs/api/core/context_managers.rst -docs/api/core/decorators.rst -docs/api/core/docs.rst -docs/api/core/network.rst -docs/api/core/operations.rst -docs/api/core/tasks.rst -docs/api/core/utils.rst -docs/usage/env.rst -docs/usage/execution.rst -docs/usage/fab.rst -docs/usage/fabfiles.rst -docs/usage/interactivity.rst -docs/usage/library.rst -docs/usage/output_controls.rst -docs/usage/parallel.rst -docs/usage/ssh.rst -docs/usage/tasks.rst fabfile/__init__.py -fabfile/docs.py fabfile/tag.py fabfile/utils.py fabric/__init__.py +fabric/__main__.py fabric/api.py fabric/auth.py fabric/colors.py @@ -75,6 +40,42 @@ fabric/contrib/django.py fabric/contrib/files.py fabric/contrib/project.py +sites/shared_conf.py +sites/_shared_static/logo.png +sites/docs/conf.py +sites/docs/index.rst +sites/docs/tutorial.rst +sites/docs/api/contrib/console.rst +sites/docs/api/contrib/django.rst +sites/docs/api/contrib/files.rst +sites/docs/api/contrib/project.rst +sites/docs/api/core/colors.rst +sites/docs/api/core/context_managers.rst +sites/docs/api/core/decorators.rst +sites/docs/api/core/docs.rst +sites/docs/api/core/network.rst +sites/docs/api/core/operations.rst +sites/docs/api/core/tasks.rst +sites/docs/api/core/utils.rst +sites/docs/usage/env.rst +sites/docs/usage/execution.rst +sites/docs/usage/fab.rst +sites/docs/usage/fabfiles.rst +sites/docs/usage/interactivity.rst +sites/docs/usage/library.rst +sites/docs/usage/output_controls.rst +sites/docs/usage/parallel.rst +sites/docs/usage/ssh.rst +sites/docs/usage/tasks.rst +sites/www/changelog.rst +sites/www/conf.py +sites/www/contact.rst +sites/www/development.rst +sites/www/faq.rst +sites/www/index.rst +sites/www/installing.rst +sites/www/roadmap.rst +sites/www/troubleshooting.rst tests/Python26SocketServer.py tests/client.key tests/client.key.pub @@ -85,6 +86,7 @@ tests/test_context_managers.py tests/test_contrib.py tests/test_decorators.py +tests/test_io.py tests/test_main.py tests/test_network.py tests/test_operations.py diff -Nru fabric-1.8.2/INSTALL fabric-1.10.0/INSTALL --- fabric-1.8.2/INSTALL 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/INSTALL 2014-09-03 22:51:54.000000000 +0000 @@ -1,2 +1,2 @@ For installation help, please see http://fabfile.org/ or (if using a source -checkout) docs/installation.rst. +checkout) sites/www/installing.rst. diff -Nru fabric-1.8.2/LICENSE fabric-1.10.0/LICENSE --- fabric-1.8.2/LICENSE 2014-02-14 18:36:36.000000000 +0000 +++ fabric-1.10.0/LICENSE 2014-09-03 22:51:54.000000000 +0000 @@ -1,4 +1,5 @@ -Copyright (c) 2013, Christian Vest Hansen and Jeffrey E. Forcier +Copyright (c) 2009-2014 Jeffrey E. Forcier +Copyright (c) 2008-2009 Christian Vest Hansen All rights reserved. Redistribution and use in source and binary forms, with or without diff -Nru fabric-1.8.2/MANIFEST.in fabric-1.10.0/MANIFEST.in --- fabric-1.8.2/MANIFEST.in 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/MANIFEST.in 2014-09-03 20:20:44.000000000 +0000 @@ -2,8 +2,9 @@ include INSTALL include LICENSE include README.rst -recursive-include docs * -recursive-exclude docs/_build * +recursive-include sites * +recursive-exclude sites/docs/_build * +recursive-exclude sites/www/_build * include requirements.txt recursive-include tests * recursive-exclude tests *.pyc *.pyo diff -Nru fabric-1.8.2/PKG-INFO fabric-1.10.0/PKG-INFO --- fabric-1.8.2/PKG-INFO 2014-02-14 18:41:08.000000000 +0000 +++ fabric-1.10.0/PKG-INFO 2014-09-04 16:48:50.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: Fabric -Version: 1.8.2 +Version: 1.10.0 Summary: Fabric is a simple, Pythonic tool for remote execution and deployment. Home-page: http://fabfile.org Author: Jeff Forcier @@ -8,7 +8,7 @@ License: UNKNOWN Description: To find out what's new in this version of Fabric, please see `the changelog - `_. + `_. You can also install the `in-development version `_ using @@ -16,10 +16,7 @@ ---- - .. image:: https://secure.travis-ci.org/fabric/fabric.png?branch=master - :target: https://travis-ci.org/fabric/fabric - - Fabric is a Python (2.5 or higher) library and command-line tool for + Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks. diff -Nru fabric-1.8.2/README.rst fabric-1.10.0/README.rst --- fabric-1.8.2/README.rst 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/README.rst 2014-09-03 20:20:44.000000000 +0000 @@ -1,7 +1,4 @@ -.. image:: https://secure.travis-ci.org/fabric/fabric.png?branch=master - :target: https://travis-ci.org/fabric/fabric - -Fabric is a Python (2.5 or higher) library and command-line tool for +Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks. diff -Nru fabric-1.8.2/setup.py fabric-1.10.0/setup.py --- fabric-1.8.2/setup.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/setup.py 2014-09-03 22:51:54.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import with_statement + import sys from setuptools import setup, find_packages @@ -7,11 +9,12 @@ from fabric.version import get_version -readme = open('README.rst').read() +with open('README.rst') as f: + readme = f.read() long_description = """ To find out what's new in this version of Fabric, please see `the changelog -`_. +`_. You can also install the `in-development version `_ using @@ -24,7 +27,13 @@ ---- For more information, please see the Fabric website or execute ``fab --help``. -""" % (get_version('branch'), readme) +""" % (readme) + +if sys.version_info[:2] < (2, 6): + install_requires=['paramiko>=1.10,<1.13'] +else: + install_requires=['paramiko>=1.10'] + setup( name='Fabric', @@ -36,8 +45,8 @@ url='http://fabfile.org', packages=find_packages(), test_suite='nose.collector', - tests_require=['nose', 'fudge<1.0'], - install_requires=['paramiko>=1.10.0'], + tests_require=['nose', 'fudge<1.0', 'jinja2'], + install_requires=install_requires, entry_points={ 'console_scripts': [ 'fab = fabric.main:main', diff -Nru fabric-1.8.2/sites/docs/api/contrib/console.rst fabric-1.10.0/sites/docs/api/contrib/console.rst --- fabric-1.8.2/sites/docs/api/contrib/console.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/contrib/console.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,5 @@ +Console Output Utilities +======================== + +.. automodule:: fabric.contrib.console + :members: diff -Nru fabric-1.8.2/sites/docs/api/contrib/django.rst fabric-1.10.0/sites/docs/api/contrib/django.rst --- fabric-1.8.2/sites/docs/api/contrib/django.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/contrib/django.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +================== +Django Integration +================== + +.. automodule:: fabric.contrib.django + :members: diff -Nru fabric-1.8.2/sites/docs/api/contrib/files.rst fabric-1.10.0/sites/docs/api/contrib/files.rst --- fabric-1.8.2/sites/docs/api/contrib/files.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/contrib/files.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +============================= +File and Directory Management +============================= + +.. automodule:: fabric.contrib.files + :members: diff -Nru fabric-1.8.2/sites/docs/api/contrib/project.rst fabric-1.10.0/sites/docs/api/contrib/project.rst --- fabric-1.8.2/sites/docs/api/contrib/project.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/contrib/project.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +============= +Project Tools +============= + +.. automodule:: fabric.contrib.project + :members: diff -Nru fabric-1.8.2/sites/docs/api/core/colors.rst fabric-1.10.0/sites/docs/api/core/colors.rst --- fabric-1.8.2/sites/docs/api/core/colors.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/colors.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,7 @@ +====================== +Color output functions +====================== + +.. automodule:: fabric.colors + :members: + :undoc-members: diff -Nru fabric-1.8.2/sites/docs/api/core/context_managers.rst fabric-1.10.0/sites/docs/api/core/context_managers.rst --- fabric-1.8.2/sites/docs/api/core/context_managers.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/context_managers.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +================ +Context Managers +================ + +.. automodule:: fabric.context_managers + :members: diff -Nru fabric-1.8.2/sites/docs/api/core/decorators.rst fabric-1.10.0/sites/docs/api/core/decorators.rst --- fabric-1.8.2/sites/docs/api/core/decorators.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/decorators.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +========== +Decorators +========== + +.. automodule:: fabric.decorators + :members: hosts, roles, runs_once, serial, parallel, task, with_settings diff -Nru fabric-1.8.2/sites/docs/api/core/docs.rst fabric-1.10.0/sites/docs/api/core/docs.rst --- fabric-1.8.2/sites/docs/api/core/docs.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/docs.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +===================== +Documentation helpers +===================== + +.. automodule:: fabric.docs + :members: diff -Nru fabric-1.8.2/sites/docs/api/core/network.rst fabric-1.10.0/sites/docs/api/core/network.rst --- fabric-1.8.2/sites/docs/api/core/network.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/network.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,7 @@ +======= +Network +======= + +.. automodule:: fabric.network + + .. autofunction:: disconnect_all diff -Nru fabric-1.8.2/sites/docs/api/core/operations.rst fabric-1.10.0/sites/docs/api/core/operations.rst --- fabric-1.8.2/sites/docs/api/core/operations.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/operations.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +========== +Operations +========== + +.. automodule:: fabric.operations + :members: diff -Nru fabric-1.8.2/sites/docs/api/core/tasks.rst fabric-1.10.0/sites/docs/api/core/tasks.rst --- fabric-1.8.2/sites/docs/api/core/tasks.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/tasks.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +===== +Tasks +===== + +.. automodule:: fabric.tasks + :members: Task, WrappedCallableTask, execute diff -Nru fabric-1.8.2/sites/docs/api/core/utils.rst fabric-1.10.0/sites/docs/api/core/utils.rst --- fabric-1.8.2/sites/docs/api/core/utils.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/api/core/utils.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,6 @@ +===== +Utils +===== + +.. automodule:: fabric.utils + :members: diff -Nru fabric-1.8.2/sites/docs/conf.py fabric-1.10.0/sites/docs/conf.py --- fabric-1.8.2/sites/docs/conf.py 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/conf.py 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,28 @@ +# Obtain shared config values +import os, sys +from os.path import abspath, join, dirname +sys.path.append(abspath(join(dirname(__file__), '..'))) +sys.path.append(abspath(join(dirname(__file__), '..', '..'))) +from shared_conf import * + +# Enable autodoc, intersphinx +extensions.extend(['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']) + +# Autodoc settings +autodoc_default_flags = ['members', 'special-members'] + +# Default is 'local' building, but reference the public WWW site when building +# under RTD. +target = join(dirname(__file__), '..', 'www', '_build') +if os.environ.get('READTHEDOCS') == 'True': + target = 'http://www.fabfile.org/' +# Intersphinx connection to stdlib + www site +intersphinx_mapping = { + 'python': ('http://docs.python.org/2.6', None), + 'www': (target, None), +} + +# Sister-site links to WWW +html_theme_options['extra_nav_links'] = { + "Main website": 'http://www.fabfile.org', +} diff -Nru fabric-1.8.2/sites/docs/index.rst fabric-1.10.0/sites/docs/index.rst --- fabric-1.8.2/sites/docs/index.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/index.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,78 @@ +================================== +Welcome to Fabric's documentation! +================================== + +This site covers Fabric's usage & API documentation. For basic info on what +Fabric is, including its public changelog & how the project is maintained, +please see `the main project website `_. + + +Tutorial +-------- + +For new users, and/or for an overview of Fabric's basic functionality, please +see the :doc:`tutorial`. The rest of the documentation will assume you're +at least passingly familiar with the material contained within. + +.. toctree:: + :hidden: + + tutorial + + +.. _usage-docs: + +Usage documentation +------------------- + +The following list contains all major sections of Fabric's prose (non-API) +documentation, which expands upon the concepts outlined in the +:doc:`tutorial` and also covers advanced topics. + +.. toctree:: + :maxdepth: 2 + :glob: + + usage/* + + +.. _api_docs: + +API documentation +----------------- + +Fabric maintains two sets of API documentation, autogenerated from the source +code's docstrings (which are typically very thorough.) + +.. _core-api: + +Core API +~~~~~~~~ + +The **core** API is loosely defined as those functions, classes and methods +which form the basic building blocks of Fabric (such as +`~fabric.operations.run` and `~fabric.operations.sudo`) upon which everything +else (the below "contrib" section, and user fabfiles) builds. + +.. toctree:: + :maxdepth: 1 + :glob: + + api/core/* + +.. _contrib-api: + +Contrib API +~~~~~~~~~~~ + +Fabric's **contrib** package contains commonly useful tools (often merged in +from user fabfiles) for tasks such as user I/O, modifying remote files, and so +forth. While the core API is likely to remain small and relatively unchanged +over time, this contrib section will grow and evolve (while trying to remain +backwards-compatible) as more use-cases are solved and added. + +.. toctree:: + :maxdepth: 1 + :glob: + + api/contrib/* diff -Nru fabric-1.8.2/sites/docs/tutorial.rst fabric-1.10.0/sites/docs/tutorial.rst --- fabric-1.8.2/sites/docs/tutorial.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/tutorial.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,468 @@ +===================== +Overview and Tutorial +===================== + +Welcome to Fabric! + +This document is a whirlwind tour of Fabric's features and a quick guide to its +use. Additional documentation (which is linked to throughout) can be found in +the :ref:`usage documentation ` -- please make sure to check it out. + + +What is Fabric? +=============== + +As the ``README`` says: + + .. include:: ../../README.rst + :end-before: It provides + +More specifically, Fabric is: + +* A tool that lets you execute **arbitrary Python functions** via the **command + line**; +* A library of subroutines (built on top of a lower-level library) to make + executing shell commands over SSH **easy** and **Pythonic**. + +Naturally, most users combine these two things, using Fabric to write and +execute Python functions, or **tasks**, to automate interactions with remote +servers. Let's take a look. + + +Hello, ``fab`` +============== + +This wouldn't be a proper tutorial without "the usual":: + + def hello(): + print("Hello world!") + +Placed in a Python module file named ``fabfile.py`` in your current working +directory, that ``hello`` function can be executed with the ``fab`` tool +(installed as part of Fabric) and does just what you'd expect:: + + $ fab hello + Hello world! + + Done. + +That's all there is to it. This functionality allows Fabric to be used as a +(very) basic build tool even without importing any of its API. + +.. note:: + + The ``fab`` tool simply imports your fabfile and executes the function or + functions you instruct it to. There's nothing magic about it -- anything + you can do in a normal Python script can be done in a fabfile! + +.. seealso:: :ref:`execution-strategy`, :doc:`/usage/tasks`, :doc:`/usage/fab` + + +Task arguments +============== + +It's often useful to pass runtime parameters into your tasks, just as you might +during regular Python programming. Fabric has basic support for this using a +shell-compatible notation: ``:,=,...``. It's +contrived, but let's extend the above example to say hello to you personally:: + + def hello(name="world"): + print("Hello %s!" % name) + +By default, calling ``fab hello`` will still behave as it did before; but now +we can personalize it:: + + $ fab hello:name=Jeff + Hello Jeff! + + Done. + +Those already used to programming in Python might have guessed that this +invocation behaves exactly the same way:: + + $ fab hello:Jeff + Hello Jeff! + + Done. + +For the time being, your argument values will always show up in Python as +strings and may require a bit of string manipulation for complex types such +as lists. Future versions may add a typecasting system to make this easier. + +.. seealso:: :ref:`task-arguments` + +Local commands +============== + +As used above, ``fab`` only really saves a couple lines of +``if __name__ == "__main__"`` boilerplate. It's mostly designed for use with +Fabric's API, which contains functions (or **operations**) for executing shell +commands, transferring files, and so forth. + +Let's build a hypothetical Web application fabfile. This example scenario is +as follows: The Web application is managed via Git on a remote host +``vcshost``. On ``localhost``, we have a local clone of said Web application. +When we push changes back to ``vcshost``, we want to be able to immediately +install these changes on a remote host ``my_server`` in an automated fashion. +We will do this by automating the local and remote Git commands. + +Fabfiles usually work best at the root of a project:: + + . + |-- __init__.py + |-- app.wsgi + |-- fabfile.py <-- our fabfile! + |-- manage.py + `-- my_app + |-- __init__.py + |-- models.py + |-- templates + | `-- index.html + |-- tests.py + |-- urls.py + `-- views.py + +.. note:: + + We're using a Django application here, but only as an example -- Fabric is + not tied to any external codebase, save for its SSH library. + +For starters, perhaps we want to run our tests and commit to our VCS so we're +ready for a deploy:: + + from fabric.api import local + + def prepare_deploy(): + local("./manage.py test my_app") + local("git add -p && git commit") + local("git push") + +The output of which might look a bit like this:: + + $ fab prepare_deploy + [localhost] run: ./manage.py test my_app + Creating test database... + Creating tables + Creating indexes + .......................................... + ---------------------------------------------------------------------- + Ran 42 tests in 9.138s + + OK + Destroying test database... + + [localhost] run: git add -p && git commit + + + + [localhost] run: git push + + + + Done. + +The code itself is straightforward: import a Fabric API function, +`~fabric.operations.local`, and use it to run and interact with local shell +commands. The rest of Fabric's API is similar -- it's all just Python. + +.. seealso:: :doc:`api/core/operations`, :ref:`fabfile-discovery` + + +Organize it your way +==================== + +Because Fabric is "just Python" you're free to organize your fabfile any way +you want. For example, it's often useful to start splitting things up into +subtasks:: + + from fabric.api import local + + def test(): + local("./manage.py test my_app") + + def commit(): + local("git add -p && git commit") + + def push(): + local("git push") + + def prepare_deploy(): + test() + commit() + push() + +The ``prepare_deploy`` task can be called just as before, but now you can make +a more granular call to one of the sub-tasks, if desired. + + +Failure +======= + +Our base case works fine now, but what happens if our tests fail? Chances are +we want to put on the brakes and fix them before deploying. + +Fabric checks the return value of programs called via operations and will abort +if they didn't exit cleanly. Let's see what happens if one of our tests +encounters an error:: + + $ fab prepare_deploy + [localhost] run: ./manage.py test my_app + Creating test database... + Creating tables + Creating indexes + .............E............................ + ====================================================================== + ERROR: testSomething (my_project.my_app.tests.MainTests) + ---------------------------------------------------------------------- + Traceback (most recent call last): + [...] + + ---------------------------------------------------------------------- + Ran 42 tests in 9.138s + + FAILED (errors=1) + Destroying test database... + + Fatal error: local() encountered an error (return code 2) while executing './manage.py test my_app' + + Aborting. + +Great! We didn't have to do anything ourselves: Fabric detected the failure and +aborted, never running the ``commit`` task. + +.. seealso:: :ref:`Failure handling (usage documentation) ` + +Failure handling +---------------- + +But what if we wanted to be flexible and give the user a choice? A setting +(or **environment variable**, usually shortened to **env var**) called +:ref:`warn_only` lets you turn aborts into warnings, allowing flexible error +handling to occur. + +Let's flip this setting on for our ``test`` function, and then inspect the +result of the `~fabric.operations.local` call ourselves:: + + from __future__ import with_statement + from fabric.api import local, settings, abort + from fabric.contrib.console import confirm + + def test(): + with settings(warn_only=True): + result = local('./manage.py test my_app', capture=True) + if result.failed and not confirm("Tests failed. Continue anyway?"): + abort("Aborting at user request.") + + [...] + +In adding this new feature we've introduced a number of new things: + +* The ``__future__`` import required to use ``with:`` in Python 2.5; +* Fabric's `contrib.console ` submodule, containing the + `~fabric.contrib.console.confirm` function, used for simple yes/no prompts; +* The `~fabric.context_managers.settings` context manager, used to apply + settings to a specific block of code; +* Command-running operations like `~fabric.operations.local` can return objects + containing info about their result (such as ``.failed``, or + ``.return_code``); +* And the `~fabric.utils.abort` function, used to manually abort execution. + +However, despite the additional complexity, it's still pretty easy to follow, +and is now much more flexible. + +.. seealso:: :doc:`api/core/context_managers`, :ref:`env-vars` + + +Making connections +================== + +Let's start wrapping up our fabfile by putting in the keystone: a ``deploy`` +task that is destined to run on one or more remote server(s), and ensures the +code is up to date:: + + def deploy(): + code_dir = '/srv/django/myproject' + with cd(code_dir): + run("git pull") + run("touch app.wsgi") + +Here again, we introduce a handful of new concepts: + +* Fabric is just Python -- so we can make liberal use of regular Python code + constructs such as variables and string interpolation; +* `~fabric.context_managers.cd`, an easy way of prefixing commands with a ``cd + /to/some/directory`` call. This is similar to `~fabric.context_managers.lcd` + which does the same locally. +* `~fabric.operations.run`, which is similar to `~fabric.operations.local` but + runs **remotely** instead of locally. + +We also need to make sure we import the new functions at the top of our file:: + + from __future__ import with_statement + from fabric.api import local, settings, abort, run, cd + from fabric.contrib.console import confirm + +With these changes in place, let's deploy:: + + $ fab deploy + No hosts found. Please specify (single) host string for connection: my_server + [my_server] run: git pull + [my_server] out: Already up-to-date. + [my_server] out: + [my_server] run: touch app.wsgi + + Done. + +We never specified any connection info in our fabfile, so Fabric doesn't know +on which host(s) the remote command should be executed. When this happens, +Fabric prompts us at runtime. Connection definitions use SSH-like "host +strings" (e.g. ``user@host:port``) and will use your local username as a +default -- so in this example, we just had to specify the hostname, +``my_server``. + + +Remote interactivity +-------------------- + +``git pull`` works fine if you've already got a checkout of your source code -- +but what if this is the first deploy? It'd be nice to handle that case too and +do the initial ``git clone``:: + + def deploy(): + code_dir = '/srv/django/myproject' + with settings(warn_only=True): + if run("test -d %s" % code_dir).failed: + run("git clone user@vcshost:/path/to/repo/.git %s" % code_dir) + with cd(code_dir): + run("git pull") + run("touch app.wsgi") + +As with our calls to `~fabric.operations.local` above, `~fabric.operations.run` +also lets us construct clean Python-level logic based on executed shell +commands. However, the interesting part here is the ``git clone`` call: since +we're using Git's SSH method of accessing the repository on our Git server, +this means our remote `~fabric.operations.run` call will need to authenticate +itself. + +Older versions of Fabric (and similar high level SSH libraries) run remote +programs in limbo, unable to be touched from the local end. This is +problematic when you have a serious need to enter passwords or otherwise +interact with the remote program. + +Fabric 1.0 and later breaks down this wall and ensures you can always talk to +the other side. Let's see what happens when we run our updated ``deploy`` task +on a new server with no Git checkout:: + + $ fab deploy + No hosts found. Please specify (single) host string for connection: my_server + [my_server] run: test -d /srv/django/myproject + + Warning: run() encountered an error (return code 1) while executing 'test -d /srv/django/myproject' + + [my_server] run: git clone user@vcshost:/path/to/repo/.git /srv/django/myproject + [my_server] out: Cloning into /srv/django/myproject... + [my_server] out: Password: + [my_server] out: remote: Counting objects: 6698, done. + [my_server] out: remote: Compressing objects: 100% (2237/2237), done. + [my_server] out: remote: Total 6698 (delta 4633), reused 6414 (delta 4412) + [my_server] out: Receiving objects: 100% (6698/6698), 1.28 MiB, done. + [my_server] out: Resolving deltas: 100% (4633/4633), done. + [my_server] out: + [my_server] run: git pull + [my_server] out: Already up-to-date. + [my_server] out: + [my_server] run: touch app.wsgi + + Done. + +Notice the ``Password:`` prompt -- that was our remote ``git`` call on our Web server, asking for the password to the Git server. We were able to type it in and the clone continued normally. + +.. seealso:: :doc:`/usage/interactivity` + + +.. _defining-connections: + +Defining connections beforehand +------------------------------- + +Specifying connection info at runtime gets old real fast, so Fabric provides a +handful of ways to do it in your fabfile or on the command line. We won't cover +all of them here, but we will show you the most common one: setting the global +host list, :ref:`env.hosts `. + +:doc:`env ` is a global dictionary-like object driving many of +Fabric's settings, and can be written to with attributes as well (in fact, +`~fabric.context_managers.settings`, seen above, is simply a wrapper for this.) +Thus, we can modify it at module level near the top of our fabfile like so:: + + from __future__ import with_statement + from fabric.api import * + from fabric.contrib.console import confirm + + env.hosts = ['my_server'] + + def test(): + do_test_stuff() + +When ``fab`` loads up our fabfile, our modification of ``env`` will execute, +storing our settings change. The end result is exactly as above: our ``deploy`` +task will run against the ``my_server`` server. + +This is also how you can tell Fabric to run on multiple remote systems at once: +because ``env.hosts`` is a list, ``fab`` iterates over it, calling the given +task once for each connection. + +.. seealso:: :doc:`usage/env`, :ref:`host-lists` + + +Conclusion +========== + +Our completed fabfile is still pretty short, as such things go. Here it is in +its entirety:: + + from __future__ import with_statement + from fabric.api import * + from fabric.contrib.console import confirm + + env.hosts = ['my_server'] + + def test(): + with settings(warn_only=True): + result = local('./manage.py test my_app', capture=True) + if result.failed and not confirm("Tests failed. Continue anyway?"): + abort("Aborting at user request.") + + def commit(): + local("git add -p && git commit") + + def push(): + local("git push") + + def prepare_deploy(): + test() + commit() + push() + + def deploy(): + code_dir = '/srv/django/myproject' + with settings(warn_only=True): + if run("test -d %s" % code_dir).failed: + run("git clone user@vcshost:/path/to/repo/.git %s" % code_dir) + with cd(code_dir): + run("git pull") + run("touch app.wsgi") + +This fabfile makes use of a large portion of Fabric's feature set: + +* defining fabfile tasks and running them with :doc:`fab `; +* calling local shell commands with `~fabric.operations.local`; +* modifying env vars with `~fabric.context_managers.settings`; +* handling command failures, prompting the user, and manually aborting; +* and defining host lists and `~fabric.operations.run`-ning remote commands. + +However, there's still a lot more we haven't covered here! Please make sure you +follow the various "see also" links, and check out the documentation table of +contents on :doc:`the main index page `. + +Thanks for reading! diff -Nru fabric-1.8.2/sites/docs/usage/env.rst fabric-1.10.0/sites/docs/usage/env.rst --- fabric-1.8.2/sites/docs/usage/env.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/env.rst 2014-09-04 00:52:45.000000000 +0000 @@ -0,0 +1,910 @@ +=================================== +The environment dictionary, ``env`` +=================================== + +A simple but integral aspect of Fabric is what is known as the "environment": a +Python dictionary subclass, which is used as a combination settings registry and +shared inter-task data namespace. + +The environment dict is currently implemented as a global singleton, +``fabric.state.env``, and is included in ``fabric.api`` for convenience. Keys +in ``env`` are sometimes referred to as "env variables". + +Environment as configuration +============================ + +Most of Fabric's behavior is controllable by modifying ``env`` variables, such +as ``env.hosts`` (as seen in :ref:`the tutorial `). Other +commonly-modified env vars include: + +* ``user``: Fabric defaults to your local username when making SSH connections, + but you can use ``env.user`` to override this if necessary. The :doc:`execution` + documentation also has info on how to specify usernames on a per-host basis. +* ``password``: Used to explicitly set your default connection or sudo password + if desired. Fabric will prompt you when necessary if this isn't set or + doesn't appear to be valid. +* ``warn_only``: a Boolean setting determining whether Fabric exits when + detecting errors on the remote end. See :doc:`execution` for more on this + behavior. + +There are a number of other env variables; for the full list, see +:ref:`env-vars` at the bottom of this document. + +The `~fabric.context_managers.settings` context manager +------------------------------------------------------- + +In many situations, it's useful to only temporarily modify ``env`` vars so that +a given settings change only applies to a block of code. Fabric provides a +`~fabric.context_managers.settings` context manager, which takes any number of +key/value pairs and will use them to modify ``env`` within its wrapped block. + +For example, there are many situations where setting ``warn_only`` (see below) +is useful. To apply it to a few lines of code, use +``settings(warn_only=True)``, as seen in this simplified version of the +``contrib`` `~fabric.contrib.files.exists` function:: + + from fabric.api import settings, run + + def exists(path): + with settings(warn_only=True): + return run('test -e %s' % path) + +See the :doc:`../api/core/context_managers` API documentation for details on +`~fabric.context_managers.settings` and other, similar tools. + +Environment as shared state +=========================== + +As mentioned, the ``env`` object is simply a dictionary subclass, so your own +fabfile code may store information in it as well. This is sometimes useful for +keeping state between multiple tasks within a single execution run. + +.. note:: + + This aspect of ``env`` is largely historical: in the past, fabfiles were + not pure Python and thus the environment was the only way to communicate + between tasks. Nowadays, you may call other tasks or subroutines directly, + and even keep module-level shared state if you wish. + + In future versions, Fabric will become threadsafe, at which point ``env`` + may be the only easy/safe way to keep global state. + +Other considerations +==================== + +While it subclasses ``dict``, Fabric's ``env`` has been modified so that its +values may be read/written by way of attribute access, as seen in some of the +above material. In other words, ``env.host_string`` and ``env['host_string']`` +are functionally identical. We feel that attribute access can often save a bit +of typing and makes the code more readable, so it's the recommended way to +interact with ``env``. + +The fact that it's a dictionary can be useful in other ways, such as with +Python's ``dict``-based string interpolation, which is especially handy if you +need to insert multiple env vars into a single string. Using "normal" string +interpolation might look like this:: + + print("Executing on %s as %s" % (env.host, env.user)) + +Using dict-style interpolation is more readable and slightly shorter:: + + print("Executing on %(host)s as %(user)s" % env) + +.. _env-vars: + +Full list of env vars +===================== + +Below is a list of all predefined (or defined by Fabric itself during +execution) environment variables. While many of them may be manipulated +directly, it's often best to use `~fabric.context_managers`, either generally +via `~fabric.context_managers.settings` or via specific context managers such +as `~fabric.context_managers.cd`. + +Note that many of these may be set via ``fab``'s command-line switches -- see +:doc:`fab` for details. Cross-references are provided where appropriate. + +.. seealso:: :option:`--set` + +.. _abort-exception: + +``abort_exception`` +------------------- + +**Default:** ``None`` + +Fabric normally handles aborting by printing an error message to stderr and +calling ``sys.exit(1)``. This setting allows you to override that behavior +(which is what happens when ``env.abort_exception`` is ``None``.) + +Give it a callable which takes a string (the error message that would have been +printed) and returns an exception instance. That exception object is then +raised instead of ``SystemExit`` (which is what ``sys.exit`` does.) + +Much of the time you'll want to simply set this to an exception class, as those +fit the above description perfectly (callable, take a string, return an +exception instance.) E.g. ``env.abort_exception = MyExceptionClass``. + +.. _abort-on-prompts: + +``abort_on_prompts`` +-------------------- + +**Default:** ``False`` + +When ``True``, Fabric will run in a non-interactive mode, calling +`~fabric.utils.abort` anytime it would normally prompt the user for input (such +as password prompts, "What host to connect to?" prompts, fabfile invocation of +`~fabric.operations.prompt`, and so forth.) This allows users to ensure a Fabric +session will always terminate cleanly instead of blocking on user input forever +when unforeseen circumstances arise. + +.. versionadded:: 1.1 +.. seealso:: :option:`--abort-on-prompts` + + +``all_hosts`` +------------- + +**Default:** ``[]`` + +Set by ``fab`` to the full host list for the currently executing command. For +informational purposes only. + +.. seealso:: :doc:`execution` + +.. _always-use-pty: + +``always_use_pty`` +------------------ + +**Default:** ``True`` + +When set to ``False``, causes `~fabric.operations.run`/`~fabric.operations.sudo` +to act as if they have been called with ``pty=False``. + +.. seealso:: :option:`--no-pty` +.. versionadded:: 1.0 + +.. _colorize-errors: + +``colorize_errors`` +------------------- + +**Default** ``False`` + +When set to ``True``, error output to the terminal is colored red and warnings +are colored magenta to make them easier to see. + +.. versionadded:: 1.7 + +.. _combine-stderr: + +``combine_stderr`` +------------------ + +**Default**: ``True`` + +Causes the SSH layer to merge a remote program's stdout and stderr streams to +avoid becoming meshed together when printed. See :ref:`combine_streams` for +details on why this is needed and what its effects are. + +.. versionadded:: 1.0 + +``command`` +----------- + +**Default:** ``None`` + +Set by ``fab`` to the currently executing command name (e.g., when executed as +``$ fab task1 task2``, ``env.command`` will be set to ``"task1"`` while +``task1`` is executing, and then to ``"task2"``.) For informational purposes +only. + +.. seealso:: :doc:`execution` + +``command_prefixes`` +-------------------- + +**Default:** ``[]`` + +Modified by `~fabric.context_managers.prefix`, and prepended to commands +executed by `~fabric.operations.run`/`~fabric.operations.sudo`. + +.. versionadded:: 1.0 + +.. _command-timeout: + +``command_timeout`` +------------------- + +**Default:** ``None`` + +Remote command timeout, in seconds. + +.. versionadded:: 1.6 +.. seealso:: :option:`--command-timeout` + +.. _connection-attempts: + +``connection_attempts`` +----------------------- + +**Default:** ``1`` + +Number of times Fabric will attempt to connect when connecting to a new server. For backwards compatibility reasons, it defaults to only one connection attempt. + +.. versionadded:: 1.4 +.. seealso:: :option:`--connection-attempts`, :ref:`timeout` + +``cwd`` +------- + +**Default:** ``''`` + +Current working directory. Used to keep state for the +`~fabric.context_managers.cd` context manager. + +.. _dedupe_hosts: + +``dedupe_hosts`` +---------------- + +**Default:** ``True`` + +Deduplicate merged host lists so any given host string is only represented once +(e.g. when using combinations of ``@hosts`` + ``@roles``, or ``-H`` and +``-R``.) + +When set to ``False``, this option relaxes the deduplication, allowing users +who explicitly want to run a task multiple times on the same host (say, in +parallel, though it works fine serially too) to do so. + +.. versionadded:: 1.5 + +.. _disable-known-hosts: + +``disable_known_hosts`` +----------------------- + +**Default:** ``False`` + +If ``True``, the SSH layer will skip loading the user's known-hosts file. +Useful for avoiding exceptions in situations where a "known host" changing its +host key is actually valid (e.g. cloud servers such as EC2.) + +.. seealso:: :option:`--disable-known-hosts <-D>`, :doc:`ssh` + + +.. _eagerly-disconnect: + +``eagerly_disconnect`` +---------------------- + +**Default:** ``False`` + +If ``True``, causes ``fab`` to close connections after each individual task +execution, instead of at the end of the run. This helps prevent a lot of +typically-unused network sessions from piling up and causing problems with +limits on per-process open files, or network hardware. + +.. note:: + When active, this setting will result in the disconnect messages appearing + throughout your output, instead of at the end. This may be improved in + future releases. + +.. _effective_roles: + +``effective_roles`` +------------------- + +**Default:** ``[]`` + +Set by ``fab`` to the roles list of the currently executing command. For +informational purposes only. + +.. versionadded:: 1.9 +.. seealso:: :doc:`execution` + +.. _exclude-hosts: + +``exclude_hosts`` +----------------- + +**Default:** ``[]`` + +Specifies a list of host strings to be :ref:`skipped over ` +during ``fab`` execution. Typically set via :option:`--exclude-hosts/-x <-x>`. + +.. versionadded:: 1.1 + + +``fabfile`` +----------- + +**Default:** ``fabfile.py`` + +Filename pattern which ``fab`` searches for when loading fabfiles. +To indicate a specific file, use the full path to the file. Obviously, it +doesn't make sense to set this in a fabfile, but it may be specified in a +``.fabricrc`` file or on the command line. + +.. seealso:: :option:`--fabfile <-f>`, :doc:`fab` + + +.. _gateway: + +``gateway`` +----------- + +**Default:** ``None`` + +Enables SSH-driven gatewaying through the indicated host. The value should be a +normal Fabric host string as used in e.g. :ref:`env.host_string `. +When this is set, newly created connections will be set to route their SSH +traffic through the remote SSH daemon to the final destination. + +.. versionadded:: 1.5 + +.. seealso:: :option:`--gateway <-g>` + + +.. _host_string: + +``host_string`` +--------------- + +**Default:** ``None`` + +Defines the current user/host/port which Fabric will connect to when executing +`~fabric.operations.run`, `~fabric.operations.put` and so forth. This is set by +``fab`` when iterating over a previously set host list, and may also be +manually set when using Fabric as a library. + +.. seealso:: :doc:`execution` + + +.. _forward-agent: + +``forward_agent`` +-------------------- + +**Default:** ``False`` + +If ``True``, enables forwarding of your local SSH agent to the remote end. + +.. versionadded:: 1.4 + +.. seealso:: :option:`--forward-agent <-A>` + + +``host`` +-------- + +**Default:** ``None`` + +Set to the hostname part of ``env.host_string`` by ``fab``. For informational +purposes only. + +.. _hosts: + +``hosts`` +--------- + +**Default:** ``[]`` + +The global host list used when composing per-task host lists. + +.. seealso:: :option:`--hosts <-H>`, :doc:`execution` + +.. _keepalive: + +``keepalive`` +------------- + +**Default:** ``0`` (i.e. no keepalive) + +An integer specifying an SSH keepalive interval to use; basically maps to the +SSH config option ``ClientAliveInterval``. Useful if you find connections are +timing out due to meddlesome network hardware or what have you. + +.. seealso:: :option:`--keepalive` +.. versionadded:: 1.1 + + +.. _key: + +``key`` +---------------- + +**Default:** ``None`` + +A string, or file-like object, containing an SSH key; used during connection +authentication. + +.. note:: + The most common method for using SSH keys is to set :ref:`key-filename`. + +.. versionadded:: 1.7 + + +.. _key-filename: + +``key_filename`` +---------------- + +**Default:** ``None`` + +May be a string or list of strings, referencing file paths to SSH key files to +try when connecting. Passed through directly to the SSH layer. May be +set/appended to with :option:`-i`. + +.. seealso:: `Paramiko's documentation for SSHClient.connect() `_ + +.. _env-linewise: + +``linewise`` +------------ + +**Default:** ``False`` + +Forces buffering by line instead of by character/byte, typically when running +in parallel mode. May be activated via :option:`--linewise`. This option is +implied by :ref:`env.parallel ` -- even if ``linewise`` is False, +if ``parallel`` is True then linewise behavior will occur. + +.. seealso:: :ref:`linewise-output` + +.. versionadded:: 1.3 + + +.. _local-user: + +``local_user`` +-------------- + +A read-only value containing the local system username. This is the same value +as :ref:`user`'s initial value, but whereas :ref:`user` may be altered by CLI +arguments, Python code or specific host strings, :ref:`local-user` will always +contain the same value. + +.. _no_agent: + +``no_agent`` +------------ + +**Default:** ``False`` + +If ``True``, will tell the SSH layer not to seek out running SSH agents when +using key-based authentication. + +.. versionadded:: 0.9.1 +.. seealso:: :option:`--no_agent <-a>` + +.. _no_keys: + +``no_keys`` +------------------ + +**Default:** ``False`` + +If ``True``, will tell the SSH layer not to load any private key files from +one's ``$HOME/.ssh/`` folder. (Key files explicitly loaded via ``fab -i`` will +still be used, of course.) + +.. versionadded:: 0.9.1 +.. seealso:: :option:`-k` + +.. _env-parallel: + +``parallel`` +------------------- + +**Default:** ``False`` + +When ``True``, forces all tasks to run in parallel. Implies :ref:`env.linewise +`. + +.. versionadded:: 1.3 +.. seealso:: :option:`--parallel <-P>`, :doc:`parallel` + +.. _password: + +``password`` +------------ + +**Default:** ``None`` + +The default password used by the SSH layer when connecting to remote hosts, +**and/or** when answering `~fabric.operations.sudo` prompts. + +.. seealso:: :option:`--initial-password-prompt <-I>`, :ref:`env.passwords `, :ref:`password-management` + +.. _passwords: + +``passwords`` +------------- + +**Default:** ``{}`` + +This dictionary is largely for internal use, and is filled automatically as a +per-host-string password cache. Keys are full :ref:`host strings +` and values are passwords (strings). + +.. warning:: + If you modify or generate this dict manually, **you must use fully + qualified host strings** with user and port values. See the link above for + details on the host string API. + +.. seealso:: :ref:`password-management` + +.. versionadded:: 1.0 + + +.. _env-path: + +``path`` +-------- + +**Default:** ``''`` + +Used to set the ``$PATH`` shell environment variable when executing commands in +`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.local`. +It is recommended to use the `~fabric.context_managers.path` context manager +for managing this value instead of setting it directly. + +.. versionadded:: 1.0 + + +.. _pool-size: + +``pool_size`` +------------- + +**Default:** ``0`` + +Sets the number of concurrent processes to use when executing tasks in parallel. + +.. versionadded:: 1.3 +.. seealso:: :option:`--pool-size <-z>`, :doc:`parallel` + +.. _prompts: + +``prompts`` +------------- + +**Default:** ``{}`` + +The ``prompts`` dictionary allows users to control interactive prompts. If a +key in the dictionary is found in a command's standard output stream, Fabric +will automatically answer with the corresponding dictionary value. + +.. versionadded:: 1.9 + +.. _port: + +``port`` +-------- + +**Default:** ``None`` + +Set to the port part of ``env.host_string`` by ``fab`` when iterating over a +host list. May also be used to specify a default port. + +.. _real-fabfile: + +``real_fabfile`` +---------------- + +**Default:** ``None`` + +Set by ``fab`` with the path to the fabfile it has loaded up, if it got that +far. For informational purposes only. + +.. seealso:: :doc:`fab` + + +.. _remote-interrupt: + +``remote_interrupt`` +-------------------- + +**Default:** ``None`` + +Controls whether Ctrl-C triggers an interrupt remotely or is captured locally, +as follows: + +* ``None`` (the default): only `~fabric.operations.open_shell` will exhibit + remote interrupt behavior, and + `~fabric.operations.run`/`~fabric.operations.sudo` will capture interrupts + locally. +* ``False``: even `~fabric.operations.open_shell` captures locally. +* ``True``: all functions will send the interrupt to the remote end. + +.. versionadded:: 1.6 + + +.. _rcfile: + +``rcfile`` +---------- + +**Default:** ``$HOME/.fabricrc`` + +Path used when loading Fabric's local settings file. + +.. seealso:: :option:`--config <-c>`, :doc:`fab` + +.. _reject-unknown-hosts: + +``reject_unknown_hosts`` +------------------------ + +**Default:** ``False`` + +If ``True``, the SSH layer will raise an exception when connecting to hosts not +listed in the user's known-hosts file. + +.. seealso:: :option:`--reject-unknown-hosts <-r>`, :doc:`ssh` + +.. _system-known-hosts: + +``system_known_hosts`` +------------------------ + +**Default:** ``None`` + +If set, should be the path to a :file:`known_hosts` file. The SSH layer will +read this file before reading the user's known-hosts file. + +.. seealso:: :doc:`ssh` + +``roledefs`` +------------ + +**Default:** ``{}`` + +Dictionary defining role name to host list mappings. + +.. seealso:: :doc:`execution` + +.. _roles: + +``roles`` +--------- + +**Default:** ``[]`` + +The global role list used when composing per-task host lists. + +.. seealso:: :option:`--roles <-R>`, :doc:`execution` + +.. _shell: + +``shell`` +--------- + +**Default:** ``/bin/bash -l -c`` + +Value used as shell wrapper when executing commands with e.g. +`~fabric.operations.run`. Must be able to exist in the form `` +""`` -- e.g. the default uses Bash's ``-c`` option which +takes a command string as its value. + +.. seealso:: :option:`--shell <-s>`, + :ref:`FAQ on bash as default shell `, :doc:`execution` + +.. _skip-bad-hosts: + +``skip_bad_hosts`` +------------------ + +**Default:** ``False`` + +If ``True``, causes ``fab`` (or non-``fab`` use of `~fabric.tasks.execute`) to skip over hosts it can't connect to. + +.. versionadded:: 1.4 +.. seealso:: + :option:`--skip-bad-hosts`, :ref:`excluding-hosts`, :doc:`execution` + + +.. _skip-unknown-tasks: + +``skip_unknown_tasks`` +---------------------- + +**Default:** ``False`` + +If ``True``, causes ``fab`` (or non-``fab`` use of `~fabric.tasks.execute`) +to skip over tasks not found, without aborting. + +.. seealso:: + :option:`--skip-unknown-tasks` + + +.. _ssh-config-path: + +``ssh_config_path`` +------------------- + +**Default:** ``$HOME/.ssh/config`` + +Allows specification of an alternate SSH configuration file path. + +.. versionadded:: 1.4 +.. seealso:: :option:`--ssh-config-path`, :ref:`ssh-config` + +``ok_ret_codes`` +------------------------ + +**Default:** ``[0]`` + +Return codes in this list are used to determine whether calls to +`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.sudo` +are considered successful. + +.. versionadded:: 1.6 + +.. _sudo_prefix: + +``sudo_prefix`` +--------------- + +**Default:** ``"sudo -S -p '%(sudo_prompt)s' " % env`` + +The actual ``sudo`` command prefixed onto `~fabric.operations.sudo` calls' +command strings. Users who do not have ``sudo`` on their default remote +``$PATH``, or who need to make other changes (such as removing the ``-p`` when +passwordless sudo is in effect) may find changing this useful. + +.. seealso:: + + The `~fabric.operations.sudo` operation; :ref:`env.sudo_prompt + ` + +.. _sudo_prompt: + +``sudo_prompt`` +--------------- + +**Default:** ``"sudo password:"`` + +Passed to the ``sudo`` program on remote systems so that Fabric may correctly +identify its password prompt. + +.. seealso:: + + The `~fabric.operations.sudo` operation; :ref:`env.sudo_prefix + ` + +.. _sudo_user: + +``sudo_user`` +------------- + +**Default:** ``None`` + +Used as a fallback value for `~fabric.operations.sudo`'s ``user`` argument if +none is given. Useful in combination with `~fabric.context_managers.settings`. + +.. seealso:: `~fabric.operations.sudo` + +.. _env-tasks: + +``tasks`` +------------- + +**Default:** ``[]`` + +Set by ``fab`` to the full tasks list to be executed for the currently +executing command. For informational purposes only. + +.. seealso:: :doc:`execution` + +.. _timeout: + +``timeout`` +----------- + +**Default:** ``10`` + +Network connection timeout, in seconds. + +.. versionadded:: 1.4 +.. seealso:: :option:`--timeout`, :ref:`connection-attempts` + +``use_shell`` +------------- + +**Default:** ``True`` + +Global setting which acts like the ``shell`` argument to +`~fabric.operations.run`/`~fabric.operations.sudo`: if it is set to ``False``, +operations will not wrap executed commands in ``env.shell``. + + +.. _use-ssh-config: + +``use_ssh_config`` +------------------ + +**Default:** ``False`` + +Set to ``True`` to cause Fabric to load your local SSH config file. + +.. versionadded:: 1.4 +.. seealso:: :ref:`ssh-config` + + +.. _user: + +``user`` +-------- + +**Default:** User's local username + +The username used by the SSH layer when connecting to remote hosts. May be set +globally, and will be used when not otherwise explicitly set in host strings. +However, when explicitly given in such a manner, this variable will be +temporarily overwritten with the current value -- i.e. it will always display +the user currently being connected as. + +To illustrate this, a fabfile:: + + from fabric.api import env, run + + env.user = 'implicit_user' + env.hosts = ['host1', 'explicit_user@host2', 'host3'] + + def print_user(): + with hide('running'): + run('echo "%(user)s"' % env) + +and its use:: + + $ fab print_user + + [host1] out: implicit_user + [explicit_user@host2] out: explicit_user + [host3] out: implicit_user + + Done. + Disconnecting from host1... done. + Disconnecting from host2... done. + Disconnecting from host3... done. + +As you can see, during execution on ``host2``, ``env.user`` was set to +``"explicit_user"``, but was restored to its previous value +(``"implicit_user"``) afterwards. + +.. note:: + + ``env.user`` is currently somewhat confusing (it's used for configuration + **and** informational purposes) so expect this to change in the future -- + the informational aspect will likely be broken out into a separate env + variable. + +.. seealso:: :doc:`execution`, :option:`--user <-u>` + +``version`` +----------- + +**Default:** current Fabric version string + +Mostly for informational purposes. Modification is not recommended, but +probably won't break anything either. + +.. seealso:: :option:`--version <-V>` + +.. _warn_only: + +``warn_only`` +------------- + +**Default:** ``False`` + +Specifies whether or not to warn, instead of abort, when +`~fabric.operations.run`/`~fabric.operations.sudo`/`~fabric.operations.local` +encounter error conditions. + +.. seealso:: :option:`--warn-only <-w>`, :doc:`execution` diff -Nru fabric-1.8.2/sites/docs/usage/execution.rst fabric-1.10.0/sites/docs/usage/execution.rst --- fabric-1.8.2/sites/docs/usage/execution.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/execution.rst 2014-09-04 00:52:45.000000000 +0000 @@ -0,0 +1,864 @@ +=============== +Execution model +=============== + +If you've read the :doc:`../tutorial`, you should already be familiar with how +Fabric operates in the base case (a single task on a single host.) However, in +many situations you'll find yourself wanting to execute multiple tasks and/or +on multiple hosts. Perhaps you want to split a big task into smaller reusable +parts, or crawl a collection of servers looking for an old user to remove. Such +a scenario requires specific rules for when and how tasks are executed. + +This document explores Fabric's execution model, including the main execution +loop, how to define host lists, how connections are made, and so forth. + + +.. _execution-strategy: + +Execution strategy +================== + +Fabric defaults to a single, serial execution method, though there is an +alternative parallel mode available as of Fabric 1.3 (see +:doc:`/usage/parallel`). This default behavior is as follows: + +* A list of tasks is created. Currently this list is simply the arguments given + to :doc:`fab `, preserving the order given. +* For each task, a task-specific host list is generated from various + sources (see :ref:`host-lists` below for details.) +* The task list is walked through in order, and each task is run once per host + in its host list. +* Tasks with no hosts in their host list are considered local-only, and will + always run once and only once. + +Thus, given the following fabfile:: + + from fabric.api import run, env + + env.hosts = ['host1', 'host2'] + + def taskA(): + run('ls') + + def taskB(): + run('whoami') + +and the following invocation:: + + $ fab taskA taskB + +you will see that Fabric performs the following: + +* ``taskA`` executed on ``host1`` +* ``taskA`` executed on ``host2`` +* ``taskB`` executed on ``host1`` +* ``taskB`` executed on ``host2`` + +While this approach is simplistic, it allows for a straightforward composition +of task functions, and (unlike tools which push the multi-host functionality +down to the individual function calls) enables shell script-like logic where +you may introspect the output or return code of a given command and decide what +to do next. + + +Defining tasks +============== + +For details on what constitutes a Fabric task and how to organize them, please see :doc:`/usage/tasks`. + + +Defining host lists +=================== + +Unless you're using Fabric as a simple build system (which is possible, but not +the primary use-case) having tasks won't do you any good without the ability to +specify remote hosts on which to execute them. There are a number of ways to do +so, with scopes varying from global to per-task, and it's possible mix and +match as needed. + +.. _host-strings: + +Hosts +----- + +Hosts, in this context, refer to what are also called "host strings": Python +strings specifying a username, hostname and port combination, in the form of +``username@hostname:port``. User and/or port (and the associated ``@`` or +``:``) may be omitted, and will be filled by the executing user's local +username, and/or port 22, respectively. Thus, ``admin@foo.com:222``, +``deploy@website`` and ``nameserver1`` could all be valid host strings. + +IPv6 address notation is also supported, for example ``::1``, ``[::1]:1222``, +``user@2001:db8::1`` or ``user@[2001:db8::1]:1222``. Square brackets +are necessary only to separate the address from the port number. If no +port number is used, the brackets are optional. Also if host string is +specified via command-line argument, it may be necessary to escape +brackets in some shells. + +.. note:: + The user/hostname split occurs at the last ``@`` found, so e.g. email + address usernames are valid and will be parsed correctly. + +During execution, Fabric normalizes the host strings given and then stores each +part (username/hostname/port) in the environment dictionary, for both its use +and for tasks to reference if the need arises. See :doc:`env` for details. + +.. _execution-roles: + +Roles +----- + +Host strings map to single hosts, but sometimes it's useful to arrange hosts in +groups. Perhaps you have a number of Web servers behind a load balancer and +want to update all of them, or want to run a task on "all client servers". +Roles provide a way of defining strings which correspond to lists of host +strings, and can then be specified instead of writing out the entire list every +time. + +This mapping is defined as a dictionary, ``env.roledefs``, which must be +modified by a fabfile in order to be used. A simple example:: + + from fabric.api import env + + env.roledefs['webservers'] = ['www1', 'www2', 'www3'] + +Since ``env.roledefs`` is naturally empty by default, you may also opt to +re-assign to it without fear of losing any information (provided you aren't +loading other fabfiles which also modify it, of course):: + + from fabric.api import env + + env.roledefs = { + 'web': ['www1', 'www2', 'www3'], + 'dns': ['ns1', 'ns2'] + } + +Role definitions are not necessary configuration of hosts only, but could hold +other role specific settings of your choice. This is achieved by defining the +roles as dicts and host strings under a ``hosts`` key:: + + from fabric.api import env + + env.roledefs = { + 'web': { + 'hosts': ['www1', 'www2', 'www3'], + 'foo': 'bar' + }, + 'dns': { + 'hosts': ['ns1', 'ns2'], + 'foo': 'baz' + } + } + +In addition to list/iterable object types, the values in ``env.roledefs`` +(or value of ``hosts`` key in dict style definition) may be callables, and will +thus be called when looked up when tasks are run instead of at module load +time. (For example, you could connect to remote servers to obtain role +definitions, and not worry about causing delays at fabfile load time when +calling e.g. ``fab --list``.) + +Use of roles is not required in any way -- it's simply a convenience in +situations where you have common groupings of servers. + +.. versionchanged:: 0.9.2 + Added ability to use callables as ``roledefs`` values. + +.. _host-lists: + +How host lists are constructed +------------------------------ + +There are a number of ways to specify host lists, either globally or per-task, +and generally these methods override one another instead of merging together +(though this may change in future releases.) Each such method is typically +split into two parts, one for hosts and one for roles. + +Globally, via ``env`` +~~~~~~~~~~~~~~~~~~~~~ + +The most common method of setting hosts or roles is by modifying two key-value +pairs in the environment dictionary, :doc:`env `: ``hosts`` and ``roles``. +The value of these variables is checked at runtime, while constructing each +tasks's host list. + +Thus, they may be set at module level, which will take effect when the fabfile +is imported:: + + from fabric.api import env, run + + env.hosts = ['host1', 'host2'] + + def mytask(): + run('ls /var/www') + +Such a fabfile, run simply as ``fab mytask``, will run ``mytask`` on ``host1`` +followed by ``host2``. + +Since the env vars are checked for *each* task, this means that if you have the +need, you can actually modify ``env`` in one task and it will affect all +following tasks:: + + from fabric.api import env, run + + def set_hosts(): + env.hosts = ['host1', 'host2'] + + def mytask(): + run('ls /var/www') + +When run as ``fab set_hosts mytask``, ``set_hosts`` is a "local" task -- its +own host list is empty -- but ``mytask`` will again run on the two hosts given. + +.. note:: + + This technique used to be a common way of creating fake "roles", but is + less necessary now that roles are fully implemented. It may still be useful + in some situations, however. + +Alongside ``env.hosts`` is ``env.roles`` (not to be confused with +``env.roledefs``!) which, if given, will be taken as a list of role names to +look up in ``env.roledefs``. + +Globally, via the command line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to modifying ``env.hosts``, ``env.roles``, and +``env.exclude_hosts`` at the module level, you may define them by passing +comma-separated string arguments to the command-line switches +:option:`--hosts/-H <-H>` and :option:`--roles/-R <-R>`, e.g.:: + + $ fab -H host1,host2 mytask + +Such an invocation is directly equivalent to ``env.hosts = ['host1', 'host2']`` +-- the argument parser knows to look for these arguments and will modify +``env`` at parse time. + +.. note:: + + It's possible, and in fact common, to use these switches to set only a + single host or role. Fabric simply calls ``string.split(',')`` on the given + string, so a string with no commas turns into a single-item list. + +It is important to know that these command-line switches are interpreted +**before** your fabfile is loaded: any reassignment to ``env.hosts`` or +``env.roles`` in your fabfile will overwrite them. + +If you wish to nondestructively merge the command-line hosts with your +fabfile-defined ones, make sure your fabfile uses ``env.hosts.extend()`` +instead:: + + from fabric.api import env, run + + env.hosts.extend(['host3', 'host4']) + + def mytask(): + run('ls /var/www') + +When this fabfile is run as ``fab -H host1,host2 mytask``, ``env.hosts`` will +then contain ``['host1', 'host2', 'host3', 'host4']`` at the time that +``mytask`` is executed. + +.. note:: + + ``env.hosts`` is simply a Python list object -- so you may use + ``env.hosts.append()`` or any other such method you wish. + +.. _hosts-per-task-cli: + +Per-task, via the command line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Globally setting host lists only works if you want all your tasks to run on the +same host list all the time. This isn't always true, so Fabric provides a few +ways to be more granular and specify host lists which apply to a single task +only. The first of these uses task arguments. + +As outlined in :doc:`fab`, it's possible to specify per-task arguments via a +special command-line syntax. In addition to naming actual arguments to your +task function, this may be used to set the ``host``, ``hosts``, ``role`` or +``roles`` "arguments", which are interpreted by Fabric when building host lists +(and removed from the arguments passed to the task itself.) + +.. note:: + + Since commas are already used to separate task arguments from one another, + semicolons must be used in the ``hosts`` or ``roles`` arguments to + delineate individual host strings or role names. Furthermore, the argument + must be quoted to prevent your shell from interpreting the semicolons. + +Take the below fabfile, which is the same one we've been using, but which +doesn't define any host info at all:: + + from fabric.api import run + + def mytask(): + run('ls /var/www') + +To specify per-task hosts for ``mytask``, execute it like so:: + + $ fab mytask:hosts="host1;host2" + +This will override any other host list and ensure ``mytask`` always runs on +just those two hosts. + +Per-task, via decorators +~~~~~~~~~~~~~~~~~~~~~~~~ + +If a given task should always run on a predetermined host list, you may wish to +specify this in your fabfile itself. This can be done by decorating a task +function with the `~fabric.decorators.hosts` or `~fabric.decorators.roles` +decorators. These decorators take a variable argument list, like so:: + + from fabric.api import hosts, run + + @hosts('host1', 'host2') + def mytask(): + run('ls /var/www') + +They will also take an single iterable argument, e.g.:: + + my_hosts = ('host1', 'host2') + @hosts(my_hosts) + def mytask(): + # ... + +When used, these decorators override any checks of ``env`` for that particular +task's host list (though ``env`` is not modified in any way -- it is simply +ignored.) Thus, even if the above fabfile had defined ``env.hosts`` or the call +to :doc:`fab ` uses :option:`--hosts/-H <-H>`, ``mytask`` would still run +on a host list of ``['host1', 'host2']``. + +However, decorator host lists do **not** override per-task command-line +arguments, as given in the previous section. + +Order of precedence +~~~~~~~~~~~~~~~~~~~ + +We've been pointing out which methods of setting host lists trump the others, +as we've gone along. However, to make things clearer, here's a quick breakdown: + +* Per-task, command-line host lists (``fab mytask:host=host1``) override + absolutely everything else. +* Per-task, decorator-specified host lists (``@hosts('host1')``) override the + ``env`` variables. +* Globally specified host lists set in the fabfile (``env.hosts = ['host1']``) + *can* override such lists set on the command-line, but only if you're not + careful (or want them to.) +* Globally specified host lists set on the command-line (``--hosts=host1``) + will initialize the ``env`` variables, but that's it. + +This logic may change slightly in the future to be more consistent (e.g. +having :option:`--hosts <-H>` somehow take precedence over ``env.hosts`` in the +same way that command-line per-task lists trump in-code ones) but only in a +backwards-incompatible release. + +.. _combining-host-lists: + +Combining host lists +-------------------- + +There is no "unionizing" of hosts between the various sources mentioned in +:ref:`host-lists`. If ``env.hosts`` is set to ``['host1', 'host2', 'host3']``, +and a per-function (e.g. via `~fabric.decorators.hosts`) host list is set to +just ``['host2', 'host3']``, that function will **not** execute on ``host1``, +because the per-task decorator host list takes precedence. + +However, for each given source, if both roles **and** hosts are specified, they +will be merged together into a single host list. Take, for example, this +fabfile where both of the decorators are used:: + + from fabric.api import env, hosts, roles, run + + env.roledefs = {'role1': ['b', 'c']} + + @hosts('a', 'b') + @roles('role1') + def mytask(): + run('ls /var/www') + +Assuming no command-line hosts or roles are given when ``mytask`` is executed, +this fabfile will call ``mytask`` on a host list of ``['a', 'b', 'c']`` -- the +union of ``role1`` and the contents of the `~fabric.decorators.hosts` call. + + +.. _deduplication: + +Host list deduplication +----------------------- + +By default, to support :ref:`combining-host-lists`, Fabric deduplicates the +final host list so any given host string is only present once. However, this +prevents explicit/intentional running of a task multiple times on the same +target host, which is sometimes useful. + +To turn off deduplication, set :ref:`env.dedupe_hosts ` to +``False``. + + +.. _excluding-hosts: + +Excluding specific hosts +------------------------ + +At times, it is useful to exclude one or more specific hosts, e.g. to override +a few bad or otherwise undesirable hosts which are pulled in from a role or an +autogenerated host list. + +.. note:: + As of Fabric 1.4, you may wish to use :ref:`skip-bad-hosts` instead, which + automatically skips over any unreachable hosts. + +Host exclusion may be accomplished globally with :option:`--exclude-hosts/-x +<-x>`:: + + $ fab -R myrole -x host2,host5 mytask + +If ``myrole`` was defined as ``['host1', 'host2', ..., 'host15']``, the above +invocation would run with an effective host list of ``['host1', 'host3', +'host4', 'host6', ..., 'host15']``. + + .. note:: + Using this option does not modify ``env.hosts`` -- it only causes the + main execution loop to skip the requested hosts. + +Exclusions may be specified per-task by using an extra ``exclude_hosts`` kwarg, +which is implemented similarly to the abovementioned ``hosts`` and ``roles`` +per-task kwargs, in that it is stripped from the actual task invocation. This +example would have the same result as the global exclude above:: + + $ fab mytask:roles=myrole,exclude_hosts="host2;host5" + +Note that the host list is semicolon-separated, just as with the ``hosts`` +per-task argument. + +Combining exclusions +~~~~~~~~~~~~~~~~~~~~ + +Host exclusion lists, like host lists themselves, are not merged together +across the different "levels" they can be declared in. For example, a global +``-x`` option will not affect a per-task host list set with a decorator or +keyword argument, nor will per-task ``exclude_hosts`` keyword arguments affect +a global ``-H`` list. + +There is one minor exception to this rule, namely that CLI-level keyword +arguments (``mytask:exclude_hosts=x,y``) **will** be taken into account when +examining host lists set via ``@hosts`` or ``@roles``. Thus a task function +decorated with ``@hosts('host1', 'host2')`` executed as ``fab +taskname:exclude_hosts=host2`` will only run on ``host1``. + +As with the host list merging, this functionality is currently limited (partly +to keep the implementation simple) and may be expanded in future releases. + + +.. _execute: + +Intelligently executing tasks with ``execute`` +============================================== + +.. versionadded:: 1.3 + +Most of the information here involves "top level" tasks executed via :doc:`fab +`, such as the first example where we called ``fab taskA taskB``. +However, it's often convenient to wrap up multi-task invocations like this into +their own, "meta" tasks. + +Prior to Fabric 1.3, this had to be done by hand, as outlined in +:doc:`/usage/library`. Fabric's design eschews magical behavior, so simply +*calling* a task function does **not** take into account decorators such as +`~fabric.decorators.roles`. + +New in Fabric 1.3 is the `~fabric.tasks.execute` helper function, which takes a +task object or name as its first argument. Using it is effectively the same as +calling the given task from the command line: all the rules given above in +:ref:`host-lists` apply. (The ``hosts`` and ``roles`` keyword arguments to +`~fabric.tasks.execute` are analogous to :ref:`CLI per-task arguments +`, including how they override all other host/role-setting +methods.) + +As an example, here's a fabfile defining two stand-alone tasks for deploying a +Web application:: + + from fabric.api import run, roles + + env.roledefs = { + 'db': ['db1', 'db2'], + 'web': ['web1', 'web2', 'web3'], + } + + @roles('db') + def migrate(): + # Database stuff here. + pass + + @roles('web') + def update(): + # Code updates here. + pass + +In Fabric <=1.2, the only way to ensure that ``migrate`` runs on the DB servers +and that ``update`` runs on the Web servers (short of manual +``env.host_string`` manipulation) was to call both as top level tasks:: + + $ fab migrate update + +Fabric >=1.3 can use `~fabric.tasks.execute` to set up a meta-task. Update the +``import`` line like so:: + + from fabric.api import run, roles, execute + +and append this to the bottom of the file:: + + def deploy(): + execute(migrate) + execute(update) + +That's all there is to it; the `~fabric.decorators.roles` decorators will be honored as expected, resulting in the following execution sequence: + +* `migrate` on `db1` +* `migrate` on `db2` +* `update` on `web1` +* `update` on `web2` +* `update` on `web3` + +.. warning:: + This technique works because tasks that themselves have no host list (this + includes the global host list settings) only run one time. If used inside a + "regular" task that is going to run on multiple hosts, calls to + `~fabric.tasks.execute` will also run multiple times, resulting in + multiplicative numbers of subtask calls -- be careful! + + If you would like your `execute` calls to only be called once, you + may use the `~fabric.decorators.runs_once` decorator. + +.. seealso:: `~fabric.tasks.execute`, `~fabric.decorators.runs_once` + + +.. _leveraging-execute-return-value: + +Leveraging ``execute`` to access multi-host results +--------------------------------------------------- + +In nontrivial Fabric runs, especially parallel ones, you may want to gather up +a bunch of per-host result values at the end - e.g. to present a summary table, +perform calculations, etc. + +It's not possible to do this in Fabric's default "naive" mode (one where you +rely on Fabric looping over host lists on your behalf), but with `.execute` +it's pretty easy. Simply switch from calling the actual work-bearing task, to +calling a "meta" task which takes control of execution with `.execute`:: + + from fabric.api import task, execute, run, runs_once + + @task + def workhorse(): + return run("get my infos") + + @task + @runs_once + def go(): + results = execute(workhorse) + print results + +In the above, ``workhorse`` can do any Fabric stuff at all -- it's literally +your old "naive" task -- except that it needs to return something useful. + +``go`` is your new entry point (to be invoked as ``fab go``, or whatnot) and +its job is to take the ``results`` dictionary from the `.execute` call and do +whatever you need with it. Check the API docs for details on the structure of +that return value. + + +.. _dynamic-hosts: + +Using ``execute`` with dynamically-set host lists +------------------------------------------------- + +A common intermediate-to-advanced use case for Fabric is to parameterize lookup +of one's target host list at runtime (when use of :ref:`execution-roles` does not +suffice). ``execute`` can make this extremely simple, like so:: + + from fabric.api import run, execute, task + + # For example, code talking to an HTTP API, or a database, or ... + from mylib import external_datastore + + # This is the actual algorithm involved. It does not care about host + # lists at all. + def do_work(): + run("something interesting on a host") + + # This is the user-facing task invoked on the command line. + @task + def deploy(lookup_param): + # This is the magic you don't get with @hosts or @roles. + # Even lazy-loading roles require you to declare available roles + # beforehand. Here, the sky is the limit. + host_list = external_datastore.query(lookup_param) + # Put this dynamically generated host list together with the work to be + # done. + execute(do_work, hosts=host_list) + +For example, if ``external_datastore`` was a simplistic "look up hosts by tag +in a database" service, and you wanted to run a task on all hosts tagged as +being related to your application stack, you might call the above like this:: + + $ fab deploy:app + +But wait! A data migration has gone awry on the DB servers. Let's fix up our +migration code in our source repo, and deploy just the DB boxes again:: + + $ fab deploy:db + +This use case looks similar to Fabric's roles, but has much more potential, and +is by no means limited to a single argument. Define the task however you wish, +query your external data store in whatever way you need -- it's just Python. + +The alternate approach +~~~~~~~~~~~~~~~~~~~~~~ + +Similar to the above, but using ``fab``'s ability to call multiple tasks in +succession instead of an explicit ``execute`` call, is to mutate +:ref:`env.hosts ` in a host-list lookup task and then call ``do_work`` +in the same session:: + + from fabric.api import run, task + + from mylib import external_datastore + + # Marked as a publicly visible task, but otherwise unchanged: still just + # "do the work, let somebody else worry about what hosts to run on". + @task + def do_work(): + run("something interesting on a host") + + @task + def set_hosts(lookup_param): + # Update env.hosts instead of calling execute() + env.hosts = external_datastore.query(lookup_param) + +Then invoke like so:: + + $ fab set_hosts:app do_work + +One benefit of this approach over the previous one is that you can replace +``do_work`` with any other "workhorse" task:: + + $ fab set_hosts:db snapshot + $ fab set_hosts:cassandra,cluster2 repair_ring + $ fab set_hosts:redis,environ=prod status + + +.. _failures: + +Failure handling +================ + +Once the task list has been constructed, Fabric will start executing them as +outlined in :ref:`execution-strategy`, until all tasks have been run on the +entirety of their host lists. However, Fabric defaults to a "fail-fast" +behavior pattern: if anything goes wrong, such as a remote program returning a +nonzero return value or your fabfile's Python code encountering an exception, +execution will halt immediately. + +This is typically the desired behavior, but there are many exceptions to the +rule, so Fabric provides ``env.warn_only``, a Boolean setting. It defaults to +``False``, meaning an error condition will result in the program aborting +immediately. However, if ``env.warn_only`` is set to ``True`` at the time of +failure -- with, say, the `~fabric.context_managers.settings` context +manager -- Fabric will emit a warning message but continue executing. + + +.. _connections: + +Connections +=========== + +``fab`` itself doesn't actually make any connections to remote hosts. Instead, +it simply ensures that for each distinct run of a task on one of its hosts, the +env var ``env.host_string`` is set to the right value. Users wanting to +leverage Fabric as a library may do so manually to achieve similar effects +(though as of Fabric 1.3, using `~fabric.tasks.execute` is preferred and more +powerful.) + +``env.host_string`` is (as the name implies) the "current" host string, and is +what Fabric uses to determine what connections to make (or re-use) when +network-aware functions are run. Operations like `~fabric.operations.run` or +`~fabric.operations.put` use ``env.host_string`` as a lookup key in a shared +dictionary which maps host strings to SSH connection objects. + +.. note:: + + The connections dictionary (currently located at + ``fabric.state.connections``) acts as a cache, opting to return previously + created connections if possible in order to save some overhead, and + creating new ones otherwise. + +Lazy connections +---------------- + +Because connections are driven by the individual operations, Fabric will not +actually make connections until they're necessary. Take for example this task +which does some local housekeeping prior to interacting with the remote +server:: + + from fabric.api import * + + @hosts('host1') + def clean_and_upload(): + local('find assets/ -name "*.DS_Store" -exec rm '{}' \;') + local('tar czf /tmp/assets.tgz assets/') + put('/tmp/assets.tgz', '/tmp/assets.tgz') + with cd('/var/www/myapp/'): + run('tar xzf /tmp/assets.tgz') + +What happens, connection-wise, is as follows: + +#. The two `~fabric.operations.local` calls will run without making any network + connections whatsoever; +#. `~fabric.operations.put` asks the connection cache for a connection to + ``host1``; +#. The connection cache fails to find an existing connection for that host + string, and so creates a new SSH connection, returning it to + `~fabric.operations.put`; +#. `~fabric.operations.put` uploads the file through that connection; +#. Finally, the `~fabric.operations.run` call asks the cache for a connection + to that same host string, and is given the existing, cached connection for + its own use. + +Extrapolating from this, you can also see that tasks which don't use any +network-borne operations will never actually initiate any connections (though +they will still be run once for each host in their host list, if any.) + +Closing connections +------------------- + +Fabric's connection cache never closes connections itself -- it leaves this up +to whatever is using it. The :doc:`fab ` tool does this bookkeeping for +you: it iterates over all open connections and closes them just before it exits +(regardless of whether the tasks failed or not.) + +Library users will need to ensure they explicitly close all open connections +before their program exits. This can be accomplished by calling +`~fabric.network.disconnect_all` at the end of your script. + +.. note:: + `~fabric.network.disconnect_all` may be moved to a more public location in + the future; we're still working on making the library aspects of Fabric + more solidified and organized. + +Multiple connection attempts and skipping bad hosts +--------------------------------------------------- + +As of Fabric 1.4, multiple attempts may be made to connect to remote servers +before aborting with an error: Fabric will try connecting +:ref:`env.connection_attempts ` times before giving up, +with a timeout of :ref:`env.timeout ` seconds each time. (These +currently default to 1 try and 10 seconds, to match previous behavior, but they +may be safely changed to whatever you need.) + +Furthermore, even total failure to connect to a server is no longer an absolute +hard stop: set :ref:`env.skip_bad_hosts ` to ``True`` and in +most situations (typically initial connections) Fabric will simply warn and +continue, instead of aborting. + +.. versionadded:: 1.4 + +.. _password-management: + +Password management +=================== + +Fabric maintains an in-memory, two-tier password cache to help remember your +login and sudo passwords in certain situations; this helps avoid tedious +re-entry when multiple systems share the same password [#]_, or if a remote +system's ``sudo`` configuration doesn't do its own caching. + +The first layer is a simple default or fallback password cache, +:ref:`env.password ` (which may also be set at the command line via +:option:`--password <-p>` or :option:`--initial-password-prompt <-I>`). This +env var stores a single password which (if non-empty) will be tried in the +event that the host-specific cache (see below) has no entry for the current +:ref:`host string `. + +:ref:`env.passwords ` (plural!) serves as a per-user/per-host cache, +storing the most recently entered password for every unique user/host/port +combination (**note** that you must include **all three values** if modifying +the structure by hand - see the above link for details). Due to this cache, +connections to multiple different users and/or hosts in the same session will +only require a single password entry for each. (Previous versions of Fabric +used only the single, default password cache and thus required password +re-entry every time the previously entered password became invalid.) + +Depending on your configuration and the number of hosts your session will +connect to, you may find setting either or both of these env vars to be useful. +However, Fabric will automatically fill them in as necessary without any +additional configuration. + +Specifically, each time a password prompt is presented to the user, the value +entered is used to update both the single default password cache, and the cache +value for the current value of ``env.host_string``. + +.. [#] We highly recommend the use of SSH `key-based access + `_ instead of relying on + homogeneous password setups, as it's significantly more secure. + + +.. _ssh-config: + +Leveraging native SSH config files +================================== + +Command-line SSH clients (such as the one provided by `OpenSSH +`_) make use of a specific configuration format typically +known as ``ssh_config``, and will read from a file in the platform-specific +location ``$HOME/.ssh/config`` (or an arbitrary path given to +:option:`--ssh-config-path`/:ref:`env.ssh_config_path `.) This +file allows specification of various SSH options such as default or per-host +usernames, hostname aliases, and toggling other settings (such as whether to +use :ref:`agent forwarding `.) + +Fabric's SSH implementation allows loading a subset of these options from one's +actual SSH config file, should it exist. This behavior is not enabled by +default (in order to be backwards compatible) but may be turned on by setting +:ref:`env.use_ssh_config ` to ``True`` at the top of your +fabfile. + +If enabled, the following SSH config directives will be loaded and honored by Fabric: + +* ``User`` and ``Port`` will be used to fill in the appropriate connection + parameters when not otherwise specified, in the following fashion: + + * Globally specified ``User``/``Port`` will be used in place of the current + defaults (local username and 22, respectively) if the appropriate env vars + are not set. + * However, if :ref:`env.user `/:ref:`env.port ` *are* set, they + override global ``User``/``Port`` values. + * User/port values in the host string itself (e.g. ``hostname:222``) will + override everything, including any ``ssh_config`` values. +* ``HostName`` can be used to replace the given hostname, just like with + regular ``ssh``. So a ``Host foo`` entry specifying ``HostName example.com`` + will allow you to give Fabric the hostname ``'foo'`` and have that expanded + into ``'example.com'`` at connection time. +* ``IdentityFile`` will extend (not replace) :ref:`env.key_filename + `. +* ``ForwardAgent`` will augment :ref:`env.forward_agent ` in an + "OR" manner: if either is set to a positive value, agent forwarding will be + enabled. +* ``ProxyCommand`` will trigger use of a proxy command for host connections, + just as with regular ``ssh``. + + .. note:: + If all you want to do is bounce SSH traffic off a gateway, you may find + :ref:`env.gateway ` to be a more efficient connection method + (which will also honor more Fabric-level settings) than the typical ``ssh + gatewayhost nc %h %p`` method of using ``ProxyCommand`` as a gateway. + + .. note:: + If your SSH config file contains ``ProxyCommand`` directives *and* you have + set :ref:`env.gateway ` to a non-``None`` value, ``env.gateway`` + will take precedence and the ``ProxyCommand`` will be ignored. + + If one has a pre-created SSH config file, rationale states it will be + easier for you to modify ``env.gateway`` (e.g. via + `~fabric.context_managers.settings`) than to work around your conf file's + contents entirely. diff -Nru fabric-1.8.2/sites/docs/usage/fabfiles.rst fabric-1.10.0/sites/docs/usage/fabfiles.rst --- fabric-1.8.2/sites/docs/usage/fabfiles.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/fabfiles.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,92 @@ +============================ +Fabfile construction and use +============================ + +This document contains miscellaneous sections about fabfiles, both how to best +write them, and how to use them once written. + +.. _fabfile-discovery: + +Fabfile discovery +================= + +Fabric is capable of loading Python modules (e.g. ``fabfile.py``) or packages +(e.g. a ``fabfile/`` directory containing an ``__init__.py``). By default, it +looks for something named (to Python's import machinery) ``fabfile`` - so +either ``fabfile/`` or ``fabfile.py``. + +The fabfile discovery algorithm searches in the invoking user's current working +directory or any parent directories. Thus, it is oriented around "project" use, +where one keeps e.g. a ``fabfile.py`` at the root of a source code tree. Such a +fabfile will then be discovered no matter where in the tree the user invokes +``fab``. + +The specific name to be searched for may be overridden on the command-line with +the :option:`-f` option, or by adding a :ref:`fabricrc ` line which +sets the value of ``fabfile``. For example, if you wanted to name your fabfile +``fab_tasks.py``, you could create such a file and then call ``fab -f +fab_tasks.py ``, or add ``fabfile = fab_tasks.py`` to +``~/.fabricrc``. + +If the given fabfile name contains path elements other than a filename (e.g. +``../fabfile.py`` or ``/dir1/dir2/custom_fabfile``) it will be treated as a +file path and directly checked for existence without any sort of searching. +When in this mode, tilde-expansion will be applied, so one may refer to e.g. +``~/personal_fabfile.py``. + +.. note:: + + Fabric does a normal ``import`` (actually an ``__import__``) of your + fabfile in order to access its contents -- it does not do any ``eval``-ing + or similar. In order for this to work, Fabric temporarily adds the found + fabfile's containing folder to the Python load path (and removes it + immediately afterwards.) + +.. versionchanged:: 0.9.2 + The ability to load package fabfiles. + + +.. _importing-the-api: + +Importing Fabric +================ + +Because Fabric is just Python, you *can* import its components any way you +want. However, for the purposes of encapsulation and convenience (and to make +life easier for Fabric's packaging script) Fabric's public API is maintained in +the ``fabric.api`` module. + +All of Fabric's :doc:`../api/core/operations`, +:doc:`../api/core/context_managers`, :doc:`../api/core/decorators` and +:doc:`../api/core/utils` are included in this module as a single, flat +namespace. This enables a very simple and consistent interface to Fabric within +your fabfiles:: + + from fabric.api import * + + # call run(), sudo(), etc etc + +This is not technically best practices (for `a +number of reasons`_) and if you're only using a couple of +Fab API calls, it *is* probably a good idea to explicitly ``from fabric.api +import env, run`` or similar. However, in most nontrivial fabfiles, you'll be +using all or most of the API, and the star import:: + + from fabric.api import * + +will be a lot easier to write and read than:: + + from fabric.api import abort, cd, env, get, hide, hosts, local, prompt, \ + put, require, roles, run, runs_once, settings, show, sudo, warn + +so in this case we feel pragmatism overrides best practices. + +.. _a number of reasons: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#importing + + +Defining tasks and importing callables +====================================== + +For important information on what exactly Fabric will consider as a task when +it loads your fabfile, as well as notes on how best to import other code, +please see :doc:`/usage/tasks` in the :doc:`execution` documentation. diff -Nru fabric-1.8.2/sites/docs/usage/fab.rst fabric-1.10.0/sites/docs/usage/fab.rst --- fabric-1.8.2/sites/docs/usage/fab.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/fab.rst 2014-09-04 00:52:45.000000000 +0000 @@ -0,0 +1,490 @@ +============================= +``fab`` options and arguments +============================= + +The most common method for utilizing Fabric is via its command-line tool, +``fab``, which should have been placed on your shell's executable path when +Fabric was installed. ``fab`` tries hard to be a good Unix citizen, using a +standard style of command-line switches, help output, and so forth. + + +Basic use +========= + +In its most simple form, ``fab`` may be called with no options at all, and +with one or more arguments, which should be task names, e.g.:: + + $ fab task1 task2 + +As detailed in :doc:`../tutorial` and :doc:`execution`, this will run ``task1`` +followed by ``task2``, assuming that Fabric was able to find a fabfile nearby +containing Python functions with those names. + +However, it's possible to expand this simple usage into something more +flexible, by using the provided options and/or passing arguments to individual +tasks. + + +.. _arbitrary-commands: + +Arbitrary remote shell commands +=============================== + +.. versionadded:: 0.9.2 + +Fabric leverages a lesser-known command line convention and may be called in +the following manner:: + + $ fab [options] -- [shell command] + +where everything after the ``--`` is turned into a temporary +`~fabric.operations.run` call, and is not parsed for ``fab`` options. If you've +defined a host list at the module level or on the command line, this usage will +act like a one-line anonymous task. + +For example, let's say you just wanted to get the kernel info for a bunch of +systems; you could do this:: + + $ fab -H system1,system2,system3 -- uname -a + +which would be literally equivalent to the following fabfile:: + + from fabric.api import run + + def anonymous(): + run("uname -a") + +as if it were executed thusly:: + + $ fab -H system1,system2,system3 anonymous + +Most of the time you will want to just write out the task in your fabfile +(anything you use once, you're likely to use again) but this feature provides a +handy, fast way to quickly dash off an SSH-borne command while leveraging your +fabfile's connection settings. + + +.. _command-line-options: + +Command-line options +==================== + +A quick overview of all possible command line options can be found via ``fab +--help``. If you're looking for details on a specific option, we go into detail +below. + +.. note:: + + ``fab`` uses Python's `optparse`_ library, meaning that it honors typical + Linux or GNU style short and long options, as well as freely mixing options + and arguments. E.g. ``fab task1 -H hostname task2 -i path/to/keyfile`` is + just as valid as the more straightforward ``fab -H hostname -i + path/to/keyfile task1 task2``. + +.. _optparse: http://docs.python.org/library/optparse.html + +.. cmdoption:: -a, --no_agent + + Sets :ref:`env.no_agent ` to ``True``, forcing our SSH layer not + to talk to the SSH agent when trying to unlock private key files. + + .. versionadded:: 0.9.1 + +.. cmdoption:: -A, --forward-agent + + Sets :ref:`env.forward_agent ` to ``True``, enabling agent + forwarding. + + .. versionadded:: 1.4 + +.. cmdoption:: --abort-on-prompts + + Sets :ref:`env.abort_on_prompts ` to ``True``, forcing + Fabric to abort whenever it would prompt for input. + + .. versionadded:: 1.1 + +.. cmdoption:: -c RCFILE, --config=RCFILE + + Sets :ref:`env.rcfile ` to the given file path, which Fabric will + try to load on startup and use to update environment variables. + +.. cmdoption:: -d COMMAND, --display=COMMAND + + Prints the entire docstring for the given task, if there is one. Does not + currently print out the task's function signature, so descriptive + docstrings are a good idea. (They're *always* a good idea, of course -- + just moreso here.) + +.. cmdoption:: --connection-attempts=M, -n M + + Set number of times to attempt connections. Sets + :ref:`env.connection_attempts `. + + .. seealso:: + :ref:`env.connection_attempts `, + :ref:`env.timeout ` + .. versionadded:: 1.4 + +.. cmdoption:: -D, --disable-known-hosts + + Sets :ref:`env.disable_known_hosts ` to ``True``, + preventing Fabric from loading the user's SSH :file:`known_hosts` file. + +.. cmdoption:: -f FABFILE, --fabfile=FABFILE + + The fabfile name pattern to search for (defaults to ``fabfile.py``), or + alternately an explicit file path to load as the fabfile (e.g. + ``/path/to/my/fabfile.py``.) + + .. seealso:: :doc:`fabfiles` + +.. cmdoption:: -F LIST_FORMAT, --list-format=LIST_FORMAT + + Allows control over the output format of :option:`--list <-l>`. ``short`` is + equivalent to :option:`--shortlist`, ``normal`` is the same as simply + omitting this option entirely (i.e. the default), and ``nested`` prints out + a nested namespace tree. + + .. versionadded:: 1.1 + .. seealso:: :option:`--shortlist`, :option:`--list <-l>` + +.. cmdoption:: -g HOST, --gateway=HOST + + Sets :ref:`env.gateway ` to ``HOST`` host string. + + .. versionadded:: 1.5 + +.. cmdoption:: -h, --help + + Displays a standard help message, with all possible options and a brief + overview of what they do, then exits. + +.. cmdoption:: --hide=LEVELS + + A comma-separated list of :doc:`output levels ` to hide by + default. + + +.. cmdoption:: -H HOSTS, --hosts=HOSTS + + Sets :ref:`env.hosts ` to the given comma-delimited list of host + strings. + +.. cmdoption:: -x HOSTS, --exclude-hosts=HOSTS + + Sets :ref:`env.exclude_hosts ` to the given comma-delimited + list of host strings to then keep out of the final host list. + + .. versionadded:: 1.1 + +.. cmdoption:: -i KEY_FILENAME + + When set to a file path, will load the given file as an SSH identity file + (usually a private key.) This option may be repeated multiple times. Sets + (or appends to) :ref:`env.key_filename `. + +.. cmdoption:: -I, --initial-password-prompt + + Forces a password prompt at the start of the session (after fabfile load + and option parsing, but before executing any tasks) in order to pre-fill + :ref:`env.password `. + + This is useful for fire-and-forget runs (especially parallel sessions, in + which runtime input is not possible) when setting the password via + :option:`--password <-p>` or by setting :ref:`env.password ` in + your fabfile, is undesirable. + + .. note:: The value entered into this prompt will *overwrite* anything + supplied via :ref:`env.password ` at module level, or via + :option:`--password <-p>`. + + .. seealso:: :ref:`password-management` + +.. cmdoption:: -k + + Sets :ref:`env.no_keys ` to ``True``, forcing the SSH layer to not + look for SSH private key files in one's home directory. + + .. versionadded:: 0.9.1 + +.. cmdoption:: --keepalive=KEEPALIVE + + Sets :ref:`env.keepalive ` to the given (integer) value, specifying an SSH keepalive interval. + + .. versionadded:: 1.1 + +.. cmdoption:: --linewise + + Forces output to be buffered line-by-line instead of byte-by-byte. Often useful or required for :ref:`parallel execution `. + + .. versionadded:: 1.3 + +.. cmdoption:: -l, --list + + Imports a fabfile as normal, but then prints a list of all discovered tasks + and exits. Will also print the first line of each task's docstring, if it + has one, next to it (truncating if necessary.) + + .. versionchanged:: 0.9.1 + Added docstring to output. + .. seealso:: :option:`--shortlist`, :option:`--list-format <-F>` + +.. cmdoption:: -p PASSWORD, --password=PASSWORD + + Sets :ref:`env.password ` to the given string; it will then be + used as the default password when making SSH connections or calling the + ``sudo`` program. + + .. seealso:: :option:`--initial-password-prompt <-I>` + +.. cmdoption:: -P, --parallel + + Sets :ref:`env.parallel ` to ``True``, causing + tasks to run in parallel. + + .. versionadded:: 1.3 + .. seealso:: :doc:`/usage/parallel` + +.. cmdoption:: --no-pty + + Sets :ref:`env.always_use_pty ` to ``False``, causing all + `~fabric.operations.run`/`~fabric.operations.sudo` calls to behave as if + one had specified ``pty=False``. + + .. versionadded:: 1.0 + +.. cmdoption:: -r, --reject-unknown-hosts + + Sets :ref:`env.reject_unknown_hosts ` to ``True``, + causing Fabric to abort when connecting to hosts not found in the user's SSH + :file:`known_hosts` file. + +.. cmdoption:: -R ROLES, --roles=ROLES + + Sets :ref:`env.roles ` to the given comma-separated list of role + names. + +.. cmdoption:: --set KEY=VALUE,... + + Allows you to set default values for arbitrary Fabric env vars. Values set + this way have a low precedence -- they will not override more specific env + vars which are also specified on the command line. E.g.:: + + fab --set password=foo --password=bar + + will result in ``env.password = 'bar'``, not ``'foo'`` + + Multiple ``KEY=VALUE`` pairs may be comma-separated, e.g. ``fab --set + var1=val1,var2=val2``. + + Other than basic string values, you may also set env vars to True by + omitting the ``=VALUE`` (e.g. ``fab --set KEY``), and you may set values to + the empty string (and thus a False-equivalent value) by keeping the equals + sign, but omitting ``VALUE`` (e.g. ``fab --set KEY=``.) + + .. versionadded:: 1.4 + +.. cmdoption:: -s SHELL, --shell=SHELL + + Sets :ref:`env.shell ` to the given string, overriding the default + shell wrapper used to execute remote commands. + +.. cmdoption:: --shortlist + + Similar to :option:`--list <-l>`, but without any embellishment, just task + names separated by newlines with no indentation or docstrings. + + .. versionadded:: 0.9.2 + .. seealso:: :option:`--list <-l>` + +.. cmdoption:: --show=LEVELS + + A comma-separated list of :doc:`output levels ` to + be added to those that are shown by + default. + + .. seealso:: `~fabric.operations.run`, `~fabric.operations.sudo` + +.. cmdoption:: --ssh-config-path + + Sets :ref:`env.ssh_config_path `. + + .. versionadded:: 1.4 + .. seealso:: :ref:`ssh-config` + +.. cmdoption:: --skip-bad-hosts + + Sets :ref:`env.skip_bad_hosts `, causing Fabric to skip + unavailable hosts. + + .. versionadded:: 1.4 + +.. cmdoption:: --skip-unknown-tasks + + Sets :ref:`env.skip_unknown_tasks `, causing Fabric to skip + unknown tasks. + + .. seealso:: + :ref:`env.skip_unknown_tasks ` + +.. cmdoption:: --timeout=N, -t N + + Set connection timeout in seconds. Sets :ref:`env.timeout `. + + .. seealso:: + :ref:`env.timeout `, + :ref:`env.connection_attempts ` + .. versionadded:: 1.4 + +.. cmdoption:: --command-timeout=N, -T N + + Set remote command timeout in seconds. Sets + :ref:`env.command_timeout `. + + .. seealso:: + :ref:`env.command_timeout `, + + .. versionadded:: 1.6 + +.. cmdoption:: -u USER, --user=USER + + Sets :ref:`env.user ` to the given string; it will then be used as the + default username when making SSH connections. + +.. cmdoption:: -V, --version + + Displays Fabric's version number, then exits. + +.. cmdoption:: -w, --warn-only + + Sets :ref:`env.warn_only ` to ``True``, causing Fabric to + continue execution even when commands encounter error conditions. + +.. cmdoption:: -z, --pool-size + + Sets :ref:`env.pool_size `, which specifies how many processes + to run concurrently during parallel execution. + + .. versionadded:: 1.3 + .. seealso:: :doc:`/usage/parallel` + + +.. _task-arguments: + +Per-task arguments +================== + +The options given in :ref:`command-line-options` apply to the invocation of +``fab`` as a whole; even if the order is mixed around, options still apply to +all given tasks equally. Additionally, since tasks are just Python functions, +it's often desirable to pass in arguments to them at runtime. + +Answering both these needs is the concept of "per-task arguments", which is a +special syntax you can tack onto the end of any task name: + +* Use a colon (``:``) to separate the task name from its arguments; +* Use commas (``,``) to separate arguments from one another (may be escaped + by using a backslash, i.e. ``\,``); +* Use equals signs (``=``) for keyword arguments, or omit them for positional + arguments. May also be escaped with backslashes. + +Additionally, since this process involves string parsing, all values will end +up as Python strings, so plan accordingly. (We hope to improve upon this in +future versions of Fabric, provided an intuitive syntax can be found.) + +For example, a "create a new user" task might be defined like so (omitting most +of the actual logic for brevity):: + + def new_user(username, admin='no', comment="No comment provided"): + print("New User (%s): %s" % (username, comment)) + pass + +You can specify just the username:: + + $ fab new_user:myusername + +Or treat it as an explicit keyword argument:: + + $ fab new_user:username=myusername + +If both args are given, you can again give them as positional args:: + + $ fab new_user:myusername,yes + +Or mix and match, just like in Python:: + + $ fab new_user:myusername,admin=yes + +The ``print`` call above is useful for illustrating escaped commas, like +so:: + + $ fab new_user:myusername,admin=no,comment='Gary\, new developer (starts Monday)' + +.. note:: + Quoting the backslash-escaped comma is required, as not doing so will cause + shell syntax errors. Quotes are also needed whenever an argument involves + other shell-related characters such as spaces. + +All of the above are translated into the expected Python function calls. For +example, the last call above would become:: + + >>> new_user('myusername', admin='yes', comment='Gary, new developer (starts Monday)') + +Roles and hosts +--------------- + +As mentioned in :ref:`the section on task execution `, +there are a handful of per-task keyword arguments (``host``, ``hosts``, +``role`` and ``roles``) which do not actually map to the task functions +themselves, but are used for setting per-task host and/or role lists. + +These special kwargs are **removed** from the args/kwargs sent to the task +function itself; this is so that you don't run into TypeErrors if your task +doesn't define the kwargs in question. (It also means that if you **do** define +arguments with these names, you won't be able to specify them in this manner -- +a regrettable but necessary sacrifice.) + +.. note:: + + If both the plural and singular forms of these kwargs are given, the value + of the plural will win out and the singular will be discarded. + +When using the plural form of these arguments, one must use semicolons (``;``) +since commas are already being used to separate arguments from one another. +Furthermore, since your shell is likely to consider semicolons a special +character, you'll want to quote the host list string to prevent shell +interpretation, e.g.:: + + $ fab new_user:myusername,hosts="host1;host2" + +Again, since the ``hosts`` kwarg is removed from the argument list sent to the +``new_user`` task function, the actual Python invocation would be +``new_user('myusername')``, and the function would be executed on a host list +of ``['host1', 'host2']``. + +.. _fabricrc: + +Settings files +============== + +Fabric currently honors a simple user settings file, or ``fabricrc`` (think +``bashrc`` but for ``fab``) which should contain one or more key-value pairs, +one per line. These lines will be subject to ``string.split('=')``, and thus +can currently only be used to specify string settings. Any such key-value pairs +will be used to update :doc:`env ` when ``fab`` runs, and is loaded prior +to the loading of any fabfile. + +By default, Fabric looks for ``~/.fabricrc``, and this may be overridden by +specifying the :option:`-c` flag to ``fab``. + +For example, if your typical SSH login username differs from your workstation +username, and you don't want to modify ``env.user`` in a project's fabfile +(possibly because you expect others to use it as well) you could write a +``fabricrc`` file like so:: + + user = ssh_user_name + +Then, when running ``fab``, your fabfile would load up with ``env.user`` set to +``'ssh_user_name'``. Other users of that fabfile could do the same, allowing +the fabfile itself to be cleanly agnostic regarding the default username. diff -Nru fabric-1.8.2/sites/docs/usage/interactivity.rst fabric-1.10.0/sites/docs/usage/interactivity.rst --- fabric-1.8.2/sites/docs/usage/interactivity.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/interactivity.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,148 @@ +================================ +Interaction with remote programs +================================ + +Fabric's primary operations, `~fabric.operations.run` and +`~fabric.operations.sudo`, are capable of sending local input to the remote +end, in a manner nearly identical to the ``ssh`` program. For example, programs +which display password prompts (e.g. a database dump utility, or changing a +user's password) will behave just as if you were interacting with them +directly. + +However, as with ``ssh`` itself, Fabric's implementation of this feature is +subject to a handful of limitations which are not always intuitive. This +document discusses such issues in detail. + +.. note:: + Readers unfamiliar with the basics of Unix stdout and stderr pipes, and/or + terminal devices, may wish to visit the Wikipedia pages for `Unix pipelines + `_ and `Pseudo terminals + `_ respectively. + + +.. _combine_streams: + +Combining stdout and stderr +=========================== + +The first issue to be aware of is that of the stdout and stderr streams, and +why they are separated or combined as needed. + +Buffering +--------- + +Fabric 0.9.x and earlier, and Python itself, buffer output on a line-by-line +basis: text is not printed to the user until a newline character is found. +This works fine in most situations but becomes problematic when one needs to +deal with partial-line output such as prompts. + +.. note:: + Line-buffered output can make programs appear to halt or freeze for no + reason, as prompts print out text without a newline, waiting for the user + to enter their input and press Return. + +Newer Fabric versions buffer both input and output on a character-by-character +basis in order to make interaction with prompts possible. This has the +convenient side effect of enabling interaction with complex programs utilizing +the "curses" libraries or which otherwise redraw the screen (think ``top``). + +Crossing the streams +-------------------- + +Unfortunately, printing to stderr and stdout simultaneously (as many programs +do) means that when the two streams are printed independently one byte at a +time, they can become garbled or meshed together. While this can sometimes be +mitigated by line-buffering one of the streams and not the other, it's still a +serious issue. + +To solve this problem, Fabric uses a setting in our SSH layer which merges the +two streams at a low level and causes output to appear more naturally. This +setting is represented in Fabric as the :ref:`combine-stderr` env var and +keyword argument, and is ``True`` by default. + +Due to this default setting, output will appear correctly, but at the +cost of an empty ``.stderr`` attribute on the return values of +`~fabric.operations.run`/`~fabric.operations.sudo`, as all output will appear +to be stdout. + +Conversely, users requiring a distinct stderr stream at the Python level and +who aren't bothered by garbled user-facing output (or who are hiding stdout and +stderr from the command in question) may opt to set this to ``False`` as +needed. + + +.. _pseudottys: + +Pseudo-terminals +================ + +The other main issue to consider when presenting interactive prompts to users +is that of echoing the user's own input. + +Echoes +------ + +Typical terminal applications or bona fide text terminals (e.g. when using a +Unix system without a running GUI) present programs with a terminal device +called a tty or pty (for pseudo-terminal). These automatically echo all text +typed into them back out to the user (via stdout), as interaction without +seeing what you had just typed would be difficult. Terminal devices are also +able to conditionally turn off echoing, allowing secure password prompts. + +However, it's possible for programs to be run without a tty or pty present at +all (consider cron jobs, for example) and in this situation, any stdin data +being fed to the program won't be echoed. This is desirable for programs being +run without any humans around, and it's also Fabric's old default mode of +operation. + +Fabric's approach +----------------- + +Unfortunately, in the context of executing commands via Fabric, when no pty is +present to echo a user's stdin, Fabric must echo it for them. This is +sufficient for many applications, but it presents problems for password +prompts, which become insecure. + +In the interests of security and meeting the principle of least surprise +(insofar as users are typically expecting things to behave as they would when +run in a terminal emulator), Fabric 1.0 and greater force a pty by default. +With a pty enabled, Fabric simply allows the remote end to handle echoing or +hiding of stdin and does not echo anything itself. + +.. note:: + In addition to allowing normal echo behavior, a pty also means programs + that behave differently when attached to a terminal device will then do so. + For example, programs that colorize output on terminals but not when run in + the background will print colored output. Be wary of this if you inspect + the return value of `~fabric.operations.run` or `~fabric.operations.sudo`! + +For situations requiring the pty behavior turned off, the :option:`--no-pty` +command-line argument and :ref:`always-use-pty` env var may be used. + + +Combining the two +================= + +As a final note, keep in mind that use of pseudo-terminals effectively implies +combining stdout and stderr -- in much the same way as the :ref:`combine_stderr +` setting does. This is because a terminal device naturally +sends both stdout and stderr to the same place -- the user's display -- thus +making it impossible to differentiate between them. + +However, at the Fabric level, the two groups of settings are distinct from one +another and may be combined in various ways. The default is for both to be set +to ``True``; the other combinations are as follows: + +* ``run("cmd", pty=False, combine_stderr=True)``: will cause Fabric to echo all + stdin itself, including passwords, as well as potentially altering ``cmd``'s + behavior. Useful if ``cmd`` behaves undesirably when run under a pty and + you're not concerned about password prompts. +* ``run("cmd", pty=False, combine_stderr=False)``: with both settings + ``False``, Fabric will echo stdin and won't issue a pty -- and this is highly + likely to result in undesired behavior for all but the simplest commands. + However, it is also the only way to access a distinct stderr stream, which is + occasionally useful. +* ``run("cmd", pty=True, combine_stderr=False)``: valid, but won't really make + much of a difference, as ``pty=True`` will still result in merged streams. + May be useful for avoiding any edge case problems in ``combine_stderr`` (none + are presently known). diff -Nru fabric-1.8.2/sites/docs/usage/library.rst fabric-1.10.0/sites/docs/usage/library.rst --- fabric-1.8.2/sites/docs/usage/library.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/library.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,61 @@ +=========== +Library Use +=========== + +Fabric's primary use case is via fabfiles and the :doc:`fab ` tool, +and this is reflected in much of the documentation. However, Fabric's internals +are written in such a manner as to be easily used without ``fab`` or fabfiles +at all -- this document will show you how. + +There's really only a couple of considerations one must keep in mind, when +compared to writing a fabfile and using ``fab`` to run it: how connections are +really made, and how disconnections occur. + +Connections +=========== + +We've documented how Fabric really connects to its hosts before, but it's +currently somewhat buried in the middle of the overall :doc:`execution docs +`. Specifically, you'll want to skip over to the +:ref:`connections` section and read it real quick. (You should really give that +entire document a once-over, but it's not absolutely required.) + +As that section mentions, the key is simply that `~fabric.operations.run`, +`~fabric.operations.sudo` and the other operations only look in one place when +connecting: :ref:`env.host_string `. All of the other mechanisms +for setting hosts are interpreted by the ``fab`` tool when it runs, and don't +matter when running as a library. + +That said, most use cases where you want to marry a given task ``X`` and a given list of hosts ``Y`` can, as of Fabric 1.3, be handled with the `~fabric.tasks.execute` function via ``execute(X, hosts=Y)``. Please see `~fabric.tasks.execute`'s documentation for details -- manual host string manipulation should be rarely necessary. + +Disconnecting +============= + +The other main thing that ``fab`` does for you is to disconnect from all hosts +at the end of a session; otherwise, Python will sit around forever waiting for +those network resources to be released. + +Fabric 0.9.4 and newer have a function you can use to do this easily: +`~fabric.network.disconnect_all`. Simply make sure your code calls this when it +terminates (typically in the ``finally`` clause of an outer ``try: finally`` +statement -- lest errors in your code prevent disconnections from happening!) +and things ought to work pretty well. + +If you're on Fabric 0.9.3 or older, you can simply do this (``disconnect_all`` +just adds a bit of nice output to this logic):: + + from fabric.state import connections + + for key in connections.keys(): + connections[key].close() + del connections[key] + + +Final note +========== + +This document is an early draft, and may not cover absolutely every difference +between ``fab`` use and library use. However, the above should highlight the +largest stumbling blocks. When in doubt, note that in the Fabric source code, +``fabric/main.py`` contains the bulk of the extra work done by ``fab``, and may +serve as a useful reference. diff -Nru fabric-1.8.2/sites/docs/usage/output_controls.rst fabric-1.10.0/sites/docs/usage/output_controls.rst --- fabric-1.8.2/sites/docs/usage/output_controls.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/output_controls.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,153 @@ +=============== +Managing output +=============== + +The ``fab`` tool is very verbose by default and prints out almost everything it +can, including the remote end's stderr and stdout streams, the command strings +being executed, and so forth. While this is necessary in many cases in order to +know just what's going on, any nontrivial Fabric task will quickly become +difficult to follow as it runs. + + +Output levels +============= + +To aid in organizing task output, Fabric output is grouped into a number of +non-overlapping levels or groups, each of which may be turned on or off +independently. This provides flexible control over what is displayed to the +user. + +.. note:: + + All levels, save for ``debug``, are on by default. + +Standard output levels +---------------------- + +The standard, atomic output levels/groups are as follows: + +* **status**: Status messages, i.e. noting when Fabric is done running, if + the user used a keyboard interrupt, or when servers are disconnected from. + These messages are almost always relevant and rarely verbose. + +* **aborts**: Abort messages. Like status messages, these should really only be + turned off when using Fabric as a library, and possibly not even then. Note + that even if this output group is turned off, aborts will still occur -- + there just won't be any output about why Fabric aborted! + +* **warnings**: Warning messages. These are often turned off when one expects a + given operation to fail, such as when using ``grep`` to test existence of + text in a file. If paired with setting ``env.warn_only`` to True, this + can result in fully silent warnings when remote programs fail. As with + ``aborts``, this setting does not control actual warning behavior, only + whether warning messages are printed or hidden. + +* **running**: Printouts of commands being executed or files transferred, e.g. + ``[myserver] run: ls /var/www``. Also controls printing of tasks being run, + e.g. ``[myserver] Executing task 'foo'``. + +* **stdout**: Local, or remote, stdout, i.e. non-error output from commands. + +* **stderr**: Local, or remote, stderr, i.e. error-related output from commands. + +* **user**: User-generated output, i.e. local output printed by fabfile code + via use of the `~fabric.utils.fastprint` or `~fabric.utils.puts` functions. + +.. versionchanged:: 0.9.2 + Added "Executing task" lines to the ``running`` output level. + +.. versionchanged:: 0.9.2 + Added the ``user`` output level. + +Debug output +------------ + +There is a final atomic output level, ``debug``, which behaves slightly +differently from the rest: + +* **debug**: Turn on debugging (which is off by default.) Currently, this is + largely used to view the "full" commands being run; take for example this + `~fabric.operations.run` call:: + + run('ls "/home/username/Folder Name With Spaces/"') + + Normally, the ``running`` line will show exactly what is passed into + `~fabric.operations.run`, like so:: + + [hostname] run: ls "/home/username/Folder Name With Spaces/" + + With ``debug`` on, and assuming you've left :ref:`shell` set to ``True``, you + will see the literal, full string as passed to the remote server:: + + [hostname] run: /bin/bash -l -c "ls \"/home/username/Folder Name With Spaces\"" + + Enabling ``debug`` output will also display full Python tracebacks during + aborts. + + .. note:: + + Where modifying other pieces of output (such as in the above example + where it modifies the 'running' line to show the shell and any escape + characters), this setting takes precedence over the others; so if + ``running`` is False but ``debug`` is True, you will still be shown the + 'running' line in its debugging form. + +.. versionchanged:: 1.0 + Debug output now includes full Python tracebacks during aborts. + +.. _output-aliases: + +Output level aliases +-------------------- + +In addition to the atomic/standalone levels above, Fabric also provides a +couple of convenience aliases which map to multiple other levels. These may be +referenced anywhere the other levels are referenced, and will effectively +toggle all of the levels they are mapped to. + +* **output**: Maps to both ``stdout`` and ``stderr``. Useful for when you only + care to see the 'running' lines and your own print statements (and warnings). + +* **everything**: Includes ``warnings``, ``running``, ``user`` and ``output`` + (see above.) Thus, when turning off ``everything``, you will only see a bare + minimum of output (just ``status`` and ``debug`` if it's on), along with your + own print statements. + +* **commands**: Includes ``stdout`` and ``running``. Good for hiding + non-erroring commands entirely, while still displaying any stderr output. + +.. versionchanged:: 1.4 + Added the ``commands`` output alias. + + +Hiding and/or showing output levels +=================================== + +You may toggle any of Fabric's output levels in a number of ways; for examples, +please see the API docs linked in each bullet point: + +* **Direct modification of fabric.state.output**: `fabric.state.output` is a + dictionary subclass (similar to :doc:`env `) whose keys are the output + level names, and whose values are either True (show that particular type of + output) or False (hide it.) + + `fabric.state.output` is the lowest-level implementation of output levels and + is what Fabric's internals reference when deciding whether or not to print + their output. + +* **Context managers**: `~fabric.context_managers.hide` and + `~fabric.context_managers.show` are twin context managers that take one or + more output level names as strings, and either hide or show them within the + wrapped block. As with Fabric's other context managers, the prior values are + restored when the block exits. + + .. seealso:: + + `~fabric.context_managers.settings`, which can nest calls to + `~fabric.context_managers.hide` and/or `~fabric.context_managers.show` + inside itself. + +* **Command-line arguments**: You may use the :option:`--hide` and/or + :option:`--show` arguments to :doc:`fab`, which behave exactly like the + context managers of the same names (but are, naturally, globally applied) and + take comma-separated strings as input. diff -Nru fabric-1.8.2/sites/docs/usage/parallel.rst fabric-1.10.0/sites/docs/usage/parallel.rst --- fabric-1.8.2/sites/docs/usage/parallel.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/parallel.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,171 @@ +================== +Parallel execution +================== + +.. _parallel-execution: + +.. versionadded:: 1.3 + +By default, Fabric executes all specified tasks **serially** (see +:ref:`execution-strategy` for details.) This document describes Fabric's +options for running tasks on multiple hosts in **parallel**, via per-task +decorators and/or global command-line switches. + + +What it does +============ + +Because Fabric 1.x is not fully threadsafe (and because in general use, task +functions do not typically interact with one another) this functionality is +implemented via the Python `multiprocessing +`_ module. It creates one +new process for each host and task combination, optionally using a +(configurable) sliding window to prevent too many processes from running at the +same time. + +For example, imagine a scenario where you want to update Web application code +on a number of Web servers, and then reload the servers once the code has been +distributed everywhere (to allow for easier rollback if code updates fail.) One +could implement this with the following fabfile:: + + from fabric.api import * + + def update(): + with cd("/srv/django/myapp"): + run("git pull") + + def reload(): + sudo("service apache2 reload") + +and execute it on a set of 3 servers, in serial, like so:: + + $ fab -H web1,web2,web3 update reload + +Normally, without any parallel execution options activated, Fabric would run +in order: + +#. ``update`` on ``web1`` +#. ``update`` on ``web2`` +#. ``update`` on ``web3`` +#. ``reload`` on ``web1`` +#. ``reload`` on ``web2`` +#. ``reload`` on ``web3`` + +With parallel execution activated (via :option:`-P` -- see below for details), +this turns into: + +#. ``update`` on ``web1``, ``web2``, and ``web3`` +#. ``reload`` on ``web1``, ``web2``, and ``web3`` + +Hopefully the benefits of this are obvious -- if ``update`` took 5 seconds to +run and ``reload`` took 2 seconds, serial execution takes (5+2)*3 = 21 seconds +to run, while parallel execution takes only a third of the time, (5+2) = 7 +seconds on average. + + +How to use it +============= + +Decorators +---------- + +Since the minimum "unit" that parallel execution affects is a task, the +functionality may be enabled or disabled on a task-by-task basis using the +`~fabric.decorators.parallel` and `~fabric.decorators.serial` decorators. For +example, this fabfile:: + + from fabric.api import * + + @parallel + def runs_in_parallel(): + pass + + def runs_serially(): + pass + +when run in this manner:: + + $ fab -H host1,host2,host3 runs_in_parallel runs_serially + +will result in the following execution sequence: + +#. ``runs_in_parallel`` on ``host1``, ``host2``, and ``host3`` +#. ``runs_serially`` on ``host1`` +#. ``runs_serially`` on ``host2`` +#. ``runs_serially`` on ``host3`` + +Command-line flags +------------------ + +One may also force all tasks to run in parallel by using the command-line flag +:option:`-P` or the env variable :ref:`env.parallel `. However, +any task specifically wrapped with `~fabric.decorators.serial` will ignore this +setting and continue to run serially. + +For example, the following fabfile will result in the same execution sequence +as the one above:: + + from fabric.api import * + + def runs_in_parallel(): + pass + + @serial + def runs_serially(): + pass + +when invoked like so:: + + $ fab -H host1,host2,host3 -P runs_in_parallel runs_serially + +As before, ``runs_in_parallel`` will run in parallel, and ``runs_serially`` in +sequence. + + +Bubble size +=========== + +With large host lists, a user's local machine can get overwhelmed by running +too many concurrent Fabric processes. Because of this, you may opt to use a +moving bubble approach that limits Fabric to a specific number of concurrently +active processes. + +By default, no bubble is used and all hosts are run in one concurrent pool. You +can override this on a per-task level by specifying the ``pool_size`` keyword +argument to `~fabric.decorators.parallel`, or globally via :option:`-z`. + +For example, to run on 5 hosts at a time:: + + from fabric.api import * + + @parallel(pool_size=5) + def heavy_task(): + # lots of heavy local lifting or lots of IO here + +Or skip the ``pool_size`` kwarg and instead:: + + $ fab -P -z 5 heavy_task + +.. _linewise-output: + +Linewise vs bytewise output +=========================== + +Fabric's default mode of printing to the terminal is byte-by-byte, in order to +support :doc:`/usage/interactivity`. This often gives poor results when running +in parallel mode, as the multiple processes may write to your terminal's +standard out stream simultaneously. + +To help offset this problem, Fabric's option for linewise output is +automatically enabled whenever parallelism is active. This will cause you to +lose most of the benefits outlined in the above link Fabric's remote +interactivity features, but as those do not map well to parallel invocations, +it's typically a fair trade. + +There's no way to avoid the multiple processes mixing up on a line-by-line +basis, but you will at least be able to tell them apart by the host-string line +prefix. + +.. note:: + Future versions will add improved logging support to make troubleshooting + parallel runs easier. diff -Nru fabric-1.8.2/sites/docs/usage/ssh.rst fabric-1.10.0/sites/docs/usage/ssh.rst --- fabric-1.8.2/sites/docs/usage/ssh.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/ssh.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,64 @@ +============ +SSH behavior +============ + +Fabric currently makes use of a pure-Python SSH re-implementation for managing +connections, meaning that there are occasionally spots where it is limited by +that library's capabilities. Below are areas of note where Fabric will exhibit +behavior that isn't consistent with, or as flexible as, the behavior of the +``ssh`` command-line program. + + +Unknown hosts +============= + +SSH's host key tracking mechanism keeps tabs on all the hosts you attempt to +connect to, and maintains a ``~/.ssh/known_hosts`` file with mappings between +identifiers (IP address, sometimes with a hostname as well) and SSH keys. (For +details on how this works, please see the `OpenSSH documentation +`_.) + +The ``paramiko`` library is capable of loading up your ``known_hosts`` file, +and will then compare any host it connects to, with that mapping. Settings are +available to determine what happens when an unknown host (a host whose username +or IP is not found in ``known_hosts``) is seen: + +* **Reject**: the host key is rejected and the connection is not made. This + results in a Python exception, which will terminate your Fabric session with a + message that the host is unknown. +* **Add**: the new host key is added to the in-memory list of known hosts, the + connection is made, and things continue normally. Note that this does **not** + modify your on-disk ``known_hosts`` file! +* **Ask**: not yet implemented at the Fabric level, this is a ``paramiko`` + library option which would result in the user being prompted about the + unknown key and whether to accept it. + +Whether to reject or add hosts, as above, is controlled in Fabric via the +:ref:`env.reject_unknown_hosts ` option, which is False +by default for convenience's sake. We feel this is a valid tradeoff between +convenience and security; anyone who feels otherwise can easily modify their +fabfiles at module level to set ``env.reject_unknown_hosts = True``. + + +Known hosts with changed keys +============================= + +The point of SSH's key/fingerprint tracking is so that man-in-the-middle +attacks can be detected: if an attacker redirects your SSH traffic to a +computer under his control, and pretends to be your original destination +server, the host keys will not match. Thus, the default behavior of SSH (and +its Python implementation) is to immediately abort the connection when a host +previously recorded in ``known_hosts`` suddenly starts sending us a different +host key. + +In some edge cases such as some EC2 deployments, you may want to ignore this +potential problem. Our SSH layer, at the time of writing, doesn't give us +control over this exact behavior, but we can sidestep it by simply skipping the +loading of ``known_hosts`` -- if the host list being compared to is empty, then +there's no problem. Set :ref:`env.disable_known_hosts ` to +True when you want this behavior; it is False by default, in order to preserve +default SSH behavior. + +.. warning:: + Enabling :ref:`env.disable_known_hosts ` will leave + you wide open to man-in-the-middle attacks! Please use with caution. diff -Nru fabric-1.8.2/sites/docs/usage/tasks.rst fabric-1.10.0/sites/docs/usage/tasks.rst --- fabric-1.8.2/sites/docs/usage/tasks.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/docs/usage/tasks.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,540 @@ +============== +Defining tasks +============== + +As of Fabric 1.1, there are two distinct methods you may use in order to define +which objects in your fabfile show up as tasks: + +* The "new" method starting in 1.1 considers instances of `~fabric.tasks.Task` + or its subclasses, and also descends into imported modules to allow building + nested namespaces. +* The "classic" method from 1.0 and earlier considers all public callable + objects (functions, classes etc) and only considers the objects in the + fabfile itself with no recursing into imported module. + +.. note:: + These two methods are **mutually exclusive**: if Fabric finds *any* + new-style task objects in your fabfile or in modules it imports, it will + assume you've committed to this method of task declaration and won't + consider any non-`~fabric.tasks.Task` callables. If *no* new-style tasks + are found, it reverts to the classic behavior. + +The rest of this document explores these two methods in detail. + +.. note:: + + To see exactly what tasks in your fabfile may be executed via ``fab``, use + :option:`fab --list <-l>`. + +.. _new-style-tasks: + +New-style tasks +=============== + +Fabric 1.1 introduced the `~fabric.tasks.Task` class to facilitate new features +and enable some programming best practices, specifically: + +* **Object-oriented tasks**. Inheritance and all that comes with it can make + for much more sensible code reuse than passing around simple function + objects. The classic style of task declaration didn't entirely rule this + out, but it also didn't make it terribly easy. +* **Namespaces**. Having an explicit method of declaring tasks makes it easier + to set up recursive namespaces without e.g. polluting your task list with the + contents of Python's ``os`` module (which would show up as valid "tasks" + under the classic methodology.) + +With the introduction of `~fabric.tasks.Task`, there are two ways to set up new +tasks: + +* Decorate a regular module level function with `@task + `, which transparently wraps the function in a + `~fabric.tasks.Task` subclass. The function name will be used as the task + name when invoking. +* Subclass `~fabric.tasks.Task` (`~fabric.tasks.Task` itself is intended to be + abstract), define a ``run`` method, and instantiate your subclass at module + level. Instances' ``name`` attributes are used as the task name; if omitted + the instance's variable name will be used instead. + +Use of new-style tasks also allows you to set up :ref:`namespaces +`. + + +.. _task-decorator: + +The ``@task`` decorator +----------------------- + +The quickest way to make use of new-style task features is to wrap basic task functions with `@task `:: + + from fabric.api import task, run + + @task + def mytask(): + run("a command") + + +When this decorator is used, it signals to Fabric that *only* functions wrapped in the decorator are to be loaded up as valid tasks. (When not present, :ref:`classic-style task ` behavior kicks in.) + +.. _task-decorator-arguments: + +Arguments +~~~~~~~~~ + +`@task ` may also be called with arguments to +customize its behavior. Any arguments not documented below are passed into the +constructor of the ``task_class`` being used, with the function itself as the +first argument (see :ref:`task-decorator-and-classes` for details.) + +* ``task_class``: The `~fabric.tasks.Task` subclass used to wrap the decorated + function. Defaults to `~fabric.tasks.WrappedCallableTask`. +* ``aliases``: An iterable of string names which will be used as aliases for + the wrapped function. See :ref:`task-aliases` for details. +* ``alias``: Like ``aliases`` but taking a single string argument instead of an + iterable. If both ``alias`` and ``aliases`` are specified, ``aliases`` will + take precedence. +* ``default``: A boolean value determining whether the decorated task also + stands in for its containing module as a task name. See :ref:`default-tasks`. +* ``name``: A string setting the name this task appears as to the command-line + interface. Useful for task names that would otherwise shadow Python builtins + (which is technically legal but frowned upon and bug-prone.) + +.. _task-aliases: + +Aliases +~~~~~~~ + +Here's a quick example of using the ``alias`` keyword argument to facilitate +use of both a longer human-readable task name, and a shorter name which is +quicker to type:: + + from fabric.api import task + + @task(alias='dwm') + def deploy_with_migrations(): + pass + +Calling :option:`--list <-l>` on this fabfile would show both the original +``deploy_with_migrations`` and its alias ``dwm``:: + + $ fab --list + Available commands: + + deploy_with_migrations + dwm + +When more than one alias for the same function is needed, simply swap in the +``aliases`` kwarg, which takes an iterable of strings instead of a single +string. + +.. _default-tasks: + +Default tasks +~~~~~~~~~~~~~ + +In a similar manner to :ref:`aliases `, it's sometimes useful to +designate a given task within a module as the "default" task, which may be +called by referencing *just* the module name. This can save typing and/or +allow for neater organization when there's a single "main" task and a number +of related tasks or subroutines. + +For example, a ``deploy`` submodule might contain tasks for provisioning new +servers, pushing code, migrating databases, and so forth -- but it'd be very +convenient to highlight a task as the default "just deploy" action. Such a +``deploy.py`` module might look like this:: + + from fabric.api import task + + @task + def migrate(): + pass + + @task + def push(): + pass + + @task + def provision(): + pass + + @task + def full_deploy(): + if not provisioned: + provision() + push() + migrate() + +With the following task list (assuming a simple top level ``fabfile.py`` that just imports ``deploy``):: + + $ fab --list + Available commands: + + deploy.full_deploy + deploy.migrate + deploy.provision + deploy.push + +Calling ``deploy.full_deploy`` on every deploy could get kind of old, or somebody new to the team might not be sure if that's really the right task to run. + +Using the ``default`` kwarg to `@task `, we can tag +e.g. ``full_deploy`` as the default task:: + + @task(default=True) + def full_deploy(): + pass + +Doing so updates the task list like so:: + + $ fab --list + Available commands: + + deploy + deploy.full_deploy + deploy.migrate + deploy.provision + deploy.push + +Note that ``full_deploy`` still exists as its own explicit task -- but now +``deploy`` shows up as a sort of top level alias for ``full_deploy``. + +If multiple tasks within a module have ``default=True`` set, the last one to +be loaded (typically the one lowest down in the file) will take precedence. + +Top-level default tasks +~~~~~~~~~~~~~~~~~~~~~~~ + +Using ``@task(default=True)`` in the top level fabfile will cause the denoted +task to execute when a user invokes ``fab`` without any task names (similar to +e.g. ``make``.) When using this shortcut, it is not possible to specify +arguments to the task itself -- use a regular invocation of the task if this +is necessary. + +.. _task-subclasses: + +``Task`` subclasses +------------------- + +If you're used to :ref:`classic-style tasks `, an easy way to +think about `~fabric.tasks.Task` subclasses is that their ``run`` method is +directly equivalent to a classic task; its arguments are the task arguments +(other than ``self``) and its body is what gets executed. + +For example, this new-style task:: + + class MyTask(Task): + name = "deploy" + def run(self, environment, domain="whatever.com"): + run("git clone foo") + sudo("service apache2 restart") + + instance = MyTask() + +is exactly equivalent to this function-based task:: + + @task + def deploy(environment, domain="whatever.com"): + run("git clone foo") + sudo("service apache2 restart") + +Note how we had to instantiate an instance of our class; that's simply normal +Python object-oriented programming at work. While it's a small bit of +boilerplate right now -- for example, Fabric doesn't care about the name you +give the instantiation, only the instance's ``name`` attribute -- it's well +worth the benefit of having the power of classes available. + +We plan to extend the API in the future to make this experience a bit smoother. + +.. _task-decorator-and-classes: + +Using custom subclasses with ``@task`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It's possible to marry custom `~fabric.tasks.Task` subclasses with `@task +`. This may be useful in cases where your core +execution logic doesn't do anything class/object-specific, but you want to +take advantage of class metaprogramming or similar techniques. + +Specifically, any `~fabric.tasks.Task` subclass which is designed to take in a +callable as its first constructor argument (as the built-in +`~fabric.tasks.WrappedCallableTask` does) may be specified as the +``task_class`` argument to `@task `. + +Fabric will automatically instantiate a copy of the given class, passing in +the wrapped function as the first argument. All other args/kwargs given to the +decorator (besides the "special" arguments documented in +:ref:`task-decorator-arguments`) are added afterwards. + +Here's a brief and somewhat contrived example to make this obvious:: + + from fabric.api import task + from fabric.tasks import Task + + class CustomTask(Task): + def __init__(self, func, myarg, *args, **kwargs): + super(CustomTask, self).__init__(*args, **kwargs) + self.func = func + self.myarg = myarg + + def run(self, *args, **kwargs): + return self.func(*args, **kwargs) + + @task(task_class=CustomTask, myarg='value', alias='at') + def actual_task(): + pass + +When this fabfile is loaded, a copy of ``CustomTask`` is instantiated, effectively calling:: + + task_obj = CustomTask(actual_task, myarg='value') + +Note how the ``alias`` kwarg is stripped out by the decorator itself and never +reaches the class instantiation; this is identical in function to how +:ref:`command-line task arguments ` work. + +.. _namespaces: + +Namespaces +---------- + +With :ref:`classic tasks `, fabfiles were limited to a single, +flat set of task names with no real way to organize them. In Fabric 1.1 and +newer, if you declare tasks the new way (via `@task ` +or your own `~fabric.tasks.Task` subclass instances) you may take advantage +of **namespacing**: + +* Any module objects imported into your fabfile will be recursed into, looking + for additional task objects. +* Within submodules, you may control which objects are "exported" by using the + standard Python ``__all__`` module-level variable name (thought they should + still be valid new-style task objects.) +* These tasks will be given new dotted-notation names based on the modules they + came from, similar to Python's own import syntax. + +Let's build up a fabfile package from simple to complex and see how this works. + +Basic +~~~~~ + +We start with a single `__init__.py` containing a few tasks (the Fabric API +import omitted for brevity):: + + @task + def deploy(): + ... + + @task + def compress(): + ... + +The output of ``fab --list`` would look something like this:: + + deploy + compress + +There's just one namespace here: the "root" or global namespace. Looks simple +now, but in a real-world fabfile with dozens of tasks, it can get difficult to +manage. + +Importing a submodule +~~~~~~~~~~~~~~~~~~~~~ + +As mentioned above, Fabric will examine any imported module objects for tasks, +regardless of where that module exists on your Python import path. For now we +just want to include our own, "nearby" tasks, so we'll make a new submodule in +our package for dealing with, say, load balancers -- ``lb.py``:: + + @task + def add_backend(): + ... + +And we'll add this to the top of ``__init__.py``:: + + import lb + +Now ``fab --list`` shows us:: + + deploy + compress + lb.add_backend + +Again, with only one task in its own submodule, it looks kind of silly, but the +benefits should be pretty obvious. + +Going deeper +~~~~~~~~~~~~ + +Namespacing isn't limited to just one level. Let's say we had a larger setup +and wanted a namespace for database related tasks, with additional +differentiation inside that. We make a sub-package named ``db/`` and inside it, +a ``migrations.py`` module:: + + @task + def list(): + ... + + @task + def run(): + ... + +We need to make sure that this module is visible to anybody importing ``db``, +so we add it to the sub-package's ``__init__.py``:: + + import migrations + +As a final step, we import the sub-package into our root-level ``__init__.py``, +so now its first few lines look like this:: + + import lb + import db + +After all that, our file tree looks like this:: + + . + ├── __init__.py + ├── db + │   ├── __init__.py + │   └── migrations.py + └── lb.py + +and ``fab --list`` shows:: + + deploy + compress + lb.add_backend + db.migrations.list + db.migrations.run + +We could also have specified (or imported) tasks directly into +``db/__init__.py``, and they would show up as ``db.`` as you might +expect. + +Limiting with ``__all__`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You may limit what Fabric "sees" when it examines imported modules, by using +the Python convention of a module level ``__all__`` variable (a list of +variable names.) If we didn't want the ``db.migrations.run`` task to show up by +default for some reason, we could add this to the top of ``db/migrations.py``:: + + __all__ = ['list'] + +Note the lack of ``'run'`` there. You could, if needed, import ``run`` directly +into some other part of the hierarchy, but otherwise it'll remain hidden. + +Switching it up +~~~~~~~~~~~~~~~ + +We've been keeping our fabfile package neatly organized and importing it in a +straightforward manner, but the filesystem layout doesn't actually matter here. +All Fabric's loader cares about is the names the modules are given when they're +imported. + +For example, if we changed the top of our root ``__init__.py`` to look like +this:: + + import db as database + +Our task list would change thusly:: + + deploy + compress + lb.add_backend + database.migrations.list + database.migrations.run + +This applies to any other import -- you could import third party modules into +your own task hierarchy, or grab a deeply nested module and make it appear near +the top level. + +Nested list output +~~~~~~~~~~~~~~~~~~ + +As a final note, we've been using the default Fabric :option:`--list <-l>` +output during this section -- it makes it more obvious what the actual task +names are. However, you can get a more nested or tree-like view by passing +``nested`` to the :option:`--list-format <-F>` option:: + + $ fab --list-format=nested --list + Available commands (remember to call as module.[...].task): + + deploy + compress + lb: + add_backend + database: + migrations: + list + run + +While it slightly obfuscates the "real" task names, this view provides a handy +way of noting the organization of tasks in large namespaces. + + +.. _classic-tasks: + +Classic tasks +============= + +When no new-style `~fabric.tasks.Task`-based tasks are found, Fabric will +consider any callable object found in your fabfile, **except** the following: + +* Callables whose name starts with an underscore (``_``). In other words, + Python's usual "private" convention holds true here. +* Callables defined within Fabric itself. Fabric's own functions such as + `~fabric.operations.run` and `~fabric.operations.sudo` will not show up in + your task list. + + +Imports +------- + +Python's ``import`` statement effectively includes the imported objects in your +module's namespace. Since Fabric's fabfiles are just Python modules, this means +that imports are also considered as possible classic-style tasks, alongside +anything defined in the fabfile itself. + + .. note:: + This only applies to imported *callable objects* -- not modules. + Imported modules only come into play if they contain :ref:`new-style + tasks `, at which point this section no longer + applies. + +Because of this, we strongly recommend that you use the ``import module`` form +of importing, followed by ``module.callable()``, which will result in a cleaner +fabfile API than doing ``from module import callable``. + +For example, here's a sample fabfile which uses ``urllib.urlopen`` to get some +data out of a webservice:: + + from urllib import urlopen + + from fabric.api import run + + def webservice_read(): + objects = urlopen('http://my/web/service/?foo=bar').read().split() + print(objects) + +This looks simple enough, and will run without error. However, look what +happens if we run :option:`fab --list <-l>` on this fabfile:: + + $ fab --list + Available commands: + + webservice_read List some directories. + urlopen urlopen(url [, data]) -> open file-like object + +Our fabfile of only one task is showing two "tasks", which is bad enough, and +an unsuspecting user might accidentally try to call ``fab urlopen``, which +probably won't work very well. Imagine any real-world fabfile, which is likely +to be much more complex, and hopefully you can see how this could get messy +fast. + +For reference, here's the recommended way to do it:: + + import urllib + + from fabric.api import run + + def webservice_read(): + objects = urllib.urlopen('http://my/web/service/?foo=bar').read().split() + print(objects) + +It's a simple change, but it'll make anyone using your fabfile a bit happier. diff -Nru fabric-1.8.2/sites/shared_conf.py fabric-1.10.0/sites/shared_conf.py --- fabric-1.8.2/sites/shared_conf.py 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/shared_conf.py 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,44 @@ +from os.path import join +from datetime import datetime + +import alabaster + + +# Alabaster theme + mini-extension +html_theme_path = [alabaster.get_path()] +extensions = ['alabaster'] +# Paths relative to invoking conf.py - not this shared file +html_static_path = [join('..', '_shared_static')] +html_theme = 'alabaster' +html_theme_options = { + 'logo': 'logo.png', + 'logo_name': True, + 'logo_text_align': 'center', + 'description': "Pythonic remote execution", + 'github_user': 'fabric', + 'github_repo': 'fabric', + 'travis_button': True, + 'gittip_user': 'bitprophet', + 'analytics_id': 'UA-18486793-1', + + 'link': '#3782BE', + 'link_hover': '#3782BE', +} +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'searchbox.html', + 'donate.html', + ] +} + +# Regular settings +project = 'Fabric' +year = datetime.now().year +copyright = '%d Jeff Forcier' % year +master_doc = 'index' +templates_path = ['_templates'] +exclude_trees = ['_build'] +source_suffix = '.rst' +default_role = 'obj' Binary files /tmp/N6trD1b267/fabric-1.8.2/sites/_shared_static/logo.png and /tmp/GW8FhdJcF_/fabric-1.10.0/sites/_shared_static/logo.png differ diff -Nru fabric-1.8.2/sites/www/changelog.rst fabric-1.10.0/sites/www/changelog.rst --- fabric-1.8.2/sites/www/changelog.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/changelog.rst 2014-09-04 16:47:58.000000000 +0000 @@ -0,0 +1,606 @@ +========= +Changelog +========= + +* :release:`1.10.0 <2014-09-04>` +* :bug:`1188 major` Update `~fabric.operations.local` to close non-pipe file + descriptors in the child process so subsequent calls to + `~fabric.operations.local` aren't blocked on e.g. already-connected network + sockets. Thanks to Tolbkni Kao for catch & patch. +* :support:`700` Added ``use_sudo`` and ``temp_dir`` params to + `~fabric.operations.get`. This allows downloading files normally not + accessible to the user using ``sudo``. Thanks to Jason Coombs for initial + report and to Alex Plugaru for the patch (:issue:`1121`). +* :feature:`1098` Add support for dict style roledefs. Thanks to Jonas + Lundberg. +* :feature:`1090` Add option to skip unknown tasks. Credit goes to Jonas + Lundberg. +* :feature:`975` Fabric can now be invoked via ``python -m fabric`` in addition + to the typical use of the ``fab`` entrypoint. Patch courtesy of Jason Coombs. + + .. note:: This functionality is only available under Python 2.7. + +* :release:`1.9.1 <2014-08-06>` +* :release:`1.8.5 <2014-08-06>` +* :release:`1.7.5 <2014-08-06>` +* :bug:`1165` Prevent infinite loop condition when a gateway host is enabled & + the same host is in the regular target host list. Thanks to ``@CzBiX`` for + catch & patch. +* :bug:`1147` Use ``stat`` instead of ``lstat`` when testing directory-ness in + the SFTP module. This allows recursive downloads to avoid recursing into + symlinks unexpectedly. Thanks to Igor Kalnitsky for the patch. +* :bug:`1146` Fix a bug where `~fabric.contrib.files.upload_template` failed to + honor ``lcd`` when ``mirror_local_mode`` is ``True``. Thanks to Laszlo Marai + for catch & patch. +* :bug:`1134` Skip bad hosts when the tasks are executed in parallel. Thanks to + Igor Maravić ``@i-maravic``. +* :bug:`852` Fix to respect ``template_dir`` for non Jinja2 templates in + `~fabric.contrib.files.upload_template`. Thanks to Adam Kowalski for the + patch and Alex Plugaru for the initial test case. +* :bug:`1096` Encode Unicode text appropriately for its target stream object to + avoid issues on non-ASCII systems. Thanks to Toru Uetani for the original + patch. +* :bug:`1059` Update IPv6 support to work with link-local address formats. + Fix courtesy of ``@obormot``. +* :bug:`1026` Fix a typo preventing quiet operation of + `~fabric.contrib.files.is_link`. Caught by ``@dongweiming``. +* :bug:`600` Clear out connection caches in full when prepping + parallel-execution subprocesses. This avoids corner cases causing + hangs/freezes due to client/socket reuse. Thanks to Ruslan Lutsenko for the + initial report and Romain Chossart for the suggested fix. +* :bug:`1167` Add Jinja to ``test_requires`` in ``setup.py`` for the couple of + newish tests that now require it. Thanks to Kubilay Kocak for the catch. +* :release:`1.9.0 <2014-06-08>` +* :feature:`1078` Add ``.command`` and ``.real_command`` attributes to + ``local`` return value. Thanks to Alexander Teves (``@alexanderteves``) and + Konrad Hałas (``@konradhalas``). +* :feature:`938` Add an env var :ref:`env.effective_roles ` + specifying roles used in the currently executing command. Thanks to + Piotr Betkier for the patch. +* :feature:`1101` Reboot operation now supports custom command. Thanks to Jonas + Lejon. +* :support:`1106` Fix a misleading/ambiguous example snippet in the ``fab`` + usage docs to be clearer. Thanks to ``@zed``. +* :release:`1.8.4 <2014-06-08>` +* :release:`1.7.4 <2014-06-08>` +* :bug:`898` Treat paths that begin with tilde "~" as absolute paths instead of + relative. Thanks to Alex Plugaru for the patch and Dan Craig for the + suggestion. +* :support:`1105 backported` Enhance ``setup.py`` to allow Paramiko 1.13+ under + Python 2.6+. Thanks to to ``@Arfrever`` for catch & patch. +* :release:`1.8.3 <2014-03-21>` +* :release:`1.7.3 <2014-03-21>` +* :support:`- backported` Modified packaging data to reflect that Fabric + requires Paramiko < 1.13 (which dropped Python 2.5 support.) +* :feature:`1082` Add ``pty`` passthrough kwarg to + `~fabric.contrib.files.upload_template`. +* :release:`1.8.2 <2014-02-14>` +* :release:`1.7.2 <2014-02-14>` +* :bug:`955` Quote directories created as part of ``put``'s recursive directory + uploads when ``use_sudo=True`` so directories with shell meta-characters + (such as spaces) work correctly. Thanks to John Harris for the catch. +* :bug:`917` Correct an issue with ``put(use_sudo=True, mode=xxx)`` where the + ``chmod`` was trying to apply to the wrong location. Thanks to Remco + (``@nl5887``) for catch & patch. +* :bug:`1046` Fix typo preventing use of ProxyCommand in some situations. + Thanks to Keith Yang. +* :release:`1.8.1 <2013-12-24>` +* :release:`1.7.1 <2013-12-24>` +* :release:`1.6.4 <2013-12-24>` 956, 957 +* :release:`1.5.5 <2013-12-24>` 956, 957 +* :bug:`956` Fix pty size detection when running inside Emacs. Thanks to + `@akitada` for catch & patch. +* :bug:`957` Fix bug preventing use of :ref:`env.gateway ` with + targets requiring password authentication. Thanks to Daniel González, + `@Bengrunt` and `@adrianbn` for their bug reports. +* :feature:`741` Add :ref:`env.prompts ` dictionary, allowing + users to set up custom prompt responses (similar to the built-in sudo prompt + auto-responder.) Thanks to Nigel Owens and David Halter for the patch. +* :bug:`965 major` Tweak IO flushing behavior when in linewise (& thus + parallel) mode so interwoven output is less frequent. Thanks to `@akidata` + for catch & patch. +* :bug:`948` Handle connection failures due to server load and try connecting + to hosts a number of times specified in :ref:`env.connection_attempts + `. +* :release:`1.8.0 <2013-09-20>` +* :feature:`931` Allow overriding of `.abort` behavior via a custom + exception-returning callable set as :ref:`env.abort_exception + `. Thanks to Chris Rose for the patch. +* :support:`984 backported` Make this changelog easier to read! Now with + per-release sections, generated automatically from the old timeline source + format. +* :feature:`910` Added a keyword argument to rsync_project to configure the + default options. Thanks to ``@moorepants`` for the patch. +* :release:`1.7.0 <2013-07-26>` +* :release:`1.6.2 <2013-07-26>` +* :feature:`925` Added `contrib.files.is_link <.is_link>`. Thanks to `@jtangas` + for the patch. +* :feature:`922` Task argument strings are now displayed when using + :option:`fab -d <-d>`. Thanks to Kevin Qiu for the patch. +* :bug:`912` Leaving ``template_dir`` un-specified when using + `.upload_template` in Jinja mode used to cause ``'NoneType' has no attribute + 'startswith'`` errors. This has been fixed. Thanks to Erick Yellott for catch + & to Erick Yellott + Kevin Williams for patches. +* :feature:`924` Add new env var option :ref:`colorize-errors` to enable + coloring errors and warnings. Thanks to Aaron Meurer for the patch. +* :bug:`593` Non-ASCII character sets in Jinja templates rendered within + `.upload_template` would cause ``UnicodeDecodeError`` when uploaded. This has + been addressed by encoding as ``utf-8`` prior to upload. Thanks to Sébastien + Fievet for the catch. +* :feature:`908` Support loading SSH keys from memory. Thanks to Caleb Groom + for the patch. +* :bug:`171` Added missing cross-references from ``env`` variables documentation + to corresponding command-line options. Thanks to Daniel D. Beck for the + contribution. +* :bug:`884` The password cache feature was not working correctly with + password-requiring SSH gateway connections. That's fixed now. Thanks to Marco + Nenciarini for the catch. +* :feature:`826` Enable sudo extraction of compressed archive via `use_sudo` + kwarg in `.upload_project`. Thanks to ``@abec`` for the patch. +* :bug:`694 major` Allow users to work around ownership issues in the default + remote login directory: add ``temp_dir`` kwarg for explicit specification of + which "bounce" folder to use when calling `.put` with ``use_sudo=True``. + Thanks to Devin Bayer for the report & Dieter Plaetinck / Jesse Myers for + suggesting the workaround. +* :bug:`882` Fix a `.get` bug regarding spaces in remote working directory + names. Thanks to Chris Rose for catch & patch. +* :release:`1.6.1 <2013-05-23>` +* :bug:`868` Substantial speedup of parallel tasks by removing an unnecessary + blocking timeout in the ``JobQueue`` loop. Thanks to Simo Kinnunen for the + patch. +* :bug:`328` `.lcd` was no longer being correctly applied to + `.upload_template`; this has been fixed. Thanks to Joseph Lawson for the + catch. +* :feature:`812` Add ``use_glob`` option to `.put` so users trying to upload + real filenames containing glob patterns (``*``, ``[`` etc) can disable the + default globbing behavior. Thanks to Michael McHugh for the patch. +* :bug:`864 major` Allow users to disable Fabric's auto-escaping in + `.run`/`.sudo`. Thanks to Christian Long and Michael McHugh for the patch. +* :bug:`870` Changes to shell env var escaping highlighted some extraneous and + now damaging whitespace in `with path(): <.path>`. This has been removed and + a regression test added. +* :bug:`871` Use of string mode values in `put(local, remote, mode="NNNN") + <.put>` would sometimes cause ``Unsupported operand`` errors. This has been + fixed. +* :bug:`84 major` Fixed problem with missing -r flag in Mac OS X sed version. + Thanks to Konrad Hałas for the patch. +* :bug:`861` Gracefully handle situations where users give a single string + literal to ``env.hosts``. Thanks to Bill Tucker for catch & patch. +* :bug:`367` Expand paths with tilde inside (``contrib.files``). Thanks to + Konrad Hałas for catch & patch. +* :feature:`845 backported` Downstream synchronization option implemented for + `~fabric.contrib.project.rsync_project`. Thanks to Antonio Barrero for the + patch. +* :release:`1.6.0 <2013-03-01>` +* :release:`1.5.4 <2013-03-01>` +* :bug:`844` Account for SSH config overhaul in Paramiko 1.10 by e.g. updating + treatment of ``IdentityFile`` to handle multiple values. **This and related + SSH config parsing changes are backwards incompatible**; we are including + them in this release because they do fix incorrect, off-spec behavior. +* :bug:`843` Ensure string ``pool_size`` values get run through ``int()`` + before deriving final result (stdlib ``min()`` has odd behavior here...). + Thanks to Chris Kastorff for the catch. +* :bug:`839` Fix bug in `~fabric.contrib.project.rsync_project` where IPv6 + address were not always correctly detected. Thanks to Antonio Barrero for + catch & patch. +* :bug:`587` Warn instead of aborting when :ref:`env.use_ssh_config + ` is True but the configured SSH conf file doesn't exist. + This allows multi-user fabfiles to enable SSH config without causing hard + stops for users lacking SSH configs. Thanks to Rodrigo Pimentel for the + report. +* :feature:`821` Add `~fabric.context_managers.remote_tunnel` to allow reverse + SSH tunneling (exposing locally-visible network ports to the remote end). + Thanks to Giovanni Bajo for the patch. +* :feature:`823` Add :ref:`env.remote_interrupt ` which + controls whether Ctrl-C is forwarded to the remote end or is captured locally + (previously, only the latter behavior was implemented). Thanks to Geert + Jansen for the patch. +* :release:`1.5.3 <2013-01-28>` +* :bug:`806` Force strings given to ``getpass`` during password prompts to be + ASCII, to prevent issues on some platforms when Unicode is encountered. + Thanks to Alex Louden for the patch. +* :bug:`805` Update `~fabric.context_managers.shell_env` to play nice with + Windows (7, at least) systems and `~fabric.operations.local`. Thanks to + Fernando Macedo for the patch. +* :bug:`654` Parallel runs whose sum total of returned data was large (e.g. + large return values from the task, or simply a large number of hosts in the + host list) were causing frustrating hangs. This has been fixed. +* :feature:`402` Attempt to detect stale SSH sessions and reconnect when they + arise. Thanks to `@webengineer` for the patch. +* :bug:`791` Cast `~fabric.operations.reboot`'s ``wait`` parameter to a numeric + type in case the caller submitted a string by mistake. Thanks to Thomas + Schreiber for the patch. +* :bug:`703 major` Add a ``shell`` kwarg to many methods in + `~fabric.contrib.files` to help avoid conflicts with + `~fabric.context_managers.cd` and similar. Thanks to `@mikek` for the patch. +* :feature:`730` Add :ref:`env.system_known_hosts/--system-known-hosts + ` to allow loading a user-specified system-level SSH + ``known_hosts`` file. Thanks to Roy Smith for the patch. +* :release:`1.5.2 <2013-01-15>` +* :feature:`818` Added :ref:`env.eagerly_disconnect ` + option to help prevent pile-up of many open connections. +* :feature:`706` Added :ref:`env.tasks `, returning list of tasks to + be executed by current ``fab`` command. +* :bug:`766` Use the variable name of a new-style ``fabric.tasks.Task`` + subclass object when the object name attribute is undefined. Thanks to + `@todddeluca` for the patch. +* :bug:`604` Fixed wrong treatment of backslashes in put operation when uploading + directory tree on Windows. Thanks to Jason Coombs for the catch and + `@diresys` & Oliver Janik for the patch. + for the patch. +* :bug:`792` The newish `~fabric.context_managers.shell_env` context manager + was incorrectly omitted from the ``fabric.api`` import endpoint. This has + been remedied. Thanks to Vishal Rana for the catch. +* :feature:`735` Add ``ok_ret_codes`` option to ``env`` to allow alternate + return codes to be treated os "ok". Thanks to Andy Kraut for the pull request. +* :bug:`775` Shell escaping was incorrectly applied to the value of ``$PATH`` + updates in our shell environment handling, causing (at the very least) + `~fabric.operations.local` binary paths to become inoperable in certain + situations. This has been fixed. +* :feature:`787` Utilize new Paramiko feature allowing us to skip the use of + temporary local files when using file-like objects in + `~fabric.operations.get`/`~fabric.operations.put`. +* :feature:`249` Allow specification of remote command timeout value by + setting :ref:`env.command_timeout `. Thanks to Paul + McMillan for suggestion & initial patch. +* Added current host string to prompt abort error messages. +* :release:`1.5.1 <2012-11-15>` +* :bug:`776` Fixed serious-but-non-obvious bug in direct-tcpip driven + gatewaying (e.g. that triggered by ``-g`` or ``env.gateway``.) Should work + correctly now. +* :bug:`771` Sphinx autodoc helper `~fabric.docs.unwrap_tasks` didn't play nice + with ``@task(name=xxx)`` in some situations. This has been fixed. +* :release:`1.5.0 <2012-11-06>` +* :release:`1.4.4 <2012-11-06>` +* :feature:`38` (also :issue:`698`) Implement both SSH-level and + ``ProxyCommand``-based gatewaying for SSH traffic. (This is distinct from + tunneling non-SSH traffic over the SSH connection, which is :issue:`78` and + not implemented yet.) + + * Thanks in no particular order to Erwin Bolwidt, Oskari Saarenmaa, Steven + Noonan, Vladimir Lazarenko, Lincoln de Sousa, Valentino Volonghi, Olle + Lundberg and Github user `@acrish` for providing the original patches to + both Fabric and Paramiko. + +* :feature:`684 backported` (also :issue:`569`) Update how + `~fabric.decorators.task` wraps task functions to preserve additional + metadata; this allows decorated functions to play nice with Sphinx autodoc. + Thanks to Jaka Hudoklin for catch & patch. +* :support:`103` (via :issue:`748`) Long standing Sphinx autodoc issue requiring + error-prone duplication of function signatures in our API docs has been + fixed. Thanks to Alex Morega for the patch. +* :bug:`767 major` Fix (and add test for) regression re: having linewise output + automatically activate when parallelism is in effect. Thanks to Alexander + Fortin and Dustin McQuay for the bug reports. +* :bug:`736 major` Ensure context managers that build env vars play nice with + ``contextlib.nested`` by deferring env var reference to entry time, not call + time. Thanks to Matthew Tretter for catch & patch. +* :feature:`763` Add :option:`--initial-password-prompt <-I>` to allow + prefilling the password cache at the start of a run. Great for sudo-powered + parallel runs. +* :feature:`665` (and #629) Update `~fabric.contrib.files.upload_template` to + have a more useful return value, namely that of its internal + `~fabric.operations.put` call. Thanks to Miquel Torres for the catch & + Rodrigue Alcazar for the patch. +* :feature:`578` Add ``name`` argument to `~fabric.decorators.task` (:ref:`docs + `) to allow overriding of the default "function + name is task name" behavior. Thanks to Daniel Simmons for catch & patch. +* :feature:`761` Allow advanced users to parameterize ``fabric.main.main()`` to + force loading of specific fabfiles. +* :bug:`749` Gracefully work around calls to ``fabric.version`` on systems + lacking ``/bin/sh`` (which causes an ``OSError`` in ``subprocess.Popen`` + calls.) +* :feature:`723` Add the ``group=`` argument to + `~fabric.operations.sudo`. Thanks to Antti Kaihola for the pull request. +* :feature:`725` Updated `~fabric.operations.local` to allow override + of which local shell is used. Thanks to Mustafa Khattab. +* :bug:`704 major` Fix up a bunch of Python 2.x style ``print`` statements to + be forwards compatible. Thanks to Francesco Del Degan for the patch. +* :feature:`491` (also :feature:`385`) IPv6 host string support. Thanks to Max + Arnold for the patch. +* :feature:`699` Allow `name` attribute on file-like objects for get/put. Thanks + to Peter Lyons for the pull request. +* :bug:`711 major` `~fabric.sftp.get` would fail when filenames had % in their + path. Thanks to John Begeman +* :bug:`702 major` `~fabric.operations.require` failed to test for "empty" + values in the env keys it checks (e.g. + ``require('a-key-whose-value-is-an-empty-list')`` would register a successful + result instead of alerting that the value was in fact empty. This has been + fixed, thanks to Rich Schumacher. +* :bug:`718` ``isinstance(foo, Bar)`` is used in `~fabric.main` instead + of ``type(foo) == Bar`` in order to fix some edge cases. + Thanks to Mikhail Korobov. +* :bug:`693` Fixed edge case where ``abort`` driven failures within parallel + tasks could result in a top level exception (a ``KeyError``) regarding error + handling. Thanks to Marcin Kuźmiński for the report. +* :support:`681 backported` Fixed outdated docstring for + `~fabric.decorators.runs_once` which claimed it would get run multiple times + in parallel mode. That behavior was fixed in an earlier release but the docs + were not updated. Thanks to Jan Brauer for the catch. +* :release:`1.4.3 <2012-07-06>` +* :release:`1.3.8 <2012-07-06>` +* :feature:`263` Shell environment variable support for + `~fabric.operations.run`/`~fabric.operations.sudo` added in the form of the + `~fabric.context_managers.shell_env` context manager. Thanks to Oliver + Tonnhofer for the original pull request, and to Kamil Kisiel for the final + implementation. +* :feature:`669` Updates to our Windows compatibility to rely more heavily on + cross-platform Python stdlib implementations. Thanks to Alexey Diyan for the + patch. +* :bug:`671` :ref:`reject-unknown-hosts` sometimes resulted in a password + prompt instead of an abort. This has been fixed. Thanks to Roy Smith for the + report. +* :bug:`659` Update docs to reflect that `~fabric.operations.local` currently + honors :ref:`env.path `. Thanks to `@floledermann + `_ for the catch. +* :bug:`652` Show available commands when aborting on invalid command names. +* :support:`651 backported` Added note about nesting ``with`` statements on + Python 2.6+. Thanks to Jens Rantil for the patch. +* :bug:`649` Don't swallow non-``abort``-driven exceptions in parallel mode. + Fabric correctly printed such exceptions, and returned them from + `~fabric.tasks.execute`, but did not actually cause the child or parent + processes to halt with a nonzero status. This has been fixed. + `~fabric.tasks.execute` now also honors :ref:`env.warn_only ` so + users may still opt to call it by hand and inspect the returned exceptions, + instead of encountering a hard stop. Thanks to Matt Robenolt for the catch. +* :feature:`241` Add the command executed as a ``.command`` attribute to the + return value of `~fabric.operations.run`/`~fabric.operations.sudo`. (Also + includes a second attribute containing the "real" command executed, including + the shell wrapper and any escaping.) +* :feature:`646` Allow specification of which local streams to use when + `~fabric.operations.run`/`~fabric.operations.sudo` print the remote + stdout/stderr, via e.g. ``run("command", stderr=sys.stdout)``. +* :support:`645 backported` Update Sphinx docs to work well when run out of a + source tarball as opposed to a Git checkout. Thanks again to `@Arfrever` for + the catch. +* :support:`640 backported` (also :issue:`644`) Update packaging manifest so + sdist tarballs include all necessary test & doc files. Thanks to Mike Gilbert + and `@Arfrever` for catch & patch. +* :feature:`627` Added convenient ``quiet`` and ``warn_only`` keyword arguments + to `~fabric.operations.run`/`~fabric.operations.sudo` which are aliases for + ``settings(hide('everything'), warn_only=True)`` and + ``settings(warn_only=True)``, respectively. (Also added corresponding + `context ` `managers + `.) Useful for remote program calls which + are expected to fail and/or whose output doesn't need to be shown to users. +* :feature:`633` Allow users to turn off host list deduping by setting + :ref:`env.dedupe_hosts ` to ``False``. This enables running the + same task multiple times on a single host, which was previously not possible. +* :support:`634 backported` Clarified that `~fabric.context_managers.lcd` does + no special handling re: the user's current working directory, and thus + relative paths given to it will be relative to ``os.getcwd()``. Thanks to + `@techtonik `_ for the catch. +* :release:`1.4.2 <2012-05-07>` +* :release:`1.3.7 <2012-05-07>` +* :bug:`562` Agent forwarding would error out or freeze when multiple uses of + the forwarded agent were used per remote invocation (e.g. a single + `~fabric.operations.run` command resulting in multiple Git or SVN checkouts.) + This has been fixed thanks to Steven McDonald and GitHub user `@lynxis`. +* :support:`626 backported` Clarity updates to the tutorial. Thanks to GitHub + user `m4z` for the patches. +* :bug:`625` `~fabric.context_managers.hide`/`~fabric.context_managers.show` + did not correctly restore prior display settings if an exception was raised + inside the block. This has been fixed. +* :bug:`624` Login password prompts did not always display the username being + authenticated for. This has been fixed. Thanks to Nick Zalutskiy for catch & + patch. +* :bug:`617` Fix the ``clean_revert`` behavior of + `~fabric.context_managers.settings` so it doesn't ``KeyError`` for newly + created settings keys. Thanks to Chris Streeter for the catch. +* :feature:`615` Updated `~fabric.operations.sudo` to honor the new setting + :ref:`env.sudo_user ` as a default for its ``user`` kwarg. +* :bug:`616` Add port number to the error message displayed upon connection + failures. +* :bug:`609` (and :issue:`564`) Document and clean up :ref:`env.sudo_prefix + ` so it can be more easily modified by users facing uncommon + use cases. Thanks to GitHub users `3point2` for the cleanup and `SirScott` + for the documentation catch. +* :bug:`610` Change detection of ``env.key_filename``'s type (added as part of + SSH config support in 1.4) so it supports arbitrary iterables. Thanks to + Brandon Rhodes for the catch. +* :release:`1.4.1 <2012-04-04>` +* :release:`1.3.6 <2012-04-04>` +* :bug:`608` Add ``capture`` kwarg to `~fabric.contrib.project.rsync_project` + to aid in debugging rsync problems. +* :bug:`607` Allow `~fabric.operations.local` to display stdout/stderr when it + warns/aborts, if it was capturing them. +* :bug:`395` Added :ref:`an FAQ entry ` detailing how to + handle init scripts which misbehave when a pseudo-tty is allocated. +* :bug:`568` `~fabric.tasks.execute` allowed too much of its internal state + changes (to variables such as ``env.host_string`` and ``env.parallel``) to + persist after execution completed; this caused a number of different + incorrect behaviors. `~fabric.tasks.execute` has been overhauled to clean up + its own state changes -- while preserving any state changes made by the task + being executed. +* :bug:`584` `~fabric.contrib.project.upload_project` did not take explicit + remote directory location into account when untarring, and now uses + `~fabric.context_managers.cd` to address this. Thanks to Ben Burry for the + patch. +* :bug:`458` `~fabric.decorators.with_settings` did not perfectly match + `~fabric.context_managers.settings`, re: ability to inline additional context + managers. This has been corrected. Thanks to Rory Geoghegan for the patch. +* :bug:`499` `contrib.files.first ` used an + outdated function signature in its wrapped `~fabric.contrib.files.exists` + call. This has been fixed. Thanks to Massimiliano Torromeo for catch & patch. +* :bug:`551` :option:`--list <-l>` output now detects terminal window size + and truncates (or doesn't truncate) accordingly. Thanks to Horacio G. de Oro + for the initial pull request. +* :bug:`572` Parallel task aborts (as oppposed to unhandled exceptions) now + correctly print their abort messages instead of tracebacks, and cause the + parent process to exit with the correct (nonzero) return code. Thanks to Ian + Langworth for the catch. +* :bug:`306` Remote paths now use posixpath for a separator. Thanks to Jason + Coombs for the patch. +* :release:`1.4.0 <2012-02-13>` +* :release:`1.3.5 <2012-02-13>` +* :release:`1.2.6 <2012-02-13>` +* :release:`1.1.8 <2012-02-13>` +* :bug:`495` Fixed documentation example showing how to subclass + `~fabric.tasks.Task`. Thanks to Brett Haydon for the catch and Mark Merritt + for the patch. +* :bug:`410` Fixed a bug where using the `~fabric.decorators.task` decorator + inside/under another decorator such as `~fabric.decorators.hosts` could cause + that task to become invalid when invoked by name (due to how old-style vs + new-style tasks are detected.) Thanks to Dan Colish for the initial patch. +* :feature:`559` `~fabric.contrib.project.rsync_project` now allows users to + append extra SSH-specific arguments to ``rsync``'s ``--rsh`` flag. +* :feature:`138` :ref:`env.port ` may now be written to at fabfile module + level to set a default nonstandard port number. Previously this value was + read-only. +* :feature:`3` Fabric can now load a subset of SSH config functionality + directly from your local ``~/.ssh/config`` if :ref:`env.use_ssh_config + ` is set to ``True``. See :ref:`ssh-config` for details. + Thanks to Kirill Pinchuk for the initial patch. +* :feature:`12` Added the ability to try connecting multiple times to + temporarily-down remote systems, instead of immediately failing. (Default + behavior is still to only try once.) See :ref:`env.timeout ` and + :ref:`env.connection_attempts ` for controlling both + connection timeouts and total number of attempts. `~fabric.operations.reboot` + has also been overhauled (but practically deprecated -- see its updated + docs.) +* :feature:`474` `~fabric.tasks.execute` now allows you to access the executed + task's return values, by itself returning a dictionary whose keys are the + host strings executed against. +* :bug:`487 major` Overhauled the regular expression escaping performed in + `~fabric.contrib.files.append` and `~fabric.contrib.files.contains` to try + and handle more corner cases. Thanks to Neilen Marais for the patch. +* :support:`532` Reorganized and cleaned up the output of ``fab --help``. +* :feature:`8` Added :option:`--skip-bad-hosts`/:ref:`env.skip_bad_hosts + ` option to allow skipping past temporarily down/unreachable + hosts. +* :feature:`13` Env vars may now be set at runtime via the new :option:`--set` + command-line flag. +* :feature:`506` A new :ref:`output alias `, ``commands``, has + been added, which allows hiding remote stdout and local "running command X" + output lines. +* :feature:`72` SSH agent forwarding support has made it into Fabric's SSH + library, and hooks for using it have been added (disabled by default; use + :option:`-A` or :ref:`env.forward_agent ` to enable.) Thanks + to Ben Davis for porting an existing Paramiko patch to `ssh` and providing + the necessary tweak to Fabric. +* :release:`1.3.4 <2012-01-12>` +* :bug:`492` `@parallel ` did not automatically + trigger :ref:`linewise output `, as was intended. This has + been fixed. Thanks to Brandon Huey for the catch. +* :bug:`510` Parallel mode is incompatible with user input, such as + password/hostname prompts, and was causing cryptic `Operation not supported + by device` errors when such prompts needed to be displayed. This behavior has + been updated to cleanly and obviously ``abort`` instead. +* :bug:`494` Fixed regression bug affecting some `env` values such as + `env.port` under parallel mode. Symptoms included + `~fabric.contrib.project.rsync_project` bailing out due to a None port value + when run under `@parallel `. Thanks to Rob + Terhaar for the report. +* :bug:`339` Don't show imported `~fabric.colors` members in :option:`--list + <-l>` output. Thanks to Nick Trew for the report. +* :release:`1.3.3 <2011-11-23>` +* :release:`1.2.5 <2011-11-23>` +* :release:`1.1.7 <2011-11-23>` +* :bug:`441` Specifying a task module as a task on the command line no longer + blows up but presents the usual "no task by that name" error message instead. + Thanks to Mitchell Hashimoto for the catch. +* :bug:`475` Allow escaping of equals signs in per-task args/kwargs. +* :bug:`450` Improve traceback display when handling ``ImportError`` for + dependencies. Thanks to David Wolever for the patches. +* :bug:`446` Add QNX to list of secondary-case `~fabric.contrib.files.sed` + targets. Thanks to Rodrigo Madruga for the tip. +* :bug:`443` `~fabric.contrib.files.exists` didn't expand tildes; now it does. + Thanks to Riccardo Magliocchetti for the patch. +* :bug:`437` `~fabric.decorators.with_settings` now correctly preserves the + wrapped function's docstring and other attributes. Thanks to Eric Buckley for + the catch and Luke Plant for the patch. +* :bug:`400` Handle corner case of systems where ``pwd.getpwuid`` raises + ``KeyError`` for the user's UID instead of returning a valid string. Thanks + to Dougal Matthews for the catch. +* :bug:`397` Some poorly behaved objects in third party modules triggered + exceptions during Fabric's "classic or new-style task?" test. A fix has been + added which tries to work around these. +* :bug:`341` `~fabric.contrib.files.append` incorrectly failed to detect that + the line(s) given already existed in files hidden to the remote user, and + continued appending every time it ran. This has been fixed. Thanks to + Dominique Peretti for the catch and Martin Vilcans for the patch. +* :bug:`342` Combining `~fabric.context_managers.cd` with + `~fabric.operations.put` and its ``use_sudo`` keyword caused an unrecoverable + error. This has been fixed. Thanks to Egor M for the report. +* :bug:`482` Parallel mode should imply linewise output; omission of this + behavior was an oversight. +* :bug:`230` Fix regression re: combo of no fabfile & arbitrary command use. + Thanks to Ali Saifee for the catch. +* :release:`1.3.2 <2011-11-07>` +* :release:`1.2.4 <2011-11-07>` +* :release:`1.1.6 <2011-11-07>` +* :support:`459 backported` Update our `setup.py` files to note that PyCrypto + released 2.4.1, which fixes the setuptools problems. +* :support:`467 backported` (also :issue:`468`, :issue:`469`) Handful of + documentation clarification tweaks. Thanks to Paul Hoffman for the patches. +* :release:`1.3.1 <2011-10-24>` +* :bug:`457` Ensured that Fabric fast-fails parallel tasks if any child + processes encountered errors. Previously, multi-task invocations would + continue to the 2nd, etc task when failures occurred, which does not fit with + how Fabric usually behaves. Thanks to Github user ``sdcooke`` for the report + and Morgan Goose for the fix. +* :release:`1.3.0 <2011-10-23>` +* :release:`1.2.3 <2011-10-23>` +* :release:`1.1.5 <2011-10-23>` +* :release:`1.0.5 <2011-10-23>` +* :support:`275` To support an edge use case of the features released in + :issue:`19`, and to lay the foundation for :issue:`275`, we have forked + Paramiko into the `Python 'ssh' library `_ + and changed our dependency to it for Fabric 1.3 and higher. This may have + implications for the more uncommon install use cases, and package + maintainers, but we hope to iron out any issues as they come up. +* :bug:`323` `~fabric.operations.put` forgot how to expand leading tildes in + the remote file path. This has been corrected. Thanks to Piet Delport for the + catch. +* :feature:`21` It is now possible, using the new `~fabric.tasks.execute` API + call, to execute task objects (by reference or by name) from within other + tasks or in library mode. `~fabric.tasks.execute` honors the other tasks' + `~fabric.decorators.hosts`/`~fabric.decorators.roles` decorators, and also + supports passing in explicit host and/or role arguments. +* :feature:`19` Tasks may now be optionally executed in parallel. Please see + the :ref:`parallel execution docs ` for details. Major + thanks to Morgan Goose for the initial implementation. +* :bug:`182` During display of remote stdout/stderr, Fabric occasionally + printed extraneous line prefixes (which in turn sometimes overwrote wrapped + text.) This has been fixed. +* :bug:`430` Tasks decorated with `~fabric.decorators.runs_once` printed + extraneous 'Executing...' status lines on subsequent invocations. This is + noisy at best and misleading at worst, and has been corrected. Thanks to + Jacob Kaplan-Moss for the report. +* :release:`1.2.2 <2011-09-01>` +* :release:`1.1.4 <2011-09-01>` +* :release:`1.0.4 <2011-09-01>` +* :bug:`252` `~fabric.context_managers.settings` would silently fail to set + ``env`` values for keys which did not exist outside the context manager + block. It now works as expected. Thanks to Will Maier for the catch and + suggested solution. +* :support:`393 backported` Fixed a typo in an example code snippet in the task + docs. Thanks to Hugo Garza for the catch. +* :bug:`396` :option:`--shortlist` broke after the addition of + :option:`--list-format <-F>` and no longer displayed the short list format + correctly. This has been fixed. +* :bug:`373` Re-added missing functionality preventing :ref:`host exclusion + ` from working correctly. +* :bug:`303` Updated terminal size detection to correctly skip over non-tty + stdout, such as when running ``fab taskname | other_command``. +* :release:`1.2.1 <2011-08-21>` +* :release:`1.1.3 <2011-08-21>` +* :release:`1.0.3 <2011-08-21>` +* :bug:`417` :ref:`abort-on-prompts` would incorrectly abort when set to True, + even if both password and host were defined. This has been fixed. Thanks to + Valerie Ishida for the report. +* :support:`416 backported` Updated documentation to reflect move from Redmine + to Github. +* :bug:`389` Fixed/improved error handling when Paramiko import fails. Thanks + to Brian Luft for the catch. +* :release:`1.2.0 <2011-07-12>` +* :feature:`22` Enhanced `@task ` to add :ref:`aliasing + `, :ref:`per-module default tasks `, and + :ref:`control over the wrapping task class `. + Thanks to Travis Swicegood for the initial work and collaboration. +* :bug:`380` Improved unicode support when testing objects for being + string-like. Thanks to Jiri Barton for catch & patch. +* :support:`382` Experimental overhaul of changelog formatting & process to + make supporting multiple lines of development less of a hassle. +* :release:`1.1.2 <2011-07-07>` +* :release:`1.0.2 <2011-06-24>` diff -Nru fabric-1.8.2/sites/www/conf.py fabric-1.10.0/sites/www/conf.py --- fabric-1.8.2/sites/www/conf.py 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/conf.py 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,28 @@ +# Obtain shared config values +import sys +import os +from os.path import abspath, join, dirname + +sys.path.append(abspath(join(dirname(__file__), '..'))) +from shared_conf import * + + +# Releases changelog extension +extensions.append('releases') +releases_github_path = "fabric/fabric" + +# Intersphinx for referencing API/usage docs +extensions.append('sphinx.ext.intersphinx') +# Default is 'local' building, but reference the public docs site when building +# under RTD. +target = join(dirname(__file__), '..', 'docs', '_build') +if os.environ.get('READTHEDOCS') == 'True': + target = 'http://docs.fabfile.org/en/latest/' +intersphinx_mapping = { + 'docs': (target, None), +} + +# Sister-site links to API docs +html_theme_options['extra_nav_links'] = { + "API Docs": 'http://docs.fabfile.org', +} diff -Nru fabric-1.8.2/sites/www/contact.rst fabric-1.10.0/sites/www/contact.rst --- fabric-1.8.2/sites/www/contact.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/contact.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,43 @@ +======= +Contact +======= + +If you've scoured the :ref:`prose ` and :ref:`API ` +documentation and still can't find an answer to your question, below are +various support resources that should help. We do request that you do at least +skim the documentation before posting tickets or mailing list questions, +however! + +Mailing list +------------ + +The best way to get help with using Fabric is via the `fab-user mailing list +`_ (currently hosted at +``nongnu.org``.) The Fabric developers do their best to reply promptly, and the +list contains an active community of other Fabric users and contributors as +well. + +Twitter +------- + +Fabric has an official Twitter account, `@pyfabric +`_, which is used for announcements and occasional +related news tidbits (e.g. "Hey, check out this neat article on Fabric!"). + +.. _bugs: + +Bugs/ticket tracker +------------------- + +To file new bugs or search existing ones, you may visit Fabric's `Github Issues +`_ page. This does require a (free, easy to set up) Github account. + +.. _irc: + +IRC +--- + +We maintain a semi-official IRC channel at ``#fabric`` on Freenode +(``irc://irc.freenode.net``) where the developers and other users may be found. +As always with IRC, we can't promise immediate responses, but some folks keep +logs of the channel and will try to get back to you when they can. diff -Nru fabric-1.8.2/sites/www/development.rst fabric-1.10.0/sites/www/development.rst --- fabric-1.8.2/sites/www/development.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/development.rst 2014-09-03 22:51:54.000000000 +0000 @@ -0,0 +1,64 @@ +=========== +Development +=========== + +The Fabric development team is headed by `Jeff Forcier +`_, aka ``bitprophet``. However, dozens of other +developers pitch in by submitting patches and ideas via `GitHub issues and pull +requests `_, :ref:`IRC ` or the `mailing +list `_. + +Get the code +============ + +Please see the :ref:`source-code-checkouts` section of the :doc:`installing` +page for details on how to obtain Fabric's source code. + +Contributing +============ + +There are a number of ways to get involved with Fabric: + +* **Use Fabric and send us feedback!** This is both the easiest and arguably + the most important way to improve the project -- let us know how you + currently use Fabric and how you want to use it. (Please do try to search the + `ticket tracker`_ first, though, + when submitting feature ideas.) +* **Report bugs or submit feature requests.** We follow `contribution-guide.org`_'s guidelines, so please check them out before + visiting the `ticket tracker`_. +* **Fix bugs or implement features!** Again, follow `contribution-guide.org`_ + for details on this process. Regarding the changelog step, our changelog is + stored in ``sites/www/changelog.rst``. + +.. _contribution-guide.org: http://contribution-guide.org +.. _ticket tracker: https://github.com/fabric/fabric/issues + +While we may not always reply promptly, we do try to make time eventually to +inspect all contributions and either incorporate them or explain why we don't +feel the change is a good fit. + + +Support of older releases +========================= + +Major and minor releases do not mark the end of the previous line or lines of +development: + +* The two most recent minor release branches will continue to receive critical + bugfixes. For example, if 1.1 were the latest minor release, it and 1.0 would + get bugfixes, but not 0.9 or earlier; and once 1.2 came out, this window + would then only extend back to 1.1. +* Depending on the nature of bugs found and the difficulty in backporting them, + older release lines may also continue to get bugfixes -- but there's no + longer a guarantee of any kind. Thus, if a bug were found in 1.1 that + affected 0.9 and could be easily applied, a new 0.9.x version *might* be + released. +* This policy may change in the future to accommodate more branches, depending + on development speed. + +We hope that this policy will allow us to have a rapid minor release cycle (and +thus keep new features coming out frequently) without causing users to feel too +much pressure to upgrade right away. At the same time, the backwards +compatibility guarantee means that users should still feel comfortable +upgrading to the next minor release in order to stay within this sliding +support window. diff -Nru fabric-1.8.2/sites/www/faq.rst fabric-1.10.0/sites/www/faq.rst --- fabric-1.8.2/sites/www/faq.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/faq.rst 2014-09-03 22:51:54.000000000 +0000 @@ -0,0 +1,280 @@ +================================ +Frequently Asked Questions (FAQ) +================================ + +These are some of the most commonly encountered problems or frequently asked +questions which we receive from users. They aren't intended as a substitute for +reading the rest of the documentation, especially the :ref:`usage docs +`, so please make sure you check those out if your question is not +answered here. + + +Fabric installs but doesn't run! +================================ + +On systems with old versions of ``setuptools`` (notably OS X Mavericks [10.9] +as well as older Linux distribution versions) users frequently have problems +running Fabric's binary scripts; this is because these ``setuptools`` are too +old to deal with the modern distribution formats Fabric and some of its +dependencies may use. + +One method we've used to recreate this error: + +* OS X 10.9 using system Python +* Pip obtained via e.g. ``sudo easy_install pip`` or ``sudo python get-pip.py`` +* ``pip install fabric`` +* ``fab [args]`` then results in the following traceback:: + + Traceback (most recent call last): + File "/usr/local/bin/fab", line 5, in + from pkg_resources import load_entry_point + File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 2603, in + working_set.require(__requires__) + File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 666, in require + needed = self.resolve(parse_requirements(requirements)) + File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 565, in resolve + raise DistributionNotFound(req) # XXX put more info here + pkg_resources.DistributionNotFound: paramiko>=1.10 + +The best solution is to obtain a newer ``setuptools`` (which fixes this bug +among many others) like so:: + + $ sudo pip install -U setuptools + +Uninstalling, then reinstalling Fabric after doing so should fix the issue. + +Another approach is to tell ``pip`` not to use the ``wheel`` format (make sure +you've already uninstalled Fabric and Paramiko beforehand):: + + $ sudo pip install fabric --no-use-wheel + +Finally, you may also find success by using a different Python +interpreter/ecosystem, such as that provided by `Homebrew `_ +(`specific Python doc page +`_). + + +How do I dynamically set host lists? +==================================== + +See :ref:`dynamic-hosts`. + + +How can I run something after my task is done on all hosts? +=========================================================== + +See :ref:`leveraging-execute-return-value`. + + +.. _init-scripts-pty: + +Init scripts don't work! +======================== + +Init-style start/stop/restart scripts (e.g. ``/etc/init.d/apache2 start``) +sometimes don't like Fabric's allocation of a pseudo-tty, which is active by +default. In almost all cases, explicitly calling the command in question with +``pty=False`` works correctly:: + + sudo("/etc/init.d/apache2 restart", pty=False) + +If you have no need for interactive behavior and run into this problem +frequently, you may want to deactivate pty allocation globally by setting +:ref:`env.always_use_pty ` to ``False``. + +.. _one-shell-per-command: + +My (``cd``/``workon``/``export``/etc) calls don't seem to work! +=============================================================== + +While Fabric can be used for many shell-script-like tasks, there's a slightly +unintuitive catch: each `~fabric.operations.run` or `~fabric.operations.sudo` +call has its own distinct shell session. This is required in order for Fabric +to reliably figure out, after your command has run, what its standard out/error +and return codes were. + +Unfortunately, it means that code like the following doesn't behave as you +might assume:: + + def deploy(): + run("cd /path/to/application") + run("./update.sh") + +If that were a shell script, the second `~fabric.operations.run` call would +have executed with a current working directory of ``/path/to/application/`` -- +but because both commands are run in their own distinct session over SSH, it +actually tries to execute ``$HOME/update.sh`` instead (since your remote home +directory is the default working directory). + +A simple workaround is to make use of shell logic operations such as ``&&``, +which link multiple expressions together (provided the left hand side executed +without error) like so:: + + def deploy(): + run("cd /path/to/application && ./update.sh") + +Fabric provides a convenient shortcut for this specific use case, in fact: +`~fabric.context_managers.cd`. There is also `~fabric.context_managers.prefix` +for arbitrary prefix commands. + +.. note:: + You might also get away with an absolute path and skip directory changing + altogether:: + + def deploy(): + run("/path/to/application/update.sh") + + However, this requires that the command in question makes no assumptions + about your current working directory! + + +How do I use ``su`` to run commands as another user? +==================================================== + +This is a special case of :ref:`one-shell-per-command`. As that FAQ explains, +commands like ``su`` which are 'stateful' do not work well in Fabric, so +workarounds must be used. + +In the case of running commands as a user distinct from the login user, you +have two options: + +#. Use `~fabric.operations.sudo` with its ``user=`` kwarg, e.g. + ``sudo("command", user="otheruser")``. If you want to factor the ``user`` + part out of a bunch of commands, use `~fabric.context_managers.settings` to + set ``env.sudo_user``:: + + with settings(sudo_user="otheruser"): + sudo("command 1") + sudo("command 2") + ... + +#. If your target system cannot use ``sudo`` for some reason, you can still use + ``su``, but you need to invoke it in a non-interactive fashion by telling it + to run a specific command instead of opening a shell. Typically this is the + ``-c`` flag, e.g. ``su otheruser -c "command"``. + + To run multiple commands in the same ``su -c`` "wrapper", you could e.g. + write a wrapper function around `~fabric.operations.run`:: + + def run_su(command, user="otheruser"): + return run('su %s -c "%s"' % (user, command)) + + +Why do I sometimes see ``err: stdin: is not a tty``? +==================================================== + +This message is typically generated by programs such as ``biff`` or ``mesg`` +lurking within your remote user's ``.profile`` or ``.bashrc`` files (or any +other such files, including system-wide ones.) Fabric's default mode of +operation involves executing the Bash shell in "login mode", which causes these +files to be executed. + +Because Fabric also doesn't bother asking the remote end for a tty by default +(as it's not usually necessary) programs fired within your startup files, which +expect a tty to be present, will complain -- and thus, stderr output about +"stdin is not a tty" or similar. + +There are multiple ways to deal with this problem: + +* Find and remove or comment out the offending program call. If the program was + not added by you on purpose and is simply a legacy of the operating system, + this may be safe to do, and is the simplest approach. +* Override ``env.shell`` to remove the ``-l`` flag. This should tell Bash not + to load your startup files. If you don't depend on the contents of your + startup files (such as aliases or whatnot) this may be a good solution. +* Pass ``pty=True`` to `run` or `sudo`, which will force allocation of a + pseudo-tty on the remote end, and hopefully cause the offending program to be + less cranky. + + +.. _faq-daemonize: + +Why can't I run programs in the background with ``&``? It makes Fabric hang. +============================================================================ + +Because Fabric executes a shell on the remote end for each invocation of +``run`` or ``sudo`` (:ref:`see also `), backgrounding a +process via the shell will not work as expected. Backgrounded processes may +still prevent the calling shell from exiting until they stop running, and this +in turn prevents Fabric from continuing on with its own execution. + +The key to fixing this is to ensure that your process' standard pipes are all +disassociated from the calling shell, which may be done in a number of ways +(listed in order of robustness): + +* Use a pre-existing daemonization technique if one exists for the program at + hand -- for example, calling an init script instead of directly invoking a + server binary. + + * Or leverage a process manager such as ``supervisord``, ``upstart`` or + ``systemd`` - such tools let you define what it means to "run" one of + your background processes, then issue init-script-like + start/stop/restart/status commands. They offer many advantages over + classic init scripts as well. + +* Use ``tmux``, ``screen`` or ``dtach`` to fully detach the process from the + running shell; these tools have the benefit of allowing you to reattach to + the process later on if needed (though they are more ad-hoc than + ``supervisord``-like tools). +* You *may* be able to the program under ``nohup`` or similar "in-shell" tools + - however we strongly recommend the prior approaches because ``nohup`` has + only worked well for a minority of our users. + + +.. _faq-bash: + +My remote system doesn't have ``bash`` installed by default, do I need to install ``bash``? +=========================================================================================== + +While Fabric is written with ``bash`` in mind, it's not an absolute +requirement. Simply change :ref:`env.shell ` to call your desired shell, and +include an argument similar to ``bash``'s ``-c`` argument, which allows us to +build shell commands of the form:: + + /bin/bash -l -c "" + +where ``/bin/bash -l -c`` is the default value of :ref:`env.shell `. + +.. note:: + + The ``-l`` argument specifies a login shell and is not absolutely + required, merely convenient in many situations. Some shells lack the option + entirely and it may be safely omitted in such cases. + +A relatively safe baseline is to call ``/bin/sh``, which may call the original +``sh`` binary, or (on some systems) ``csh``, and give it the ``-c`` +argument, like so:: + + from fabric.api import env + + env.shell = "/bin/sh -c" + +This has been shown to work on FreeBSD and may work on other systems as well. + + +I'm sometimes incorrectly asked for a passphrase instead of a password. +======================================================================= + +Due to a bug of sorts in our SSH layer, it's not currently possible for Fabric +to always accurately detect the type of authentication needed. We have to try +and guess whether we're being asked for a private key passphrase or a remote +server password, and in some cases our guess ends up being wrong. + +The most common such situation is where you, the local user, appear to have an +SSH keychain agent running, but the remote server is not able to honor your SSH +key, e.g. you haven't yet transferred the public key over or are using an +incorrect username. In this situation, Fabric will prompt you with "Please +enter passphrase for private key", but the text you enter is actually being +sent to the remote end's password authentication. + +We hope to address this in future releases by modifying a fork of the +aforementioned SSH library. + + +Is Fabric thread-safe? +====================== + +Currently, no, it's not -- the present version of Fabric relies heavily on +shared state in order to keep the codebase simple. However, there are definite +plans to update its internals so that Fabric may be either threaded or +otherwise parallelized so your tasks can run on multiple servers concurrently. diff -Nru fabric-1.8.2/sites/www/index.rst fabric-1.10.0/sites/www/index.rst --- fabric-1.8.2/sites/www/index.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/index.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,24 @@ +Welcome to Fabric! +================== + +.. include:: ../../README.rst + +---- + +This website covers project information for Fabric such as the changelog, +contribution guidelines, development roadmap, news/blog, and so forth. +Detailed usage and API documentation can be found at our code documentation +site, `docs.fabfile.org `_. + +Please see the navigation sidebar to the left to begin. + +.. toctree:: + :hidden: + + changelog + FAQs + installing + troubleshooting + development + Roadmap + contact diff -Nru fabric-1.8.2/sites/www/installing.rst fabric-1.10.0/sites/www/installing.rst --- fabric-1.8.2/sites/www/installing.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/installing.rst 2014-09-03 22:51:54.000000000 +0000 @@ -0,0 +1,190 @@ +========== +Installing +========== + +Fabric is best installed via `pip `_ (highly +recommended) or `easy_install +`_ (older, but still works +fine), e.g.:: + + $ pip install fabric + +You may also opt to use your operating system's package manager; the package is +typically called ``fabric`` or ``python-fabric``. E.g.:: + + $ sudo apt-get install fabric + +Advanced users wanting to install a development version may use ``pip`` to grab +the latest master branch (as well as the dev version of the Paramiko +dependency):: + + $ pip install paramiko==dev + $ pip install fabric==dev + +Or, to install an editable version for debugging/hacking, execute ``pip +install -e .`` (or ``python setup.py develop``) inside a :ref:`downloaded +` or :ref:`cloned ` copy of the source code. + +.. warning:: + + Any development installs of Fabric (whether via ``==dev`` or ``install + -e``) require the development version of Paramiko to be installed + beforehand, or Fabric's installation may fail. + + +Dependencies +============ + +In order for Fabric's installation to succeed, you will need four primary pieces of software: + +* the Python programming language; +* the ``setuptools`` packaging/installation library; +* the Python `Paramiko `_ SSH library; +* and Paramiko's dependency, the PyCrypto cryptography library. + +and, if using the :ref:`parallel execution mode `: + +* the `multiprocessing`_ library. + +If you're using Paramiko 1.12 or above, you will also need an additional +dependency for Paramiko: + +* the `ecdsa `_ library + +Please read on for important details on these -- there are a few gotchas. + +Python +------ + +Fabric requires `Python `_ version 2.5 or 2.6. Some caveats +and notes about other Python versions: + +* We are not planning on supporting **Python 2.4** given its age and the number + of useful tools in Python 2.5 such as context managers and new modules. + That said, the actual amount of 2.5-specific functionality is not + prohibitively large, and we would link to -- but not support -- a third-party + 2.4-compatible fork. (No such fork exists at this time, to our knowledge.) +* Fabric has not yet been tested on **Python 3.x** and is thus likely to be + incompatible with that line of development. However, we try to be at least + somewhat forward-looking (e.g. using ``print()`` instead of ``print``) and + will definitely be porting to 3.x in the future once our dependencies do. + +setuptools +---------- + +`Setuptools`_ comes with some Python installations by default; if yours doesn't, +you'll need to grab it. In such situations it's typically packaged as +``python-setuptools``, ``py25-setuptools`` or similar. Fabric may drop its +setuptools dependency in the future, or include alternative support for the +`Distribute`_ project, but for now setuptools is required for installation. + +.. _setuptools: http://pypi.python.org/pypi/setuptools +.. _Distribute: http://pypi.python.org/pypi/distribute + +``multiprocessing`` +------------------- + +An optional dependency, the ``multiprocessing`` library is included in Python's +standard library in version 2.6 and higher. If you're using Python 2.5 and want +to make use of Fabric's :ref:`parallel execution features ` +you'll need to install it manually; the recommended route, as usual, is via +``pip``. Please see the `multiprocessing PyPI page +`_ for details. + + +.. warning:: + Early versions of Python 2.6 (in our testing, 2.6.0 through 2.6.2) ship + with a buggy ``multiprocessing`` module that appears to cause Fabric to + hang at the end of sessions involving large numbers of concurrent hosts. + If you encounter this problem, either use :ref:`env.pool_size / -z + ` to limit the amount of concurrency, or upgrade to Python + >=2.6.3. + + Python 2.5 is unaffected, as it requires the PyPI version of + ``multiprocessing``, which is newer than that shipped with Python <2.6.3. + +Development dependencies +------------------------ + +If you are interested in doing development work on Fabric (or even just running +the test suite), you may also need to install some or all of the following +packages: + +* `git `_ and `Mercurial`_, in order to obtain some of the + other dependencies below; +* `Nose `_ +* `Coverage `_ +* `PyLint `_ +* `Fudge `_ +* `Sphinx `_ + +For an up-to-date list of exact testing/development requirements, including +version numbers, please see the ``requirements.txt`` file included with the +source distribution. This file is intended to be used with ``pip``, e.g. ``pip +install -r requirements.txt``. + +.. _Mercurial: http://mercurial.selenic.com/wiki/ + + +.. _downloads: + +Downloads +========= + +To obtain a tar.gz or zip archive of the Fabric source code, you may visit +`Fabric's PyPI page `_, which offers manual +downloads in addition to being the entry point for ``pip`` and +``easy-install``. + + +.. _source-code-checkouts: + +Source code checkouts +===================== + +The Fabric developers manage the project's source code with the `Git +`_ DVCS. To follow Fabric's development via Git instead of +downloading official releases, you have the following options: + +* Clone the canonical repository straight from `the Fabric organization's + repository on Github `_, + ``git://github.com/fabric/fabric.git`` +* Make your own fork of the Github repository by making a Github account, + visiting `fabric/fabric `_ and clicking the + "fork" button. + +.. note:: + + If you've obtained the Fabric source via source control and plan on + updating your checkout in the future, we highly suggest using ``python + setup.py develop`` instead -- it will use symbolic links instead of file + copies, ensuring that imports of the library or use of the command-line + tool will always refer to your checkout. + +For information on the hows and whys of Fabric development, including which +branches may be of interest and how you can help out, please see the +:doc:`development` page. + + +.. _pypm: + +ActivePython and PyPM +===================== + +Windows users who already have ActiveState's `ActivePython +`_ distribution installed +may find Fabric is best installed with `its package manager, PyPM +`_. Below is example output from an +installation of Fabric via ``pypm``:: + + C:\> pypm install fabric + The following packages will be installed into "%APPDATA%\Python" (2.7): + paramiko-1.7.8 pycrypto-2.4 fabric-1.3.0 + Get: [pypm-free.activestate.com] fabric 1.3.0 + Get: [pypm-free.activestate.com] paramiko 1.7.8 + Get: [pypm-free.activestate.com] pycrypto 2.4 + Installing paramiko-1.7.8 + Installing pycrypto-2.4 + Installing fabric-1.3.0 + Fixing script %APPDATA%\Python\Scripts\fab-script.py + C:\> diff -Nru fabric-1.8.2/sites/www/roadmap.rst fabric-1.10.0/sites/www/roadmap.rst --- fabric-1.8.2/sites/www/roadmap.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/roadmap.rst 2014-09-03 22:51:54.000000000 +0000 @@ -0,0 +1,68 @@ +=================== +Development roadmap +=================== + +This document outlines Fabric's intended development path. Please make sure +you're reading `the latest version `_ of this +document! + +.. warning:: + This information is subject to change without warning, and should not be + used as a basis for any life- or career-altering decisions! + +Fabric 1.x +========== + +Fabric 1.x, while not end-of-life'd, has reached a tipping point regarding +internal tech debt & ability to make significant improvements without harming +backwards compatibility. + +As such, future 1.x releases (**1.6** onwards) will emphasize small-to-medium +features (new features not requiring major overhauls of the internals) and +bugfixes. + +Invoke, Fabric 2.x and Patchwork +================================ + +While 1.x moves on as above, we are working on a reimagined 2.x version of the +tool, and plan to: + +* Finish and release `the Invoke tool/library + `_ (see also :issue:`565`), which is a + revamped and standalone version of Fabric's task running components. + + * As of late 2013, Invoke is approaching maturity and already has a handful of + features lacking in Fabric itself, including but not limited to: + + * a more explicit and powerful namespacing implementation + * "regular" style CLI flags, + * before/after hooks + * explicit context management + + * Invoke is already Python 3 compatible, due to being a new codebase with + few dependencies. + * As Fabric 2 is developed, Invoke will continue to grow & change to suit + Fabric's needs while remaining a high quality standalone task runner. + +* Start putting together Fabric 2.0, a mostly-rewritten Fabric core: + + * Leverage Invoke for task running, leaving Fabric itself much more library + oriented. + * Implement object-oriented hosts/host lists and all the fun stuff that + provides (e.g. no more hacky host string and unintuitive env var + manipulation.) + * No more shared state by default (thanks to Invoke's context design.) + * Any other core overhauls difficult to do in a backwards compatible + fashion. + * Test-driven development (Invoke does this as well.) + +* Spin off ``fabric.contrib.*`` into a standalone "super-Fabric" (as in, "above + Fabric") library, `Patchwork `_. + + * This lets core "execute commands on hosts" functionality iterate + separately from "commonly useful shortcuts using Fabric core". + * Lots of preliminary work & prior-art scanning has been done in + :issue:`461`. + * A public-but-alpha codebase for Patchwork exists as we think about the + API, and is currently based on Fabric 1.x. It will likely be Fabric 2.x + based by the time it is stable. diff -Nru fabric-1.8.2/sites/www/troubleshooting.rst fabric-1.10.0/sites/www/troubleshooting.rst --- fabric-1.8.2/sites/www/troubleshooting.rst 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/sites/www/troubleshooting.rst 2014-09-03 20:20:44.000000000 +0000 @@ -0,0 +1,52 @@ +=============== +Troubleshooting +=============== + +Stuck? Having a problem? Here are the steps to try before you submit a bug +report. + +* **Make sure you're on the latest version.** If you're not on the most recent + version, your problem may have been solved already! Upgrading is always the + best first step. +* **Try older versions.** If you're already *on* the latest Fabric, try rolling + back a few minor versions (e.g. if on 1.7, try Fabric 1.5 or 1.6) and see if + the problem goes away. This will help the devs narrow down when the problem + first arose in the commit log. +* **Try switching up your Paramiko.** Fabric relies heavily on the Paramiko + library for its SSH functionality, so try applying the above two steps to + your Paramiko install as well. + + .. note:: + Fabric versions sometimes have different Paramiko dependencies - so to + try older Paramikos you may need to downgrade Fabric as well. + +* **Make sure Fabric is really the problem.** If your problem is in the + behavior or output of a remote command, try recreating it without Fabric + involved: + + * Run Fabric with ``--show=debug`` and look for the ``run:`` or ``sudo:`` + line about the command in question. Try running that exact command, + including any ``/bin/bash`` wrapper, remotely and see what happens. This + may find problems related to the bash or sudo wrappers. + * Execute the command (both the normal version, and the 'unwrapped' version + seen via ``--show=debug``) from your local workstation using ``ssh``, + e.g.:: + + $ ssh -t mytarget "my command" + + The ``-t`` flag matches Fabric's default behavior of enabling a PTY + remotely. This helps identify apps that behave poorly when run in a + non-shell-spawned PTY. + +* **Enable Paramiko-level debug logging.** If your issue is in the lower level + Paramiko library, it can help us to see the debug output Paramiko prints. At + top level in your fabfile, add the following:: + + import logging + logging.basicConfig(level=logging.DEBUG) + + This should start printing Paramiko's debug statements to your standard error + stream. (Feel free to add more logging kwargs to ``basicConfig()`` such as + ``filename='/path/to/a/file'`` if you like.) + + Then submit this info to anybody helping you on IRC or in your bug report. diff -Nru fabric-1.8.2/tests/test_context_managers.py fabric-1.10.0/tests/test_context_managers.py --- fabric-1.8.2/tests/test_context_managers.py 2013-12-26 18:41:52.000000000 +0000 +++ fabric-1.10.0/tests/test_context_managers.py 2014-09-03 20:20:44.000000000 +0000 @@ -2,6 +2,7 @@ import os import sys +from StringIO import StringIO from nose.tools import eq_, ok_ @@ -9,10 +10,8 @@ from fabric.context_managers import (cd, settings, lcd, hide, shell_env, quiet, warn_only, prefix, path) from fabric.operations import run, local - from utils import mock_streams, FabricTest from server import server -from StringIO import StringIO # @@ -23,8 +22,10 @@ """ cd cleans up after itself even in case of an exception """ + class TestException(Exception): pass + try: with cd('somewhere'): raise TestException('Houston, we have a problem.') @@ -49,6 +50,52 @@ eq_(env.cwd, existing + '/' + additional) +def test_cd_home_dir(): + """ + cd() should work with home directories + """ + homepath = "~/somepath" + with cd(homepath): + eq_(env.cwd, homepath) + + +def test_cd_nested_home_abs_dirs(): + """ + cd() should work with nested user homedir (starting with ~) paths. + + It should always take the last path if the new path begins with `/` or `~` + """ + + home_path = "~/somepath" + abs_path = "/some/random/path" + relative_path = "some/random/path" + + # 2 nested homedir paths + with cd(home_path): + eq_(env.cwd, home_path) + another_path = home_path + "/another/path" + with cd(another_path): + eq_(env.cwd, another_path) + + # first absolute path, then a homedir path + with cd(abs_path): + eq_(env.cwd, abs_path) + with cd(home_path): + eq_(env.cwd, home_path) + + # first relative path, then a homedir path + with cd(relative_path): + eq_(env.cwd, relative_path) + with cd(home_path): + eq_(env.cwd, home_path) + + # first home path, then a a relative path + with cd(home_path): + eq_(env.cwd, home_path) + with cd(relative_path): + eq_(env.cwd, home_path + "/" + relative_path) + + # # prefix # @@ -107,6 +154,7 @@ eq_(env.testval, "inner value") eq_(env.testval, "outer value") + def test_settings_with_multiple_kwargs(): """ settings() should temporarily override env dict with given key/value pairS @@ -119,6 +167,7 @@ eq_(env.testval1, "outer 1") eq_(env.testval2, "outer 2") + def test_settings_with_other_context_managers(): """ settings() should take other context managers, and use them with other overrided @@ -168,6 +217,7 @@ eq_(env.shell_env, {}) + class TestQuietAndWarnOnly(FabricTest): @server() @mock_streams('both') diff -Nru fabric-1.8.2/tests/test_contrib.py fabric-1.10.0/tests/test_contrib.py --- fabric-1.8.2/tests/test_contrib.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/tests/test_contrib.py 2014-09-03 22:51:54.000000000 +0000 @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- from __future__ import with_statement - +from fabric.operations import local import os from fabric.api import hide, get, show from fabric.contrib.files import upload_template, contains +from fabric.context_managers import lcd from utils import FabricTest, eq_contents from server import server @@ -38,6 +39,25 @@ get(remote, local) eq_contents(local, var) + @server() + def test_upload_template_handles_template_dir(self): + """ + upload_template() should work OK with template dir + """ + template = self.mkfile('template.txt', '%(varname)s') + template_dir = os.path.dirname(template) + local = self.path('result.txt') + remote = '/configfile.txt' + var = 'foobar' + with hide('everything'): + upload_template( + 'template.txt', remote, {'varname': var}, + template_dir=template_dir + ) + get(remote, local) + eq_contents(local, var) + + @server(responses={ 'egrep "text" "/file.txt"': ( "sudo: unable to resolve host fabric", @@ -81,3 +101,31 @@ upload_template(fname, '/configfile.txt', {}, use_jinja=True) finally: os.remove(fname) + + + def test_upload_template_obeys_lcd(self): + for jinja in (True, False): + for mirror in (True, False): + self._upload_template_obeys_lcd(jinja=jinja, mirror=mirror) + + @server() + def _upload_template_obeys_lcd(self, jinja, mirror): + template_content = {True: '{{ varname }}s', False: '%(varname)s'} + + template_dir = 'template_dir' + template_name = 'template.txt' + if not self.exists_locally(self.path(template_dir)): + os.mkdir(self.path(template_dir)) + + self.mkfile( + os.path.join(template_dir, template_name), template_content[jinja] + ) + + remote = '/configfile.txt' + var = 'foobar' + with hide('everything'): + with lcd(self.path(template_dir)): + upload_template( + template_name, remote, {'varname': var}, + mirror_local_mode=mirror + ) diff -Nru fabric-1.8.2/tests/test_io.py fabric-1.10.0/tests/test_io.py --- fabric-1.8.2/tests/test_io.py 1970-01-01 00:00:00.000000000 +0000 +++ fabric-1.10.0/tests/test_io.py 2014-09-03 22:51:54.000000000 +0000 @@ -0,0 +1,28 @@ +from __future__ import with_statement + +from nose.tools import eq_ + +from fabric.io import OutputLooper +from fabric.context_managers import settings + + +def test_request_prompts(): + """ + Test valid responses from prompts + """ + def run(txt, prompts): + with settings(prompts=prompts): + # try to fulfil the OutputLooper interface, only want to test + # _get_prompt_response. (str has a method upper) + ol = OutputLooper(str, 'upper', None, list(txt), None) + return ol._get_prompt_response() + + prompts = {"prompt2": "response2", + "prompt1": "response1", + "prompt": "response" + } + + eq_(run("this is a prompt for prompt1", prompts), ("prompt1", "response1")) + eq_(run("this is a prompt for prompt2", prompts), ("prompt2", "response2")) + eq_(run("this is a prompt for promptx:", prompts), (None, None)) + eq_(run("prompt for promp", prompts), (None, None)) diff -Nru fabric-1.8.2/tests/test_main.py fabric-1.10.0/tests/test_main.py --- fabric-1.8.2/tests/test_main.py 2014-02-14 17:28:48.000000000 +0000 +++ fabric-1.10.0/tests/test_main.py 2014-09-04 00:52:45.000000000 +0000 @@ -94,11 +94,16 @@ # # Allow calling Task.get_hosts as function instead (meh.) -def get_hosts(command, *args): - return WrappedCallableTask(command).get_hosts(*args) +def get_hosts_and_effective_roles(command, *args): + return WrappedCallableTask(command).get_hosts_and_effective_roles(*args) -def eq_hosts(command, host_list, env=None, func=set): - eq_(func(get_hosts(command, [], [], [], env)), func(host_list)) +def eq_hosts(command, expected_hosts, cli_hosts=None, excluded_hosts=None, env=None, func=set): + eq_(func(get_hosts_and_effective_roles(command, cli_hosts or [], [], excluded_hosts or [], env)[0]), + func(expected_hosts)) + +def eq_effective_roles(command, expected_effective_roles, cli_roles=None, env=None, func=set): + eq_(func(get_hosts_and_effective_roles(command, [], cli_roles or [], [], env)[1]), + func(expected_effective_roles)) true_eq_hosts = partial(eq_hosts, func=lambda x: x) @@ -128,6 +133,27 @@ def command(): pass eq_hosts(command, ['a', 'b'], env={'roledefs': fake_roles}) + eq_effective_roles(command, ['r1'], env={'roledefs': fake_roles}) + +def test_roles_decorator_overrides_env_roles(): + """ + If @roles is used it replaces any env.roles value + """ + @roles('r1') + def command(): + pass + eq_effective_roles(command, ['r1'], env={'roledefs': fake_roles, + 'roles': ['r2']}) + +def test_cli_roles_override_decorator_roles(): + """ + If CLI roles are provided they replace roles defined in @roles. + """ + @roles('r1') + def command(): + pass + eq_effective_roles(command, ['r2'], cli_roles=['r2'], env={'roledefs': fake_roles}) + def test_hosts_and_roles_together(): """ @@ -138,6 +164,7 @@ def command(): pass eq_hosts(command, ['a', 'b', 'c', 'd'], env={'roledefs': fake_roles}) + eq_effective_roles(command, ['r1', 'r2'], env={'roledefs': fake_roles}) def test_host_role_merge_deduping(): """ @@ -181,6 +208,7 @@ def command(): pass eq_hosts(command, ['a', 'b'], env={'roledefs': tuple_roles}) + eq_effective_roles(command, ['r1'], env={'roledefs': fake_roles}) def test_hosts_as_tuples(): @@ -199,8 +227,7 @@ @hosts('bar') def command(): pass - eq_hosts(command, ['bar']) - assert 'foo' not in get_hosts(command, [], [], [], {'hosts': ['foo']}) + eq_hosts(command, ['bar'], env={'hosts': ['foo']}) def test_hosts_decorator_overrides_env_hosts_with_task_decorator_first(): """ @@ -210,16 +237,14 @@ @hosts('bar') def command(): pass - eq_hosts(command, ['bar']) - assert 'foo' not in get_hosts(command, [], [], {'hosts': ['foo']}) + eq_hosts(command, ['bar'], env={'hosts': ['foo']}) def test_hosts_decorator_overrides_env_hosts_with_task_decorator_last(): @hosts('bar') @task def command(): pass - eq_hosts(command, ['bar']) - assert 'foo' not in get_hosts(command, [], [], {'hosts': ['foo']}) + eq_hosts(command, ['bar'], env={'hosts': ['foo']}) def test_hosts_stripped_env_hosts(): """ @@ -228,7 +253,7 @@ def command(): pass myenv = {'hosts': [' foo ', 'bar '], 'roles': [], 'exclude_hosts': []} - eq_hosts(command, ['foo', 'bar'], myenv) + eq_hosts(command, ['foo', 'bar'], env=myenv) spaced_roles = { @@ -243,7 +268,22 @@ @roles('r1') def command(): pass - eq_hosts(command, ['a', 'b'], {'roledefs': spaced_roles}) + eq_hosts(command, ['a', 'b'], env={'roledefs': spaced_roles}) + + +dict_roles = { + 'r1': {'hosts': ['a', 'b']}, + 'r2': ['b', 'c'], +} + +def test_hosts_in_role_dict(): + """ + Make sure hosts defined in env.roles are cleaned of extra spaces + """ + @roles('r1') + def command(): + pass + eq_hosts(command, ['a', 'b'], env={'roledefs': dict_roles}) def test_hosts_decorator_expands_single_iterable(): @@ -278,14 +318,17 @@ def dummy(): pass def test_get_hosts_excludes_cli_exclude_hosts_from_cli_hosts(): - assert 'foo' not in get_hosts(dummy, ['foo', 'bar'], [], ['foo']) + eq_hosts(dummy, ['bar'], cli_hosts=['foo', 'bar'], excluded_hosts=['foo']) def test_get_hosts_excludes_cli_exclude_hosts_from_decorator_hosts(): - assert 'foo' not in get_hosts(hosts('foo', 'bar')(dummy), [], [], ['foo']) + @hosts('foo', 'bar') + def command(): + pass + eq_hosts(command, ['bar'], excluded_hosts=['foo']) def test_get_hosts_excludes_global_exclude_hosts_from_global_hosts(): fake_env = {'hosts': ['foo', 'bar'], 'exclude_hosts': ['foo']} - assert 'foo' not in get_hosts(dummy, [], [], [], fake_env) + eq_hosts(dummy, ['bar'], env=fake_env) @@ -302,7 +345,7 @@ def test_accepts_non_list_hosts(): """ - Aborts if hosts is a string, not a list + Coerces given host string to a one-item list """ assert merge('badhosts', [], [], {}) == ['badhosts'] diff -Nru fabric-1.8.2/tests/test_network.py fabric-1.10.0/tests/test_network.py --- fabric-1.8.2/tests/test_network.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/tests/test_network.py 2014-09-03 22:51:54.000000000 +0000 @@ -18,6 +18,7 @@ from fabric.operations import run, sudo, prompt from fabric.exceptions import NetworkError from fabric.tasks import execute +from fabric.api import parallel from fabric import utils # for patching from utils import * @@ -547,6 +548,27 @@ execute(subtask, hosts=['nope.nonexistent.com']) +@parallel +def parallel_subtask(): + run("This should never execute") + +class TestParallelConnections(FabricTest): + @aborts + def test_should_abort_when_cannot_connect(self): + """ + By default, connecting to a nonexistent server should abort. + """ + with hide('everything'): + execute(parallel_subtask, hosts=['nope.nonexistent.com']) + + def test_should_warn_when_skip_bad_hosts_is_True(self): + """ + env.skip_bad_hosts = True => execute() skips current host + """ + with settings(hide('everything'), skip_bad_hosts=True): + execute(parallel_subtask, hosts=['nope.nonexistent.com']) + + class TestSSHConfig(FabricTest): def env_setup(self): super(TestSSHConfig, self).env_setup() diff -Nru fabric-1.8.2/tests/test_operations.py fabric-1.10.0/tests/test_operations.py --- fabric-1.8.2/tests/test_operations.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/tests/test_operations.py 2014-09-04 00:59:16.000000000 +0000 @@ -1,24 +1,17 @@ from __future__ import with_statement -import os -import shutil -import sys -import types from contextlib import nested from StringIO import StringIO -import unittest -import random -import types - -from nose.tools import raises, eq_, ok_ -from fudge import with_patched_object +from nose.tools import ok_ +from fudge import with_fakes, Fake +from fudge.inspector import arg as fudge_arg +from paramiko.sftp_client import SFTPClient # for patching from fabric.state import env, output from fabric.operations import require, prompt, _sudo_prefix, _shell_wrap, \ _shell_escape from fabric.api import get, put, hide, show, cd, lcd, local, run, sudo, quiet -from fabric.sftp import SFTP from fabric.exceptions import CommandTimeout from fabric.decorators import with_settings @@ -730,6 +723,54 @@ sftp = SFTP(env.host_string) eq_(sftp.glob(path), [path]) + @server() + @with_fakes + def test_get_use_sudo(self): + """ + get(use_sudo=True) works by copying to a temporary path, downloading it and then removing it at the end + """ + # the sha1 hash is the unique filename of the file being downloaded. sha1() + fake_run = Fake('_run_command', callable=True, expect_call=True).with_matching_args( + 'cp -p "/etc/apache2/apache2.conf" "229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ).next_call().with_matching_args( + 'chmod 404 "229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ).next_call().with_matching_args( + 'rm -f "229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ) + fake_get = Fake('get', callable=True, expect_call=True).with_args('229a29e5693876645e39de0cb0532e43ad73311a', + fudge_arg.any_value()) + + with hide('everything'): + with patched_context('fabric.operations', '_run_command', fake_run): + with patched_context(SFTPClient, 'get', fake_get): + retval = get('/etc/apache2/apache2.conf', self.path(), use_sudo=True) + # check that the downloaded file has the same name as the one requested + assert retval[0].endswith('apache2.conf') + + @server() + @with_fakes + def test_get_use_sudo_temp_dir(self): + """ + get(use_sudo=True, temp_dir="/tmp") works by copying to a /tmp/sha1_hash, downloading it and then removing it at the end + """ + # the sha1 hash is the unique filename of the file being downloaded. sha1() + fake_run = Fake('_run_command', callable=True, expect_call=True).with_matching_args( + 'cp -p "/etc/apache2/apache2.conf" "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ).next_call().with_matching_args( + 'chmod 404 "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ).next_call().with_matching_args( + 'rm -f "/tmp/229a29e5693876645e39de0cb0532e43ad73311a"', True, True, None, + ) + fake_get = Fake('get', callable=True, expect_call=True).with_args('/tmp/229a29e5693876645e39de0cb0532e43ad73311a', + fudge_arg.any_value()) + + with hide('everything'): + with patched_context('fabric.operations', '_run_command', fake_run): + with patched_context(SFTPClient, 'get', fake_get): + retval = get('/etc/apache2/apache2.conf', self.path(), use_sudo=True, temp_dir="/tmp") + # check that the downloaded file has the same name as the one requested + assert retval[0].endswith('apache2.conf') + # # put() # @@ -876,6 +917,48 @@ get('/foo[bar].txt', local2) eq_contents(local2, text) + @server() + @with_fakes + def test_put_use_sudo(self): + """ + put(use_sudo=True) works by uploading a the `local_path` to a temporary path and then moving it to a `remote_path` + """ + # the sha1 hash is the unique filename of the file being downloaded. sha1() + fake_run = Fake('_run_command', callable=True, expect_call=True).with_matching_args( + 'mv "7c91837ec0b3570264a325df6b7ef949ee22bc56" "/foobar.txt"', True, True, None, + ) + fake_put = Fake('put', callable=True, expect_call=True).with_args(fudge_arg.any_value(), + '7c91837ec0b3570264a325df6b7ef949ee22bc56') + + local_path = self.mkfile('foobar.txt', "baz") + with hide('everything'): + with patched_context('fabric.operations', '_run_command', fake_run): + with patched_context(SFTPClient, 'put', fake_put): + retval = put(local_path, "/", use_sudo=True) + # check that the downloaded file has the same name as the one requested + assert retval[0].endswith('foobar.txt') + + @server() + @with_fakes + def test_put_use_sudo_temp_dir(self): + """ + put(use_sudo=True, temp_dir='/tmp/') works by uploading a file to /tmp/ and then moving it to a `remote_path` + """ + # the sha1 hash is the unique filename of the file being downloaded. sha1() + fake_run = Fake('_run_command', callable=True, expect_call=True).with_matching_args( + 'mv "/tmp/7c91837ec0b3570264a325df6b7ef949ee22bc56" "/foobar.txt"', True, True, None, + ) + fake_put = Fake('put', callable=True, expect_call=True).with_args(fudge_arg.any_value(), + '/tmp/7c91837ec0b3570264a325df6b7ef949ee22bc56') + + local_path = self.mkfile('foobar.txt', "baz") + with hide('everything'): + with patched_context('fabric.operations', '_run_command', fake_run): + with patched_context(SFTPClient, 'put', fake_put): + retval = put(local_path, "/", use_sudo=True, temp_dir='/tmp/') + # check that the downloaded file has the same name as the one requested + assert retval[0].endswith('foobar.txt') + # # Interactions with cd() diff -Nru fabric-1.8.2/tests/test_tasks.py fabric-1.10.0/tests/test_tasks.py --- fabric-1.8.2/tests/test_tasks.py 2014-02-14 17:28:56.000000000 +0000 +++ fabric-1.10.0/tests/test_tasks.py 2014-09-04 00:52:45.000000000 +0000 @@ -211,6 +211,15 @@ """ execute('thisisnotavalidtaskname') + def test_should_not_abort_if_task_name_not_found_with_skip(self): + """ + should not abort if given an invalid task name + and skip_unknown_tasks in env + """ + env.skip_unknown_tasks = True + execute('thisisnotavalidtaskname') + del env['skip_unknown_tasks'] + @with_fakes def test_should_pass_through_args_kwargs(self): """