From bdfb9f19c4086a60ef010d2431768850c26d838a Mon Sep 17 00:00:00 2001 From: ohemorange Date: Thu, 28 Jan 2021 12:34:50 -0800 Subject: [PATCH 01/21] Remove deprecated options as early as possible using an explicit list (#8617) * Remove deprecated options as early as possible using an explicit list * add deprecated options to cli init import list * use correct dict comprehension syntax for py3 * lint * add test for renewal reconstitution code * add test to ensure we're not saving deprecated values * comment code --- certbot/certbot/_internal/cli/__init__.py | 11 ++++++++++- .../certbot/_internal/cli/cli_constants.py | 5 +++++ certbot/certbot/_internal/renewal.py | 14 ++++++++++++++ .../sample-renewal-deprecated-option.conf | 14 ++++++++++++++ certbot/tests/renewal_test.py | 19 +++++++++++++++++++ certbot/tests/storage_test.py | 11 +++++++++++ 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 certbot/certbot/tests/testdata/sample-renewal-deprecated-option.conf diff --git a/certbot/certbot/_internal/cli/__init__.py b/certbot/certbot/_internal/cli/__init__.py index e50cb338a..c69bb3564 100644 --- a/certbot/certbot/_internal/cli/__init__.py +++ b/certbot/certbot/_internal/cli/__init__.py @@ -28,7 +28,8 @@ from certbot._internal.cli.cli_constants import ( ARGPARSE_PARAMS_TO_REMOVE, EXIT_ACTIONS, ZERO_ARG_ACTIONS, - VAR_MODIFIERS + VAR_MODIFIERS, + DEPRECATED_OPTIONS ) from certbot._internal.cli.cli_utils import ( @@ -471,6 +472,11 @@ def set_by_cli(var): (CLI or config file) including if the user explicitly set it to the default. Returns False if the variable was assigned a default value. """ + # We should probably never actually hit this code. But if we do, + # a deprecated option has logically never been set by the CLI. + if var in DEPRECATED_OPTIONS: + return False + detector = set_by_cli.detector # type: ignore if detector is None and helpful_parser is not None: # Setup on first run: `detector` is a weird version of config in which @@ -531,6 +537,9 @@ def option_was_set(option, value): :rtype: bool """ + # If an option is deprecated, it was effectively not set by the user. + if option in DEPRECATED_OPTIONS: + return False return set_by_cli(option) or not has_default_value(option, value) diff --git a/certbot/certbot/_internal/cli/cli_constants.py b/certbot/certbot/_internal/cli/cli_constants.py index 4bc84bfe7..dc199e152 100644 --- a/certbot/certbot/_internal/cli/cli_constants.py +++ b/certbot/certbot/_internal/cli/cli_constants.py @@ -105,3 +105,8 @@ VAR_MODIFIERS = {"account": {"server",}, "renew_hook": {"deploy_hook",}, "server": {"dry_run", "staging",}, "webroot_map": {"webroot_path",}} + +# This is a list of all CLI options that we have ever deprecated. It lets us +# opt out of the default detection, which can interact strangely with option +# deprecation. See https://github.com/certbot/certbot/issues/8540 for more info. +DEPRECATED_OPTIONS = {"manual_public_ip_logging_ok",} diff --git a/certbot/certbot/_internal/renewal.py b/certbot/certbot/_internal/renewal.py index 3a550d355..f4c7b4502 100644 --- a/certbot/certbot/_internal/renewal.py +++ b/certbot/certbot/_internal/renewal.py @@ -85,6 +85,7 @@ def _reconstitute(config, full_path): return None # Now restore specific values along with their data types, if # those elements are present. + renewalparams = _remove_deprecated_config_elements(renewalparams) try: restore_required_config_elements(config, renewalparams) _restore_plugin_configs(config, renewalparams) @@ -188,6 +189,19 @@ def restore_required_config_elements(config, renewalparams): setattr(config, item_name, value) +def _remove_deprecated_config_elements(renewalparams): + """Removes deprecated config options from the parsed renewalparams. + + :param dict renewalparams: list of parsed renewalparams + + :returns: list of renewalparams with deprecated config options removed + :rtype: dict + + """ + return {option_name: v for (option_name, v) in renewalparams.items() + if option_name not in cli.DEPRECATED_OPTIONS} + + def _restore_pref_challs(unused_name, value): """Restores preferred challenges from a renewal config file. diff --git a/certbot/certbot/tests/testdata/sample-renewal-deprecated-option.conf b/certbot/certbot/tests/testdata/sample-renewal-deprecated-option.conf new file mode 100644 index 000000000..2b777d3de --- /dev/null +++ b/certbot/certbot/tests/testdata/sample-renewal-deprecated-option.conf @@ -0,0 +1,14 @@ +# renew_before_expiry = 30 days +version = 1.11.0 +archive_dir = MAGICDIR/live/sample-renewal-deprecated-option +cert = MAGICDIR/live/sample-renewal-deprecated-option/cert.pem +privkey = MAGICDIR/live/sample-renewal-deprecated-option/privkey.pem +chain = MAGICDIR/live/sample-renewal-deprecated-option/chain.pem +fullchain = MAGICDIR/live/sample-renewal-deprecated-option/fullchain.pem + +# Options used in the renewal process +[renewalparams] +account = ffffffffffffffffffffffffffffffff +authenticator = nginx +installer = nginx +manual_public_ip_logging_ok = None diff --git a/certbot/tests/renewal_test.py b/certbot/tests/renewal_test.py index 4af8c6e7f..7c9c53fb4 100644 --- a/certbot/tests/renewal_test.py +++ b/certbot/tests/renewal_test.py @@ -1,4 +1,6 @@ """Tests for certbot._internal.renewal""" +import copy + import unittest try: @@ -98,6 +100,23 @@ class RenewalTest(test_util.ConfigTestCase): assert self.config.elliptic_curve == 'secp256r1' + @test_util.patch_get_utility() + @mock.patch('certbot._internal.renewal.cli.set_by_cli') + def test_remove_deprecated_config_elements(self, mock_set_by_cli, unused_mock_get_utility): + mock_set_by_cli.return_value = False + config = configuration.NamespaceConfig(self.config) + config.certname = "sample-renewal-deprecated-option" + + rc_path = test_util.make_lineage( + self.config.config_dir, 'sample-renewal-deprecated-option.conf') + + from certbot._internal import renewal + lineage_config = copy.deepcopy(self.config) + renewal_candidate = renewal._reconstitute(lineage_config, rc_path) + # This means that manual_public_ip_logging_ok was not modified in the config based on its + # value in the renewal conf file + self.assertTrue(isinstance(lineage_config.manual_public_ip_logging_ok, mock.MagicMock)) + class RestoreRequiredConfigElementsTest(test_util.ConfigTestCase): """Tests for certbot._internal.renewal.restore_required_config_elements.""" diff --git a/certbot/tests/storage_test.py b/certbot/tests/storage_test.py index 9ae26532f..914304cd4 100644 --- a/certbot/tests/storage_test.py +++ b/certbot/tests/storage_test.py @@ -77,6 +77,17 @@ class RelevantValuesTest(unittest.TestCase): self.assertEqual(self._call(self.values), expected_relevant_values) + @mock.patch("certbot._internal.cli.set_by_cli") + def test_deprecated_item(self, unused_mock_set_by_cli): + # deprecated items should never be relevant to store + expected_relevant_values = self.values.copy() + self.values["manual_public_ip_logging_ok"] = None + self.assertEqual(self._call(self.values), expected_relevant_values) + self.values["manual_public_ip_logging_ok"] = True + self.assertEqual(self._call(self.values), expected_relevant_values) + self.values["manual_public_ip_logging_ok"] = False + self.assertEqual(self._call(self.values), expected_relevant_values) + class BaseRenewableCertTest(test_util.ConfigTestCase): """Base class for setting up Renewable Cert tests. From 2e33aec8a849ba56afa6acd2764b4f3b328aa88e Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 29 Jan 2021 15:31:11 -0800 Subject: [PATCH 02/21] add tests with external mock library --- tox.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tox.ini b/tox.ini index 94cd305aa..fd9105e8b 100644 --- a/tox.ini +++ b/tox.ini @@ -137,6 +137,11 @@ commands = setenv = {[testenv:oldest]setenv} +[testenv:external-mock] +commands = + python {toxinidir}/tools/pip_install.py mock + {[base]install_and_test} {[base]all_packages} + [testenv:lint] basepython = python3 # separating into multiple invocations disables cross package From 534af33a50c6de9900f7066bf848fe61e4a13f62 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 29 Jan 2021 15:32:04 -0800 Subject: [PATCH 03/21] add external-mock tests to azure config --- .azure-pipelines/templates/jobs/extended-tests-jobs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.azure-pipelines/templates/jobs/extended-tests-jobs.yml b/.azure-pipelines/templates/jobs/extended-tests-jobs.yml index 48fcae18f..cffedfcb2 100644 --- a/.azure-pipelines/templates/jobs/extended-tests-jobs.yml +++ b/.azure-pipelines/templates/jobs/extended-tests-jobs.yml @@ -21,6 +21,8 @@ jobs: PYTHON_VERSION: 3.7 TOXENV: py37 CERTBOT_NO_PIN: 1 + linux-external-mock: + TOXENV: external-mock linux-boulder-v1-integration-certbot-oldest: PYTHON_VERSION: 3.6 TOXENV: integration-certbot-oldest From f0b32783f01d8e37ce9f68a24af93e003bf30933 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 1 Feb 2021 13:11:04 -0800 Subject: [PATCH 04/21] Start disabling certbot-auto upgrades (#8623) * add amazon linux to auto targets * disable updates outside of debian and rhel * test certbot-auto with disabled upgrades * try new approach to testing * remove bad space * tweak error text * add changelog entry * fix bad certbot-auto commit * test new error text * update changelog * update error text --- certbot/CHANGELOG.md | 5 ++ letsencrypt-auto-source/letsencrypt-auto | 14 +++++- .../letsencrypt-auto.template | 14 +++++- tests/letstest/auto_targets.yaml | 7 +++ .../letstest/scripts/test_leauto_upgrades.sh | 49 ++++++++++++++++++- 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 0ffed42d1..1be23a130 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -15,6 +15,11 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). every certificate in the chain. See [#8577](https://github.com/certbot/certbot/issues/8577). * Support for Python 2 has been removed. +* In previous releases, we caused certbot-auto to stop updating its Certbot + installation. In this release, we are beginning to disable updates to the + certbot-auto script itself. This release includes Amazon Linux users, and all + other systems that are not based on Debian or RHEL. We plan to make this + change to the certbot-auto script for all users in the coming months. ### Fixed diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 4ff1ddae9..f1adb9a43 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -803,6 +803,7 @@ if [ -f /etc/debian_version ]; then elif [ -f /etc/mageia-release ]; then # Mageia has both /etc/mageia-release and /etc/redhat-release DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 # Run DeterminePythonVersion to decide on the basis of available Python versions @@ -863,22 +864,31 @@ elif [ -f /etc/redhat-release ]; then LE_PYTHON="$prev_le_python" elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/arch-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/manjaro-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/gentoo-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq FreeBSD ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq Darwin ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 else DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 fi # We handle this case after determining the normal bootstrap version to allow @@ -1107,7 +1117,9 @@ if [ "$1" = "--le-auto-phase2" ]; then fi if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then - error "Certbot will no longer receive updates." + error "certbot-auto and its Certbot installation will no longer receive updates." + error "You will not receive any bug fixes including those fixing server compatibility" + error "or security problems." error "Please visit https://certbot.eff.org/ to check for other alternatives." "$VENV_BIN/letsencrypt" "$@" exit 0 diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index bc27469fb..783268571 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -325,6 +325,7 @@ if [ -f /etc/debian_version ]; then elif [ -f /etc/mageia-release ]; then # Mageia has both /etc/mageia-release and /etc/redhat-release DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 # Run DeterminePythonVersion to decide on the basis of available Python versions @@ -385,22 +386,31 @@ elif [ -f /etc/redhat-release ]; then LE_PYTHON="$prev_le_python" elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/arch-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/manjaro-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/gentoo-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq FreeBSD ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq Darwin ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 else DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 fi # We handle this case after determining the normal bootstrap version to allow @@ -521,7 +531,9 @@ if [ "$1" = "--le-auto-phase2" ]; then fi if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then - error "Certbot will no longer receive updates." + error "certbot-auto and its Certbot installation will no longer receive updates." + error "You will not receive any bug fixes including those fixing server compatibility" + error "or security problems." error "Please visit https://certbot.eff.org/ to check for other alternatives." "$VENV_BIN/letsencrypt" "$@" exit 0 diff --git a/tests/letstest/auto_targets.yaml b/tests/letstest/auto_targets.yaml index 01d410227..164580e86 100644 --- a/tests/letstest/auto_targets.yaml +++ b/tests/letstest/auto_targets.yaml @@ -57,3 +57,10 @@ targets: type: centos virt: hvm user: centos + #----------------------------------------------------------------------------- + # Amazon Linux + - ami: ami-0ff8a91507f77f867 + name: amazon + type: centos + virt: hvm + user: ec2-user diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index c599623cb..d24258a22 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -43,9 +43,11 @@ fi # directory to be served. MY_TEMP_DIR=$(mktemp -d) PORT_FILE="$MY_TEMP_DIR/port" +LOG_FILE="$MY_TEMP_DIR/log" SERVER_PATH=$("$PYTHON_NAME" tools/readlink.py tools/simple_http_server.py) cd "$MY_TEMP_DIR" -"$PYTHON_NAME" "$SERVER_PATH" 0 > $PORT_FILE & +# We set PYTHONUNBUFFERED to disable buffering of output to LOG_FILE +PYTHONUNBUFFERED=1 "$PYTHON_NAME" "$SERVER_PATH" 0 > $PORT_FILE 2> "$LOG_FILE" & SERVER_PID=$! trap 'kill "$SERVER_PID" && rm -rf "$MY_TEMP_DIR"' EXIT cd ~- @@ -119,3 +121,48 @@ if ! diff letsencrypt-auto letsencrypt-auto-source/letsencrypt-auto ; then echo letsencrypt-auto and letsencrypt-auto-source/letsencrypt-auto differ exit 1 fi + +# Now let's test if letsencrypt-auto still tries to upgrade to a new version. +# Regardless of the OS, versions of the script with development version numbers +# ending in .dev0 will not upgrade. See +# https://github.com/certbot/certbot/blob/bdfb9f19c4086a60ef010d2431768850c26d838a/certbot-auto#L1947-L1948. +# In order to test the process of different OSes setting NO_SELF_UPGRADE as +# part of the script's deprecation, we make use of the fact that +# letsencrypt-auto should still attempt to fetch the version number from PyPI +# even if it has a development version number unless NO_SELF_UPGRADE is set in +# which case all of that logic should be skipped. +# +# First we make a copy of the current server logs. +PREVIOUS_LOG_FILE="$MY_TEMP_DIR/previous-log" +cp "$LOG_FILE" "$PREVIOUS_LOG_FILE" + +# Next we run letsencrypt-auto and make sure there were no problems checking +# for updates, the Certbot install still works, the version number is what +# we expect, and it prints a message about not receiving updates. +if ./letsencrypt-auto -v --debug --version | grep "WARNING: couldn't find Python" ; then + echo "Had problems checking for updates!" + exit 1 +fi +if ! ./letsencrypt-auto -v --debug --version 2>&1 | tail -n1 | grep "^certbot $EXPECTED_VERSION$" ; then + echo unexpected certbot version found + exit 1 +fi +if ! ./letsencrypt-auto -v --debug --version 2>&1 | grep "will no longer receive updates" ; then + echo script did not print warning about not receiving updates! + exit 1 +fi + +# Finally, we check if our local server received more requests. Over time, +# we'll move more and more OSes into this case until it this is the expected +# behavior on all systems. +if [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue; then + if ! diff "$LOG_FILE" "$PREVIOUS_LOG_FILE" ; then + echo our local server received unexpected requests + exit 1 + fi +else + if diff "$LOG_FILE" "$PREVIOUS_LOG_FILE" ; then + echo our local server did not receive the requests we expected + exit 1 + fi +fi From df866b907b4d5eaecb110d784b858d50a1726c9e Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Tue, 2 Feb 2021 10:58:41 -0800 Subject: [PATCH 05/21] Update changelog for 1.12.0 release --- certbot/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 1be23a130..c7ab33f71 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -2,7 +2,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). -## 1.12.0 - master +## 1.12.0 - 2021-02-02 ### Added From 786a130b7d821f38fc1873ede5fd5ce4d99bbd28 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Tue, 2 Feb 2021 11:06:40 -0800 Subject: [PATCH 06/21] Release 1.12.0 --- acme/setup.py | 2 +- certbot-apache/setup.py | 2 +- certbot-auto | 40 ++++++++++++------ certbot-compatibility-test/setup.py | 2 +- certbot-dns-cloudflare/setup.py | 2 +- certbot-dns-cloudxns/setup.py | 2 +- certbot-dns-digitalocean/setup.py | 2 +- certbot-dns-dnsimple/setup.py | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- certbot-dns-gehirn/setup.py | 2 +- certbot-dns-google/setup.py | 2 +- certbot-dns-linode/setup.py | 2 +- certbot-dns-luadns/setup.py | 2 +- certbot-dns-nsone/setup.py | 2 +- certbot-dns-ovh/setup.py | 2 +- certbot-dns-rfc2136/setup.py | 2 +- certbot-dns-route53/setup.py | 2 +- certbot-dns-sakuracloud/setup.py | 2 +- certbot-nginx/setup.py | 2 +- certbot/certbot/__init__.py | 2 +- certbot/docs/cli-help.txt | 8 ++-- letsencrypt-auto | 40 ++++++++++++------ letsencrypt-auto-source/certbot-auto.asc | 16 +++---- letsencrypt-auto-source/letsencrypt-auto | 26 ++++++------ letsencrypt-auto-source/letsencrypt-auto.sig | Bin 256 -> 256 bytes .../pieces/certbot-requirements.txt | 24 +++++------ 26 files changed, 108 insertions(+), 84 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index 056b00107..eadd742ac 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index bebca6b25..7ebb978b1 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-auto b/certbot-auto index e8012439a..002fd5ffc 100755 --- a/certbot-auto +++ b/certbot-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="1.11.0" +LE_AUTO_VERSION="1.12.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -803,6 +803,7 @@ if [ -f /etc/debian_version ]; then elif [ -f /etc/mageia-release ]; then # Mageia has both /etc/mageia-release and /etc/redhat-release DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 # Run DeterminePythonVersion to decide on the basis of available Python versions @@ -863,22 +864,31 @@ elif [ -f /etc/redhat-release ]; then LE_PYTHON="$prev_le_python" elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/arch-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/manjaro-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/gentoo-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq FreeBSD ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq Darwin ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 else DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 fi # We handle this case after determining the normal bootstrap version to allow @@ -1107,7 +1117,9 @@ if [ "$1" = "--le-auto-phase2" ]; then fi if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then - error "Certbot will no longer receive updates." + error "certbot-auto and its Certbot installation will no longer receive updates." + error "You will not receive any bug fixes including those fixing server compatibility" + error "or security problems." error "Please visit https://certbot.eff.org/ to check for other alternatives." "$VENV_BIN/letsencrypt" "$@" exit 0 @@ -1475,18 +1487,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==1.11.0 \ - --hash=sha256:b7faa66c40a1ce5a31bfc8668d8feb5d2db6f7af9e791079a6d95c77b6593bf4 \ - --hash=sha256:6b0ce04e55379aff0a47f873fa05c084538ad0f4a9b79f33108dbb0a7a668b43 -acme==1.11.0 \ - --hash=sha256:77d6ce61b155315d7d7031489bbd245c0ea42c0453a04d4304393414e741a56d \ - --hash=sha256:092eb09a074a935da4c10f66cb8634ffb2cc2d2cc1035d2998d608996efab924 -certbot-apache==1.11.0 \ - --hash=sha256:ea7ac88733aad91a89c700289effda2a0c0658778da1ae2c54a0aefaee351285 \ - --hash=sha256:3ed001427ec0b49324f2b9af7170fa6e6e88948fa51c3678b07bf17f8138863d -certbot-nginx==1.11.0 \ - --hash=sha256:79de69782a1199e577787ff9790dee02a44aac17dbecd6a7287593030842a306 \ - --hash=sha256:9afe611f99a78b8898941b8ad7bdcf7f3c2b6e0fce27125268f7c713e64b34ee +certbot==1.12.0 \ + --hash=sha256:f4bb3da5391e4a28e9a2e52ab54986171c0864feff17eaaaca6729a1d4c433a6 \ + --hash=sha256:5ee738773479bcb7794e43fedd2415acc0969b75bdd2a21f451e3bff9d99df59 +acme==1.12.0 \ + --hash=sha256:ca4ad044429f1b8b670b958e5c7ea38159def9d601f4af2359355993918c3317 \ + --hash=sha256:aa363474d50e9fdda27acb8b1aa7efb26fecc5650e02039a0de3a3f0e696c2f2 +certbot-apache==1.12.0 \ + --hash=sha256:38899f6fa08799de9535795d919acf968f288d7208909baf7733f9a763c15227 \ + --hash=sha256:e5679b40d99bd241f4fcd9fe44b73e6e25ccc969a617131ff6ebc90d562a49f2 +certbot-nginx==1.12.0 \ + --hash=sha256:332cd70067bbcf6db52a002650ffa4844d0bd9780279d662aa6725b43f776c14 \ + --hash=sha256:3fb6a55290d37ad466681a89a85ceca4c4026fdd8702f3010b87a74266a6fe7b UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index e7b7d9c3a..759fd2184 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' install_requires = [ 'certbot', diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index 7ee81c103..ebff99f35 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index f57eb4d64..cb004af82 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index d1e84710d..6676df656 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index f73f6f7c8..fec8642f6 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index e7cd2e1ed..42c1940e7 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index 0cba57800..7ca395a90 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 09dace6c0..7b20fff09 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 6f796b45c..0e3c00a18 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index ee4fc352e..eea5b24bb 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index fe667fe6c..7dd6a563e 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index fc8402ff2..42a841bfc 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 2af5566c4..9351bda38 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index 4b60d8570..eb78c9a0b 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index b4d59e7b6..63e1b3f3b 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 4f6f7ed2a..7bd4070e0 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0.dev0' +version = '1.12.0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot/certbot/__init__.py b/certbot/certbot/__init__.py index a196def66..17fda1223 100644 --- a/certbot/certbot/__init__.py +++ b/certbot/certbot/__init__.py @@ -1,3 +1,3 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '1.12.0.dev0' +__version__ = '1.12.0' diff --git a/certbot/docs/cli-help.txt b/certbot/docs/cli-help.txt index 4ba70587f..4482ea439 100644 --- a/certbot/docs/cli-help.txt +++ b/certbot/docs/cli-help.txt @@ -99,9 +99,9 @@ optional arguments: before submitting to CA (default: False) --preferred-chain PREFERRED_CHAIN If the CA offers multiple certificate chains, prefer - the chain with an issuer matching this Subject Common - Name. If no match, the default offered chain will be - used. (default: None) + the chain whose topmost certificate was issued from + this Subject Common Name. If no match, the default + offered chain will be used. (default: None) --preferred-challenges PREF_CHALLS A sorted, comma delimited list of the preferred challenge to use during authorization with the most @@ -118,7 +118,7 @@ optional arguments: case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/1.11.0 + "". (default: CertbotACMEClient/1.12.0 (certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). The flags encoded in the diff --git a/letsencrypt-auto b/letsencrypt-auto index e8012439a..002fd5ffc 100755 --- a/letsencrypt-auto +++ b/letsencrypt-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="1.11.0" +LE_AUTO_VERSION="1.12.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -803,6 +803,7 @@ if [ -f /etc/debian_version ]; then elif [ -f /etc/mageia-release ]; then # Mageia has both /etc/mageia-release and /etc/redhat-release DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 # Run DeterminePythonVersion to decide on the basis of available Python versions @@ -863,22 +864,31 @@ elif [ -f /etc/redhat-release ]; then LE_PYTHON="$prev_le_python" elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/arch-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/manjaro-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/gentoo-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq FreeBSD ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif uname | grep -iq Darwin ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 else DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 fi # We handle this case after determining the normal bootstrap version to allow @@ -1107,7 +1117,9 @@ if [ "$1" = "--le-auto-phase2" ]; then fi if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then - error "Certbot will no longer receive updates." + error "certbot-auto and its Certbot installation will no longer receive updates." + error "You will not receive any bug fixes including those fixing server compatibility" + error "or security problems." error "Please visit https://certbot.eff.org/ to check for other alternatives." "$VENV_BIN/letsencrypt" "$@" exit 0 @@ -1475,18 +1487,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==1.11.0 \ - --hash=sha256:b7faa66c40a1ce5a31bfc8668d8feb5d2db6f7af9e791079a6d95c77b6593bf4 \ - --hash=sha256:6b0ce04e55379aff0a47f873fa05c084538ad0f4a9b79f33108dbb0a7a668b43 -acme==1.11.0 \ - --hash=sha256:77d6ce61b155315d7d7031489bbd245c0ea42c0453a04d4304393414e741a56d \ - --hash=sha256:092eb09a074a935da4c10f66cb8634ffb2cc2d2cc1035d2998d608996efab924 -certbot-apache==1.11.0 \ - --hash=sha256:ea7ac88733aad91a89c700289effda2a0c0658778da1ae2c54a0aefaee351285 \ - --hash=sha256:3ed001427ec0b49324f2b9af7170fa6e6e88948fa51c3678b07bf17f8138863d -certbot-nginx==1.11.0 \ - --hash=sha256:79de69782a1199e577787ff9790dee02a44aac17dbecd6a7287593030842a306 \ - --hash=sha256:9afe611f99a78b8898941b8ad7bdcf7f3c2b6e0fce27125268f7c713e64b34ee +certbot==1.12.0 \ + --hash=sha256:f4bb3da5391e4a28e9a2e52ab54986171c0864feff17eaaaca6729a1d4c433a6 \ + --hash=sha256:5ee738773479bcb7794e43fedd2415acc0969b75bdd2a21f451e3bff9d99df59 +acme==1.12.0 \ + --hash=sha256:ca4ad044429f1b8b670b958e5c7ea38159def9d601f4af2359355993918c3317 \ + --hash=sha256:aa363474d50e9fdda27acb8b1aa7efb26fecc5650e02039a0de3a3f0e696c2f2 +certbot-apache==1.12.0 \ + --hash=sha256:38899f6fa08799de9535795d919acf968f288d7208909baf7733f9a763c15227 \ + --hash=sha256:e5679b40d99bd241f4fcd9fe44b73e6e25ccc969a617131ff6ebc90d562a49f2 +certbot-nginx==1.12.0 \ + --hash=sha256:332cd70067bbcf6db52a002650ffa4844d0bd9780279d662aa6725b43f776c14 \ + --hash=sha256:3fb6a55290d37ad466681a89a85ceca4c4026fdd8702f3010b87a74266a6fe7b UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc index 524293e31..aba5f1140 100644 --- a/letsencrypt-auto-source/certbot-auto.asc +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- -iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl/0pwwACgkQTRfJlc2X -dfL4eQf+MyI6XGuG9jKbfRRfYWNjc3B4nxjvpeaOys6ZNIFoI5sElR/8siv6lexc -iDZ0h6PkIfh4NkIOQJQqgGP885P4aPZBg1mOTnssa6u3+1R3QRb/L/QcppysQZnf -Jve+94Zpkz1r2pF8KI4mZYDl5iN01TrMlQLddEeWOzY1tzoEVBq19KBEUwnk8awt -WOxKfhITFPbU2jyR5O4przDJLGsqG6WC6etCbmWYnb/he3pWa70ITsv2a1RCoTDf -EsBb5QVa3SEw+NT3jyE9P3FothSQZyvsYojd6/B4/bwZarWwqh1mTMz55U2rJl87 -XpjglPXfhrv/s5oWNWthXTpz+11xvA== -=nhC8 +iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAmAZorcACgkQTRfJlc2X +dfI6Ogf+LFASyH9sgTV1k9hs1zbmO3CxyE9QQs1JLXpoKOQ1tKv+v+kpt+lJ005g +rielyRSssXtZSyfLchCSBh6qaEBodoOcz8RS2z7rDnR9jKOJv252Buh2oSa3KPmn +WPjRmB3zVXnhq/XmPKQTnoflUlBg+MtZuZXt0Fvu8rvQB+RY3AUfB5Xs83nxJNj4 +W9qNpZYl0sJWWiydr23bEk35MJSt62sKDvyqIVjUfgDfXHmauOpg0foz2xS6XP8i +Ke66GUKaQ1ap2BTucwVT0hieXiQZpxx1PitUeEOjOH9PUfrAxyFlQ0XQaVlqoBhc +YM3nzJw9yf12b+XCUvMzHyQmDA5vdQ== +=AUGt -----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index f1adb9a43..002fd5ffc 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="1.12.0.dev0" +LE_AUTO_VERSION="1.12.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -1487,18 +1487,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==1.11.0 \ - --hash=sha256:b7faa66c40a1ce5a31bfc8668d8feb5d2db6f7af9e791079a6d95c77b6593bf4 \ - --hash=sha256:6b0ce04e55379aff0a47f873fa05c084538ad0f4a9b79f33108dbb0a7a668b43 -acme==1.11.0 \ - --hash=sha256:77d6ce61b155315d7d7031489bbd245c0ea42c0453a04d4304393414e741a56d \ - --hash=sha256:092eb09a074a935da4c10f66cb8634ffb2cc2d2cc1035d2998d608996efab924 -certbot-apache==1.11.0 \ - --hash=sha256:ea7ac88733aad91a89c700289effda2a0c0658778da1ae2c54a0aefaee351285 \ - --hash=sha256:3ed001427ec0b49324f2b9af7170fa6e6e88948fa51c3678b07bf17f8138863d -certbot-nginx==1.11.0 \ - --hash=sha256:79de69782a1199e577787ff9790dee02a44aac17dbecd6a7287593030842a306 \ - --hash=sha256:9afe611f99a78b8898941b8ad7bdcf7f3c2b6e0fce27125268f7c713e64b34ee +certbot==1.12.0 \ + --hash=sha256:f4bb3da5391e4a28e9a2e52ab54986171c0864feff17eaaaca6729a1d4c433a6 \ + --hash=sha256:5ee738773479bcb7794e43fedd2415acc0969b75bdd2a21f451e3bff9d99df59 +acme==1.12.0 \ + --hash=sha256:ca4ad044429f1b8b670b958e5c7ea38159def9d601f4af2359355993918c3317 \ + --hash=sha256:aa363474d50e9fdda27acb8b1aa7efb26fecc5650e02039a0de3a3f0e696c2f2 +certbot-apache==1.12.0 \ + --hash=sha256:38899f6fa08799de9535795d919acf968f288d7208909baf7733f9a763c15227 \ + --hash=sha256:e5679b40d99bd241f4fcd9fe44b73e6e25ccc969a617131ff6ebc90d562a49f2 +certbot-nginx==1.12.0 \ + --hash=sha256:332cd70067bbcf6db52a002650ffa4844d0bd9780279d662aa6725b43f776c14 \ + --hash=sha256:3fb6a55290d37ad466681a89a85ceca4c4026fdd8702f3010b87a74266a6fe7b UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig index 3674e3a786eb92743c1a4f7183bdb79edc13158e..ac143de5133fe67f7e2603a9be2f33665e78fa2c 100644 GIT binary patch literal 256 zcmV+b0ssELVZ#xGplvu?ImflZrq&>KEMOKcX;|~NR_4j^#_pW5KEftEPHR&7d6>tM z25sS8!q>0X2i1!j^>r7H3#_3h+9Hd?a0>T0w3bDqFtv1&?YEiLe&nlJm$Hh)Kyg6) zgqN!!#FtpuwhEdp+myusw`M`ny<6n)L%{I6g57Roqh20pjWc`Ewg6gn`Ye-p$Q(?^ zbC^pt$wV}Dv&JQ!aJ+c?Nd9eta%CF`q+j!a9ju|3PdE}u_D5)b8cm|&VKzf+NR;!^}QJCBfs#!{4g*!dJU;1Q3KMo}D}Mn(9F GX@)sSp?~iH diff --git a/letsencrypt-auto-source/pieces/certbot-requirements.txt b/letsencrypt-auto-source/pieces/certbot-requirements.txt index 67ec23be3..4d4c91a5d 100644 --- a/letsencrypt-auto-source/pieces/certbot-requirements.txt +++ b/letsencrypt-auto-source/pieces/certbot-requirements.txt @@ -1,12 +1,12 @@ -certbot==1.11.0 \ - --hash=sha256:b7faa66c40a1ce5a31bfc8668d8feb5d2db6f7af9e791079a6d95c77b6593bf4 \ - --hash=sha256:6b0ce04e55379aff0a47f873fa05c084538ad0f4a9b79f33108dbb0a7a668b43 -acme==1.11.0 \ - --hash=sha256:77d6ce61b155315d7d7031489bbd245c0ea42c0453a04d4304393414e741a56d \ - --hash=sha256:092eb09a074a935da4c10f66cb8634ffb2cc2d2cc1035d2998d608996efab924 -certbot-apache==1.11.0 \ - --hash=sha256:ea7ac88733aad91a89c700289effda2a0c0658778da1ae2c54a0aefaee351285 \ - --hash=sha256:3ed001427ec0b49324f2b9af7170fa6e6e88948fa51c3678b07bf17f8138863d -certbot-nginx==1.11.0 \ - --hash=sha256:79de69782a1199e577787ff9790dee02a44aac17dbecd6a7287593030842a306 \ - --hash=sha256:9afe611f99a78b8898941b8ad7bdcf7f3c2b6e0fce27125268f7c713e64b34ee +certbot==1.12.0 \ + --hash=sha256:f4bb3da5391e4a28e9a2e52ab54986171c0864feff17eaaaca6729a1d4c433a6 \ + --hash=sha256:5ee738773479bcb7794e43fedd2415acc0969b75bdd2a21f451e3bff9d99df59 +acme==1.12.0 \ + --hash=sha256:ca4ad044429f1b8b670b958e5c7ea38159def9d601f4af2359355993918c3317 \ + --hash=sha256:aa363474d50e9fdda27acb8b1aa7efb26fecc5650e02039a0de3a3f0e696c2f2 +certbot-apache==1.12.0 \ + --hash=sha256:38899f6fa08799de9535795d919acf968f288d7208909baf7733f9a763c15227 \ + --hash=sha256:e5679b40d99bd241f4fcd9fe44b73e6e25ccc969a617131ff6ebc90d562a49f2 +certbot-nginx==1.12.0 \ + --hash=sha256:332cd70067bbcf6db52a002650ffa4844d0bd9780279d662aa6725b43f776c14 \ + --hash=sha256:3fb6a55290d37ad466681a89a85ceca4c4026fdd8702f3010b87a74266a6fe7b From 57cba3690dfce7b324ed46bb544ee75e03f1f7f8 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Tue, 2 Feb 2021 11:06:47 -0800 Subject: [PATCH 07/21] Add contents to certbot/CHANGELOG.md for next version --- certbot/CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index c7ab33f71..d83a258e2 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -2,6 +2,22 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). +## 1.13.0 - master + +### Added + +* + +### Changed + +* + +### Fixed + +* + +More details about these changes can be found on our GitHub repo. + ## 1.12.0 - 2021-02-02 ### Added From 2bcd8c59dbdee4905976367e98ea9006b56c9c91 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Tue, 2 Feb 2021 11:06:48 -0800 Subject: [PATCH 08/21] Bump version to 1.13.0 --- acme/setup.py | 2 +- certbot-apache/setup.py | 2 +- certbot-compatibility-test/setup.py | 2 +- certbot-dns-cloudflare/setup.py | 2 +- certbot-dns-cloudxns/setup.py | 2 +- certbot-dns-digitalocean/setup.py | 2 +- certbot-dns-dnsimple/setup.py | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- certbot-dns-gehirn/setup.py | 2 +- certbot-dns-google/setup.py | 2 +- certbot-dns-linode/setup.py | 2 +- certbot-dns-luadns/setup.py | 2 +- certbot-dns-nsone/setup.py | 2 +- certbot-dns-ovh/setup.py | 2 +- certbot-dns-rfc2136/setup.py | 2 +- certbot-dns-route53/setup.py | 2 +- certbot-dns-sakuracloud/setup.py | 2 +- certbot-nginx/setup.py | 2 +- certbot/certbot/__init__.py | 2 +- letsencrypt-auto-source/letsencrypt-auto | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index eadd742ac..2fafe845c 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 7ebb978b1..12aeac06b 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 759fd2184..19ee74efe 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' install_requires = [ 'certbot', diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index ebff99f35..b4f7222c0 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index cb004af82..e7ae702ef 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 6676df656..fca973e81 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index fec8642f6..329977aed 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 42c1940e7..def4ed1f0 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index 7ca395a90..a074b0eb2 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 7b20fff09..d104929b6 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 0e3c00a18..ddb9c2ef7 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index eea5b24bb..4b83ba2c0 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index 7dd6a563e..6ebe9decb 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 42a841bfc..9e7ec3675 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 9351bda38..cd0766585 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index eb78c9a0b..82cb50ddb 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 63e1b3f3b..6bb76b514 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 7bd4070e0..988f30052 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -version = '1.12.0' +version = '1.13.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. diff --git a/certbot/certbot/__init__.py b/certbot/certbot/__init__.py index 17fda1223..be06b5803 100644 --- a/certbot/certbot/__init__.py +++ b/certbot/certbot/__init__.py @@ -1,3 +1,3 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '1.12.0' +__version__ = '1.13.0.dev0' diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 002fd5ffc..14e71c615 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="1.12.0" +LE_AUTO_VERSION="1.13.0.dev0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates From 13af3f7ec21a689a6235006d2f97664bc8789a5f Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 3 Feb 2021 12:03:09 -0800 Subject: [PATCH 09/21] Cleanup venv scripts (#8629) Fixes https://github.com/certbot/certbot/issues/8387. * update _venv_common.py * delete venv.py scripts * rename venv script * update relevant venv3 references * remove set_python_envvars --- .dockerignore | 1 - .envrc | 2 +- Dockerfile-dev | 4 +- certbot-compatibility-test/Dockerfile | 6 +- certbot/docs/contributing.rst | 12 +- tests/letstest/scripts/set_python_envvars.sh | 17 -- tests/letstest/scripts/test_apache2.sh | 10 +- .../letstest/scripts/test_leauto_upgrades.sh | 9 +- tests/letstest/scripts/test_sdists.sh | 4 +- tests/letstest/scripts/test_tests.sh | 4 +- tools/_venv_common.py | 244 ----------------- tools/venv.py | 259 ++++++++++++++++-- tools/venv3.py | 30 -- 13 files changed, 268 insertions(+), 334 deletions(-) delete mode 100755 tests/letstest/scripts/set_python_envvars.sh delete mode 100644 tools/_venv_common.py delete mode 100755 tools/venv3.py diff --git a/.dockerignore b/.dockerignore index b94bf7960..2ce8a8209 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,5 +8,4 @@ .git .tox venv -venv3 docs diff --git a/.envrc b/.envrc index 4d2077ebb..43c3170d6 100644 --- a/.envrc +++ b/.envrc @@ -3,7 +3,7 @@ # activated and then deactivated when you cd elsewhere. Developers have to have # direnv set up and run `direnv allow` to allow this file to execute on their # system. You can find more information at https://direnv.net/. -. venv3/bin/activate +. venv/bin/activate # direnv doesn't support modifying PS1 so we unset it to squelch the error # it'll otherwise print about this being done in the activate script. See # https://github.com/direnv/direnv/wiki/PS1. If you would like your shell diff --git a/Dockerfile-dev b/Dockerfile-dev index ae197b1cb..86847f8fd 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -15,6 +15,6 @@ RUN apt-get update && \ /tmp/* \ /var/tmp/* -RUN VENV_NAME="../venv3" python3 tools/venv3.py +RUN VENV_NAME="../venv" python3 tools/venv.py -ENV PATH /opt/certbot/venv3/bin:$PATH +ENV PATH /opt/certbot/venv/bin:$PATH diff --git a/certbot-compatibility-test/Dockerfile b/certbot-compatibility-test/Dockerfile index f66e4c945..e0a439d01 100644 --- a/certbot-compatibility-test/Dockerfile +++ b/certbot-compatibility-test/Dockerfile @@ -8,11 +8,11 @@ RUN apt-get update && \ WORKDIR /opt/certbot/src # We copy all contents of the build directory to allow us to easily use -# things like tools/venv3.py which expects all of our packages to be available. +# things like tools/venv.py which expects all of our packages to be available. COPY . . -RUN tools/venv3.py -ENV PATH /opt/certbot/src/venv3/bin:$PATH +RUN tools/venv.py +ENV PATH /opt/certbot/src/venv/bin:$PATH # install in editable mode (-e) to save space: it's not possible to # "rm -rf /opt/certbot/src" (it's stays in the underlaying image); diff --git a/certbot/docs/contributing.rst b/certbot/docs/contributing.rst index ab07823f5..def2c7fcd 100644 --- a/certbot/docs/contributing.rst +++ b/certbot/docs/contributing.rst @@ -56,18 +56,18 @@ Set up the Python virtual environment that will host your Certbot local instance .. code-block:: shell cd certbot - python tools/venv3.py + python tools/venv.py .. note:: You may need to repeat this when Certbot's dependencies change or when a new plugin is introduced. You can now run the copy of Certbot from git either by executing -``venv3/bin/certbot``, or by activating the virtual environment. You can do the +``venv/bin/certbot``, or by activating the virtual environment. You can do the latter by running: .. code-block:: shell - source venv3/bin/activate + source venv/bin/activate After running this command, ``certbot`` and development tools like ``ipdb``, ``ipython``, ``pytest``, and ``tox`` are available in the shell where you ran @@ -169,7 +169,7 @@ To do so you need: - Docker installed, and a user with access to the Docker client, - an available `local copy`_ of Certbot. -The virtual environment set up with `python tools/venv3.py` contains two CLI tools +The virtual environment set up with `python tools/venv.py` contains two CLI tools that can be used once the virtual environment is activated: .. code-block:: shell @@ -197,8 +197,8 @@ using an HTTP-01 challenge on a machine with Python 3: .. code-block:: shell - python tools/venv3.py - source venv3/bin/activate + python tools/venv.py + source venv/bin/activate run_acme_server & certbot_test certonly --standalone -d test.example.com # To stop Pebble, launch `fg` to get back the background job, then press CTRL+C diff --git a/tests/letstest/scripts/set_python_envvars.sh b/tests/letstest/scripts/set_python_envvars.sh deleted file mode 100755 index 668444209..000000000 --- a/tests/letstest/scripts/set_python_envvars.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# This is a simple script that can be sourced to set Python environment -# variables for use in Certbot's letstest test farm tests. - -# Some distros like Fedora may only have an executable named python3 installed. -if command -v python; then - PYTHON_NAME="python" - VENV_SCRIPT="tools/venv.py" - VENV_PATH="venv" -else - # We could check for "python2" here, however, the addition of "python3" - # only systems is what necessitated this change so checking for "python2" - # isn't necessary. - PYTHON_NAME="python3" - VENV_PATH="venv3" - VENV_SCRIPT="tools/venv3.py" -fi diff --git a/tests/letstest/scripts/test_apache2.sh b/tests/letstest/scripts/test_apache2.sh index 247191610..77dc35f1e 100755 --- a/tests/letstest/scripts/test_apache2.sh +++ b/tests/letstest/scripts/test_apache2.sh @@ -64,7 +64,7 @@ if [ $? -ne 0 ] ; then exit 1 fi -tools/venv3.py -e acme[dev] -e certbot[dev,docs] -e certbot-apache -e certbot-ci +tools/venv.py -e acme[dev] -e certbot[dev,docs] -e certbot-apache -e certbot-ci PEBBLE_LOGS="acme_server.log" PEBBLE_URL="https://localhost:14000/dir" # We configure Pebble to use port 80 for http-01 validation rather than an @@ -73,7 +73,7 @@ PEBBLE_URL="https://localhost:14000/dir" # and closer to the default configuration on various OSes. # 2) As of writing this, Certbot's Apache plugin requires there to be an # existing virtual host for the port used for http-01 validation. -venv3/bin/run_acme_server --http-01-port 80 > "${PEBBLE_LOGS}" 2>&1 & +venv/bin/run_acme_server --http-01-port 80 > "${PEBBLE_LOGS}" 2>&1 & DumpPebbleLogs() { if [ -f "${PEBBLE_LOGS}" ] ; then @@ -96,7 +96,7 @@ if ! curl --insecure "${PEBBLE_URL}" 2>/dev/null; then exit 1 fi -sudo "venv3/bin/certbot" -v --debug --text --agree-tos --no-verify-ssl \ +sudo "venv/bin/certbot" -v --debug --text --agree-tos --no-verify-ssl \ --renew-by-default --redirect --register-unsafely-without-email \ --domain "${PUBLIC_HOSTNAME}" --server "${PEBBLE_URL}" if [ $? -ne 0 ] ; then @@ -113,7 +113,7 @@ elif [ "$OS_TYPE" = "centos" ]; then fi OPENSSL_VERSION=$(strings "$MOD_SSL_LOCATION" | egrep -o -m1 '^OpenSSL ([0-9]\.[^ ]+) ' | tail -c +9) APACHE_VERSION=$(sudo $APACHE_NAME -v | egrep -o 'Apache/([0-9]\.[^ ]+)' | tail -c +8) -"venv3/bin/python" tests/letstest/scripts/test_openssl_version.py "$OPENSSL_VERSION" "$APACHE_VERSION" +"venv/bin/python" tests/letstest/scripts/test_openssl_version.py "$OPENSSL_VERSION" "$APACHE_VERSION" if [ $? -ne 0 ] ; then FAIL=1 fi @@ -121,7 +121,7 @@ fi if [ "$OS_TYPE" = "ubuntu" ] ; then export SERVER="${PEBBLE_URL}" - "venv3/bin/tox" -e apacheconftest + "venv/bin/tox" -e apacheconftest else echo Not running hackish apache tests on $OS_TYPE fi diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index d24258a22..d0b941736 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -33,10 +33,11 @@ if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | tail -n1 | exit 1 fi -# This script sets the environment variables PYTHON_NAME, VENV_PATH, and -# VENV_SCRIPT based on the version of Python available on the system. For -# instance, Fedora uses Python 3 and Python 2 is not installed. -. tests/letstest/scripts/set_python_envvars.sh +if command -v python; then + PYTHON_NAME="python" +else + PYTHON_NAME="python3" +fi # Now that python and openssl have been installed, we can set up a fake server # to provide a new version of letsencrypt-auto. First, we start the server and diff --git a/tests/letstest/scripts/test_sdists.sh b/tests/letstest/scripts/test_sdists.sh index a038caff6..aa12d5610 100755 --- a/tests/letstest/scripts/test_sdists.sh +++ b/tests/letstest/scripts/test_sdists.sh @@ -3,7 +3,7 @@ cd letsencrypt BOOTSTRAP_SCRIPT="tests/letstest/scripts/bootstrap_os_packages.sh" -VENV_PATH=venv3 +VENV_PATH=venv # install OS packages sudo $BOOTSTRAP_SCRIPT @@ -18,7 +18,7 @@ python3 tools/strip_hashes.py letsencrypt-auto-source/pieces/dependency-requirem # marker that'd normally prevent it from being installed, and this package is # not needed for any OS tested here. sed -i '/enum34/d' requirements.txt -CERTBOT_PIP_NO_BINARY=:all: tools/venv3.py --requirement requirements.txt +CERTBOT_PIP_NO_BINARY=:all: tools/venv.py --requirement requirements.txt . "$VENV_PATH/bin/activate" # pytest is needed to run tests on some of our packages so we install a pinned version here. tools/pip_install.py pytest diff --git a/tests/letstest/scripts/test_tests.sh b/tests/letstest/scripts/test_tests.sh index f07e3b78e..858fc1f18 100755 --- a/tests/letstest/scripts/test_tests.sh +++ b/tests/letstest/scripts/test_tests.sh @@ -9,9 +9,9 @@ LE_AUTO="$REPO_ROOT/letsencrypt-auto-source/letsencrypt-auto" LE_AUTO="$LE_AUTO --debug --no-self-upgrade --non-interactive" MODULES="acme certbot certbot-apache certbot-nginx" PIP_INSTALL="tools/pip_install.py" -VENV_NAME=venv3 +VENV_NAME=venv BOOTSTRAP_SCRIPT="$REPO_ROOT/tests/letstest/scripts/bootstrap_os_packages.sh" -VENV_SCRIPT="tools/venv3.py" +VENV_SCRIPT="tools/venv.py" sudo $BOOTSTRAP_SCRIPT diff --git a/tools/_venv_common.py b/tools/_venv_common.py deleted file mode 100644 index 58c05ed09..000000000 --- a/tools/_venv_common.py +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env python -"""Aids in creating a developer virtual environment for Certbot. - -When this module is run as a script, it takes the arguments that should -be passed to pip to install the Certbot packages as command line -arguments. The virtual environment will be created with the name "venv" -in the current working directory and will use the default version of -Python for the virtualenv executable in your PATH. You can change the -name of the virtual environment by setting the environment variable -VENV_NAME. -""" - -from __future__ import print_function - -from distutils.version import LooseVersion -import glob -import os -import re -import shutil -import subprocess -import sys -import time - -REQUIREMENTS = [ - '-e acme[dev]', - '-e certbot[dev,docs]', - '-e certbot-apache', - '-e certbot-dns-cloudflare', - '-e certbot-dns-cloudxns', - '-e certbot-dns-digitalocean', - '-e certbot-dns-dnsimple', - '-e certbot-dns-dnsmadeeasy', - '-e certbot-dns-gehirn', - '-e certbot-dns-google', - '-e certbot-dns-linode', - '-e certbot-dns-luadns', - '-e certbot-dns-nsone', - '-e certbot-dns-ovh', - '-e certbot-dns-rfc2136', - '-e certbot-dns-route53', - '-e certbot-dns-sakuracloud', - '-e certbot-nginx', - '-e certbot-compatibility-test', - '-e certbot-ci', -] - -VERSION_PATTERN = re.compile(r'^(\d+)\.(\d+).*$') - - -class PythonExecutableNotFoundError(Exception): - pass - - -def find_python_executable(python_major): - # type: (int) -> str - """ - Find the relevant python executable that is of the given python major version. - Will test, in decreasing priority order: - - * the current Python interpreter - * 'pythonX' executable in PATH (with X the given major version) if available - * 'python' executable in PATH if available - * Windows Python launcher 'py' executable in PATH if available - - Incompatible python versions for Certbot will be evicted (e.g. Python 3 - versions less than 3.6). - - :param int python_major: the Python major version to target (2 or 3) - :rtype: str - :return: the relevant python executable path - :raise RuntimeError: if no relevant python executable path could be found - """ - python_executable_path = None - - # First try, current python executable - if _check_version('{0}.{1}.{2}'.format( - sys.version_info[0], sys.version_info[1], sys.version_info[2]), python_major): - return sys.executable - - # Second try, with python executables in path - versions_to_test = ['2.7', '2', ''] if python_major == 2 else ['3', ''] - for one_version in versions_to_test: - try: - one_python = 'python{0}'.format(one_version) - output = subprocess.check_output([one_python, '--version'], - universal_newlines=True, stderr=subprocess.STDOUT) - if _check_version(output.strip().split()[1], python_major): - return subprocess.check_output([one_python, '-c', - 'import sys; sys.stdout.write(sys.executable);'], - universal_newlines=True) - except (subprocess.CalledProcessError, OSError): - pass - - # Last try, with Windows Python launcher - try: - env_arg = '-{0}'.format(python_major) - output_version = subprocess.check_output(['py', env_arg, '--version'], - universal_newlines=True, stderr=subprocess.STDOUT) - if _check_version(output_version.strip().split()[1], python_major): - return subprocess.check_output(['py', env_arg, '-c', - 'import sys; sys.stdout.write(sys.executable);'], - universal_newlines=True) - except (subprocess.CalledProcessError, OSError): - pass - - if not python_executable_path: - raise RuntimeError('Error, no compatible Python {0} executable for Certbot could be found.' - .format(python_major)) - - -def _check_version(version_str, major_version): - search = VERSION_PATTERN.search(version_str) - - if not search: - return False - - version = (int(search.group(1)), int(search.group(2))) - - minimal_version_supported = (2, 7) - if major_version == 3: - minimal_version_supported = (3, 6) - - if version >= minimal_version_supported: - return True - - print('Incompatible python version for Certbot found: {0}'.format(version_str)) - return False - - -def subprocess_with_print(cmd, env=None, shell=False): - if env is None: - env = os.environ - print('+ {0}'.format(subprocess.list2cmdline(cmd)) if isinstance(cmd, list) else cmd) - subprocess.check_call(cmd, env=env, shell=shell) - - -def subprocess_output_with_print(cmd, env=None, shell=False): - if env is None: - env = os.environ - print('+ {0}'.format(subprocess.list2cmdline(cmd)) if isinstance(cmd, list) else cmd) - return subprocess.check_output(cmd, env=env, shell=shell) - - -def get_venv_python_path(venv_path): - python_linux = os.path.join(venv_path, 'bin/python') - if os.path.isfile(python_linux): - return os.path.abspath(python_linux) - python_windows = os.path.join(venv_path, 'Scripts\\python.exe') - if os.path.isfile(python_windows): - return os.path.abspath(python_windows) - - raise ValueError(( - 'Error, could not find python executable in venv path {0}: is it a valid venv ?' - .format(venv_path))) - - -def prepare_venv_path(venv_name): - """Determines the venv path and prepares it for use. - - This function cleans up any Python eggs in the current working directory - and ensures the venv path is available for use. The path used is the - VENV_NAME environment variable if it is set and venv_name otherwise. If - there is already a directory at the desired path, the existing directory is - renamed by appending a timestamp to the directory name. - - :param str venv_name: The name or path at where the virtual - environment should be created if VENV_NAME isn't set. - - :returns: path where the virtual environment should be created - :rtype: str - - """ - for path in glob.glob('*.egg-info'): - if os.path.isdir(path): - shutil.rmtree(path) - else: - os.remove(path) - - env_venv_name = os.environ.get('VENV_NAME') - if env_venv_name: - print('Creating venv at {0}' - ' as specified in VENV_NAME'.format(env_venv_name)) - venv_name = env_venv_name - - if os.path.isdir(venv_name): - os.rename(venv_name, '{0}.{1}.bak'.format(venv_name, int(time.time()))) - - return venv_name - - -def install_packages(venv_name, pip_args): - """Installs packages in the given venv. - - :param str venv_name: The name or path at where the virtual - environment should be created. - :param pip_args: Command line arguments that should be given to - pip to install packages - :type pip_args: `list` of `str` - - """ - # Using the python executable from venv, we ensure to execute following commands in this venv. - py_venv = get_venv_python_path(venv_name) - subprocess_with_print([py_venv, os.path.abspath('tools/pipstrap.py')]) - # We only use this value during pip install because: - # 1) We're really only adding it for installing cryptography, which happens here, and - # 2) There are issues with calling it along with VIRTUALENV_NO_DOWNLOAD, which applies at the - # steps above, not during pip install. - env_pip_no_binary = os.environ.get('CERTBOT_PIP_NO_BINARY') - if env_pip_no_binary: - # Check OpenSSL version. If it's too low, don't apply the env variable. - openssl_version_string = str(subprocess_output_with_print(['openssl', 'version'])) - matches = re.findall(r'OpenSSL ([^ ]+) ', openssl_version_string) - if not matches: - print('Could not find OpenSSL version, not setting PIP_NO_BINARY.') - else: - openssl_version = matches[0] - - if LooseVersion(openssl_version) >= LooseVersion('1.0.2'): - print('Setting PIP_NO_BINARY to {0}' - ' as specified in CERTBOT_PIP_NO_BINARY'.format(env_pip_no_binary)) - os.environ['PIP_NO_BINARY'] = env_pip_no_binary - else: - print('Not setting PIP_NO_BINARY, as OpenSSL version is too old.') - command = [py_venv, os.path.abspath('tools/pip_install.py')] - command.extend(pip_args) - subprocess_with_print(command) - if 'PIP_NO_BINARY' in os.environ: - del os.environ['PIP_NO_BINARY'] - - if os.path.isdir(os.path.join(venv_name, 'bin')): - # Linux/OSX specific - print('-------------------------------------------------------------------') - print('Please run the following command to activate developer environment:') - print('source {0}/bin/activate'.format(venv_name)) - print('-------------------------------------------------------------------') - elif os.path.isdir(os.path.join(venv_name, 'Scripts')): - # Windows specific - print('---------------------------------------------------------------------------') - print('Please run one of the following commands to activate developer environment:') - print('{0}\\Scripts\\activate.bat (for Batch)'.format(venv_name)) - print('.\\{0}\\Scripts\\Activate.ps1 (for Powershell)'.format(venv_name)) - print('---------------------------------------------------------------------------') - else: - raise ValueError('Error, directory {0} is not a valid venv.'.format(venv_name)) diff --git a/tools/venv.py b/tools/venv.py index f99386eff..ae542df96 100755 --- a/tools/venv.py +++ b/tools/venv.py @@ -1,36 +1,261 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Developer virtualenv setup for Certbot client -import os -import sys +"""Aids in creating a developer virtual environment for Certbot. -import _venv_common +When this module is run as a script, it takes the arguments that should +be passed to pip to install the Certbot packages as command line +arguments. If no arguments are provided, all Certbot packages and their +development dependencies are installed. The virtual environment will be +created with the name "venv" in the current working directory. You can +change the name of the virtual environment by setting the environment +variable VENV_NAME. + +""" + +from __future__ import print_function + +from distutils.version import LooseVersion +import glob +import os +import re +import shutil +import subprocess +import sys +import time + +REQUIREMENTS = [ + '-e acme[dev]', + '-e certbot[dev,dev3,docs]', + '-e certbot-apache', + '-e certbot-dns-cloudflare', + '-e certbot-dns-cloudxns', + '-e certbot-dns-digitalocean', + '-e certbot-dns-dnsimple', + '-e certbot-dns-dnsmadeeasy', + '-e certbot-dns-gehirn', + '-e certbot-dns-google', + '-e certbot-dns-linode', + '-e certbot-dns-luadns', + '-e certbot-dns-nsone', + '-e certbot-dns-ovh', + '-e certbot-dns-rfc2136', + '-e certbot-dns-route53', + '-e certbot-dns-sakuracloud', + '-e certbot-nginx', + '-e certbot-compatibility-test', + '-e certbot-ci', +] + +VERSION_PATTERN = re.compile(r'^(\d+)\.(\d+).*$') + + +class PythonExecutableNotFoundError(Exception): + pass + + +def find_python_executable() -> str: + """ + Find the relevant python executable that is of the given python major version. + Will test, in decreasing priority order: + + * the current Python interpreter + * 'pythonX' executable in PATH (with X the given major version) if available + * 'python' executable in PATH if available + * Windows Python launcher 'py' executable in PATH if available + + Incompatible python versions for Certbot will be evicted (e.g. Python 3 + versions less than 3.6). + + :rtype: str + :return: the relevant python executable path + :raise RuntimeError: if no relevant python executable path could be found + """ + python_executable_path = None + + # First try, current python executable + if _check_version('{0}.{1}.{2}'.format( + sys.version_info[0], sys.version_info[1], sys.version_info[2])): + return sys.executable + + # Second try, with python executables in path + for one_version in ('3', '',): + try: + one_python = 'python{0}'.format(one_version) + output = subprocess.check_output([one_python, '--version'], + universal_newlines=True, stderr=subprocess.STDOUT) + if _check_version(output.strip().split()[1]): + return subprocess.check_output([one_python, '-c', + 'import sys; sys.stdout.write(sys.executable);'], + universal_newlines=True) + except (subprocess.CalledProcessError, OSError): + pass + + # Last try, with Windows Python launcher + try: + output_version = subprocess.check_output(['py', '-3', '--version'], + universal_newlines=True, stderr=subprocess.STDOUT) + if _check_version(output_version.strip().split()[1]): + return subprocess.check_output(['py', env_arg, '-c', + 'import sys; sys.stdout.write(sys.executable);'], + universal_newlines=True) + except (subprocess.CalledProcessError, OSError): + pass + + if not python_executable_path: + raise RuntimeError('Error, no compatible Python executable for Certbot could be found.') + + +def _check_version(version_str): + search = VERSION_PATTERN.search(version_str) + + if not search: + return False + + version = (int(search.group(1)), int(search.group(2))) + + if version >= (3, 6): + return True + + print('Incompatible python version for Certbot found: {0}'.format(version_str)) + return False + + +def subprocess_with_print(cmd, env=None, shell=False): + if env is None: + env = os.environ + print('+ {0}'.format(subprocess.list2cmdline(cmd)) if isinstance(cmd, list) else cmd) + subprocess.check_call(cmd, env=env, shell=shell) + + +def subprocess_output_with_print(cmd, env=None, shell=False): + if env is None: + env = os.environ + print('+ {0}'.format(subprocess.list2cmdline(cmd)) if isinstance(cmd, list) else cmd) + return subprocess.check_output(cmd, env=env, shell=shell) + + +def get_venv_python_path(venv_path): + python_linux = os.path.join(venv_path, 'bin/python') + if os.path.isfile(python_linux): + return os.path.abspath(python_linux) + python_windows = os.path.join(venv_path, 'Scripts\\python.exe') + if os.path.isfile(python_windows): + return os.path.abspath(python_windows) + + raise ValueError(( + 'Error, could not find python executable in venv path {0}: is it a valid venv ?' + .format(venv_path))) + + +def prepare_venv_path(venv_name): + """Determines the venv path and prepares it for use. + + This function cleans up any Python eggs in the current working directory + and ensures the venv path is available for use. The path used is the + VENV_NAME environment variable if it is set and venv_name otherwise. If + there is already a directory at the desired path, the existing directory is + renamed by appending a timestamp to the directory name. + + :param str venv_name: The name or path at where the virtual + environment should be created if VENV_NAME isn't set. + + :returns: path where the virtual environment should be created + :rtype: str + + """ + for path in glob.glob('*.egg-info'): + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + + env_venv_name = os.environ.get('VENV_NAME') + if env_venv_name: + print('Creating venv at {0}' + ' as specified in VENV_NAME'.format(env_venv_name)) + venv_name = env_venv_name + + if os.path.isdir(venv_name): + os.rename(venv_name, '{0}.{1}.bak'.format(venv_name, int(time.time()))) + + return venv_name + + +def install_packages(venv_name, pip_args): + """Installs packages in the given venv. + + :param str venv_name: The name or path at where the virtual + environment should be created. + :param pip_args: Command line arguments that should be given to + pip to install packages + :type pip_args: `list` of `str` + + """ + # Using the python executable from venv, we ensure to execute following commands in this venv. + py_venv = get_venv_python_path(venv_name) + subprocess_with_print([py_venv, os.path.abspath('tools/pipstrap.py')]) + # We only use this value during pip install because: + # 1) We're really only adding it for installing cryptography, which happens here, and + # 2) There are issues with calling it along with VIRTUALENV_NO_DOWNLOAD, which applies at the + # steps above, not during pip install. + env_pip_no_binary = os.environ.get('CERTBOT_PIP_NO_BINARY') + if env_pip_no_binary: + # Check OpenSSL version. If it's too low, don't apply the env variable. + openssl_version_string = str(subprocess_output_with_print(['openssl', 'version'])) + matches = re.findall(r'OpenSSL ([^ ]+) ', openssl_version_string) + if not matches: + print('Could not find OpenSSL version, not setting PIP_NO_BINARY.') + else: + openssl_version = matches[0] + + if LooseVersion(openssl_version) >= LooseVersion('1.0.2'): + print('Setting PIP_NO_BINARY to {0}' + ' as specified in CERTBOT_PIP_NO_BINARY'.format(env_pip_no_binary)) + os.environ['PIP_NO_BINARY'] = env_pip_no_binary + else: + print('Not setting PIP_NO_BINARY, as OpenSSL version is too old.') + command = [py_venv, os.path.abspath('tools/pip_install.py')] + command.extend(pip_args) + subprocess_with_print(command) + if 'PIP_NO_BINARY' in os.environ: + del os.environ['PIP_NO_BINARY'] + + if os.path.isdir(os.path.join(venv_name, 'bin')): + # Linux/OSX specific + print('-------------------------------------------------------------------') + print('Please run the following command to activate developer environment:') + print('source {0}/bin/activate'.format(venv_name)) + print('-------------------------------------------------------------------') + elif os.path.isdir(os.path.join(venv_name, 'Scripts')): + # Windows specific + print('---------------------------------------------------------------------------') + print('Please run one of the following commands to activate developer environment:') + print('{0}\\Scripts\\activate.bat (for Batch)'.format(venv_name)) + print('.\\{0}\\Scripts\\Activate.ps1 (for Powershell)'.format(venv_name)) + print('---------------------------------------------------------------------------') + else: + raise ValueError('Error, directory {0} is not a valid venv.'.format(venv_name)) def create_venv(venv_path): - """Create a Python 2 virtual environment at venv_path. + """Create a Python virtual environment at venv_path. :param str venv_path: path where the venv should be created """ - python2 = _venv_common.find_python_executable(2) - command = [sys.executable, '-m', 'virtualenv', '--python', python2, venv_path] - - environ = os.environ.copy() - environ['VIRTUALENV_NO_DOWNLOAD'] = '1' - _venv_common.subprocess_with_print(command, environ) + python = find_python_executable() + command = [python, '-m', 'venv', venv_path] + subprocess_with_print(command) def main(pip_args=None): - if os.name == 'nt': - raise ValueError('Certbot for Windows is not supported on Python 2.x.') - - venv_path = _venv_common.prepare_venv_path('venv') + venv_path = prepare_venv_path('venv') create_venv(venv_path) if not pip_args: - pip_args = _venv_common.REQUIREMENTS + pip_args = REQUIREMENTS - _venv_common.install_packages(venv_path, pip_args) + install_packages(venv_path, pip_args) if __name__ == '__main__': diff --git a/tools/venv3.py b/tools/venv3.py deleted file mode 100755 index 7ead82bd5..000000000 --- a/tools/venv3.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# Developer virtualenv setup for Certbot client -import sys - -import _venv_common - - -def create_venv(venv_path): - """Create a Python 3 virtual environment at venv_path. - - :param str venv_path: path where the venv should be created - - """ - python3 = _venv_common.find_python_executable(3) - command = [python3, '-m', 'venv', venv_path] - _venv_common.subprocess_with_print(command) - - -def main(pip_args=None): - venv_path = _venv_common.prepare_venv_path('venv3') - create_venv(venv_path) - - if not pip_args: - pip_args = _venv_common.REQUIREMENTS + ['-e certbot[dev3]'] - - _venv_common.install_packages(venv_path, pip_args) - - -if __name__ == '__main__': - main(sys.argv[1:]) From 666ee35e29e803e395b9235058ecebe8b5e9b56a Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 4 Feb 2021 02:04:03 -0800 Subject: [PATCH 10/21] remove crufty pytest warning (#8638) --- pytest.ini | 3 --- 1 file changed, 3 deletions(-) diff --git a/pytest.ini b/pytest.ini index 16aa9a193..d7fe53494 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,8 +2,6 @@ # settings we want to also change there must be added to the release script # directly. [pytest] -# In general, all warnings are treated as errors. Here are the exceptions: -# 1- decodestring: https://github.com/rthalley/dnspython/issues/338 # Warnings being triggered by our plugins using deprecated features in # acme/certbot should be fixed by having our plugins no longer using the # deprecated code rather than adding them to the list of ignored warnings here. @@ -13,4 +11,3 @@ # we release breaking changes. filterwarnings = error - ignore:decodestring:DeprecationWarning From c668172ef0844ebd641575aeac865d91c59eaa8e Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 4 Feb 2021 02:31:47 -0800 Subject: [PATCH 11/21] merge dev and dev3 (#8639) --- certbot/setup.py | 16 ++++++---------- tools/venv.py | 2 +- tox.ini | 2 -- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/certbot/setup.py b/certbot/setup.py index e1c86308e..0d80dfd05 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -81,7 +81,13 @@ elif sys.version_info < (3,3): install_requires.append('mock') dev_extras = [ + 'astroid', + 'azure-devops', 'coverage', + 'ipdb', + 'mypy', + 'PyGithub', + 'pylint', 'pytest', 'pytest-cov', 'pytest-xdist', @@ -90,15 +96,6 @@ dev_extras = [ 'wheel', ] -dev3_extras = [ - 'astroid', - 'azure-devops', - 'ipdb', - 'mypy', - 'PyGithub', - 'pylint', -] - docs_extras = [ # If you have Sphinx<1.5.1, you need docutils<0.13.1 # https://github.com/sphinx-doc/sphinx/issues/3212 @@ -144,7 +141,6 @@ setup( install_requires=install_requires, extras_require={ 'dev': dev_extras, - 'dev3': dev3_extras, 'docs': docs_extras, }, diff --git a/tools/venv.py b/tools/venv.py index ae542df96..9f7488008 100755 --- a/tools/venv.py +++ b/tools/venv.py @@ -25,7 +25,7 @@ import time REQUIREMENTS = [ '-e acme[dev]', - '-e certbot[dev,dev3,docs]', + '-e certbot[dev,docs]', '-e certbot-apache', '-e certbot-dns-cloudflare', '-e certbot-dns-cloudxns', diff --git a/tox.ini b/tox.ini index fd9105e8b..9f63b897c 100644 --- a/tox.ini +++ b/tox.ini @@ -149,14 +149,12 @@ basepython = python3 # continue, but tox return code will reflect previous error commands = {[base]install_packages} - {[base]pip_install} certbot[dev3] python -m pylint --reports=n --rcfile=.pylintrc {[base]source_paths} [testenv:mypy] basepython = python3 commands = {[base]install_packages} - {[base]pip_install} certbot[dev3] mypy {[base]source_paths} [testenv:apacheconftest] From c2ee0d29382d9613cc3a8d4cee6cb4aa3ce239c4 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 5 Feb 2021 15:33:45 -0800 Subject: [PATCH 12/21] Remove requests[security] dependency (#8626) Fixes https://github.com/certbot/certbot/issues/7901. * stop using requests[security] * add changelog entry * remove unused import --- acme/acme/client.py | 12 ------------ acme/setup.py | 2 +- certbot/CHANGELOG.md | 4 +++- tools/oldest_constraints.txt | 2 +- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/acme/acme/client.py b/acme/acme/client.py index d413ce13d..6adfe4b78 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -6,7 +6,6 @@ from email.utils import parsedate_tz import heapq import logging import re -import sys import time import josepy as jose @@ -30,17 +29,6 @@ from acme.mixins import VersionedLEACMEMixin logger = logging.getLogger(__name__) -# Prior to Python 2.7.9 the stdlib SSL module did not allow a user to configure -# many important security related options. On these platforms we use PyOpenSSL -# for SSL, which does allow these options to be configured. -# https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning -if sys.version_info < (2, 7, 9): # pragma: no cover - try: - requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore - except AttributeError: - import urllib3.contrib.pyopenssl - urllib3.contrib.pyopenssl.inject_into_urllib3() - DEFAULT_NETWORK_TIMEOUT = 45 DER_CONTENT_TYPE = 'application/pkix-cert' diff --git a/acme/setup.py b/acme/setup.py index 2fafe845c..c62562ff3 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -17,7 +17,7 @@ install_requires = [ 'PyOpenSSL>=17.3.0', 'pyrfc3339', 'pytz', - 'requests[security]>=2.6.0', # security extras added in 2.4.1 + 'requests>=2.6.0', 'requests-toolbelt>=0.3.0', 'setuptools>=39.0.1', 'six>=1.11.0', diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index d83a258e2..a4a53c88e 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -10,7 +10,9 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Changed -* +* The acme library no longer depends on the `security` extras from `requests` + which was needed to support SNI in TLS requests when using old versions of + Python 2. ### Fixed diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 1aabf6eeb..f6528f396 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -47,7 +47,7 @@ pyparsing==2.2.0 apacheconfig==0.3.2 cloudflare==1.5.1 python-digitalocean==1.11 -requests[security]==2.6.0 +requests==2.6.0 # Ubuntu Xenial constraints # Ubuntu Xenial only has versions of Python which we do not support available From 711cc95dc466c569c120bd7fcda8e67c135cb101 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 5 Feb 2021 15:51:18 -0800 Subject: [PATCH 13/21] Remove mock dependency (#8630) Fixes https://github.com/certbot/certbot/issues/7913. I only added the deprecation warning to `certbot.tests.util` because that's the only place where I think someone could be using the `mock` module through our API. * remove external mock from acme * update Certbot's mock usage * remove mock dependency in plugins * remove external mock from compatibility test * add changelog entry --- acme/setup.py | 11 ----------- acme/tests/challenges_test.py | 5 +---- acme/tests/client_test.py | 5 +---- acme/tests/errors_test.py | 6 +----- acme/tests/magic_typing_test.py | 6 +----- acme/tests/messages_test.py | 5 +---- acme/tests/standalone_test.py | 5 +---- certbot-apache/setup.py | 13 ------------- .../configurators/apache/common.py | 5 +---- .../certbot_compatibility_test/validator_test.py | 5 +---- certbot-compatibility-test/setup.py | 11 ----------- certbot-dns-cloudflare/setup.py | 11 ----------- certbot-dns-cloudxns/setup.py | 11 ----------- certbot-dns-digitalocean/setup.py | 11 ----------- certbot-dns-dnsimple/setup.py | 11 ----------- certbot-dns-dnsmadeeasy/setup.py | 11 ----------- certbot-dns-gehirn/setup.py | 11 ----------- certbot-dns-google/setup.py | 11 ----------- certbot-dns-linode/setup.py | 11 ----------- certbot-dns-luadns/setup.py | 11 ----------- certbot-dns-nsone/setup.py | 11 ----------- certbot-dns-ovh/setup.py | 11 ----------- certbot-dns-rfc2136/setup.py | 11 ----------- certbot-dns-route53/setup.py | 11 ----------- certbot-dns-sakuracloud/setup.py | 11 ----------- certbot-nginx/setup.py | 13 ------------- certbot/CHANGELOG.md | 4 ++++ certbot/certbot/tests/util.py | 7 +++++++ certbot/setup.py | 8 -------- 29 files changed, 19 insertions(+), 244 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index c62562ff3..745169cbf 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -1,7 +1,5 @@ -from distutils.version import LooseVersion import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -23,15 +21,6 @@ install_requires = [ 'six>=1.11.0', ] -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - dev_extras = [ 'pytest', 'pytest-xdist', diff --git a/acme/tests/challenges_test.py b/acme/tests/challenges_test.py index 70371051c..22e67be3c 100644 --- a/acme/tests/challenges_test.py +++ b/acme/tests/challenges_test.py @@ -1,12 +1,9 @@ """Tests for acme.challenges.""" import unittest +from unittest import mock import josepy as jose import OpenSSL -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import requests from six.moves.urllib import parse as urllib_parse diff --git a/acme/tests/client_test.py b/acme/tests/client_test.py index c84878c42..a1be59056 100644 --- a/acme/tests/client_test.py +++ b/acme/tests/client_test.py @@ -4,12 +4,9 @@ import copy import datetime import json import unittest +from unittest import mock import josepy as jose -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import OpenSSL import requests from six.moves import http_client # pylint: disable=import-error diff --git a/acme/tests/errors_test.py b/acme/tests/errors_test.py index fb90a3f0d..11c57059c 100644 --- a/acme/tests/errors_test.py +++ b/acme/tests/errors_test.py @@ -1,10 +1,6 @@ """Tests for acme.errors.""" import unittest - -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore +from unittest import mock class BadNonceTest(unittest.TestCase): diff --git a/acme/tests/magic_typing_test.py b/acme/tests/magic_typing_test.py index 9e4fd29f5..048995916 100644 --- a/acme/tests/magic_typing_test.py +++ b/acme/tests/magic_typing_test.py @@ -1,11 +1,7 @@ """Tests for acme.magic_typing.""" import sys import unittest - -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore +from unittest import mock class MagicTypingTest(unittest.TestCase): diff --git a/acme/tests/messages_test.py b/acme/tests/messages_test.py index 70b05b419..74d1737ec 100644 --- a/acme/tests/messages_test.py +++ b/acme/tests/messages_test.py @@ -1,11 +1,8 @@ """Tests for acme.messages.""" import unittest +from unittest import mock import josepy as jose -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore from acme import challenges import test_util diff --git a/acme/tests/standalone_test.py b/acme/tests/standalone_test.py index 3d068fb46..5bbc2ccce 100644 --- a/acme/tests/standalone_test.py +++ b/acme/tests/standalone_test.py @@ -2,12 +2,9 @@ import socket import threading import unittest +from unittest import mock import josepy as jose -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import requests from six.moves import http_client # pylint: disable=import-error from six.moves import socketserver # type: ignore # pylint: disable=import-error diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 12aeac06b..f129343b3 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -1,7 +1,3 @@ -from distutils.version import LooseVersion -import sys - -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -18,15 +14,6 @@ install_requires = [ 'zope.interface', ] -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - dev_extras = [ 'apacheconfig>=0.3.2', ] diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index b6fbe2817..2b3f94581 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -2,11 +2,8 @@ import os import shutil import subprocess +from unittest import mock -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import zope.interface from certbot import errors as le_errors diff --git a/certbot-compatibility-test/certbot_compatibility_test/validator_test.py b/certbot-compatibility-test/certbot_compatibility_test/validator_test.py index 0b1056561..711d1b38e 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/validator_test.py +++ b/certbot-compatibility-test/certbot_compatibility_test/validator_test.py @@ -1,10 +1,7 @@ """Tests for certbot_compatibility_test.validator.""" import unittest +from unittest import mock -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import OpenSSL import requests diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 19ee74efe..0236773f0 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -1,7 +1,5 @@ -from distutils.version import LooseVersion import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -15,15 +13,6 @@ install_requires = [ 'zope.interface', ] -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - if sys.version_info < (2, 7, 9): # For secure SSL connexion with Python 2.7 (InsecurePlatformWarning) install_requires.append('ndg-httpsclient') diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index b4f7222c0..eab6cdb70 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index e7ae702ef..83513ef7c 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index fca973e81..8c6ac78d5 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -28,15 +26,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 329977aed..f1fcfd11d 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -26,15 +24,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - # This package normally depends on dns-lexicon>=3.2.1 to address the # problem described in https://github.com/AnalogJ/lexicon/issues/387, # however, the fix there has been backported to older versions of diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index def4ed1f0..185048a2d 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index a074b0eb2..0ae9c1bf7 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -26,15 +24,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index d104929b6..b16d014c6 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -30,15 +28,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index ddb9c2ef7..21ccf9d42 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -26,15 +24,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 4b83ba2c0..2312d6fcc 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index 6ebe9decb..658027b9a 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 9e7ec3675..b4f73ddb4 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index cd0766585..ce74611cd 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index 82cb50ddb..8def9a702 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -27,15 +25,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 6bb76b514..6f4f8e506 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -1,8 +1,6 @@ -from distutils.version import LooseVersion import os import sys -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -26,15 +24,6 @@ elif 'bdist_wheel' in sys.argv[1:]: if os.environ.get('SNAP_BUILD'): install_requires.append('packaging') -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 988f30052..385f4cc17 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -1,7 +1,3 @@ -from distutils.version import LooseVersion -import sys - -from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup @@ -18,15 +14,6 @@ install_requires = [ 'zope.interface', ] -setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - setup( name='certbot-nginx', version=version, diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index a4a53c88e..1333d2420 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -10,6 +10,10 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Changed +* Certbot no longer conditionally depends on an external mock module. Certbot's + test API will continue to use it if it is available for backwards + compatibility, however, this behavior has been deprecated and will be removed + in a future release. * The acme library no longer depends on the `security` extras from `requests` which was needed to support SNI in TLS requests when using old versions of Python 2. diff --git a/certbot/certbot/tests/util.py b/certbot/certbot/tests/util.py index b9d5caa08..acb31819f 100644 --- a/certbot/certbot/tests/util.py +++ b/certbot/certbot/tests/util.py @@ -6,12 +6,19 @@ import shutil import sys import tempfile import unittest +import warnings from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization import josepy as jose try: import mock + warnings.warn( + "The external mock module is being used for backwards compatibility " + "since it is available, however, future versions of Certbot's tests will " + "use unittest.mock. Be sure to update your code accordingly.", + PendingDeprecationWarning + ) except ImportError: # pragma: no cover from unittest import mock # type: ignore import OpenSSL diff --git a/certbot/setup.py b/certbot/setup.py index 0d80dfd05..4ea98e574 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -72,14 +72,6 @@ elif os.name == 'nt': # setuptools, pywin32 will not be specified as a dependency. install_requires.append(pywin32_req) -if setuptools_known_environment_markers: - install_requires.append('mock ; python_version < "3.3"') -elif 'bdist_wheel' in sys.argv[1:]: - raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' - 'of setuptools. Version 36.2+ of setuptools is required.') -elif sys.version_info < (3,3): - install_requires.append('mock') - dev_extras = [ 'astroid', 'azure-devops', From 2a16aa16c37308dd0e357d96b51d2b0ffb36add8 Mon Sep 17 00:00:00 2001 From: Matt W Date: Sat, 6 Feb 2021 23:19:49 -0800 Subject: [PATCH 14/21] Update cli.ini (#8603) * Update cli.ini Sharing back some extended examples I desired, did not find, and derived on my own * Update cli.ini Alex, ok - simplified as requested Matt * Update cli.ini removed trailing quote on line 32 * Update certbot/examples/cli.ini Co-authored-by: alexzorin * Update certbot/examples/cli.ini Co-authored-by: alexzorin * Update certbot/examples/cli.ini Co-authored-by: alexzorin * remove stray newline Co-authored-by: alexzorin --- certbot/examples/cli.ini | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/certbot/examples/cli.ini b/certbot/examples/cli.ini index dfb1d6fff..8471558ee 100644 --- a/certbot/examples/cli.ini +++ b/certbot/examples/cli.ini @@ -24,3 +24,11 @@ rsa-key-size = 4096 # path to the public_html / webroot folder being served by your web server. # authenticator = webroot # webroot-path = /usr/share/nginx/html + +# Uncomment to automatically agree to the terms of service of the ACME server +# agree-tos = true + +# An example of using an alternate ACME server that uses EAB credentials +# server = https://acme.sectigo.com/v2/InCommonRSAOV +# eab-kid = somestringofstuffwithoutquotes +# eab-hmac-key = yaddayaddahexhexnotquoted From edad9bd82b11e2e6fdc2bfd633e8c790e0da23d7 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 9 Feb 2021 04:29:31 -0600 Subject: [PATCH 15/21] Fix Sphinx manpage Building (#8646) * certbot docs: include & orphan 'man/cerbot.rst'; fixes manpage building * acme docs: include & orphan 'man/jws.rst'; fixes manpage building --- acme/docs/conf.py | 1 - acme/docs/man/jws.rst | 2 ++ certbot/docs/conf.py | 1 - certbot/docs/man/certbot.rst | 2 ++ 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/acme/docs/conf.py b/acme/docs/conf.py index 9d3c4d05c..d419326df 100644 --- a/acme/docs/conf.py +++ b/acme/docs/conf.py @@ -87,7 +87,6 @@ language = 'en' # directories to ignore when looking for source files. exclude_patterns = [ '_build', - 'man/*' ] # The reST default role (used for this markup: `text`) to use for all diff --git a/acme/docs/man/jws.rst b/acme/docs/man/jws.rst index d7ff8f405..7e83328b2 100644 --- a/acme/docs/man/jws.rst +++ b/acme/docs/man/jws.rst @@ -1 +1,3 @@ +:orphan: + .. literalinclude:: ../jws-help.txt diff --git a/certbot/docs/conf.py b/certbot/docs/conf.py index 52820b69d..254bd3edd 100644 --- a/certbot/docs/conf.py +++ b/certbot/docs/conf.py @@ -97,7 +97,6 @@ language = None # directories to ignore when looking for source files. exclude_patterns = [ '_build', - 'man', 'challenges.rst', 'ciphers.rst' ] diff --git a/certbot/docs/man/certbot.rst b/certbot/docs/man/certbot.rst index d03f3eed4..2f25504b0 100644 --- a/certbot/docs/man/certbot.rst +++ b/certbot/docs/man/certbot.rst @@ -1 +1,3 @@ +:orphan: + .. literalinclude:: ../cli-help.txt From 3d0dad8718e3b1904c1acb7da530a08053ced08f Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 9 Feb 2021 11:43:15 -0800 Subject: [PATCH 16/21] Remove dependency on six (#8650) Fixes https://github.com/certbot/certbot/issues/8494. I left the `six` dependency pinned in `tests/letstest/requirements.txt` and `tools/oldest_constraints.txt` because `six` is still a transitive dependency with our current pinnings. The extra moving around of imports is due to me using `isort` to help me keep dependencies in sorted order after replacing imports of `six`. * remove some six usage in acme * remove six from acme * remove six.add_metaclass usage * fix six.moves.zip * fix six.moves.builtins.open * six.moves server fixes * 's/six\.moves\.range/range/g' * stop using six.moves.xrange * fix urllib imports * s/six\.binary_type/bytes/g * s/six\.string_types/str/g * 's/six\.text_type/str/g' * fix six.iteritems usage * fix itervalues usage * switch from six.StringIO to io.StringIO * remove six imports * misc fixes * stop using six.reload_module * no six.PY2 * rip out six * keep six pinned in oldest constraints * fix log_test.py * update changelog --- .pylintrc | 2 +- acme/acme/challenges.py | 4 +-- acme/acme/client.py | 7 ++-- acme/acme/messages.py | 2 -- acme/acme/standalone.py | 7 ++-- acme/acme/util.py | 3 +- acme/setup.py | 1 - acme/tests/challenges_test.py | 2 +- acme/tests/client_test.py | 2 +- acme/tests/crypto_util_test.py | 12 +++---- acme/tests/standalone_test.py | 4 +-- .../certbot_apache/_internal/interfaces.py | 14 +++----- .../certbot_apache/_internal/parser.py | 3 +- certbot-apache/tests/autohsts_test.py | 1 - certbot-apache/tests/configurator_test.py | 5 ++- .../certbot_integration_tests/utils/misc.py | 4 +-- .../utils/pebble_ocsp_server.py | 2 +- .../certbot_integration_tests/utils/proxy.py | 2 +- certbot-ci/setup.py | 1 - .../certbot_compatibility_test/validator.py | 8 ++--- certbot-compatibility-test/setup.py | 1 - certbot-dns-digitalocean/setup.py | 1 - .../certbot_nginx/_internal/nginxparser.py | 13 ++++---- certbot-nginx/certbot_nginx/_internal/obj.py | 5 ++- .../certbot_nginx/_internal/parser.py | 5 ++- .../certbot_nginx/_internal/parser_obj.py | 9 +++--- certbot-nginx/tests/http_01_test.py | 3 +- certbot/CHANGELOG.md | 1 + certbot/certbot/_internal/account.py | 3 +- certbot/certbot/_internal/cli/helpful.py | 5 ++- certbot/certbot/_internal/configuration.py | 2 +- certbot/certbot/_internal/plugins/disco.py | 15 ++++----- .../certbot/_internal/plugins/selection.py | 3 +- .../certbot/_internal/plugins/standalone.py | 3 +- certbot/certbot/_internal/plugins/webroot.py | 5 ++- certbot/certbot/_internal/renewal.py | 13 ++++---- certbot/certbot/_internal/reporter.py | 2 +- certbot/certbot/_internal/storage.py | 3 +- certbot/certbot/crypto_util.py | 12 ++----- certbot/certbot/display/util.py | 4 +-- certbot/certbot/interfaces.py | 13 +++----- certbot/certbot/plugins/dns_test_common.py | 3 +- certbot/certbot/plugins/enhancements.py | 5 +-- certbot/certbot/reverter.py | 3 +- certbot/certbot/tests/acme_util.py | 3 +- certbot/certbot/tests/util.py | 28 ++++++++-------- certbot/certbot/util.py | 7 ++-- certbot/setup.py | 6 ++-- certbot/tests/account_test.py | 4 +-- certbot/tests/cli_test.py | 17 +++++----- certbot/tests/display/completer_test.py | 9 +++--- certbot/tests/display/util_test.py | 28 +++++++--------- certbot/tests/log_test.py | 24 +++++++------- certbot/tests/main_test.py | 32 ++++++++++--------- certbot/tests/plugins/disco_test.py | 5 ++- certbot/tests/plugins/manual_test.py | 3 +- certbot/tests/plugins/null_test.py | 3 +- certbot/tests/plugins/standalone_test.py | 3 +- certbot/tests/plugins/storage_test.py | 2 +- certbot/tests/plugins/webroot_test.py | 7 ++-- certbot/tests/reporter_test.py | 5 +-- certbot/tests/reverter_test.py | 3 +- certbot/tests/storage_test.py | 19 ++++++----- certbot/tests/util_test.py | 21 ++++++------ tests/letstest/multitester.py | 4 +-- 65 files changed, 196 insertions(+), 255 deletions(-) diff --git a/.pylintrc b/.pylintrc index 0e78828bd..a2468b0cf 100644 --- a/.pylintrc +++ b/.pylintrc @@ -254,7 +254,7 @@ ignore-mixin-members=yes # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis -ignored-modules=pkg_resources,confargparse,argparse,six.moves,six.moves.urllib +ignored-modules=pkg_resources,confargparse,argparse # import errors ignored only in 1.4.4 # https://bitbucket.org/logilab/pylint/commits/cd000904c9e2 diff --git a/acme/acme/challenges.py b/acme/acme/challenges.py index 376e9a382..41a2aa258 100644 --- a/acme/acme/challenges.py +++ b/acme/acme/challenges.py @@ -9,7 +9,6 @@ import socket from cryptography.hazmat.primitives import hashes # type: ignore import josepy as jose import requests -import six from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052 from OpenSSL import crypto @@ -145,8 +144,7 @@ class KeyAuthorizationChallengeResponse(ChallengeResponse): return jobj -@six.add_metaclass(abc.ABCMeta) -class KeyAuthorizationChallenge(_TokenChallenge): +class KeyAuthorizationChallenge(_TokenChallenge, metaclass=abc.ABCMeta): """Challenge based on Key Authorization. :param response_cls: Subclass of `KeyAuthorizationChallengeResponse` diff --git a/acme/acme/client.py b/acme/acme/client.py index 6adfe4b78..c3f8c550f 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -4,6 +4,7 @@ import collections import datetime from email.utils import parsedate_tz import heapq +import http.client as http_client import logging import re import time @@ -14,8 +15,6 @@ import requests from requests.adapters import HTTPAdapter from requests.utils import parse_header_links from requests_toolbelt.adapters.source import SourceAddressAdapter -import six -from six.moves import http_client from acme import crypto_util from acme import errors @@ -248,7 +247,7 @@ class Client(ClientBase): if net is None: net = ClientNetwork(key, alg=alg, verify_ssl=verify_ssl) - if isinstance(directory, six.string_types): + if isinstance(directory, str): directory = messages.Directory.from_json( net.get(directory).json()) super(Client, self).__init__(directory=directory, @@ -463,7 +462,7 @@ class Client(ClientBase): exhausted.add(authzr) if exhausted or any(authzr.body.status == messages.STATUS_INVALID - for authzr in six.itervalues(updated)): + for authzr in updated.values()): raise errors.PollError(exhausted, updated) updated_authzrs = tuple(updated[authzr] for authzr in authzrs) diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 3a505843d..038cda04b 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -2,7 +2,6 @@ import json import josepy as jose -import six from acme import challenges from acme import errors @@ -68,7 +67,6 @@ def is_acme_error(err): return False -@six.python_2_unicode_compatible class Error(jose.JSONObjectWithFields, errors.Error): """ACME error. diff --git a/acme/acme/standalone.py b/acme/acme/standalone.py index 7a61ba868..94397f0de 100644 --- a/acme/acme/standalone.py +++ b/acme/acme/standalone.py @@ -1,14 +1,13 @@ """Support for standalone client challenge solvers. """ import collections import functools +import http.client as http_client +import http.server as BaseHTTPServer import logging import socket +import socketserver import threading -from six.moves import BaseHTTPServer # type: ignore -from six.moves import http_client -from six.moves import socketserver # type: ignore - from acme import challenges from acme import crypto_util from acme.magic_typing import List diff --git a/acme/acme/util.py b/acme/acme/util.py index b3b0d79eb..20fa455fd 100644 --- a/acme/acme/util.py +++ b/acme/acme/util.py @@ -1,7 +1,6 @@ """ACME utilities.""" -import six def map_keys(dikt, func): """Map dictionary keys.""" - return {func(key): value for key, value in six.iteritems(dikt)} + return {func(key): value for key, value in dikt.items()} diff --git a/acme/setup.py b/acme/setup.py index 745169cbf..847ca9299 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -18,7 +18,6 @@ install_requires = [ 'requests>=2.6.0', 'requests-toolbelt>=0.3.0', 'setuptools>=39.0.1', - 'six>=1.11.0', ] dev_extras = [ diff --git a/acme/tests/challenges_test.py b/acme/tests/challenges_test.py index 22e67be3c..cc604b0de 100644 --- a/acme/tests/challenges_test.py +++ b/acme/tests/challenges_test.py @@ -1,11 +1,11 @@ """Tests for acme.challenges.""" +import urllib.parse as urllib_parse import unittest from unittest import mock import josepy as jose import OpenSSL import requests -from six.moves.urllib import parse as urllib_parse from acme import errors diff --git a/acme/tests/client_test.py b/acme/tests/client_test.py index a1be59056..6f9aecda2 100644 --- a/acme/tests/client_test.py +++ b/acme/tests/client_test.py @@ -2,6 +2,7 @@ # pylint: disable=too-many-lines import copy import datetime +import http.client as http_client import json import unittest from unittest import mock @@ -9,7 +10,6 @@ from unittest import mock import josepy as jose import OpenSSL import requests -from six.moves import http_client # pylint: disable=import-error from acme import challenges from acme import errors diff --git a/acme/tests/crypto_util_test.py b/acme/tests/crypto_util_test.py index 705a3c856..f271ad37d 100644 --- a/acme/tests/crypto_util_test.py +++ b/acme/tests/crypto_util_test.py @@ -1,14 +1,13 @@ """Tests for acme.crypto_util.""" import itertools import socket +import socketserver import threading import time import unittest import josepy as jose import OpenSSL -import six -from six.moves import socketserver # type: ignore # pylint: disable=import-error from acme import errors import test_util @@ -27,8 +26,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): class _TestServer(socketserver.TCPServer): - # six.moves.* | pylint: disable=attribute-defined-outside-init,no-init - def server_bind(self): # pylint: disable=missing-docstring self.socket = SSLSocket(socket.socket(), certs) @@ -62,7 +59,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): self.assertRaises(errors.Error, self._probe, b'bar') def test_probe_connection_error(self): - # pylint has a hard time with six self.server.server_close() original_timeout = socket.getdefaulttimeout() try: @@ -121,9 +117,9 @@ class PyOpenSSLCertOrReqSANTest(unittest.TestCase): @classmethod def _get_idn_names(cls): """Returns expected names from '{cert,csr}-idnsans.pem'.""" - chars = [six.unichr(i) for i in itertools.chain(range(0x3c3, 0x400), - range(0x641, 0x6fc), - range(0x1820, 0x1877))] + chars = [chr(i) for i in itertools.chain(range(0x3c3, 0x400), + range(0x641, 0x6fc), + range(0x1820, 0x1877))] return [''.join(chars[i: i + 45]) + '.invalid' for i in range(0, len(chars), 45)] diff --git a/acme/tests/standalone_test.py b/acme/tests/standalone_test.py index 5bbc2ccce..e6aa8f2d6 100644 --- a/acme/tests/standalone_test.py +++ b/acme/tests/standalone_test.py @@ -1,13 +1,13 @@ """Tests for acme.standalone.""" +import http.client as http_client import socket +import socketserver import threading import unittest from unittest import mock import josepy as jose import requests -from six.moves import http_client # pylint: disable=import-error -from six.moves import socketserver # type: ignore # pylint: disable=import-error from acme import challenges from acme import crypto_util diff --git a/certbot-apache/certbot_apache/_internal/interfaces.py b/certbot-apache/certbot_apache/_internal/interfaces.py index 647790c41..77daa5b56 100644 --- a/certbot-apache/certbot_apache/_internal/interfaces.py +++ b/certbot-apache/certbot_apache/_internal/interfaces.py @@ -100,12 +100,10 @@ For this reason the internal representation of data should not ignore the case. """ import abc -import six -@six.add_metaclass(abc.ABCMeta) -class ParserNode(object): +class ParserNode(object, metaclass=abc.ABCMeta): """ ParserNode is the basic building block of the tree of such nodes, representing the structure of the configuration. It is largely meant to keep @@ -204,9 +202,7 @@ class ParserNode(object): """ -# Linter rule exclusion done because of https://github.com/PyCQA/pylint/issues/179 -@six.add_metaclass(abc.ABCMeta) # pylint: disable=abstract-method -class CommentNode(ParserNode): +class CommentNode(ParserNode, metaclass=abc.ABCMeta): """ CommentNode class is used for representation of comments within the parsed configuration structure. Because of the nature of comments, it is not able @@ -249,8 +245,7 @@ class CommentNode(ParserNode): metadata=kwargs.get('metadata', {})) # pragma: no cover -@six.add_metaclass(abc.ABCMeta) -class DirectiveNode(ParserNode): +class DirectiveNode(ParserNode, metaclass=abc.ABCMeta): """ DirectiveNode class represents a configuration directive within the configuration. It can have zero or more parameters attached to it. Because of the nature of @@ -325,8 +320,7 @@ class DirectiveNode(ParserNode): """ -@six.add_metaclass(abc.ABCMeta) -class BlockNode(DirectiveNode): +class BlockNode(DirectiveNode, metaclass=abc.ABCMeta): """ BlockNode class represents a block of nested configuration directives, comments and other blocks as its children. A BlockNode can have zero or more parameters diff --git a/certbot-apache/certbot_apache/_internal/parser.py b/certbot-apache/certbot_apache/_internal/parser.py index 4d997545b..75be0833f 100644 --- a/certbot-apache/certbot_apache/_internal/parser.py +++ b/certbot-apache/certbot_apache/_internal/parser.py @@ -5,7 +5,6 @@ import logging import re import sys -import six from acme.magic_typing import Dict from acme.magic_typing import List @@ -275,7 +274,7 @@ class ApacheParser(object): while len(mods) != prev_size: prev_size = len(mods) - for match_name, match_filename in six.moves.zip( + for match_name, match_filename in zip( iterator, iterator): mod_name = self.get_arg(match_name) mod_filename = self.get_arg(match_filename) diff --git a/certbot-apache/tests/autohsts_test.py b/certbot-apache/tests/autohsts_test.py index d15600215..db1c46b52 100644 --- a/certbot-apache/tests/autohsts_test.py +++ b/certbot-apache/tests/autohsts_test.py @@ -7,7 +7,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock # type: ignore -import six # pylint: disable=unused-import # six is used in mock.patch() from certbot import errors from certbot_apache._internal import constants diff --git a/certbot-apache/tests/configurator_test.py b/certbot-apache/tests/configurator_test.py index 6753995c6..302bf0023 100644 --- a/certbot-apache/tests/configurator_test.py +++ b/certbot-apache/tests/configurator_test.py @@ -10,7 +10,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock # type: ignore -import six # pylint: disable=unused-import # six is used in mock.patch() from acme import challenges from certbot import achallenges @@ -726,7 +725,7 @@ class MultipleVhostsTest(util.ApacheTest): # This calls open self.config.reverter.register_file_creation = mock.Mock() mock_open.side_effect = IOError - with mock.patch("six.moves.builtins.open", mock_open): + with mock.patch("builtins.open", mock_open): self.assertRaises( errors.PluginError, self.config.make_vhost_ssl, self.vh_truth[0]) @@ -1834,7 +1833,7 @@ class InstallSslOptionsConfTest(util.ApacheTest): def test_open_module_file(self): mock_open = mock.mock_open(read_data="testing 12 3") - with mock.patch("six.moves.builtins.open", mock_open): + with mock.patch("builtins.open", mock_open): self.assertEqual(self.config._open_module_file("/nonsense/"), "testing 12 3") if __name__ == "__main__": diff --git a/certbot-ci/certbot_integration_tests/utils/misc.py b/certbot-ci/certbot_integration_tests/utils/misc.py index 799b079fe..e6b9f0c88 100644 --- a/certbot-ci/certbot_integration_tests/utils/misc.py +++ b/certbot-ci/certbot_integration_tests/utils/misc.py @@ -4,10 +4,12 @@ or outside during setup/teardown of the integration tests environment. """ import contextlib import errno +import http.server as SimpleHTTPServer import multiprocessing import os import re import shutil +import socketserver import stat import sys import tempfile @@ -23,8 +25,6 @@ from cryptography.x509 import load_pem_x509_certificate from OpenSSL import crypto import pkg_resources import requests -from six.moves import SimpleHTTPServer -from six.moves import socketserver from certbot_integration_tests.utils.constants import \ PEBBLE_ALTERNATE_ROOTS, PEBBLE_MANAGEMENT_URL diff --git a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py index b86e1cbc9..4db72998f 100755 --- a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py +++ b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py @@ -4,6 +4,7 @@ This runnable module interfaces itself with the Pebble management interface in o to serve a mock OCSP responder during integration tests against Pebble. """ import datetime +import http.server as BaseHTTPServer import re from cryptography import x509 @@ -13,7 +14,6 @@ from cryptography.hazmat.primitives import serialization from cryptography.x509 import ocsp from dateutil import parser import requests -from six.moves import BaseHTTPServer from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT from certbot_integration_tests.utils.constants import PEBBLE_MANAGEMENT_URL diff --git a/certbot-ci/certbot_integration_tests/utils/proxy.py b/certbot-ci/certbot_integration_tests/utils/proxy.py index 225f98e6e..7c46e640d 100644 --- a/certbot-ci/certbot_integration_tests/utils/proxy.py +++ b/certbot-ci/certbot_integration_tests/utils/proxy.py @@ -1,12 +1,12 @@ #!/usr/bin/env python # pylint: disable=missing-module-docstring +import http.server as BaseHTTPServer import json import re import sys import requests -from six.moves import BaseHTTPServer from certbot_integration_tests.utils.misc import GracefulTCPServer diff --git a/certbot-ci/setup.py b/certbot-ci/setup.py index 3277df1c0..9f9c1f462 100644 --- a/certbot-ci/setup.py +++ b/certbot-ci/setup.py @@ -18,7 +18,6 @@ install_requires = [ 'python-dateutil', 'pyyaml', 'requests', - 'six' ] # Add pywin32 on Windows platforms to handle low-level system calls. diff --git a/certbot-compatibility-test/certbot_compatibility_test/validator.py b/certbot-compatibility-test/certbot_compatibility_test/validator.py index bfa03f22d..9a082523a 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/validator.py +++ b/certbot-compatibility-test/certbot_compatibility_test/validator.py @@ -3,8 +3,6 @@ import logging import socket import requests -import six -from six.moves import xrange from acme import crypto_util from acme import errors as acme_errors @@ -19,11 +17,11 @@ class Validator(object): """Verifies the certificate presented at name is cert""" if alt_host is None: host = socket.gethostbyname(name).encode() - elif isinstance(alt_host, six.binary_type): + elif isinstance(alt_host, bytes): host = alt_host else: host = alt_host.encode() - name = name if isinstance(name, six.binary_type) else name.encode() + name = name if isinstance(name, bytes) else name.encode() try: presented_cert = crypto_util.probe_sni(name, host, port) @@ -62,7 +60,7 @@ class Validator(object): else: response = requests.get(url, allow_redirects=False) - return response.status_code in xrange(300, 309) + return response.status_code in range(300, 309) def hsts(self, name): """Test for HTTP Strict Transport Security header""" diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 0236773f0..af19b126e 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -8,7 +8,6 @@ version = '1.13.0.dev0' install_requires = [ 'certbot', 'certbot-apache', - 'six', 'requests', 'zope.interface', ] diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 8c6ac78d5..6e60444cf 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -11,7 +11,6 @@ version = '1.13.0.dev0' install_requires = [ 'python-digitalocean>=1.11', 'setuptools>=39.0.1', - 'six>=1.11.0', 'zope.interface', ] diff --git a/certbot-nginx/certbot_nginx/_internal/nginxparser.py b/certbot-nginx/certbot_nginx/_internal/nginxparser.py index 5f723dcef..f043b0e4d 100644 --- a/certbot-nginx/certbot_nginx/_internal/nginxparser.py +++ b/certbot-nginx/certbot_nginx/_internal/nginxparser.py @@ -15,7 +15,6 @@ from pyparsing import restOfLine from pyparsing import stringEnd from pyparsing import White from pyparsing import ZeroOrMore -import six from acme.magic_typing import IO, Any # pylint: disable=unused-import logger = logging.getLogger(__name__) @@ -79,7 +78,7 @@ class RawNginxDumper(object): """Iterates the dumped nginx content.""" blocks = blocks or self.blocks for b0 in blocks: - if isinstance(b0, six.string_types): + if isinstance(b0, str): yield b0 continue item = copy.deepcopy(b0) @@ -96,7 +95,7 @@ class RawNginxDumper(object): yield '}' else: # not a block - list of strings semicolon = ";" - if isinstance(item[0], six.string_types) and item[0].strip() == '#': # comment + if isinstance(item[0], str) and item[0].strip() == '#': # comment semicolon = "" yield "".join(item) + semicolon @@ -131,14 +130,14 @@ def load(_file): def dumps(blocks): - # type: (UnspacedList) -> six.text_type + # type: (UnspacedList) -> str """Dump to a Unicode string. :param UnspacedList block: The parsed tree - :rtype: six.text_type + :rtype: str """ - return six.text_type(RawNginxDumper(blocks.spaced)) + return str(RawNginxDumper(blocks.spaced)) def dump(blocks, _file): @@ -154,7 +153,7 @@ def dump(blocks, _file): _file.write(dumps(blocks)) -spacey = lambda x: (isinstance(x, six.string_types) and x.isspace()) or x == '' +spacey = lambda x: (isinstance(x, str) and x.isspace()) or x == '' class UnspacedList(list): """Wrap a list [of lists], making any whitespace entries magically invisible""" diff --git a/certbot-nginx/certbot_nginx/_internal/obj.py b/certbot-nginx/certbot_nginx/_internal/obj.py index 4e0d8cf35..2dd02f180 100644 --- a/certbot-nginx/certbot_nginx/_internal/obj.py +++ b/certbot-nginx/certbot_nginx/_internal/obj.py @@ -1,7 +1,6 @@ """Module contains classes used by the Nginx Configurator.""" import re -import six from certbot.plugins import common @@ -211,7 +210,7 @@ class VirtualHost(object): def contains_list(self, test): """Determine if raw server block contains test list at top level """ - for i in six.moves.range(0, len(self.raw) - len(test) + 1): + for i in range(0, len(self.raw) - len(test) + 1): if self.raw[i:i + len(test)] == test: return True return False @@ -250,7 +249,7 @@ def _find_directive(directives, directive_name, match_content=None): """Find a directive of type directive_name in directives. If match_content is given, Searches for `match_content` in the directive arguments. """ - if not directives or isinstance(directives, six.string_types): + if not directives or isinstance(directives, str): return None # If match_content is None, just match on directive type. Otherwise, match on diff --git a/certbot-nginx/certbot_nginx/_internal/parser.py b/certbot-nginx/certbot_nginx/_internal/parser.py index 72091b03f..fe5d7bb31 100644 --- a/certbot-nginx/certbot_nginx/_internal/parser.py +++ b/certbot-nginx/certbot_nginx/_internal/parser.py @@ -7,7 +7,6 @@ import logging import re import pyparsing -import six from acme.magic_typing import Dict from acme.magic_typing import List @@ -549,7 +548,7 @@ def _is_include_directive(entry): """ return (isinstance(entry, list) and len(entry) == 2 and entry[0] == 'include' and - isinstance(entry[1], six.string_types)) + isinstance(entry[1], str)) def _is_ssl_on_directive(entry): """Checks if an nginx parsed entry is an 'ssl on' directive. @@ -654,7 +653,7 @@ def _add_directive(block, directive, insert_at_top): directive_name = directive[0] def can_append(loc, dir_name): """ Can we append this directive to the block? """ - return loc is None or (isinstance(dir_name, six.string_types) + return loc is None or (isinstance(dir_name, str) and dir_name in REPEATABLE_DIRECTIVES) err_fmt = 'tried to insert directive "{0}" but found conflicting "{1}".' diff --git a/certbot-nginx/certbot_nginx/_internal/parser_obj.py b/certbot-nginx/certbot_nginx/_internal/parser_obj.py index 390e18e4d..d616a1a99 100644 --- a/certbot-nginx/certbot_nginx/_internal/parser_obj.py +++ b/certbot-nginx/certbot_nginx/_internal/parser_obj.py @@ -4,7 +4,6 @@ raw lists of tokens from pyparsing. """ import abc import logging -import six from acme.magic_typing import List from certbot import errors @@ -152,7 +151,7 @@ class Statements(Parsable): if not isinstance(raw_list, list): raise errors.MisconfigurationError("Statements parsing expects a list!") # If there's a trailing whitespace in the list of statements, keep track of it. - if raw_list and isinstance(raw_list[-1], six.string_types) and raw_list[-1].isspace(): + if raw_list and isinstance(raw_list[-1], str) and raw_list[-1].isspace(): self._trailing_whitespace = raw_list[-1] raw_list = raw_list[:-1] self._data = [parse_raw(elem, self, add_spaces) for elem in raw_list] @@ -184,7 +183,7 @@ class Statements(Parsable): def _space_list(list_): """ Inserts whitespace between adjacent non-whitespace tokens. """ spaced_statement = [] # type: List[str] - for i in reversed(six.moves.xrange(len(list_))): + for i in reversed(range(len(list_))): spaced_statement.insert(0, list_[i]) if i > 0 and not list_[i].isspace() and not list_[i-1].isspace(): spaced_statement.insert(0, " ") @@ -206,7 +205,7 @@ class Sentence(Parsable): :returns: whether this lists is parseable by `Sentence`. """ return isinstance(lists, list) and len(lists) > 0 and \ - all(isinstance(elem, six.string_types) for elem in lists) + all(isinstance(elem, str) for elem in lists) def parse(self, raw_list, add_spaces=False): """ Parses a list of string types into this object. @@ -214,7 +213,7 @@ class Sentence(Parsable): if add_spaces: raw_list = _space_list(raw_list) if not isinstance(raw_list, list) or \ - any(not isinstance(elem, six.string_types) for elem in raw_list): + any(not isinstance(elem, str) for elem in raw_list): raise errors.MisconfigurationError("Sentence parsing expects a list of string types.") self._data = raw_list diff --git a/certbot-nginx/tests/http_01_test.py b/certbot-nginx/tests/http_01_test.py index 8f0673c1f..2947b099d 100644 --- a/certbot-nginx/tests/http_01_test.py +++ b/certbot-nginx/tests/http_01_test.py @@ -6,7 +6,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock # type: ignore -import six from acme import challenges from certbot import achallenges @@ -79,7 +78,7 @@ class HttpPerformTest(util.NginxTest): http_responses = self.http01.perform() self.assertEqual(len(http_responses), 4) - for i in six.moves.range(4): + for i in range(4): self.assertEqual(http_responses[i], acme_responses[i]) def test_mod_config(self): diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 1333d2420..370282f38 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -17,6 +17,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). * The acme library no longer depends on the `security` extras from `requests` which was needed to support SNI in TLS requests when using old versions of Python 2. +* Certbot and all of its components no longer depend on the library `six`. ### Fixed diff --git a/certbot/certbot/_internal/account.py b/certbot/certbot/_internal/account.py index b4619beba..dbe111fbc 100644 --- a/certbot/certbot/_internal/account.py +++ b/certbot/certbot/_internal/account.py @@ -10,7 +10,6 @@ from cryptography.hazmat.primitives import serialization import josepy as jose import pyrfc3339 import pytz -import six from acme import fields as acme_fields from acme import messages @@ -101,7 +100,7 @@ class AccountMemoryStorage(interfaces.AccountStorage): self.accounts = initial_accounts if initial_accounts is not None else {} def find_all(self): - return list(six.itervalues(self.accounts)) + return list(self.accounts.values()) def save(self, account, client): if account.id in self.accounts: diff --git a/certbot/certbot/_internal/cli/helpful.py b/certbot/certbot/_internal/cli/helpful.py index 2cb506157..80afe5db4 100644 --- a/certbot/certbot/_internal/cli/helpful.py +++ b/certbot/certbot/_internal/cli/helpful.py @@ -7,7 +7,6 @@ import glob import sys import configargparse -import six import zope.component import zope.interface @@ -99,7 +98,7 @@ class HelpfulArgumentParser(object): if isinstance(help1, bool) and isinstance(help2, bool): self.help_arg = help1 or help2 else: - self.help_arg = help1 if isinstance(help1, six.string_types) else help2 + self.help_arg = help1 if isinstance(help1, str) else help2 short_usage = self._usage_string(plugins, self.help_arg) @@ -470,7 +469,7 @@ class HelpfulArgumentParser(object): may or may not be displayed as help topics. """ - for name, plugin_ep in six.iteritems(plugins): + for name, plugin_ep in plugins.items(): parser_or_group = self.add_group(name, description=plugin_ep.long_description) plugin_ep.plugin_cls.inject_parser_options(parser_or_group, name) diff --git a/certbot/certbot/_internal/configuration.py b/certbot/certbot/_internal/configuration.py index f1e85f9fe..1b5cf5da7 100644 --- a/certbot/certbot/_internal/configuration.py +++ b/certbot/certbot/_internal/configuration.py @@ -1,7 +1,7 @@ """Certbot user-supplied configuration.""" import copy +from urllib import parse -from six.moves.urllib import parse import zope.interface from certbot import errors diff --git a/certbot/certbot/_internal/plugins/disco.py b/certbot/certbot/_internal/plugins/disco.py index bed22b4ae..dbcecb067 100644 --- a/certbot/certbot/_internal/plugins/disco.py +++ b/certbot/certbot/_internal/plugins/disco.py @@ -5,7 +5,6 @@ import logging import sys import pkg_resources -import six import zope.interface import zope.interface.verify @@ -215,7 +214,7 @@ class PluginsRegistry(Mapping): # This prevents deadlock caused by plugins acquiring a lock # and ensures at least one concurrent Certbot instance will run # successfully. - self._plugins = collections.OrderedDict(sorted(six.iteritems(plugins))) + self._plugins = collections.OrderedDict(sorted(plugins.items())) @classmethod def find_all(cls): @@ -276,12 +275,12 @@ class PluginsRegistry(Mapping): def init(self, config): """Initialize all plugins in the registry.""" return [plugin_ep.init(config) for plugin_ep - in six.itervalues(self._plugins)] + in self._plugins.values()] def filter(self, pred): """Filter plugins based on predicate.""" return type(self)({name: plugin_ep for name, plugin_ep - in six.iteritems(self._plugins) if pred(plugin_ep)}) + in self._plugins.items() if pred(plugin_ep)}) def visible(self): """Filter plugins based on visibility.""" @@ -297,7 +296,7 @@ class PluginsRegistry(Mapping): def prepare(self): """Prepare all plugins in the registry.""" - return [plugin_ep.prepare() for plugin_ep in six.itervalues(self._plugins)] + return [plugin_ep.prepare() for plugin_ep in self._plugins.values()] def available(self): """Filter plugins based on availability.""" @@ -319,7 +318,7 @@ class PluginsRegistry(Mapping): """ # use list instead of set because PluginEntryPoint is not hashable - candidates = [plugin_ep for plugin_ep in six.itervalues(self._plugins) + candidates = [plugin_ep for plugin_ep in self._plugins.values() if plugin_ep.initialized and plugin_ep.init() is plugin] assert len(candidates) <= 1 if candidates: @@ -329,9 +328,9 @@ class PluginsRegistry(Mapping): def __repr__(self): return "{0}({1})".format( self.__class__.__name__, ','.join( - repr(p_ep) for p_ep in six.itervalues(self._plugins))) + repr(p_ep) for p_ep in self._plugins.values())) def __str__(self): if not self._plugins: return "No plugins" - return "\n\n".join(str(p_ep) for p_ep in six.itervalues(self._plugins)) + return "\n\n".join(str(p_ep) for p_ep in self._plugins.values()) diff --git a/certbot/certbot/_internal/plugins/selection.py b/certbot/certbot/_internal/plugins/selection.py index 0b04791c6..e5c311efe 100644 --- a/certbot/certbot/_internal/plugins/selection.py +++ b/certbot/certbot/_internal/plugins/selection.py @@ -3,7 +3,6 @@ from __future__ import print_function import logging -import six import zope.component from certbot import errors @@ -108,7 +107,7 @@ def pick_plugin(config, default, plugins, question, ifaces): if len(prepared) > 1: logger.debug("Multiple candidate plugins: %s", prepared) - plugin_ep = choose_plugin(list(six.itervalues(prepared)), question) + plugin_ep = choose_plugin(list(prepared.values()), question) if plugin_ep is None: return None return plugin_ep.init() diff --git a/certbot/certbot/_internal/plugins/standalone.py b/certbot/certbot/_internal/plugins/standalone.py index bbb56178c..60c9558cb 100644 --- a/certbot/certbot/_internal/plugins/standalone.py +++ b/certbot/certbot/_internal/plugins/standalone.py @@ -6,7 +6,6 @@ import socket from socket import errno as socket_errors # type: ignore import OpenSSL # pylint: disable=unused-import -import six import zope.interface from acme import challenges @@ -183,7 +182,7 @@ class Authenticator(common.Plugin): for achall in achalls: if achall in server_achalls: server_achalls.remove(achall) - for port, servers in six.iteritems(self.servers.running()): + for port, servers in self.servers.running().items(): if not self.served[servers]: self.servers.stop(port) diff --git a/certbot/certbot/_internal/plugins/webroot.py b/certbot/certbot/_internal/plugins/webroot.py index 88e02998d..8789db604 100644 --- a/certbot/certbot/_internal/plugins/webroot.py +++ b/certbot/certbot/_internal/plugins/webroot.py @@ -4,7 +4,6 @@ import collections import json import logging -import six import zope.component import zope.interface @@ -92,7 +91,7 @@ to serve all files under specified web root ({0}).""" for achall in achalls: self.conf("map").setdefault(achall.domain, webroot_path) else: - known_webroots = list(set(six.itervalues(self.conf("map")))) + known_webroots = list(set(self.conf("map").values())) for achall in achalls: if achall.domain not in self.conf("map"): new_webroot = self._prompt_for_webroot(achall.domain, @@ -242,7 +241,7 @@ class _WebrootMapAction(argparse.Action): """Action class for parsing webroot_map.""" def __call__(self, parser, namespace, webroot_map, option_string=None): - for domains, webroot_path in six.iteritems(json.loads(webroot_map)): + for domains, webroot_path in json.loads(webroot_map).items(): webroot_path = _validate_webroot(webroot_path) namespace.webroot_map.update( (d, webroot_path) for d in cli.add_domains(namespace, domains)) diff --git a/certbot/certbot/_internal/renewal.py b/certbot/certbot/_internal/renewal.py index f4c7b4502..9fe9cb546 100644 --- a/certbot/certbot/_internal/renewal.py +++ b/certbot/certbot/_internal/renewal.py @@ -13,7 +13,6 @@ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import ec, rsa from cryptography.hazmat.primitives.serialization import load_pem_private_key import OpenSSL -import six import zope.component from acme.magic_typing import List @@ -120,7 +119,7 @@ def _restore_webroot_config(config, renewalparams): # see https://github.com/certbot/certbot/pull/7095 if "webroot_path" in renewalparams and not cli.set_by_cli("webroot_path"): wp = renewalparams["webroot_path"] - if isinstance(wp, six.string_types): # prior to 0.1.0, webroot_path was a string + if isinstance(wp, str): # prior to 0.1.0, webroot_path was a string wp = [wp] config.webroot_path = wp @@ -155,7 +154,7 @@ def _restore_plugin_configs(config, renewalparams): for plugin_prefix in set(plugin_prefixes): plugin_prefix = plugin_prefix.replace('-', '_') - for config_item, config_value in six.iteritems(renewalparams): + for config_item, config_value in renewalparams.items(): if config_item.startswith(plugin_prefix + "_") and not cli.set_by_cli(config_item): # Values None, True, and False need to be treated specially, # As their types aren't handled correctly by configobj @@ -180,9 +179,9 @@ def restore_required_config_elements(config, renewalparams): required_items = itertools.chain( (("pref_challs", _restore_pref_challs),), - six.moves.zip(BOOL_CONFIG_ITEMS, itertools.repeat(_restore_bool)), - six.moves.zip(INT_CONFIG_ITEMS, itertools.repeat(_restore_int)), - six.moves.zip(STR_CONFIG_ITEMS, itertools.repeat(_restore_str))) + zip(BOOL_CONFIG_ITEMS, itertools.repeat(_restore_bool)), + zip(INT_CONFIG_ITEMS, itertools.repeat(_restore_int)), + zip(STR_CONFIG_ITEMS, itertools.repeat(_restore_str))) for item_name, restore_func in required_items: if item_name in renewalparams and not cli.set_by_cli(item_name): value = restore_func(item_name, renewalparams[item_name]) @@ -220,7 +219,7 @@ def _restore_pref_challs(unused_name, value): # If pref_challs has only one element, configobj saves the value # with a trailing comma so it's parsed as a list. If this comma is # removed by the user, the value is parsed as a str. - value = [value] if isinstance(value, six.string_types) else value + value = [value] if isinstance(value, str) else value return cli.parse_preferred_challenges(value) diff --git a/certbot/certbot/_internal/reporter.py b/certbot/certbot/_internal/reporter.py index d781f3d9d..64c0fbd6d 100644 --- a/certbot/certbot/_internal/reporter.py +++ b/certbot/certbot/_internal/reporter.py @@ -3,10 +3,10 @@ from __future__ import print_function import collections import logging +import queue import sys import textwrap -from six.moves import queue # type: ignore import zope.interface from certbot import interfaces diff --git a/certbot/certbot/_internal/storage.py b/certbot/certbot/_internal/storage.py index ff58313e5..690567a17 100644 --- a/certbot/certbot/_internal/storage.py +++ b/certbot/certbot/_internal/storage.py @@ -9,7 +9,6 @@ import stat import configobj import parsedatetime import pytz -import six from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey from cryptography.hazmat.primitives.serialization import load_pem_private_key @@ -275,7 +274,7 @@ def relevant_values(all_values): rv = dict( (option, value) - for option, value in six.iteritems(all_values) + for option, value in all_values.items() if _relevant(namespaces, option) and cli.option_was_set(option, value)) # We always save the server value to help with forward compatibility # and behavioral consistency when versions of Certbot with different diff --git a/certbot/certbot/crypto_util.py b/certbot/certbot/crypto_util.py index edd4f9eb3..f67d95d97 100644 --- a/certbot/certbot/crypto_util.py +++ b/certbot/certbot/crypto_util.py @@ -22,7 +22,6 @@ from OpenSSL import crypto from OpenSSL import SSL # type: ignore import pyrfc3339 -import six import zope.component from acme import crypto_util as acme_crypto_util @@ -215,7 +214,7 @@ def make_key(bits=1024, key_type="rsa", elliptic_curve=None): except TypeError: raise errors.Error("Unsupported elliptic curve: {}".format(elliptic_curve)) except UnsupportedAlgorithm as e: - raise six.raise_from(e, errors.Error(str(e))) + raise e from errors.Error(str(e)) _key_pem = _key.private_bytes( encoding=Encoding.PEM, format=PrivateFormat.TraditionalOpenSSL, @@ -492,14 +491,9 @@ def _notAfterBefore(cert_path, method): reformatted_timestamp = [timestamp[0:4], b"-", timestamp[4:6], b"-", timestamp[6:8], b"T", timestamp[8:10], b":", timestamp[10:12], b":", timestamp[12:]] - # pyrfc3339 always uses the type `str`. This means that in Python 2, it - # expects str/bytes and in Python 3 it expects its str type or the Python 2 - # equivalent of the type unicode. + # pyrfc3339 always uses the type `str` timestamp_bytes = b"".join(reformatted_timestamp) - if six.PY3: - timestamp_str = timestamp_bytes.decode('ascii') - else: - timestamp_str = timestamp_bytes + timestamp_str = timestamp_bytes.decode('ascii') return pyrfc3339.parse(timestamp_str) diff --git a/certbot/certbot/display/util.py b/certbot/certbot/display/util.py index c48454637..9da981892 100644 --- a/certbot/certbot/display/util.py +++ b/certbot/certbot/display/util.py @@ -71,7 +71,7 @@ def _wrap_lines(msg): def input_with_timeout(prompt=None, timeout=36000.0): """Get user input with a timeout. - Behaves the same as six.moves.input, however, an error is raised if + Behaves the same as the builtin input, however, an error is raised if a user doesn't answer after timeout seconds. The default timeout value was chosen to place it just under 12 hours for users following our advice and running Certbot twice a day. @@ -85,7 +85,7 @@ def input_with_timeout(prompt=None, timeout=36000.0): :raises errors.Error if no answer is given before the timeout """ - # use of sys.stdin and sys.stdout to mimic six.moves.input based on + # use of sys.stdin and sys.stdout to mimic the builtin input based on # https://github.com/python/cpython/blob/baf7bb30a02aabde260143136bdf5b3738a1d409/Lib/getpass.py#L129 if prompt: sys.stdout.write(prompt) diff --git a/certbot/certbot/interfaces.py b/certbot/certbot/interfaces.py index 28c6f2ac1..ddbee8ddc 100644 --- a/certbot/certbot/interfaces.py +++ b/certbot/certbot/interfaces.py @@ -1,14 +1,12 @@ """Certbot client interfaces.""" import abc -import six import zope.interface # pylint: disable=no-self-argument,no-method-argument,inherit-non-class -@six.add_metaclass(abc.ABCMeta) -class AccountStorage(object): +class AccountStorage(object, metaclass=abc.ABCMeta): """Accounts storage interface.""" @abc.abstractmethod @@ -547,8 +545,7 @@ class IReporter(zope.interface.Interface): """Prints messages to the user and clears the message queue.""" -@six.add_metaclass(abc.ABCMeta) -class RenewableCert(object): +class RenewableCert(object, metaclass=abc.ABCMeta): """Interface to a certificate lineage.""" @abc.abstractproperty @@ -613,8 +610,7 @@ class RenewableCert(object): # an update during the run or install subcommand, it should do so when # :func:`IInstaller.deploy_cert` is called. -@six.add_metaclass(abc.ABCMeta) -class GenericUpdater(object): +class GenericUpdater(object, metaclass=abc.ABCMeta): """Interface for update types not currently specified by Certbot. This class allows plugins to perform types of updates that Certbot hasn't @@ -646,8 +642,7 @@ class GenericUpdater(object): """ -@six.add_metaclass(abc.ABCMeta) -class RenewDeployer(object): +class RenewDeployer(object, metaclass=abc.ABCMeta): """Interface for update types run when a lineage is renewed This class allows plugins to perform types of updates that need to run at diff --git a/certbot/certbot/plugins/dns_test_common.py b/certbot/certbot/plugins/dns_test_common.py index d5044d336..a3a26a7a1 100644 --- a/certbot/certbot/plugins/dns_test_common.py +++ b/certbot/certbot/plugins/dns_test_common.py @@ -6,7 +6,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock # type: ignore -import six from acme import challenges from certbot import achallenges @@ -31,7 +30,7 @@ class BaseAuthenticatorTest(object): challb=acme_util.DNS01, domain=DOMAIN, account_key=KEY) def test_more_info(self): - self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) # pylint: disable=no-member + self.assertTrue(isinstance(self.auth.more_info(), str)) # pylint: disable=no-member def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref(None), [challenges.DNS01]) # pylint: disable=no-member diff --git a/certbot/certbot/plugins/enhancements.py b/certbot/certbot/plugins/enhancements.py index 4abce2d2f..e674c32a2 100644 --- a/certbot/certbot/plugins/enhancements.py +++ b/certbot/certbot/plugins/enhancements.py @@ -1,8 +1,6 @@ """New interface style Certbot enhancements""" import abc -import six - from acme.magic_typing import Any from acme.magic_typing import Dict from acme.magic_typing import List @@ -91,8 +89,7 @@ def populate_cli(add): help=enh["cli_help"]) -@six.add_metaclass(abc.ABCMeta) -class AutoHSTSEnhancement(object): +class AutoHSTSEnhancement(object, metaclass=abc.ABCMeta): """ Enhancement interface that installer plugins can implement in order to provide functionality that configures the software to have a diff --git a/certbot/certbot/reverter.py b/certbot/certbot/reverter.py index 58e1216b7..be9d78a11 100644 --- a/certbot/certbot/reverter.py +++ b/certbot/certbot/reverter.py @@ -7,7 +7,6 @@ import sys import time import traceback -import six from certbot import errors from certbot import util @@ -518,7 +517,7 @@ class Reverter(object): # It is possible save checkpoints faster than 1 per second resulting in # collisions in the naming convention. - for _ in six.moves.range(2): + for _ in range(2): timestamp = self._checkpoint_timestamp() final_dir = os.path.join(self.config.backup_dir, timestamp) try: diff --git a/certbot/certbot/tests/acme_util.py b/certbot/certbot/tests/acme_util.py index f4a20ea86..49ca88bf5 100644 --- a/certbot/certbot/tests/acme_util.py +++ b/certbot/certbot/tests/acme_util.py @@ -2,7 +2,6 @@ import datetime import josepy as jose -import six from acme import challenges from acme import messages @@ -69,7 +68,7 @@ def gen_authzr(authz_status, domain, challs, statuses, combos=True): """ challbs = tuple( chall_to_challb(chall, status) - for chall, status in six.moves.zip(challs, statuses) + for chall, status in zip(challs, statuses) ) authz_kwargs = { "identifier": messages.Identifier( diff --git a/certbot/certbot/tests/util.py b/certbot/certbot/tests/util.py index acb31819f..558bfbed3 100644 --- a/certbot/certbot/tests/util.py +++ b/certbot/certbot/tests/util.py @@ -1,4 +1,6 @@ """Test utilities.""" +from importlib import reload as reload_module +import io import logging from multiprocessing import Event from multiprocessing import Process @@ -11,20 +13,8 @@ import warnings from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization import josepy as jose -try: - import mock - warnings.warn( - "The external mock module is being used for backwards compatibility " - "since it is available, however, future versions of Certbot's tests will " - "use unittest.mock. Be sure to update your code accordingly.", - PendingDeprecationWarning - ) -except ImportError: # pragma: no cover - from unittest import mock # type: ignore import OpenSSL import pkg_resources -import six -from six.moves import reload_module from certbot import interfaces from certbot import util @@ -36,6 +26,18 @@ from certbot.compat import filesystem from certbot.compat import os from certbot.display import util as display_util +try: + import mock + warnings.warn( + "The external mock module is being used for backwards compatibility " + "since it is available, however, future versions of Certbot's tests will " + "use unittest.mock. Be sure to update your code accordingly.", + PendingDeprecationWarning + ) +except ImportError: # pragma: no cover + from unittest import mock # type: ignore + + def vector_path(*names): """Path to a test vector.""" @@ -177,7 +179,7 @@ def patch_get_utility_with_stdout(target='zope.component.getUtility', :rtype: mock.MagicMock """ - stdout = stdout if stdout else six.StringIO() + stdout = stdout if stdout else io.StringIO() freezable_mock = _create_get_utility_mock_with_stdout(stdout) return mock.patch(target, new=freezable_mock) diff --git a/certbot/certbot/util.py b/certbot/certbot/util.py index 8db5ab34a..7bbc02f5f 100644 --- a/certbot/certbot/util.py +++ b/certbot/certbot/util.py @@ -15,7 +15,6 @@ import subprocess import sys import configargparse -import six from acme.magic_typing import Text from acme.magic_typing import Tuple @@ -153,7 +152,7 @@ def lock_dir_until_exit(dir_path): def _release_locks(): - for dir_lock in six.itervalues(_LOCKS): + for dir_lock in _LOCKS.values(): try: dir_lock.release() except: # pylint: disable=bare-except @@ -517,7 +516,7 @@ def enforce_domain_sanity(domain): """ # Unicode try: - if isinstance(domain, six.binary_type): + if isinstance(domain, bytes): domain = domain.decode('utf-8') domain.encode('ascii') except UnicodeError: @@ -579,7 +578,7 @@ def is_wildcard_domain(domain): """ wildcard_marker = b"*." # type: Union[Text, bytes] - if isinstance(domain, six.text_type): + if isinstance(domain, str): wildcard_marker = u"*." return domain.startswith(wildcard_marker) diff --git a/certbot/setup.py b/certbot/setup.py index 4ea98e574..8b2874f20 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -31,9 +31,9 @@ meta = dict(re.findall(r"""__([a-z]+)__ = '([^']+)""", read_file(init_fn))) readme = read_file(os.path.join(here, 'README.rst')) version = meta['version'] -# This package relies on PyOpenSSL, requests, and six, however, it isn't -# specified here to avoid masking the more specific request requirements in -# acme. See https://github.com/pypa/pip/issues/988 for more info. +# This package relies on PyOpenSSL and requests, however, it isn't specified +# here to avoid masking the more specific request requirements in acme. See +# https://github.com/pypa/pip/issues/988 for more info. install_requires = [ 'acme>=1.8.0', # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index f9c218cd3..d0448a1db 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -276,14 +276,14 @@ class AccountFileStorageTest(test_util.ConfigTestCase): self.storage.save(self.acc, self.mock_client) mock_open = mock.mock_open() mock_open.side_effect = IOError - with mock.patch("six.moves.builtins.open", mock_open): + with mock.patch("builtins.open", mock_open): self.assertRaises( errors.AccountStorageError, self.storage.load, self.acc.id) def test_save_ioerrors(self): mock_open = mock.mock_open() mock_open.side_effect = IOError # TODO: [None, None, IOError] - with mock.patch("six.moves.builtins.open", mock_open): + with mock.patch("builtins.open", mock_open): self.assertRaises( errors.AccountStorageError, self.storage.save, self.acc, self.mock_client) diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py index e65ec32ec..2ec798a08 100644 --- a/certbot/tests/cli_test.py +++ b/certbot/tests/cli_test.py @@ -1,16 +1,11 @@ """Tests for certbot._internal.cli.""" import argparse import copy +from importlib import reload as reload_module +import io import tempfile import unittest -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock -import six -from six.moves import reload_module # pylint: disable=import-error - from acme import challenges from certbot import errors from certbot._internal import cli @@ -21,6 +16,12 @@ from certbot.compat import os import certbot.tests.util as test_util from certbot.tests.util import TempDirTestCase +try: + import mock +except ImportError: # pragma: no cover + from unittest import mock + + PLUGINS = disco.PluginsRegistry.find_all() @@ -91,7 +92,7 @@ class ParseTest(unittest.TestCase): def _help_output(self, args): "Run a command, and return the output string for scrutiny" - output = six.StringIO() + output = io.StringIO() def write_msg(message, *args, **kwargs): # pylint: disable=missing-docstring,unused-argument output.write(message) diff --git a/certbot/tests/display/completer_test.py b/certbot/tests/display/completer_test.py index 0852ab175..8ae6290bf 100644 --- a/certbot/tests/display/completer_test.py +++ b/certbot/tests/display/completer_test.py @@ -3,19 +3,20 @@ try: import readline # pylint: disable=import-error except ImportError: import certbot._internal.display.dummy_readline as readline # type: ignore +from importlib import reload as reload_module import string import sys import unittest +from certbot.compat import filesystem # pylint: disable=ungrouped-imports +from certbot.compat import os # pylint: disable=ungrouped-imports +import certbot.tests.util as test_util # pylint: disable=ungrouped-imports + try: import mock except ImportError: # pragma: no cover from unittest import mock -from six.moves import reload_module # pylint: disable=import-error -from certbot.compat import filesystem # pylint: disable=ungrouped-imports -from certbot.compat import os # pylint: disable=ungrouped-imports -import certbot.tests.util as test_util # pylint: disable=ungrouped-imports class CompleterTest(test_util.TempDirTestCase): diff --git a/certbot/tests/display/util_test.py b/certbot/tests/display/util_test.py index 1b22d3422..30b33bbc9 100644 --- a/certbot/tests/display/util_test.py +++ b/certbot/tests/display/util_test.py @@ -1,20 +1,22 @@ """Test :mod:`certbot.display.util`.""" import inspect +import io import socket import tempfile import unittest -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock -import six from certbot import errors from certbot import interfaces from certbot.display import util as display_util import certbot.tests.util as test_util +try: + import mock +except ImportError: # pragma: no cover + from unittest import mock + + CHOICES = [("First", "Description1"), ("Second", "Description2")] TAGS = ["tag1", "tag2", "tag3"] TAGS_CHOICES = [("1", "tag1"), ("2", "tag2"), ("3", "tag3")] @@ -34,7 +36,7 @@ class InputWithTimeoutTest(unittest.TestCase): def test_input(self, prompt=None): expected = "foo bar" - stdin = six.StringIO(expected + "\n") + stdin = io.StringIO(expected + "\n") with mock.patch("certbot.compat.misc.select.select") as mock_select: mock_select.return_value = ([stdin], [], [],) self.assertEqual(self._call(prompt), expected) @@ -328,11 +330,7 @@ class FileOutputDisplayTest(unittest.TestCase): # Every IDisplay method implemented by FileDisplay must take # force_interactive to prevent workflow regressions. for name in interfaces.IDisplay.names(): - if six.PY2: - getargspec = inspect.getargspec - else: - getargspec = inspect.getfullargspec - arg_spec = getargspec(getattr(self.displayer, name)) # pylint: disable=deprecated-method + arg_spec = inspect.getfullargspec(getattr(self.displayer, name)) self.assertTrue("force_interactive" in arg_spec.args) @@ -402,12 +400,8 @@ class NoninteractiveDisplayTest(unittest.TestCase): for name in interfaces.IDisplay.names(): # pylint: disable=E1120 method = getattr(self.displayer, name) # asserts method accepts arbitrary keyword arguments - if six.PY2: - result = inspect.getargspec(method).keywords # pylint:deprecated-method - self.assertFalse(result is None) - else: - result = inspect.getfullargspec(method).varkw - self.assertFalse(result is None) + result = inspect.getfullargspec(method).varkw + self.assertFalse(result is None) class SeparateListInputTest(unittest.TestCase): diff --git a/certbot/tests/log_test.py b/certbot/tests/log_test.py index 76764e61b..088faa0fb 100644 --- a/certbot/tests/log_test.py +++ b/certbot/tests/log_test.py @@ -1,15 +1,11 @@ """Tests for certbot._internal.log.""" +import io import logging import logging.handlers import sys import time import unittest -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock -import six from acme import messages from certbot import errors @@ -19,6 +15,12 @@ from certbot.compat import filesystem from certbot.compat import os from certbot.tests import util as test_util +try: + import mock +except ImportError: # pragma: no cover + from unittest import mock + + class PreArgParseSetupTest(unittest.TestCase): """Tests for certbot._internal.log.pre_arg_parse_setup.""" @@ -75,7 +77,7 @@ class PostArgParseSetupTest(test_util.ConfigTestCase): self.devnull = open(os.devnull, 'w') from certbot._internal.log import ColoredStreamHandler - self.stream_handler = ColoredStreamHandler(six.StringIO()) + self.stream_handler = ColoredStreamHandler(io.StringIO()) from certbot._internal.log import MemoryHandler, TempHandler self.temp_handler = TempHandler() self.temp_path = self.temp_handler.path @@ -179,7 +181,7 @@ class ColoredStreamHandlerTest(unittest.TestCase): """Tests for certbot._internal.log.ColoredStreamHandler""" def setUp(self): - self.stream = six.StringIO() + self.stream = io.StringIO() self.stream.isatty = lambda: True self.logger = logging.getLogger() self.logger.setLevel(logging.DEBUG) @@ -213,7 +215,7 @@ class MemoryHandlerTest(unittest.TestCase): self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) self.msg = 'hi there' - self.stream = six.StringIO() + self.stream = io.StringIO() self.stream_handler = logging.StreamHandler(self.stream) from certbot._internal.log import MemoryHandler @@ -238,7 +240,7 @@ class MemoryHandlerTest(unittest.TestCase): def test_target_reset(self): self._test_log_debug() - new_stream = six.StringIO() + new_stream = io.StringIO() new_stream_handler = logging.StreamHandler(new_stream) self.handler.setTarget(new_stream_handler) self.handler.flush(force=True) @@ -325,7 +327,7 @@ class PostArgParseExceptHookTest(unittest.TestCase): def test_acme_error(self): # Get an arbitrary error code - acme_code = next(six.iterkeys(messages.ERROR_CODES)) + acme_code = next(iter(messages.ERROR_CODES)) def get_acme_error(msg): """Wraps ACME errors so the constructor takes only a msg.""" @@ -349,7 +351,7 @@ class PostArgParseExceptHookTest(unittest.TestCase): def _test_common(self, error_type, debug): """Returns the mocked logger and stderr output.""" - mock_err = six.StringIO() + mock_err = io.StringIO() def write_err(*args, **unused_kwargs): """Write error to mock_err.""" diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py index 5471248b4..ddd911c8d 100644 --- a/certbot/tests/main_test.py +++ b/certbot/tests/main_test.py @@ -4,6 +4,8 @@ from __future__ import print_function import datetime +from importlib import reload as reload_module +import io import itertools import json import shutil @@ -13,13 +15,7 @@ import traceback import unittest import josepy as jose -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock import pytz -import six -from six.moves import reload_module # pylint: disable=import-error from certbot import crypto_util from certbot import errors @@ -39,6 +35,12 @@ from certbot.compat import os from certbot.plugins import enhancements import certbot.tests.util as test_util +try: + import mock +except ImportError: # pragma: no cover + from unittest import mock + + CERT_PATH = test_util.vector_path('cert_512.pem') CERT = test_util.vector_path('cert_512.pem') @@ -598,7 +600,7 @@ class MainTest(test_util.ConfigTestCase): "Run the client with output streams mocked out" args = self.standard_args + args - toy_stdout = stdout if stdout else six.StringIO() + toy_stdout = stdout if stdout else io.StringIO() with mock.patch('certbot._internal.main.sys.stdout', new=toy_stdout): with mock.patch('certbot._internal.main.sys.stderr') as stderr: with mock.patch("certbot.util.atexit"): @@ -611,8 +613,8 @@ class MainTest(test_util.ConfigTestCase): self.assertEqual(1, mock_run.call_count) def test_version_string_program_name(self): - toy_out = six.StringIO() - toy_err = six.StringIO() + toy_out = io.StringIO() + toy_err = io.StringIO() with mock.patch('certbot._internal.main.sys.stdout', new=toy_out): with mock.patch('certbot._internal.main.sys.stderr', new=toy_err): try: @@ -820,7 +822,7 @@ class MainTest(test_util.ConfigTestCase): flags = ['--init', '--prepare', '--authenticators', '--installers'] for args in itertools.chain( *(itertools.combinations(flags, r) - for r in six.moves.range(len(flags)))): + for r in range(len(flags)))): self._call(['plugins'] + list(args)) @mock.patch('certbot._internal.main.plugins_disco') @@ -829,7 +831,7 @@ class MainTest(test_util.ConfigTestCase): ifaces = [] # type: List[interfaces.IPlugin] plugins = mock_disco.PluginsRegistry.find_all() - stdout = six.StringIO() + stdout = io.StringIO() with test_util.patch_get_utility_with_stdout(stdout=stdout): _, stdout, _, _ = self._call(['plugins'], stdout) @@ -849,7 +851,7 @@ class MainTest(test_util.ConfigTestCase): _, _, _ = directory, mode, strict raise errors.Error() - stdout = six.StringIO() + stdout = io.StringIO() with mock.patch('certbot.util.set_up_core_dir') as mock_set_up_core_dir: with test_util.patch_get_utility_with_stdout(stdout=stdout): mock_set_up_core_dir.side_effect = throw_error @@ -866,7 +868,7 @@ class MainTest(test_util.ConfigTestCase): ifaces = [] # type: List[interfaces.IPlugin] plugins = mock_disco.PluginsRegistry.find_all() - stdout = six.StringIO() + stdout = io.StringIO() with test_util.patch_get_utility_with_stdout(stdout=stdout): _, stdout, _, _ = self._call(['plugins', '--init'], stdout) @@ -884,7 +886,7 @@ class MainTest(test_util.ConfigTestCase): ifaces = [] # type: List[interfaces.IPlugin] plugins = mock_disco.PluginsRegistry.find_all() - stdout = six.StringIO() + stdout = io.StringIO() with test_util.patch_get_utility_with_stdout(stdout=stdout): _, stdout, _, _ = self._call(['plugins', '--init', '--prepare'], stdout) @@ -1033,7 +1035,7 @@ class MainTest(test_util.ConfigTestCase): mock_certr = mock.MagicMock() mock_key = mock.MagicMock(pem='pem_key') mock_client = mock.MagicMock() - stdout = six.StringIO() + stdout = io.StringIO() mock_client.obtain_certificate.return_value = (mock_certr, 'chain', mock_key, 'csr') diff --git a/certbot/tests/plugins/disco_test.py b/certbot/tests/plugins/disco_test.py index ed13544de..a97de24b9 100644 --- a/certbot/tests/plugins/disco_test.py +++ b/certbot/tests/plugins/disco_test.py @@ -8,7 +8,6 @@ try: except ImportError: # pragma: no cover from unittest import mock import pkg_resources -import six import zope.interface from certbot import errors @@ -56,7 +55,7 @@ class PluginEntryPointTest(unittest.TestCase): EP_SA: "sa", } - for entry_point, name in six.iteritems(names): + for entry_point, name in names.items(): self.assertEqual( name, PluginEntryPoint.entry_point_to_plugin_name(entry_point, with_prefix=False)) @@ -70,7 +69,7 @@ class PluginEntryPointTest(unittest.TestCase): self.ep3: "p3:ep3", } - for entry_point, name in six.iteritems(names): + for entry_point, name in names.items(): self.assertEqual( name, PluginEntryPoint.entry_point_to_plugin_name(entry_point, with_prefix=True)) diff --git a/certbot/tests/plugins/manual_test.py b/certbot/tests/plugins/manual_test.py index 7318783fd..f3c580517 100644 --- a/certbot/tests/plugins/manual_test.py +++ b/certbot/tests/plugins/manual_test.py @@ -6,7 +6,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock -import six from acme import challenges from certbot import errors @@ -53,7 +52,7 @@ class AuthenticatorTest(test_util.TempDirTestCase): self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): - self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) + self.assertTrue(isinstance(self.auth.more_info(), str)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), diff --git a/certbot/tests/plugins/null_test.py b/certbot/tests/plugins/null_test.py index 47708e340..dad5b270a 100644 --- a/certbot/tests/plugins/null_test.py +++ b/certbot/tests/plugins/null_test.py @@ -5,7 +5,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock -import six class InstallerTest(unittest.TestCase): @@ -16,7 +15,7 @@ class InstallerTest(unittest.TestCase): self.installer = Installer(config=mock.MagicMock(), name="null") def test_it(self): - self.assertTrue(isinstance(self.installer.more_info(), six.string_types)) + self.assertTrue(isinstance(self.installer.more_info(), str)) self.assertEqual([], self.installer.get_all_names()) self.assertEqual([], self.installer.supported_enhancements()) diff --git a/certbot/tests/plugins/standalone_test.py b/certbot/tests/plugins/standalone_test.py index 751b9d943..596cee622 100644 --- a/certbot/tests/plugins/standalone_test.py +++ b/certbot/tests/plugins/standalone_test.py @@ -10,7 +10,6 @@ try: except ImportError: # pragma: no cover from unittest import mock import OpenSSL.crypto # pylint: disable=unused-import -import six from acme import challenges from acme import standalone as acme_standalone # pylint: disable=unused-import @@ -91,7 +90,7 @@ class AuthenticatorTest(unittest.TestCase): self.auth.servers = mock.MagicMock() def test_more_info(self): - self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) + self.assertTrue(isinstance(self.auth.more_info(), str)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref(domain=None), diff --git a/certbot/tests/plugins/storage_test.py b/certbot/tests/plugins/storage_test.py index 4b0d1da83..2999d306e 100644 --- a/certbot/tests/plugins/storage_test.py +++ b/certbot/tests/plugins/storage_test.py @@ -33,7 +33,7 @@ class PluginStorageTest(test_util.ConfigTestCase): mock_open.side_effect = IOError self.plugin.storage.storagepath = os.path.join(self.config.config_dir, ".pluginstorage.json") - with mock.patch("six.moves.builtins.open", mock_open): + with mock.patch("builtins.open", mock_open): with mock.patch('certbot.compat.os.path.isfile', return_value=True): with mock.patch("certbot.reverter.util"): self.assertRaises(errors.PluginStorageError, diff --git a/certbot/tests/plugins/webroot_test.py b/certbot/tests/plugins/webroot_test.py index e57e09eae..e6fbd8e88 100644 --- a/certbot/tests/plugins/webroot_test.py +++ b/certbot/tests/plugins/webroot_test.py @@ -14,7 +14,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock -import six from acme import challenges from certbot import achallenges @@ -59,7 +58,7 @@ class AuthenticatorTest(unittest.TestCase): def test_more_info(self): more_info = self.auth.more_info() - self.assertTrue(isinstance(more_info, six.string_types)) + self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): @@ -83,7 +82,7 @@ class AuthenticatorTest(unittest.TestCase): self.assertTrue(self.achall.domain in call[0][0]) self.assertTrue(all( webroot in call[0][1] - for webroot in six.itervalues(self.config.webroot_map))) + for webroot in self.config.webroot_map.values())) self.assertEqual(self.config.webroot_map[self.achall.domain], self.path) @@ -100,7 +99,7 @@ class AuthenticatorTest(unittest.TestCase): self.assertTrue(self.achall.domain in call[0][0]) self.assertTrue(all( webroot in call[0][1] - for webroot in six.itervalues(self.config.webroot_map))) + for webroot in self.config.webroot_map.values())) @test_util.patch_get_utility() def test_new_webroot(self, mock_get_utility): diff --git a/certbot/tests/reporter_test.py b/certbot/tests/reporter_test.py index 7d03f1821..7a37f782e 100644 --- a/certbot/tests/reporter_test.py +++ b/certbot/tests/reporter_test.py @@ -1,12 +1,13 @@ """Tests for certbot._internal.reporter.""" +import io import sys import unittest + try: import mock except ImportError: # pragma: no cover from unittest import mock -import six class ReporterTest(unittest.TestCase): @@ -16,7 +17,7 @@ class ReporterTest(unittest.TestCase): self.reporter = reporter.Reporter(mock.MagicMock(quiet=False)) self.old_stdout = sys.stdout # type: ignore - sys.stdout = six.StringIO() + sys.stdout = io.StringIO() def tearDown(self): sys.stdout = self.old_stdout diff --git a/certbot/tests/reverter_test.py b/certbot/tests/reverter_test.py index d67aa431a..af01a9a1b 100644 --- a/certbot/tests/reverter_test.py +++ b/certbot/tests/reverter_test.py @@ -9,7 +9,6 @@ try: import mock except ImportError: # pragma: no cover from unittest import mock -import six from certbot import errors from certbot.compat import os @@ -156,7 +155,7 @@ class ReverterCheckpointLocalTest(test_util.ConfigTestCase): act_coms = get_undo_commands(self.config.temp_checkpoint_dir) - for a_com, com in six.moves.zip(act_coms, coms): + for a_com, com in zip(act_coms, coms): self.assertEqual(a_com, com) def test_bad_register_undo_command(self): diff --git a/certbot/tests/storage_test.py b/certbot/tests/storage_test.py index 914304cd4..abd496c8d 100644 --- a/certbot/tests/storage_test.py +++ b/certbot/tests/storage_test.py @@ -11,7 +11,6 @@ try: except ImportError: # pragma: no cover from unittest import mock import pytz -import six import certbot from certbot import errors @@ -286,7 +285,7 @@ class RenewableCertTests(BaseRenewableCertTest): self.assertEqual(self.test_rc.current_version("cert"), None) def test_latest_and_next_versions(self): - for ver in six.moves.range(1, 6): + for ver in range(1, 6): for kind in ALL_FOUR: self._write_out_kind(kind, ver) self.assertEqual(self.test_rc.latest_common_version(), 5) @@ -326,7 +325,7 @@ class RenewableCertTests(BaseRenewableCertTest): def test_update_link_to(self): - for ver in six.moves.range(1, 6): + for ver in range(1, 6): for kind in ALL_FOUR: self._write_out_kind(kind, ver) self.assertEqual(ver, self.test_rc.current_version(kind)) @@ -353,12 +352,12 @@ class RenewableCertTests(BaseRenewableCertTest): os.path.basename(self.test_rc.version("cert", 8))) def test_update_all_links_to_success(self): - for ver in six.moves.range(1, 6): + for ver in range(1, 6): for kind in ALL_FOUR: self._write_out_kind(kind, ver) self.assertEqual(ver, self.test_rc.current_version(kind)) self.assertEqual(self.test_rc.latest_common_version(), 5) - for ver in six.moves.range(1, 6): + for ver in range(1, 6): self.test_rc.update_all_links_to(ver) for kind in ALL_FOUR: self.assertEqual(ver, self.test_rc.current_version(kind)) @@ -396,11 +395,11 @@ class RenewableCertTests(BaseRenewableCertTest): self.assertEqual(self.test_rc.current_version(kind), 11) def test_has_pending_deployment(self): - for ver in six.moves.range(1, 6): + for ver in range(1, 6): for kind in ALL_FOUR: self._write_out_kind(kind, ver) self.assertEqual(ver, self.test_rc.current_version(kind)) - for ver in six.moves.range(1, 6): + for ver in range(1, 6): self.test_rc.update_all_links_to(ver) for kind in ALL_FOUR: self.assertEqual(ver, self.test_rc.current_version(kind)) @@ -498,7 +497,7 @@ class RenewableCertTests(BaseRenewableCertTest): # (to avoid instantiating parser) mock_rv.side_effect = lambda x: x - for ver in six.moves.range(1, 6): + for ver in range(1, 6): for kind in ALL_FOUR: self._write_out_kind(kind, ver) self.test_rc.update_all_links_to(3) @@ -529,7 +528,7 @@ class RenewableCertTests(BaseRenewableCertTest): self.test_rc.version("privkey", i)))) for kind in ALL_FOUR: - self.assertEqual(self.test_rc.available_versions(kind), list(six.moves.range(1, 9))) + self.assertEqual(self.test_rc.available_versions(kind), list(range(1, 9))) self.assertEqual(self.test_rc.current_version(kind), 3) # Test updating from latest version rather than old version self.test_rc.update_all_links_to(8) @@ -538,7 +537,7 @@ class RenewableCertTests(BaseRenewableCertTest): b'attempt', self.config)) for kind in ALL_FOUR: self.assertEqual(self.test_rc.available_versions(kind), - list(six.moves.range(1, 10))) + list(range(1, 10))) self.assertEqual(self.test_rc.current_version(kind), 8) with open(self.test_rc.version("fullchain", 9)) as f: self.assertEqual(f.read(), "last" + "attempt") diff --git a/certbot/tests/util_test.py b/certbot/tests/util_test.py index 7b510fbb6..18947c342 100644 --- a/certbot/tests/util_test.py +++ b/certbot/tests/util_test.py @@ -1,21 +1,22 @@ """Tests for certbot.util.""" import argparse import errno +from importlib import reload as reload_module +import io import sys import unittest -try: - import mock -except ImportError: # pragma: no cover - from unittest import mock -import six -from six.moves import reload_module # pylint: disable=import-error - from certbot import errors from certbot.compat import filesystem from certbot.compat import os import certbot.tests.util as test_util +try: + import mock +except ImportError: # pragma: no cover + from unittest import mock + + class EnvNoSnapForExternalCallsTest(unittest.TestCase): """Tests for certbot.util.env_no_snap_for_external_calls.""" @@ -265,11 +266,11 @@ class UniqueLineageNameTest(test_util.TempDirTestCase): def test_multiple(self): items = [] - for _ in six.moves.range(10): + for _ in range(10): items.append(self._call("wow")) f, name = items[-1] self.assertTrue(isinstance(f, file_type)) - self.assertTrue(isinstance(name, six.string_types)) + self.assertTrue(isinstance(name, str)) self.assertTrue("wow-0009.conf" in name) for f, _ in items: f.close() @@ -361,7 +362,7 @@ class AddDeprecatedArgumentTest(unittest.TestCase): def test_help(self): self._call("--old-option", 2) - stdout = six.StringIO() + stdout = io.StringIO() with mock.patch("sys.stdout", new=stdout): try: self.parser.parse_args(["-h"]) diff --git a/tests/letstest/multitester.py b/tests/letstest/multitester.py index 5ad1d8c15..83a92e6dc 100644 --- a/tests/letstest/multitester.py +++ b/tests/letstest/multitester.py @@ -39,11 +39,11 @@ import socket import sys import time import traceback +import urllib.error as urllib_error +import urllib.request as urllib_request import boto3 from botocore.exceptions import ClientError -from six.moves.urllib import error as urllib_error -from six.moves.urllib import request as urllib_request import yaml from fabric import Config From cf062f4c6dd7642cf124f5e7279fdc3f6ded063b Mon Sep 17 00:00:00 2001 From: Steffen Neumann Date: Tue, 9 Feb 2021 21:18:29 +0100 Subject: [PATCH 17/21] Fix ubuntu package name (#8654) Since Ubuntu 18.04 there is python3-certbot-apache which should be the recommended version. The Debian package names should probably be updated accordingly. --- certbot/docs/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot/docs/install.rst b/certbot/docs/install.rst index 4366080e0..8ae1c82f2 100644 --- a/certbot/docs/install.rst +++ b/certbot/docs/install.rst @@ -191,7 +191,7 @@ Optionally to install the Certbot Apache plugin, you can use: .. code-block:: shell - sudo apt-get install python-certbot-apache + sudo apt-get install python3-certbot-apache **Fedora** From c59775c3c069ce7106eca63e8f16294d99fbb021 Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Thu, 11 Feb 2021 00:17:51 +0100 Subject: [PATCH 18/21] Disable certbot-auto upgrade on RHEL-like systems (#8653) Fixes #8637 * Disable upgrade for RHEL-like systems * Remove letstest on Amazon Linux * Update changelog --- certbot/CHANGELOG.md | 1 + letsencrypt-auto-source/letsencrypt-auto | 1 + letsencrypt-auto-source/letsencrypt-auto.template | 1 + tests/letstest/auto_targets.yaml | 7 ------- tests/letstest/scripts/test_leauto_upgrades.sh | 2 +- 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 370282f38..eac783bdb 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -18,6 +18,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). which was needed to support SNI in TLS requests when using old versions of Python 2. * Certbot and all of its components no longer depend on the library `six`. +* The update of certbot-auto itself is now disabled on all RHEL-like systems. ### Fixed diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 14e71c615..224abaf01 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -806,6 +806,7 @@ elif [ -f /etc/mageia-release ]; then NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 # Run DeterminePythonVersion to decide on the basis of available Python versions # whether to use 2.x or 3.x on RedHat-like systems. # Then, revert LE_PYTHON to its previous state. diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index 783268571..70b75176e 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -328,6 +328,7 @@ elif [ -f /etc/mageia-release ]; then NO_SELF_UPGRADE=1 elif [ -f /etc/redhat-release ]; then DEPRECATED_OS=1 + NO_SELF_UPGRADE=1 # Run DeterminePythonVersion to decide on the basis of available Python versions # whether to use 2.x or 3.x on RedHat-like systems. # Then, revert LE_PYTHON to its previous state. diff --git a/tests/letstest/auto_targets.yaml b/tests/letstest/auto_targets.yaml index 164580e86..01d410227 100644 --- a/tests/letstest/auto_targets.yaml +++ b/tests/letstest/auto_targets.yaml @@ -57,10 +57,3 @@ targets: type: centos virt: hvm user: centos - #----------------------------------------------------------------------------- - # Amazon Linux - - ami: ami-0ff8a91507f77f867 - name: amazon - type: centos - virt: hvm - user: ec2-user diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index d0b941736..407a865f2 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -156,7 +156,7 @@ fi # Finally, we check if our local server received more requests. Over time, # we'll move more and more OSes into this case until it this is the expected # behavior on all systems. -if [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue; then +if [ -f /etc/redhat-release ]; then if ! diff "$LOG_FILE" "$PREVIOUS_LOG_FILE" ; then echo our local server received unexpected requests exit 1 From c0eccdd35845161ced2ba56f77131c05ae2634fd Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Sat, 13 Feb 2021 01:14:46 +0100 Subject: [PATCH 19/21] Deprecate certbot-auto specific flags (#8641) This PR deprecates the certbot-auto specific CLI flags, in the perspective of removing them in a future release as said in #8483. * Deprecate certbot-auto specific flags * Update changelog * Clean tests Co-authored-by: Brad Warren --- certbot/CHANGELOG.md | 2 ++ certbot/certbot/_internal/cli/__init__.py | 27 +++++-------------- .../certbot/_internal/cli/cli_constants.py | 8 +++++- certbot/tests/cli_test.py | 4 --- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index eac783bdb..1067c3b92 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -10,6 +10,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Changed +* CLI flags `--os-packages-only`, `--no-self-upgrade`, `--no-bootstrap` and `--no-permissions-check`, + which are related to certbot-auto, are deprecated and will be removed in a future release. * Certbot no longer conditionally depends on an external mock module. Certbot's test API will continue to use it if it is available for backwards compatibility, however, this behavior has been deprecated and will be removed diff --git a/certbot/certbot/_internal/cli/__init__.py b/certbot/certbot/_internal/cli/__init__.py index c69bb3564..8d2f7c329 100644 --- a/certbot/certbot/_internal/cli/__init__.py +++ b/certbot/certbot/_internal/cli/__init__.py @@ -249,27 +249,6 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): default=flag_default("duplicate"), help="Allow making a certificate lineage that duplicates an existing one " "(both can be renewed in parallel)") - helpful.add( - "automation", "--os-packages-only", action="store_true", - default=flag_default("os_packages_only"), - help="(certbot-auto only) install OS package dependencies and then stop") - helpful.add( - "automation", "--no-self-upgrade", action="store_true", - default=flag_default("no_self_upgrade"), - help="(certbot-auto only) prevent the certbot-auto script from" - " upgrading itself to newer released versions (default: Upgrade" - " automatically)") - helpful.add( - "automation", "--no-bootstrap", action="store_true", - default=flag_default("no_bootstrap"), - help="(certbot-auto only) prevent the certbot-auto script from" - " installing OS-level dependencies (default: Prompt to install " - " OS-wide dependencies, but exit if the user says 'No')") - helpful.add( - "automation", "--no-permissions-check", action="store_true", - default=flag_default("no_permissions_check"), - help="(certbot-auto only) skip the check on the file system" - " permissions of the certbot-auto script") helpful.add( ["automation", "renew", "certonly", "run"], "-q", "--quiet", dest="quiet", action="store_true", @@ -451,6 +430,12 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): default=flag_default("autorenew"), dest="autorenew", help="Disable auto renewal of certificates.") + # Deprecated arguments + helpful.add_deprecated_argument("--os-packages-only", 0) + helpful.add_deprecated_argument("--no-self-upgrade", 0) + helpful.add_deprecated_argument("--no-bootstrap", 0) + helpful.add_deprecated_argument("--no-permissions-check", 0) + # Populate the command line parameters for new style enhancements enhancements.populate_cli(helpful.add) diff --git a/certbot/certbot/_internal/cli/cli_constants.py b/certbot/certbot/_internal/cli/cli_constants.py index dc199e152..bd25f9bee 100644 --- a/certbot/certbot/_internal/cli/cli_constants.py +++ b/certbot/certbot/_internal/cli/cli_constants.py @@ -109,4 +109,10 @@ VAR_MODIFIERS = {"account": {"server",}, # This is a list of all CLI options that we have ever deprecated. It lets us # opt out of the default detection, which can interact strangely with option # deprecation. See https://github.com/certbot/certbot/issues/8540 for more info. -DEPRECATED_OPTIONS = {"manual_public_ip_logging_ok",} +DEPRECATED_OPTIONS = { + "manual_public_ip_logging_ok", + "os_packages_only", + "no_self_upgrade", + "no_bootstrap", + "no_permissions_check", +} diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py index 2ec798a08..fca2b3e3e 100644 --- a/certbot/tests/cli_test.py +++ b/certbot/tests/cli_test.py @@ -480,10 +480,6 @@ class ParseTest(unittest.TestCase): for topic in ['all', 'plugins', 'dns-route53']: self.assertFalse('certbot-route53:auth' in self._help_output([help_flag, topic])) - def test_no_permissions_check_accepted(self): - namespace = self.parse(["--no-permissions-check"]) - self.assertTrue(namespace.no_permissions_check) - class DefaultTest(unittest.TestCase): """Tests for certbot._internal.cli._Default.""" From ef265eccaf125a51a8c260d28e2f501e1c3111dc Mon Sep 17 00:00:00 2001 From: Mads Jensen Date: Sun, 21 Feb 2021 23:23:42 +0100 Subject: [PATCH 20/21] Remove import fallback for collections.abc (#8674) --- acme/acme/messages.py | 8 +------- certbot/certbot/_internal/plugins/disco.py | 7 +------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 038cda04b..44ecb143c 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -1,5 +1,6 @@ """ACME protocol messages.""" import json +from collections.abc import Hashable import josepy as jose @@ -10,13 +11,6 @@ from acme import jws from acme import util from acme.mixins import ResourceMixin -try: - from collections.abc import Hashable -except ImportError: # pragma: no cover - from collections import Hashable - - - OLD_ERROR_PREFIX = "urn:acme:error:" ERROR_PREFIX = "urn:ietf:params:acme:error:" diff --git a/certbot/certbot/_internal/plugins/disco.py b/certbot/certbot/_internal/plugins/disco.py index dbcecb067..d19fdd3ef 100644 --- a/certbot/certbot/_internal/plugins/disco.py +++ b/certbot/certbot/_internal/plugins/disco.py @@ -3,6 +3,7 @@ import collections import itertools import logging import sys +from collections.abc import Mapping import pkg_resources import zope.interface @@ -14,12 +15,6 @@ from certbot import interfaces from certbot._internal import constants from certbot.compat import os -try: - # Python 3.3+ - from collections.abc import Mapping -except ImportError: # pragma: no cover - from collections import Mapping - logger = logging.getLogger(__name__) PREFIX_FREE_DISTRIBUTIONS = [ From 0f3f07b5cb3bf1d2c3d8834a83022fd11d7566fc Mon Sep 17 00:00:00 2001 From: Mads Jensen Date: Sun, 21 Feb 2021 23:34:56 +0100 Subject: [PATCH 21/21] Removed backport of unittest.assertLogs (#8673) * Removed backport of unittest.assertLogs * Update parser_test.py --- certbot-nginx/tests/test_log_util.py | 125 --------------------------- certbot-nginx/tests/test_util.py | 3 +- 2 files changed, 1 insertion(+), 127 deletions(-) delete mode 100644 certbot-nginx/tests/test_log_util.py diff --git a/certbot-nginx/tests/test_log_util.py b/certbot-nginx/tests/test_log_util.py deleted file mode 100644 index 7aebf2151..000000000 --- a/certbot-nginx/tests/test_log_util.py +++ /dev/null @@ -1,125 +0,0 @@ -"""Backport for `TestCase.assertLogs()`. - -Most of the idea and code are from CPython implementation. -https://github.com/python/cpython/blob/b76518d43fb82ed9e5d27025d18c90a23d525c90/Lib/unittest/case.py -""" -import logging -import collections - -__all__ = ['AssertLogsMixin'] - -LoggingWatcher = collections.namedtuple('LoggingWatcher', ['records', 'output']) - - -class CapturingHandler(logging.Handler): - """ - A logging handler capturing all (raw and formatted) logging output. - """ - - def __init__(self): - super(CapturingHandler, self).__init__() - self.watcher = LoggingWatcher([], []) - - def flush(self): - pass - - def emit(self, record): - self.watcher.records.append(record) - self.watcher.output.append(self.format(record)) - - - -class AssertLogsContext(object): - """ - A context manager used to implement `TestCase.assertLogs()`. - """ - - LOGGING_FORMAT = '%(levelname)s:%(name)s:%(message)s' - - def __init__(self, test_case, logger_name, level): - self.test_case = test_case - - self.logger_name = logger_name - self.logger_states = None - self.logger = None - - if level: - # pylint: disable=protected-access,no-member - try: - # In Python 3.x - name_to_level = logging._nameToLevel # type: ignore - except AttributeError: - # In Python 2.7 - name_to_level = logging._levelNames # type: ignore - - self.level = name_to_level.get(level, level) - else: - self.level = logging.INFO - - self.watcher = None - - def _save_logger_states(self): - self.logger_states = (self.logger.handlers[:], self.logger.level, self.logger.propagate) - - def _restore_logger_states(self): - self.logger.handlers, self.logger.level, self.logger.propagate = self.logger_states - - def __enter__(self): - if isinstance(self.logger_name, logging.Logger): - self.logger = self.logger_name - else: - self.logger = logging.getLogger(self.logger_name) - - formatter = logging.Formatter(self.LOGGING_FORMAT) - - handler = CapturingHandler() - handler.setFormatter(formatter) - - self._save_logger_states() - self.logger.handlers = [handler] - self.logger.setLevel(self.level) - self.logger.propagate = False - - self.watcher = handler.watcher - return handler.watcher - - def __exit__(self, exc_type, exc_value, tb): - self._restore_logger_states() - - if exc_type is not None: - # let unexpected exceptions pass through - return - - if not self.watcher.records: - self._raiseFailure( - "no logs of level {} or higher triggered on {}" - .format(logging.getLevelName(self.level), self.logger.name)) - - def _raiseFailure(self, message): - message = self.test_case._formatMessage(None, message) # pylint: disable=protected-access - raise self.test_case.failureException(message) - - -class AssertLogsMixin(object): - """ - A mixin that implements `TestCase.assertLogs()`. - """ - - def assertLogs(self, logger=None, level=None): - """Fail unless a log message of level *level* or higher is emitted - on *logger_name* or its children. If omitted, *level* defaults to - INFO and *logger* defaults to the root logger. - This method must be used as a context manager, and will yield - a recording object with two attributes: `output` and `records`. - At the end of the context manager, the `output` attribute will - be a list of the matching formatted log messages and the - `records` attribute will be a list of the corresponding LogRecord - objects. - Example:: - with self.assertLogs('foo', level='INFO') as cm: - logging.getLogger('foo').info('first message') - logging.getLogger('foo.bar').error('second message') - self.assertEqual(cm.output, ['INFO:foo:first message', - 'ERROR:foo.bar:second message']) - """ - return AssertLogsContext(self, logger, level) diff --git a/certbot-nginx/tests/test_util.py b/certbot-nginx/tests/test_util.py index f545dc5bc..ee53e8e1e 100644 --- a/certbot-nginx/tests/test_util.py +++ b/certbot-nginx/tests/test_util.py @@ -17,10 +17,9 @@ from certbot.plugins import common from certbot.tests import util as test_util from certbot_nginx._internal import configurator from certbot_nginx._internal import nginxparser -import test_log_util -class NginxTest(test_log_util.AssertLogsMixin, test_util.ConfigTestCase): +class NginxTest(test_util.ConfigTestCase): def setUp(self): super(NginxTest, self).setUp()