Hello community, here is the log from the commit of package python-Fabric for openSUSE:Factory checked in at 2019-09-25 08:08:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Fabric (Old) and /work/SRC/openSUSE:Factory/.python-Fabric.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Fabric" Wed Sep 25 08:08:49 2019 rev:31 rq:731953 version:2.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Fabric/python-Fabric.changes 2019-04-19 18:38:26.191188786 +0200 +++ /work/SRC/openSUSE:Factory/.python-Fabric.new.7948/python-Fabric.changes 2019-09-25 08:08:52.622547010 +0200 @@ -1,0 +2,14 @@ +Thu Sep 12 12:47:06 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Update to 2.5.0: + * [Feature] #1989: Reinstate command timeouts, by supporting the + implementation of that feature in Invoke + * [Feature]: Allow specifying connection timeouts + * [Feature] #1985: Add support for explicitly closing remote subprocess’ + stdin when local stdin sees an EOF, by implementing a new command-runner + method recently added to Invoke; this prevents remote programs that + ‘follow’ stdin from blocking forever. + * [Bug]: Anonymous/’remainder’ subprocess execution (eg fab -H host -- + command, as opposed to the use of Connection.run inside tasks) + +------------------------------------------------------------------- Old: ---- fabric-2.4.0.tar.gz New: ---- fabric-2.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Fabric.spec ++++++ --- /var/tmp/diff_new_pack.rhf2ct/_old 2019-09-25 08:08:53.406546899 +0200 +++ /var/tmp/diff_new_pack.rhf2ct/_new 2019-09-25 08:08:53.406546899 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Fabric -Version: 2.4.0 +Version: 2.5.0 Release: 0 Summary: A Pythonic tool for remote execution and deployment License: BSD-2-Clause @@ -27,7 +27,7 @@ Source: https://files.pythonhosted.org/packages/source/f/fabric/fabric-%{version}.tar.gz BuildRequires: %{python_module cryptography >= 1.1} BuildRequires: %{python_module decorator} -BuildRequires: %{python_module invoke >= 1.1} +BuildRequires: %{python_module invoke >= 1.3} BuildRequires: %{python_module mock >= 2.0.0} BuildRequires: %{python_module paramiko >= 2.4} BuildRequires: %{python_module pytest >= 3.2.5} @@ -38,7 +38,7 @@ BuildRequires: python-rpm-macros Requires: python-cryptography >= 1.1 Requires: python-decorator -Requires: python-invoke >= 1.1 +Requires: python-invoke >= 1.3 Requires: python-paramiko >= 2.4 Requires: python-setuptools Requires: python-six ++++++ fabric-2.4.0.tar.gz -> fabric-2.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/LICENSE new/fabric-2.5.0/LICENSE --- old/fabric-2.4.0/LICENSE 2018-09-06 21:28:02.000000000 +0200 +++ new/fabric-2.5.0/LICENSE 2019-07-19 18:30:31.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright (c) 2018 Jeff Forcier. +Copyright (c) 2019 Jeff Forcier. All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/PKG-INFO new/fabric-2.5.0/PKG-INFO --- old/fabric-2.4.0/PKG-INFO 2018-09-14 00:29:24.000000000 +0200 +++ new/fabric-2.5.0/PKG-INFO 2019-08-07 00:57:39.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fabric -Version: 2.4.0 +Version: 2.5.0 Summary: High level SSH command execution Home-page: http://fabfile.org Author: Jeff Forcier @@ -42,6 +42,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries @@ -49,5 +50,5 @@ Classifier: Topic :: System :: Clustering Classifier: Topic :: System :: Software Distribution Classifier: Topic :: System :: Systems Administration -Provides-Extra: testing Provides-Extra: pytest +Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/dev-requirements.txt new/fabric-2.5.0/dev-requirements.txt --- old/fabric-2.4.0/dev-requirements.txt 2018-09-14 00:28:20.000000000 +0200 +++ new/fabric-2.5.0/dev-requirements.txt 2019-08-06 20:33:19.000000000 +0200 @@ -1,6 +1,8 @@ # Invoke implicitly required by self/pip install -e . # Invocations for common project tasks invocations>=1.0,<2.0 +# Invoke from git, temporarily? +-e git+https://github.com/pyinvoke/invoke#egg=invoke # pytest-relaxed for test organization, display etc tweaks pytest-relaxed>=1.0.1,<1.1 pytest==3.2.5 @@ -10,13 +12,13 @@ # Mock for test mocking mock==2.0.0 # Linting! -flake8==2.4.0 +flake8==3.6.0 # Coverage! coverage==3.7.1 codecov==1.6.3 # Documentation tools sphinx>=1.4,<1.7 -alabaster>=0.7,<2.0 +alabaster==0.7.12 releases>=1.5,<2.0 # Release tools semantic_version>=2.4,<2.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric/_version.py new/fabric-2.5.0/fabric/_version.py --- old/fabric-2.4.0/fabric/_version.py 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/fabric/_version.py 2019-08-07 00:57:28.000000000 +0200 @@ -1,2 +1,2 @@ -__version_info__ = (2, 4, 0) +__version_info__ = (2, 5, 0) __version__ = ".".join(map(str, __version_info__)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric/connection.py new/fabric-2.5.0/fabric/connection.py --- old/fabric-2.4.0/fabric/connection.py 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/fabric/connection.py 2019-07-19 18:29:16.000000000 +0200 @@ -65,6 +65,14 @@ level operations with that `~paramiko.client.SSHClient` and `~paramiko.channel.Channel` instances generated from it. + .. _connect_kwargs: + + .. note:: + Many SSH specific options -- such as specifying private keys and + passphrases, timeouts, disabling SSH agents, etc -- are handled + directly by Paramiko and should be specified via the + :ref:`connect_kwargs argument <connect_kwargs-arg>` of the constructor. + **Lifecycle** `.Connection` has a basic "`create <__init__>`, `connect/open <open>`, `do @@ -292,6 +300,8 @@ Default: ``config.timeouts.connect``. + .. _connect_kwargs-arg: + :param dict connect_kwargs: Keyword arguments handed verbatim to `SSHClient.connect <paramiko.client.SSHClient.connect>` (when @@ -299,8 +309,17 @@ `.Connection` tries not to grow additional settings/kwargs of its own unless it is adding value of some kind; thus, - ``connect_kwargs`` is currently the right place to hand in - parameters such as ``pkey`` or ``key_filename``. + ``connect_kwargs`` is currently the right place to hand in paramiko + connection parameters such as ``pkey`` or ``key_filename``. For + example:: + + c = Connection( + host="hostname", + user="admin", + connect_kwargs={ + "key_filename": "/home/myuser/.ssh/private.key", + }, + ) Default: ``config.connect_kwargs``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric/executor.py new/fabric-2.5.0/fabric/executor.py --- old/fabric-2.4.0/fabric/executor.py 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/fabric/executor.py 2019-08-06 20:36:27.000000000 +0200 @@ -25,6 +25,14 @@ """ Normalize mixed host-strings-or-kwarg-dicts into kwarg dicts only. + In other words, transforms data taken from the CLI (--hosts, always + strings) or decorator arguments (may be strings or kwarg dicts) into + kwargs suitable for creating Connection instances. + + Subclasses may wish to override or extend this to perform, for example, + database or custom config file lookups (vs this default behavior, which + is to simply assume that strings are 'host' kwargs). + :param hosts: Potentially heterogenous list of host connection values, as per the ``hosts`` param to `.task`. @@ -80,10 +88,7 @@ ) def anonymous(c): - # TODO: how to make all our tests configure in_stream=False? - # TODO: doesn't this preclude users wanting to submit stdin to - # remainder commands? - c.run(self.core.remainder, in_stream=False) + c.run(self.core.remainder) anon = Call(Task(body=anonymous)) # TODO: see above TODOs about non-parameterized setups, roles etc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric/main.py new/fabric-2.5.0/fabric/main.py --- old/fabric-2.4.0/fabric/main.py 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/fabric/main.py 2019-08-06 20:33:19.000000000 +0200 @@ -24,10 +24,6 @@ core_args = super(Fab, self).core_args() my_args = [ Argument( - names=("S", "ssh-config"), - help="Path to runtime SSH config file.", - ), - Argument( names=("H", "hosts"), help="Comma-separated host name(s) to execute tasks against.", ), @@ -49,6 +45,15 @@ kind=bool, help="Request an upfront SSH key passphrase prompt.", ), + Argument( + names=("S", "ssh-config"), + help="Path to runtime SSH config file.", + ), + Argument( + names=("t", "connect-timeout"), + kind=int, + help="Specifies default connection timeout, in seconds.", + ), ] return core_args + my_args @@ -120,6 +125,10 @@ path = self.args["identity"].value if path: connect_kwargs["key_filename"] = path + # Ditto for connect timeout + timeout = self.args["connect-timeout"].value + if timeout: + connect_kwargs["timeout"] = timeout # Secrets prompts that want to happen at handoff time instead of # later/at user-time. # TODO: should this become part of Invoke proper in case other @@ -137,6 +146,14 @@ self.config.merge() -program = Fab( - name="Fabric", version=fabric, executor_class=Executor, config_class=Config -) +# Mostly a concession to testing. +def make_program(): + return Fab( + name="Fabric", + version=fabric, + executor_class=Executor, + config_class=Config, + ) + + +program = make_program() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric/runners.py new/fabric-2.5.0/fabric/runners.py --- old/fabric-2.4.0/fabric/runners.py 2018-09-14 00:29:00.000000000 +0200 +++ new/fabric-2.5.0/fabric/runners.py 2019-08-06 20:36:27.000000000 +0200 @@ -32,7 +32,7 @@ self.inline_env = kwargs.pop("inline_env", None) super(Remote, self).__init__(*args, **kwargs) - def start(self, command, shell, env): + def start(self, command, shell, env, timeout=None): self.channel = self.context.create_session() if self.using_pty: rows, cols = pty_size() @@ -55,8 +55,6 @@ command = "export {} && {}".format(parameters, command) else: self.channel.update_environment(env) - # TODO: pass in timeout= here when invoke grows timeout functionality - # in Runner/Local. self.channel.exec_command(command) def read_proc_stdout(self, num_bytes): @@ -68,6 +66,9 @@ def _write_proc_stdin(self, data): return self.channel.sendall(data) + def close_proc_stdin(self): + return self.channel.shutdown_write() + @property def process_is_finished(self): return self.channel.exit_status_ready() @@ -99,8 +100,15 @@ if hasattr(self, "channel"): self.channel.close() + def kill(self): + # Just close the channel immediately, which is about as close as we can + # get to a local SIGKILL unfortunately. + # TODO: consider _also_ calling .send_interrupt() and only doing this + # after another few seconds; but A) kinda fragile/complex and B) would + # belong in invoke.Runner anyways? + self.channel.close() + # TODO: shit that is in fab 1 run() but could apply to invoke.Local too: - # * command timeout control # * see rest of stuff in _run_command/_execute in operations.py...there is # a bunch that applies generally like optional exit codes, etc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric.egg-info/PKG-INFO new/fabric-2.5.0/fabric.egg-info/PKG-INFO --- old/fabric-2.4.0/fabric.egg-info/PKG-INFO 2018-09-14 00:29:24.000000000 +0200 +++ new/fabric-2.5.0/fabric.egg-info/PKG-INFO 2019-08-07 00:57:38.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fabric -Version: 2.4.0 +Version: 2.5.0 Summary: High level SSH command execution Home-page: http://fabfile.org Author: Jeff Forcier @@ -42,6 +42,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries @@ -49,5 +50,5 @@ Classifier: Topic :: System :: Clustering Classifier: Topic :: System :: Software Distribution Classifier: Topic :: System :: Systems Administration -Provides-Extra: testing Provides-Extra: pytest +Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/fabric.egg-info/requires.txt new/fabric-2.5.0/fabric.egg-info/requires.txt --- old/fabric-2.4.0/fabric.egg-info/requires.txt 2018-09-14 00:29:24.000000000 +0200 +++ new/fabric-2.5.0/fabric.egg-info/requires.txt 2019-08-07 00:57:38.000000000 +0200 @@ -1,6 +1,5 @@ -invoke<2.0,>=1.1 +invoke<2.0,>=1.3 paramiko>=2.4 -cryptography>=1.1 [pytest] mock<3.0,>=2.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/integration/connection.py new/fabric-2.5.0/integration/connection.py --- old/fabric-2.4.0/integration/connection.py 2018-09-06 21:28:02.000000000 +0200 +++ new/fabric-2.5.0/integration/connection.py 2019-08-06 20:33:19.000000000 +0200 @@ -1,7 +1,8 @@ import os +import time -from invoke import pty_size -from pytest import skip +from invoke import pty_size, CommandTimedOut +from pytest import skip, raises from fabric import Connection, Config @@ -116,3 +117,20 @@ # When bug present, # lines received is significantly fewer than the # true count in the file (by thousands). assert len(lines) == len(words) + + class command_timeout: + def setup(self): + self.cxn = Connection("localhost") + + def does_not_raise_exception_when_under_timeout(self): + assert self.cxn.run("sleep 1", timeout=3) + + def raises_exception_when_over_timeout(self): + with raises(CommandTimedOut) as info: + start = time.time() + self.cxn.run("sleep 5", timeout=1) + elapsed = time.time() - start + assert info.value.timeout == 1 + # Catch scenarios where we except but don't actually shut down + # early (w/ a bit of fudge time for overhead) + assert elapsed <= 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/setup.py new/fabric-2.5.0/setup.py --- old/fabric-2.4.0/setup.py 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/setup.py 2019-08-06 20:36:43.000000000 +0200 @@ -67,11 +67,7 @@ author="Jeff Forcier", author_email="[email protected]", url="http://fabfile.org", - install_requires=[ - "invoke>=1.1,<2.0", - "paramiko>=2.4", - "cryptography>=1.1", - ], + install_requires=["invoke>=1.3,<2.0", "paramiko>=2.4"], extras_require={ "testing": testing_deps, "pytest": testing_deps + pytest_deps, @@ -99,6 +95,7 @@ "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", "Topic :: Software Development", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/docs/cli.rst new/fabric-2.5.0/sites/docs/cli.rst --- old/fabric-2.4.0/sites/docs/cli.rst 2018-09-06 21:28:02.000000000 +0200 +++ new/fabric-2.5.0/sites/docs/cli.rst 2019-08-06 20:33:19.000000000 +0200 @@ -18,10 +18,6 @@ <prompt-for-sudo-password>` -- from Invoke, which handles sudo autoresponse concerns. -.. option:: -S, --ssh-config - - Takes a path to load as a runtime SSH config file. See :ref:`ssh-config`. - .. option:: -H, --hosts Takes a comma-separated string listing hostnames against which tasks @@ -39,6 +35,14 @@ Default: ``[]``. +.. option:: --prompt-for-login-password + + Causes Fabric to prompt 'up front' for a value to store as the + ``connect_kwargs.password`` config setting (used by Paramiko when + authenticating via passwords and, in some versions, also used for key + passphrases.) Useful if you do not want to configure such values in on-disk + conf files or via shell environment variables. + .. option:: --prompt-for-passphrase Causes Fabric to prompt 'up front' for a value to store as the @@ -46,13 +50,14 @@ private key files.) Useful if you do not want to configure such values in on-disk conf files or via shell environment variables. -.. option:: --prompt-for-login-password +.. option:: -S, --ssh-config - Causes Fabric to prompt 'up front' for a value to store as the - ``connect_kwargs.password`` config setting (used by Paramiko when - authenticating via passwords and, in some versions, also used for key - passphrases.) Useful if you do not want to configure such values in on-disk - conf files or via shell environment variables. + Takes a path to load as a runtime SSH config file. See :ref:`ssh-config`. + +.. option:: -t, --connect-timeout + + Takes an integer of seconds after which connection should time out. + Supplies the default value for the ``timeouts.connect`` config setting. Seeking & loading tasks diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/docs/getting-started.rst new/fabric-2.5.0/sites/docs/getting-started.rst --- old/fabric-2.4.0/sites/docs/getting-started.rst 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/sites/docs/getting-started.rst 2019-07-19 18:29:16.000000000 +0200 @@ -100,6 +100,11 @@ of details seen above: what was requested, what happened while the remote action occurred, and what the final result was. +.. note:: + Many lower-level SSH connection arguments (such as private keys and + timeouts) can be given directly to the SSH backend by using the + :ref:`connect_kwargs argument <connect_kwargs-arg>`. + Superuser privileges via auto-response ====================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/shared_conf.py new/fabric-2.5.0/sites/shared_conf.py --- old/fabric-2.4.0/sites/shared_conf.py 2018-09-14 00:28:20.000000000 +0200 +++ new/fabric-2.5.0/sites/shared_conf.py 2019-07-19 18:29:15.000000000 +0200 @@ -21,6 +21,7 @@ "github_repo": "fabric", "travis_button": True, "codecov_button": True, + "tidelift_url": "https://tidelift.com/subscription/pkg/pypi-fabric?utm_source=pypi-fabric&utm_medium=referral&utm_campaign=docs", "analytics_id": "UA-18486793-1", "link": "#3782BE", "link_hover": "#3782BE", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/www/changelog-v1.rst new/fabric-2.5.0/sites/www/changelog-v1.rst --- old/fabric-2.4.0/sites/www/changelog-v1.rst 2018-09-06 21:28:02.000000000 +0200 +++ new/fabric-2.5.0/sites/www/changelog-v1.rst 2019-07-19 18:30:31.000000000 +0200 @@ -6,6 +6,67 @@ This is the changelog for the legacy 1.x version of Fabric. For the current (2.0+) changelog, please see :doc:`the main changelog </changelog>`. +* :release:`1.14.1 <2018-11-27>` +* :bug:`1341` (via :issue:`1586`) Attempt to ``rm -f`` the temporary file used + by ``put``'s sudo mode, when exceptions are encountered; previously, the + internal ``sudo mv`` call could potentially fail and leave the file around. + Thanks to Andrei Sura for the report and Uku Loskit for the fix. +* :bug:`1242` (via :issue:`1243`) `~fabric.contrib.project.rsync_project`: only + supply the ``-p <number>`` option to generated ``rsync`` commands when the + port number differs from the default; this allows removing ``--rsh`` entirely + most of the time, and thus enables things like using rsync's daemon mode on + the remote end. Reported & patched by Arnaud Rocher. +* :bug:`1227` Remove a bash/zsh-ism from + `~fabric.contrib.files.upload_template` when backing up the target file, + preventing issues on simpler remote shells. Patch courtesy of Paul + Chakravarti. +* :bug:`983` Move a ``getpass`` import inside a Windows-oriented + ``try``/``except ImportError`` so password prompting is less likely to + explode on certain systems. Thanks to ``@dongweiming`` for the patch. +* :support:`- backported` Update packaging metadata so wheel archives include + the ``LICENSE`` file. +* :release:`1.14.0 <2017-08-25>` +* :feature:`1475` Honor ``env.timeout`` when opening new remote sessions (as + opposed to the initial overall connection, which already honored timeout + settings.) Thanks to ``@EugeniuZ`` for the report & ``@jrmsgit`` for the + first draft of the patch. + + .. note:: + This feature only works with Paramiko 1.14.3 and above; if your Paramiko + version is older, no timeout can be set, and the previous behavior will + occur instead. + +* :release:`1.13.2 <2017-04-24>` +* :release:`1.12.2 <2017-04-24>` +* :bug:`1542` (via :issue:`1543`) Catch Paramiko-level gateway connection + errors (``ChannelError``) when raising ``NetworkError``; this prevents an + issue where gateway related issues were being treated as authentication + errors. Thanks to Charlie Stanley for catch & patch. +* :bug:`1555` Multiple simultaneous `~fabric.operations.get` and/or + `~fabric.operations.put` with ``use_sudo=True`` and for the same remote host + and path could fail unnecessarily. Thanks ``@arnimarj`` for the report and + Pierce Lopez for the patch. +* :bug:`1427` (via :issue:`1428`) Locate ``.pyc`` files when searching for + fabfiles to load; previously we only used the presence of ``.py`` files to + determine whether loading should be attempted. Credit: Ray Chen. +* :bug:`1294` fix text escaping for `~fabric.contrib.files.contains` and + `~fabric.contrib.files.append` which would fail if the text contained e.g. + ``>``. Thanks to ``@ecksun`` for report & Pierce Lopez for the patch. +* :support:`1065 backported` Fix incorrect SSH config reference in the docs for + ``env.keepalive``; it corresponds to ``ServerAliveInterval``, not + ``ClientAliveInterval``. Credit: Harry Percival. +* :bug:`1574` `~fabric.contrib.project.upload_project` failed for folder in + current directory specified without any path separator. Thanks ``@aidanmelen`` + for the report and Pierce Lopez for the patch. +* :support:`1590 backported` Replace a reference to ``fab`` in a test + subprocess, to use the ``python -m <package>`` style instead; this allows + ``python setup.py test`` to run the test suite without having Fabric already + installed. Thanks to ``@BenSturmfels`` for catch & patch. +* :support:`- backported` Backport :issue:`1462` to 1.12.x (was previously only + backported to 1.13.x.) +* :support:`1416 backported` Add explicit "Python 2 only" note to ``setup.py`` + trove classifiers to help signal that fact to various info-gathering tools. + Patch courtesy of Gavin Bisesi. * :bug:`1526` Disable use of PTY and shell for a background command execution within ``contrib.sed``, preventing a small class of issues on some platforms/environments. Thanks to ``@doflink`` for the report and Pierce diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/www/changelog.rst new/fabric-2.5.0/sites/www/changelog.rst --- old/fabric-2.4.0/sites/www/changelog.rst 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/sites/www/changelog.rst 2019-08-07 00:57:25.000000000 +0200 @@ -5,16 +5,44 @@ .. note:: Looking for the Fabric 1.x changelog? See :doc:`/changelog-v1`. +- :release:`2.5.0 <2019-08-06>` +- :support:`-` Update minimum Invoke version requirement to ``>=1.3``. +- :feature:`1985` Add support for explicitly closing remote subprocess' stdin + when local stdin sees an EOF, by implementing a new command-runner method + recently added to Invoke; this prevents remote programs that 'follow' stdin + from blocking forever. +- :bug:`- major` Anonymous/'remainder' subprocess execution (eg ``fab -H host + -- command``, as opposed to the use of `Connection.run + <fabric.connection.Connection.run>` inside tasks) was explicitly specifying + ``in_stream=False`` (i.e. "disconnect from stdin") under the hood; this was + leftover from early development and prevented use of interactive (or other + stdin-reading) programs via this avenue. + + It has been removed; ``cat 'text' | fab -H somehost -- reads-from-stdin`` (or + similar use cases) should work again. +- :support:`-` Removed unnecessary Cryptography version pin from packaging + metadata; this was an artifact from early development. At this point in + time, only Paramiko's own direct dependency specification should matter. + + This is unlikely to affect anybody's install, since Paramiko has required + newer Cryptography versions for a number of years now. +- :feature:`-` Allow specifying connection timeouts (already available via + `~fabric.connection.Connection` constructor argument and configuration + option) on the command-line, via :option:`-t/--connect-timeout <-t>`. +- :feature:`1989` Reinstate command timeouts, by supporting the implementation + of that feature in Invoke (`pyinvoke/invoke#539 + <https://github.com/pyinvoke/invoke/issues/539>`_). Thanks to Israel Fruchter + for report and early patchset. - :release:`2.4.0 <2018-09-13>` - :release:`2.3.2 <2018-09-13>` - :release:`2.2.3 <2018-09-13>` - :release:`2.1.6 <2018-09-13>` - :release:`2.0.5 <2018-09-13>` - :feature:`1849` Add `Connection.from_v1 - <fabric.connection.Connection.from_v1>` for easy creation of a modern - ``Connection`` object from the currently configured Fabric 1.x - environment. Should make upgrading piecemeal much easier for many use - cases. + <fabric.connection.Connection.from_v1>` (and `Config.from_v1 + <fabric.config.Config.from_v1>`) for easy creation of modern + ``Connection``/``Config`` objects from the currently configured Fabric 1.x + environment. Should make upgrading piecemeal much easier for many use cases. - :feature:`1780` Add context manager behavior to `~fabric.group.Group`, to match the same feature in `~fabric.connection.Connection`. Feature request by István Sárándi. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/sites/www/upgrading.rst new/fabric-2.5.0/sites/www/upgrading.rst --- old/fabric-2.4.0/sites/www/upgrading.rst 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/sites/www/upgrading.rst 2019-08-06 20:33:19.000000000 +0200 @@ -170,6 +170,10 @@ * - ``always_use_pty`` - Config: ``run.pty``. + * - ``command_timeout`` + - Config: ``timeouts.command``; timeouts are now their own config + subtree, whereas in v1 it was possible for the ambiguous ``timeout`` + setting -- see below -- to work for either connect OR command timeouts. * - ``forward_agent`` - Config: ``connect_kwargs.forward_agent``. * - ``gateway`` @@ -226,8 +230,8 @@ * - ``sudo_prompt`` - Config: ``sudo.prompt``. * - ``timeout`` - - Config: ``timeouts.connection`` (because v1's ambiguously named - ``timeout`` setting was, in fact, for connection timeouts). + - Config: ``timeouts.connection``, for connection timeouts, or + ``timeouts.command`` for command timeouts (see above). * - ``use_ssh_config`` - Config: ``load_ssh_configs``. * - ``user`` @@ -647,11 +651,11 @@ well return as a configuration value. * - ``-t``/``--timeout`` controlling connection timeout - Ported - - This is now part of the direct passthrough to Paramiko-level connection - parameters, the ``connect_kwargs`` config value. + - It's now ``-t``/``--connect-timeout`` as ``--timeout`` was technically + ambiguous re: connect vs command timeout. * - ``-T``/``--command-timeout`` - - `Pending <https://github.com/pyinvoke/invoke/issues/539>`__ - - See notes in :ref:`upgrading-commands` around the ``timeout`` kwarg. + - Ported + - Implemented in Invoke and preserved in ``fab`` under the same name. * - ``-u``/``--user`` to set global default username - Removed - Most of the time, configuration (env vars for true runtime, or eg @@ -743,9 +747,11 @@ system. * - ``timeout`` kwarg and the ``CommandTimeout`` exception raised when said command-runtime timeout was violated - - `Pending <https://github.com/pyinvoke/invoke/issues/539>`__ - - Command timeouts have not been ported yet, but will likely be added (at - the Invoke layer) in future. + - Ported + - Primarily lives at the Invoke layer now, but applies to all command + execution, local or remote; see the ``timeout`` argument to + `~invoke.runners.Runner.run` and its related configuration value and + CLI flag. * - ``pty`` kwarg and ``env.always_use_pty``, controlling whether commands run in a pseudo-terminal or are invoked directly - Ported @@ -990,10 +996,14 @@ * - ``env.connection_attempts`` for setting connection retries - `Pending <https://github.com/fabric/fabric/issues/1808>`__ - Not ported yet. - * - ``env.timeout`` for controlling connection timeout + * - ``env.timeout`` for controlling connection (and sometimes command + execution) timeout - Ported - - This is now controllable both via the configuration system and a direct - kwarg on `fabric.connection.Connection`. + - Connection timeout is now controllable both via the configuration + system (as ``timeouts.connect``) and a direct kwarg on + `fabric.connection.Connection`. Command execution timeout is its own + setting now, ``timeouts.command`` and a ``timeout`` kwarg to ``run`` + and friends. Authentication -------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/tasks.py new/fabric-2.5.0/tasks.py --- old/fabric-2.4.0/tasks.py 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/tasks.py 2019-08-06 20:33:19.000000000 +0200 @@ -5,7 +5,7 @@ from invocations import travis from invocations.checks import blacken from invocations.docs import docs, www, sites, watch_docs -from invocations.pytest import test, integration, coverage +from invocations.pytest import test, integration as integration_, coverage from invocations.packaging import release from invocations.util import tmpdir @@ -97,6 +97,23 @@ assert cxn.port == 2222 +# TODO: as usual, this just wants a good pattern for "that other task, with a +# tweaked default arg value" +@task +def integration( + c, + opts=None, + pty=True, + x=False, + k=None, + verbose=True, + color=True, + capture="no", + module=None, +): + return integration_(c, opts, pty, x, k, verbose, color, capture, module) + + # Better than nothing, since we haven't solved "pretend I have some other # task's signature" yet... publish.__doc__ = release.publish.__doc__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/tests/_support/fabfile.py new/fabric-2.5.0/tests/_support/fabfile.py --- old/fabric-2.4.0/tests/_support/fabfile.py 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/tests/_support/fabfile.py 2019-08-06 20:33:19.000000000 +0200 @@ -61,6 +61,11 @@ @task +def expect_connect_timeout(c): + assert c.config.connect_kwargs["timeout"] == 5 + + +@task def first(c): print("First!") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/tests/_util.py new/fabric-2.5.0/tests/_util.py --- old/fabric-2.4.0/tests/_util.py 2018-09-14 00:29:20.000000000 +0200 +++ new/fabric-2.5.0/tests/_util.py 2019-07-19 18:29:16.000000000 +0200 @@ -7,7 +7,7 @@ from pytest_relaxed import trap from fabric import Connection as Connection_, Config as Config_ -from fabric.main import program as fab_program +from fabric.main import make_program from paramiko import SSHConfig @@ -37,7 +37,7 @@ @trap def expect(invocation, out, program=None, test="equals"): if program is None: - program = fab_program + program = make_program() program.run("fab {}".format(invocation), exit=False) output = sys.stdout.getvalue() if test == "equals": diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/tests/main.py new/fabric-2.5.0/tests/main.py --- old/fabric-2.4.0/tests/main.py 2018-09-14 00:28:41.000000000 +0200 +++ new/fabric-2.5.0/tests/main.py 2019-08-06 20:33:19.000000000 +0200 @@ -13,7 +13,7 @@ from pytest_relaxed import raises from fabric.config import Config -from fabric.main import program +from fabric.main import make_program from fabric.exceptions import NothingToDo from fabric.testing.base import Session @@ -52,12 +52,12 @@ def executes_remainder_as_anonymous_task(self, remote): remote.expect(host="myhost", cmd="whoami") - program.run("fab -H myhost -- whoami", exit=False) + make_program().run("fab -H myhost -- whoami", exit=False) def uses_FABRIC_env_prefix(self, environ): environ["FABRIC_RUN_ECHO"] = "1" with cd(support): - program.run("fab expect-from-env") + make_program().run("fab expect-from-env") def basic_pre_and_post_tasks_still_work(self): with cd(support): @@ -79,6 +79,7 @@ basic-run build deploy + expect-connect-timeout expect-from-env expect-identities expect-identity @@ -104,7 +105,7 @@ with cd(os.path.join(support, "{}_conf".format(type_))): # This task, in each subdir, expects data present in a # fabric.<ext> nearby to show up in the config. - program.run("fab expect-conf-value") + make_program().run("fab expect-conf-value") class runtime_ssh_config_path: def _run( @@ -117,7 +118,7 @@ # Relies on asserts within the task, which will bubble up as # it's executed in-process cmd = "fab -c runtime_fabfile {} {} -H runtime {}" - program.run(cmd.format(flag, file_, tasks)) + make_program().run(cmd.format(flag, file_, tasks)) def capital_F_flag_specifies_runtime_ssh_config_file(self): self._run(flag="-S") @@ -151,24 +152,24 @@ # dumb bug where one appends to, instead of replacing, the task # list during parameterization/expansion XD with cd(support): - program.run("fab -H myhost basic-run") + make_program().run("fab -H myhost basic-run") def comma_separated_string_is_multiple_hosts(self, remote): remote.expect_sessions( Session("host1", cmd="nope"), Session("host2", cmd="nope") ) with cd(support): - program.run("fab -H host1,host2 basic-run") + make_program().run("fab -H host1,host2 basic-run") def multiple_hosts_works_with_remainder_too(self, remote): remote.expect_sessions( Session("host1", cmd="whoami"), Session("host2", cmd="whoami") ) - program.run("fab -H host1,host2 -- whoami") + make_program().run("fab -H host1,host2 -- whoami") def host_string_shorthand_is_passed_through(self, remote): remote.expect(host="host1", port=1234, user="someuser") - program.run("fab -H someuser@host1:1234 -- whoami") + make_program().run("fab -H someuser@host1:1234 -- whoami") # NOTE: no mocking because no actual run() under test, only # parameterization @@ -180,12 +181,16 @@ @pytest.mark.skip def config_mutation_not_preserved(self): with cd(support): - program.run("fab -H host1,host2 expect-mutation-to-fail") + make_program().run( + "fab -H host1,host2 expect-mutation-to-fail" + ) @trap def pre_post_tasks_are_not_parameterized_across_hosts(self): with cd(support): - program.run("fab -H hostA,hostB,hostC second --show-host") + make_program().run( + "fab -H hostA,hostB,hostC second --show-host" + ) output = sys.stdout.getvalue() # Expect pre once, 3x main, post once, as opposed to e.g. both # pre and main task @@ -205,19 +210,19 @@ def single_string_is_single_exec(self, remote): remote.expect(host="myhost", cmd="nope") with cd(support): - program.run("fab hosts-are-myhost") + make_program().run("fab hosts-are-myhost") def multiple_strings_is_multiple_host_args(self, remote): remote.expect_sessions( Session("host1", cmd="nope"), Session("host2", cmd="nope") ) with cd(support): - program.run("fab two-hosts") + make_program().run("fab two-hosts") def host_string_shorthand_works_ok(self, remote): remote.expect(host="host1", port=1234, user="someuser") with cd(support): - program.run("fab hosts-are-host-stringlike") + make_program().run("fab hosts-are-host-stringlike") def may_give_Connection_init_kwarg_dicts(self, remote): remote.expect_sessions( @@ -225,7 +230,7 @@ Session("host2", cmd="nope"), ) with cd(support): - program.run("fab hosts-are-init-kwargs") + make_program().run("fab hosts-are-init-kwargs") def may_give_mixed_value_types(self, remote): remote.expect_sessions( @@ -233,26 +238,37 @@ Session("host2", cmd="nope"), ) with cd(support): - program.run("fab hosts-are-mixed-values") + make_program().run("fab hosts-are-mixed-values") class no_hosts_flag_or_task_arg: def calls_task_once_with_invoke_context(self): with cd(support): - program.run("fab expect-vanilla-Context") + make_program().run("fab expect-vanilla-Context") def vanilla_Invoke_task_works_too(self): with cd(support): - program.run("fab vanilla-Task-works-ok") + make_program().run("fab vanilla-Task-works-ok") @raises(NothingToDo) def generates_exception_if_combined_with_remainder(self): - program.run("fab -- nope") + make_program().run("fab -- nope") def invokelike_multitask_invocation_preserves_config_mutation(self): # Mostly a guard against Executor subclass tweaks breaking Invoke # behavior added in pyinvoke/invoke#309 with cd(support): - program.run("fab mutate expect-mutation") + make_program().run("fab mutate expect-mutation") + + class connect_timeout: + def dash_t_supplies_default_connect_timeout(self): + with cd(support): + make_program().run("fab -t 5 expect-connect-timeout") + + def double_dash_connect_timeout_also_works(self): + with cd(support): + make_program().run( + "fab --connect-timeout 5 expect-connect-timeout" + ) class runtime_identity_file: def dash_i_supplies_default_connect_kwarg_key_filename(self): @@ -261,15 +277,17 @@ # relying on other tests to prove connect_kwargs makes its way into # that context. with cd(support): - program.run("fab -i identity.key expect-identity") + make_program().run("fab -i identity.key expect-identity") def double_dash_identity_also_works(self): with cd(support): - program.run("fab --identity identity.key expect-identity") + make_program().run( + "fab --identity identity.key expect-identity" + ) def may_be_given_multiple_times(self): with cd(support): - program.run( + make_program().run( "fab -i identity.key -i identity2.key expect-identities" ) @@ -280,7 +298,7 @@ with cd(support): # Expect that the given key was found in the context. cmd = "fab -c prompting {} expect-connect-kwarg --key {} --val {}" # noqa - program.run(cmd.format(flag, key, value)) + make_program().run(cmd.format(flag, key, value)) # Then we also expect that getpass was called w/ expected prompt getpass.assert_called_once_with(prompt) @@ -307,11 +325,11 @@ # test fixtures, which has a fabric.yml w/ a # connect_kwargs.key_filename value of [private.key, other.key]. with cd(os.path.join(support, "yml_conf")): - program.run("fab expect-conf-key-filename") + make_program().run("fab expect-conf-key-filename") def cli_identity_still_overrides_when_non_empty(self): with cd(os.path.join(support, "yml_conf")): - program.run("fab -i cli.key expect-cli-key-filename") + make_program().run("fab -i cli.key expect-cli-key-filename") class completion: # NOTE: most completion tests are in Invoke too; this is just an @@ -322,7 +340,7 @@ # collections because it thinks it's in remainder-only, # work-without-a-collection mode. with cd(support): - program.run("fab --complete -- fab", exit=False) + make_program().run("fab --complete -- fab", exit=False) # Cherry-picked sanity checks looking for tasks from fixture # fabfile output = sys.stdout.getvalue() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fabric-2.4.0/tests/runners.py new/fabric-2.5.0/tests/runners.py --- old/fabric-2.4.0/tests/runners.py 2018-09-14 00:29:00.000000000 +0200 +++ new/fabric-2.5.0/tests/runners.py 2019-08-06 20:33:19.000000000 +0200 @@ -3,6 +3,7 @@ except ImportError: from six import StringIO +from mock import Mock from pytest import skip # noqa from invoke import pty_size, Result @@ -131,3 +132,9 @@ r = Remote(context=_Connection("host"), inline_env=True) r.run(CMD, env={"PATH": "/opt/bin", "DEBUG": "1"}) assert not chan.update_environment.called + + def kill_closes_the_channel(self): + runner = _runner() + runner.channel = Mock() + runner.kill() + runner.channel.close.assert_called_once_with()
