Compare commits

...

27 Commits

Author SHA1 Message Date
Brad Warren
3af4944034 remove outdated python 2 oldest constraints 2021-01-07 15:06:14 -08:00
Brad Warren
a581287654 Pin asn1crypto 2021-01-07 14:49:40 -08:00
Brad Warren
cc2be83b00 set basepython for a nicer error message 2021-01-07 13:35:28 -08:00
Brad Warren
18d22af9ba update min six version 2021-01-07 13:29:45 -08:00
Brad Warren
a21a4a694f properly pin asn1crypto 2021-01-07 12:24:06 -08:00
Brad Warren
bf65f1de92 use Python 3.6 for oldest integration tests 2021-01-07 11:44:12 -08:00
Brad Warren
ef3761d250 use Python 3.6 in the oldest tests 2021-01-07 11:29:56 -08:00
Brad Warren
c1451c0aa5 quote tox env name 2021-01-07 11:22:28 -08:00
Brad Warren
18ebfb74d5 update min parsedatetime version 2021-01-07 10:47:39 -08:00
Brad Warren
50480d43e9 update min configobj version 2021-01-06 16:24:40 -08:00
Brad Warren
d84bb7b57b clarify oldest comment 2021-01-06 16:19:26 -08:00
Brad Warren
524069035b expand oldest_constraints comments 2021-01-06 16:19:26 -08:00
Brad Warren
48161458b6 update transitive asn1crypto dependency
This fixes tests on macOS. See
https://github.com/pyca/pyopenssl/issues/874.
2021-01-06 16:19:26 -08:00
Brad Warren
db8249c7c7 update cffi, pyparsing, and idna 2021-01-06 16:19:26 -08:00
Brad Warren
9448078f6f upgrade setuptools and pyopenssl 2021-01-06 12:55:17 -08:00
Brad Warren
aba9fae6e7 remove run_oldest_tests.sh 2021-01-06 12:35:36 -08:00
Brad Warren
6e1ab76c65 update min cryptography version 2021-01-06 12:33:43 -08:00
Brad Warren
d85ff7c330 remove py27 from oldest name 2021-01-06 12:29:11 -08:00
Brad Warren
c44a5a7701 Fix plugin param type (#8578)
* Fix plugin param type in updater

The command used to do this was:

sed -i 's/\(:type .*plugins:\) `list` of `str`/\1 certbot._internal.plugins.disco.PluginsRegistry/g' certbot/certbot/_internal/updater.py

* fix plugin param type in main.py

The command used to do this was:

sed -i 's/\(:type .*plugins:\) `list` of `str`/\1 plugins_disco.PluginsRegistry/g' certbot/certbot/_internal/main.py
2021-01-06 18:26:01 +11:00
Brad Warren
6e1d042f76 mock out plugin discovery in test_plugins (#8576) 2021-01-06 18:14:43 +11:00
Brad Warren
daf989fc21 skip meta creation to speed up tests (#8575) 2021-01-06 17:47:25 +11:00
ohemorange
5c3fd7d9ee Merge pull request #8573 from certbot/candidate-1.11.0
Update files from 1.11.0 release
2021-01-05 13:25:11 -08:00
Brad Warren
fc6c238bf9 Bump version to 1.12.0 2021-01-05 09:51:11 -08:00
Brad Warren
a49b84d64e Add contents to certbot/CHANGELOG.md for next version 2021-01-05 09:51:10 -08:00
Brad Warren
7567e8d8db Release 1.11.0 2021-01-05 09:51:09 -08:00
Brad Warren
02a5d000cb Update changelog for 1.11.0 release 2021-01-05 09:37:05 -08:00
Adrien Ferrand
98fb9d2d93 Forbid os.readlink() (#8472)
The method `os.readlink()` has a significant behavior change with Python 3.8+ on Windows. 

Starting with this version, it will return the resolved path in its "extended-style" form unconditionally, a form which allows to use more than 259 characters in a Windows path, and its string representation is prepended with "\\\\?\\".

See https://docs.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#maximum-path-length-limitation

Problem is that `os.readlink()` does it for any path, including paths that could be represented with the normal form. As a consequence, any string comparison with a path provided in the normal form will fail even if it represents the same path. This makes Certbot partially break on Windows with Python 3.8.

My proposition in this PR is to forbid `os.readlink()`, and provide `certbot.compat.filesystem.readlink()` which serves the same purpose at resolving the pointed path of a link, and has a consistent behavior over supported Python versions.

* Forbid os.readlink()

* Use readlink

* Raise error with long paths on Windows

* Add unit tests

* Update certbot/certbot/compat/filesystem.py

Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2021-01-05 09:34:12 -08:00
45 changed files with 310 additions and 267 deletions

View File

@@ -22,15 +22,19 @@ jobs:
TOXENV: py37
CERTBOT_NO_PIN: 1
linux-boulder-v1-integration-certbot-oldest:
PYTHON_VERSION: 3.6
TOXENV: integration-certbot-oldest
ACME_SERVER: boulder-v1
linux-boulder-v2-integration-certbot-oldest:
PYTHON_VERSION: 3.6
TOXENV: integration-certbot-oldest
ACME_SERVER: boulder-v2
linux-boulder-v1-integration-nginx-oldest:
PYTHON_VERSION: 3.6
TOXENV: integration-nginx-oldest
ACME_SERVER: boulder-v1
linux-boulder-v2-integration-nginx-oldest:
PYTHON_VERSION: 3.6
TOXENV: integration-nginx-oldest
ACME_SERVER: boulder-v2
linux-boulder-v1-py27-integration:

View File

@@ -26,10 +26,12 @@ jobs:
TOXENV: integration-certbot
linux-oldest-tests-1:
IMAGE_NAME: ubuntu-18.04
TOXENV: py27-{acme,apache,apache-v2,certbot}-oldest
PYTHON_VERSION: 3.6
TOXENV: '{acme,apache,apache-v2,certbot}-oldest'
linux-oldest-tests-2:
IMAGE_NAME: ubuntu-18.04
TOXENV: py27-{dns,nginx}-oldest
PYTHON_VERSION: 3.6
TOXENV: '{dns,nginx}-oldest'
linux-py27:
IMAGE_NAME: ubuntu-18.04
PYTHON_VERSION: 2.7

View File

@@ -45,11 +45,7 @@ steps:
export TARGET_BRANCH="`echo "${BUILD_SOURCEBRANCH}" | sed -E 's!refs/(heads|tags)/!!g'`"
[ -z "${SYSTEM_PULLREQUEST_TARGETBRANCH}" ] || export TARGET_BRANCH="${SYSTEM_PULLREQUEST_TARGETBRANCH}"
env
if [[ "${TOXENV}" == *"oldest"* ]]; then
tools/run_oldest_tests.sh
else
python -m tox
fi
python -m tox
env:
AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)

View File

@@ -5,25 +5,22 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Please update tox.ini when modifying dependency version requirements
install_requires = [
# load_pem_private/public_key (>=0.6)
# rsa_recover_prime_factors (>=0.8)
'cryptography>=1.2.3',
'cryptography>=2.1.4',
# formerly known as acme.jose:
# 1.1.0+ is required to avoid the warnings described at
# https://github.com/certbot/josepy/issues/13.
'josepy>=1.1.0',
# Connection.set_tlsext_host_name (>=0.13) + matching Xenial requirements (>=0.15.1)
'PyOpenSSL>=0.15.1',
'PyOpenSSL>=17.3.0',
'pyrfc3339',
'pytz',
'requests[security]>=2.6.0', # security extras added in 2.4.1
'requests-toolbelt>=0.3.0',
'setuptools',
'six>=1.9.0', # needed for python_2_unicode_compatible
'setuptools>=39.0.1',
'six>=1.11.0',
]
setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2'))

View File

@@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
@@ -13,7 +13,7 @@ install_requires = [
'acme>=0.29.0',
'certbot>=1.6.0',
'python-augeas',
'setuptools',
'setuptools>=39.0.1',
'zope.component',
'zope.interface',
]

View File

@@ -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.10.1"
LE_AUTO_VERSION="1.11.0"
BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -804,6 +804,7 @@ elif [ -f /etc/mageia-release ]; then
# Mageia has both /etc/mageia-release and /etc/redhat-release
DEPRECATED_OS=1
elif [ -f /etc/redhat-release ]; then
DEPRECATED_OS=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.
@@ -836,12 +837,7 @@ elif [ -f /etc/redhat-release ]; then
INTERACTIVE_BOOTSTRAP=1
fi
Bootstrap() {
BootstrapMessage "Legacy RedHat-based OSes that will use Python3"
BootstrapRpmPython3Legacy
}
USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION"
# Try now to enable SCL rh-python36 for systems already bootstrapped
# NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto
@@ -860,18 +856,7 @@ elif [ -f /etc/redhat-release ]; then
fi
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
Bootstrap() {
BootstrapMessage "RedHat-based OSes that will use Python3"
BootstrapRpmPython3
}
USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
else
Bootstrap() {
BootstrapMessage "RedHat-based OSes"
BootstrapRpmCommon
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
fi
fi
@@ -889,10 +874,7 @@ elif uname | grep -iq FreeBSD ; then
elif uname | grep -iq Darwin ; then
DEPRECATED_OS=1
elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
Bootstrap() {
ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
DEPRECATED_OS=1
elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
DEPRECATED_OS=1
else
@@ -1493,18 +1475,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==1.10.1 \
--hash=sha256:011ac980fa21b9f29e02c9b8d8b86e8a4bf4670b51b6ad91656e401e9d2d2231 \
--hash=sha256:0d9ee3fc09e0d03b2d1b1f1c4916e61ecfc6904b4216ddef4e6a5ca1424d9cb7
acme==1.10.1 \
--hash=sha256:752d598e54e98ad1e874de53fd50c61044f1b566d6deb790db5676ce9c573546 \
--hash=sha256:fcbb559aedc96b404edf593e78517dcd7291984d5a37036c3fc77f3c5c122fd8
certbot-apache==1.10.1 \
--hash=sha256:f077b4b7f166627ef5e0921fe7cde57700670fc86e9ad9dbdfaf2c573cc0f2fa \
--hash=sha256:97ed637b4c7b03820db6c69aa90145dc989933351d46a3d62baf6b71674f0a10
certbot-nginx==1.10.1 \
--hash=sha256:7c36459021f8a1ec3b6c062e4c4fc866bfaa1dbf26ccd29e043dd6848003be08 \
--hash=sha256:c0bbeccf85f46b728fd95e6bb8c2649d32d3383d7f47ea4b9c312d12bf04d2f0
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
UNLIKELY_EOF
# -------------------------------------------------------------------------

View File

@@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
install_requires = [
'certbot',

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'cloudflare>=1.5.1',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,14 +6,14 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'python-digitalocean>=1.11',
'setuptools',
'six',
'setuptools>=39.0.1',
'six>=1.11.0',
'zope.interface',
]

View File

@@ -6,12 +6,12 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,12 +6,12 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Please update tox.ini when modifying dependency version requirements
install_requires = [
'dns-lexicon>=2.1.22',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,14 +6,14 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'google-api-python-client>=1.5.5',
'oauth2client>=4.0',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
# already a dependency of google-api-python-client, but added for consistency
'httplib2'

View File

@@ -6,12 +6,12 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Please update tox.ini when modifying dependency version requirements
install_requires = [
'dns-lexicon>=2.2.3',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'dnspython',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,13 +6,13 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'boto3',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -6,12 +6,12 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Please update tox.ini when modifying dependency version requirements
install_requires = [
'dns-lexicon>=2.1.23',
'setuptools',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -5,16 +5,16 @@ from setuptools import __version__ as setuptools_version
from setuptools import find_packages
from setuptools import setup
version = '1.11.0.dev0'
version = '1.12.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'acme>=1.4.0',
'certbot>=1.6.0',
'PyOpenSSL',
'pyparsing>=1.5.5', # Python3 support
'setuptools',
'PyOpenSSL>=17.3.0',
'pyparsing>=2.2.0',
'setuptools>=39.0.1',
'zope.interface',
]

View File

@@ -2,7 +2,23 @@
Certbot adheres to [Semantic Versioning](https://semver.org/).
## 1.11.0 - master
## 1.12.0 - master
### Added
*
### Changed
*
### Fixed
*
More details about these changes can be found on our GitHub repo.
## 1.11.0 - 2021-01-05
### Added

View File

@@ -3,7 +3,7 @@ import warnings
import sys
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '1.11.0.dev0'
__version__ = '1.12.0.dev0'
if sys.version_info[0] == 2:
warnings.warn(

View File

@@ -20,6 +20,7 @@ from certbot import interfaces
from certbot import util
from certbot._internal import constants
from certbot.compat import os
from certbot.compat import filesystem
logger = logging.getLogger(__name__)
@@ -324,7 +325,7 @@ class AccountFileStorage(interfaces.AccountStorage):
if server_path in reused_servers:
next_server_path = reused_servers[server_path]
next_dir_path = link_func(next_server_path)
if os.path.islink(next_dir_path) and os.readlink(next_dir_path) == dir_path:
if os.path.islink(next_dir_path) and filesystem.readlink(next_dir_path) == dir_path:
possible_next_link = True
server_path = next_server_path
dir_path = next_dir_path
@@ -332,7 +333,7 @@ class AccountFileStorage(interfaces.AccountStorage):
# if there's not a next one up to delete, then delete me
# and whatever I link to
while os.path.islink(dir_path):
target = os.readlink(dir_path)
target = filesystem.readlink(dir_path)
os.unlink(dir_path)
dir_path = target

View File

@@ -666,7 +666,7 @@ def unregister(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -706,7 +706,7 @@ def register(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None` or a string indicating and error
:rtype: None or str
@@ -736,7 +736,7 @@ def update_account(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None` or a string indicating and error
:rtype: None or str
@@ -813,7 +813,7 @@ def install(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -896,7 +896,7 @@ def plugins_cmd(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -935,7 +935,7 @@ def enhance(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -994,7 +994,7 @@ def rollback(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1012,7 +1012,7 @@ def update_symlinks(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1030,7 +1030,7 @@ def rename(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1048,7 +1048,7 @@ def delete(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1064,7 +1064,7 @@ def certificates(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1081,7 +1081,7 @@ def revoke(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None` or string indicating error in case of error
:rtype: None or str
@@ -1126,7 +1126,7 @@ def run(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1213,7 +1213,7 @@ def renew_cert(config, plugins, lineage):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:param lineage: Certificate lineage object
:type lineage: storage.RenewableCert
@@ -1258,7 +1258,7 @@ def certonly(config, plugins):
:type config: interfaces.IConfig
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None
@@ -1308,7 +1308,7 @@ def renew(config, unused_plugins):
:type config: interfaces.IConfig
:param unused_plugins: List of plugins (deprecated)
:type unused_plugins: `list` of `str`
:type unused_plugins: plugins_disco.PluginsRegistry
:returns: `None`
:rtype: None

View File

@@ -214,7 +214,7 @@ def get_link_target(link):
"""
try:
target = os.readlink(link)
target = filesystem.readlink(link)
except OSError:
raise errors.CertStorageError(
"Expected {0} to be a symlink".format(link))
@@ -223,6 +223,7 @@ def get_link_target(link):
target = os.path.join(os.path.dirname(link), target)
return os.path.abspath(target)
def _write_live_readme_to(readme_path, is_base_dir=False):
prefix = ""
if is_base_dir:
@@ -665,7 +666,7 @@ class RenewableCert(interfaces.RenewableCert):
current_link = getattr(self, kind)
if os.path.lexists(current_link):
os.unlink(current_link)
os.symlink(os.readlink(previous_link), current_link)
os.symlink(filesystem.readlink(previous_link), current_link)
for _, link in previous_symlinks:
if os.path.exists(link):
@@ -846,7 +847,7 @@ class RenewableCert(interfaces.RenewableCert):
link = getattr(self, kind)
filename = "{0}{1}.pem".format(kind, version)
# Relative rather than absolute target directory
target_directory = os.path.dirname(os.readlink(link))
target_directory = os.path.dirname(filesystem.readlink(link))
# TODO: it could be safer to make the link first under a temporary
# filename, then unlink the old link, then rename the new link
# to the old link; this ensures that this process is able to
@@ -1121,7 +1122,7 @@ class RenewableCert(interfaces.RenewableCert):
# The behavior below keeps the prior key by creating a new
# symlink to the old key or the target of the old key symlink.
if os.path.islink(old_privkey):
old_privkey = os.readlink(old_privkey)
old_privkey = filesystem.readlink(old_privkey)
else:
old_privkey = "privkey{0}.pem".format(prior_version)
logger.debug("Writing symlink to old private key, %s.", old_privkey)

View File

@@ -18,7 +18,7 @@ def run_generic_updaters(config, lineage, plugins):
:type lineage: storage.RenewableCert
:param plugins: List of plugins
:type plugins: `list` of `str`
:type plugins: certbot._internal.plugins.disco.PluginsRegistry
:returns: `None`
:rtype: None

View File

@@ -4,6 +4,7 @@ from __future__ import absolute_import
import errno
import os # pylint: disable=os-module-forbidden
import stat
import sys
from acme.magic_typing import List
@@ -361,7 +362,8 @@ def realpath(file_path):
"""
original_path = file_path
if POSIX_MODE:
# Since Python 3.8, os.path.realpath also resolves symlinks on Windows.
if POSIX_MODE or sys.version_info >= (3, 8):
path = os.path.realpath(file_path)
if os.path.islink(path):
# If path returned by realpath is still a link, it means that it failed to
@@ -383,8 +385,36 @@ def realpath(file_path):
return os.path.abspath(file_path)
def readlink(link_path):
# type: (str) -> str
"""
Return a string representing the path to which the symbolic link points.
:param str link_path: The symlink path to resolve
:return: The path the symlink points to
:returns: str
:raise: ValueError if a long path (260> characters) is encountered on Windows
"""
path = os.readlink(link_path)
if POSIX_MODE or not path.startswith('\\\\?\\'):
return path
# At this point, we know we are on Windows and that the path returned uses
# the extended form which is done for all paths in Python 3.8+
# Max length of a normal path is 260 characters on Windows, including the non printable
# termination character "<NUL>". The termination character is not included in Python
# strings, giving a max length of 259 characters, + 4 characters for the extended form
# prefix, to an effective max length 263 characters on a string representing a normal path.
if len(path) < 264:
return path[4:]
raise ValueError("Long paths are not supported by Certbot on Windows.")
# On Windows is_executable run from an unprivileged shell may claim that a path is
# executable when it is excutable only if run from a privileged shell. This result
# executable when it is executable only if run from a privileged shell. This result
# is due to the fact that GetEffectiveRightsFromAcl calculate effective rights
# without taking into consideration if the target user has currently required the
# elevated privileges or not. However this is not a problem since certbot always

View File

@@ -152,3 +152,14 @@ def fstat(*unused_args, **unused_kwargs):
raise RuntimeError('Usage of os.fstat() is forbidden. '
'Use certbot.compat.filesystem functions instead '
'(eg. has_min_permissions, has_same_ownership).')
# Method os.readlink has a significant behavior change with Python 3.8+. Starting
# with this version, it will return the resolved path in its "extended-style" form
# unconditionally, which allows to use more than 259 characters, and its string
# representation is prepended with "\\?\". Problem is that it does it for any path,
# and will make equality comparison fail with paths that will use the simple form.
def readlink(*unused_args, **unused_kwargs):
"""Method os.readlink() is forbidden"""
raise RuntimeError('Usage of os.readlink() is forbidden. '
'Use certbot.compat.filesystem.realpath() instead.')

View File

@@ -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.10.1
"". (default: CertbotACMEClient/1.11.0
(certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX
Installer/YYY (SUBCOMMAND; flags: FLAGS)
Py/major.minor.patchlevel). The flags encoded in the
@@ -539,8 +539,8 @@ dns-cloudxns:
CloudXNS credentials INI file. (default: None)
dns-digitalocean:
Obtain certs using a DNS TXT record (if you are using DigitalOcean for
DNS).
Obtain certificates using a DNS TXT record (if you are using DigitalOcean
for DNS).
--dns-digitalocean-propagation-seconds DNS_DIGITALOCEAN_PROPAGATION_SECONDS
The number of seconds to wait for DNS to propagate
@@ -601,7 +601,8 @@ dns-google:
therequired permissions.) (default: None)
dns-linode:
Obtain certs using a DNS TXT record (if you are using Linode for DNS).
Obtain certificates using a DNS TXT record (if you are using Linode for
DNS).
--dns-linode-propagation-seconds DNS_LINODE_PROPAGATION_SECONDS
The number of seconds to wait for DNS to propagate

View File

@@ -40,16 +40,16 @@ install_requires = [
# saying so here causes a runtime error against our temporary fork of 0.9.3
# in which we added 2.6 support (see #2243), so we relax the requirement.
'ConfigArgParse>=0.9.3',
'configobj',
'cryptography>=1.2.3', # load_pem_x509_certificate
'configobj>=5.0.6',
'cryptography>=2.1.4',
'distro>=1.0.1',
# 1.1.0+ is required to avoid the warnings described at
# https://github.com/certbot/josepy/issues/13.
'josepy>=1.1.0',
'parsedatetime>=1.3', # Calendar.parseDT
'parsedatetime>=2.4',
'pyrfc3339',
'pytz',
'setuptools',
'setuptools>=39.0.1',
'zope.component',
'zope.interface',
]

View File

@@ -113,11 +113,16 @@ class AccountFileStorageTest(test_util.ConfigTestCase):
from certbot._internal.account import Account
new_authzr_uri = "hi"
meta = Account.Meta(
creation_host="test.example.org",
creation_dt=datetime.datetime(
2021, 1, 5, 14, 4, 10, tzinfo=pytz.UTC))
self.acc = Account(
regr=messages.RegistrationResource(
uri=None, body=messages.Registration(),
new_authzr_uri=new_authzr_uri),
key=KEY)
key=KEY,
meta=meta)
self.mock_client = mock.MagicMock()
self.mock_client.directory.new_authz = new_authzr_uri

View File

@@ -99,7 +99,7 @@ class UpdateLiveSymlinksTest(BaseCertManagerTest):
for kind in ALL_FOUR:
os.chdir(os.path.dirname(self.config_files[domain][kind]))
self.assertEqual(
filesystem.realpath(os.readlink(self.config_files[domain][kind])),
filesystem.realpath(filesystem.readlink(self.config_files[domain][kind])),
filesystem.realpath(archive_paths[domain][kind]))
finally:
os.chdir(prev_dir)

View File

@@ -597,6 +597,32 @@ class IsExecutableTest(test_util.TempDirTestCase):
self.assertFalse(filesystem.is_executable("exe"))
class ReadlinkTest(unittest.TestCase):
@unittest.skipUnless(POSIX_MODE, reason='Tests specific to Linux')
@mock.patch("certbot.compat.filesystem.os.readlink")
def test_path_posix(self, mock_readlink):
mock_readlink.return_value = "/normal/path"
self.assertEqual(filesystem.readlink("dummy"), "/normal/path")
@unittest.skipIf(POSIX_MODE, reason='Tests specific to Windows')
@mock.patch("certbot.compat.filesystem.os.readlink")
def test_normal_path_windows(self, mock_readlink):
# Python <3.8
mock_readlink.return_value = "C:\\short\\path"
self.assertEqual(filesystem.readlink("dummy"), "C:\\short\\path")
# Python >=3.8 (os.readlink always returns the extended form)
mock_readlink.return_value = "\\\\?\\C:\\short\\path"
self.assertEqual(filesystem.readlink("dummy"), "C:\\short\\path")
@unittest.skipIf(POSIX_MODE, reason='Tests specific to Windows')
@mock.patch("certbot.compat.filesystem.os.readlink")
def test_extended_path_windows(self, mock_readlink):
# Following path is largely over the 260 characters permitted in the normal form.
mock_readlink.return_value = "\\\\?\\C:\\long" + 1000 * "\\path"
with self.assertRaises(ValueError):
filesystem.readlink("dummy")
@contextlib.contextmanager
def _fix_windows_runtime():
if os.name != 'nt':

View File

@@ -813,8 +813,10 @@ class MainTest(test_util.ConfigTestCase):
self._call_no_clientmock(['delete'])
self.assertEqual(1, mock_cert_manager.call_count)
@mock.patch('certbot._internal.main.plugins_disco')
@mock.patch('certbot._internal.main.cli.HelpfulArgumentParser.determine_help_topics')
@mock.patch('certbot._internal.log.post_arg_parse_setup')
def test_plugins(self, _):
def test_plugins(self, _, _det, mock_disco):
flags = ['--init', '--prepare', '--authenticators', '--installers']
for args in itertools.chain(
*(itertools.combinations(flags, r)

View File

@@ -330,7 +330,7 @@ class RenewableCertTests(BaseRenewableCertTest):
self.test_rc._update_link_to("chain", 3000)
# However, current_version doesn't allow querying the resulting
# version (because it's a broken link).
self.assertEqual(os.path.basename(os.readlink(self.test_rc.chain)),
self.assertEqual(os.path.basename(filesystem.readlink(self.test_rc.chain)),
"chain3000.pem")
def test_version(self):
@@ -514,7 +514,7 @@ class RenewableCertTests(BaseRenewableCertTest):
# privkey.
for i in (6, 7, 8):
self.assertTrue(os.path.islink(self.test_rc.version("privkey", i)))
self.assertEqual("privkey3.pem", os.path.basename(os.readlink(
self.assertEqual("privkey3.pem", os.path.basename(filesystem.readlink(
self.test_rc.version("privkey", i))))
for kind in ALL_FOUR:

View File

@@ -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.10.1"
LE_AUTO_VERSION="1.11.0"
BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -804,6 +804,7 @@ elif [ -f /etc/mageia-release ]; then
# Mageia has both /etc/mageia-release and /etc/redhat-release
DEPRECATED_OS=1
elif [ -f /etc/redhat-release ]; then
DEPRECATED_OS=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.
@@ -836,12 +837,7 @@ elif [ -f /etc/redhat-release ]; then
INTERACTIVE_BOOTSTRAP=1
fi
Bootstrap() {
BootstrapMessage "Legacy RedHat-based OSes that will use Python3"
BootstrapRpmPython3Legacy
}
USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION"
# Try now to enable SCL rh-python36 for systems already bootstrapped
# NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto
@@ -860,18 +856,7 @@ elif [ -f /etc/redhat-release ]; then
fi
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
Bootstrap() {
BootstrapMessage "RedHat-based OSes that will use Python3"
BootstrapRpmPython3
}
USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
else
Bootstrap() {
BootstrapMessage "RedHat-based OSes"
BootstrapRpmCommon
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
fi
fi
@@ -889,10 +874,7 @@ elif uname | grep -iq FreeBSD ; then
elif uname | grep -iq Darwin ; then
DEPRECATED_OS=1
elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
Bootstrap() {
ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
DEPRECATED_OS=1
elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
DEPRECATED_OS=1
else
@@ -1493,18 +1475,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==1.10.1 \
--hash=sha256:011ac980fa21b9f29e02c9b8d8b86e8a4bf4670b51b6ad91656e401e9d2d2231 \
--hash=sha256:0d9ee3fc09e0d03b2d1b1f1c4916e61ecfc6904b4216ddef4e6a5ca1424d9cb7
acme==1.10.1 \
--hash=sha256:752d598e54e98ad1e874de53fd50c61044f1b566d6deb790db5676ce9c573546 \
--hash=sha256:fcbb559aedc96b404edf593e78517dcd7291984d5a37036c3fc77f3c5c122fd8
certbot-apache==1.10.1 \
--hash=sha256:f077b4b7f166627ef5e0921fe7cde57700670fc86e9ad9dbdfaf2c573cc0f2fa \
--hash=sha256:97ed637b4c7b03820db6c69aa90145dc989933351d46a3d62baf6b71674f0a10
certbot-nginx==1.10.1 \
--hash=sha256:7c36459021f8a1ec3b6c062e4c4fc866bfaa1dbf26ccd29e043dd6848003be08 \
--hash=sha256:c0bbeccf85f46b728fd95e6bb8c2649d32d3383d7f47ea4b9c312d12bf04d2f0
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
UNLIKELY_EOF
# -------------------------------------------------------------------------

View File

@@ -1,11 +1,11 @@
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl/JL3kACgkQTRfJlc2X
dfKJMwf/RXjfg5KScEjWiR+YMAcTVxGl4ITDMNBvmPoqCfrPwIJQewy1k6yQUITr
tMe0tkPneGgGccJreLAuO4+RdmNqm2MKBO3wMW9YZobJxcbMmrtVxyBD2OP4K/lL
oCZvjcN5pLvje6OlMwJ/fQ+zGY8mFUpfKIluxKrqkkO3p6Q+i/wPXF5Gjjb2J/bI
N+TczQJYUkDWAw7Tp4ho3J9xpqIn3zyOc2hI3wQDMC1o9sU5a80Vyc/mEqpE8SQ3
qOWg9Gdx3DXTWOztcx2IxZtFEkIukPM8iD/Fkr//3XHeIc3+mqRAQdY+w7EopzbP
hLwjHVEJs1EMYq8ntWmMFjZ4+ImFgw==
=Peuv
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl/0pwwACgkQTRfJlc2X
dfL4eQf+MyI6XGuG9jKbfRRfYWNjc3B4nxjvpeaOys6ZNIFoI5sElR/8siv6lexc
iDZ0h6PkIfh4NkIOQJQqgGP885P4aPZBg1mOTnssa6u3+1R3QRb/L/QcppysQZnf
Jve+94Zpkz1r2pF8KI4mZYDl5iN01TrMlQLddEeWOzY1tzoEVBq19KBEUwnk8awt
WOxKfhITFPbU2jyR5O4przDJLGsqG6WC6etCbmWYnb/he3pWa70ITsv2a1RCoTDf
EsBb5QVa3SEw+NT3jyE9P3FothSQZyvsYojd6/B4/bwZarWwqh1mTMz55U2rJl87
XpjglPXfhrv/s5oWNWthXTpz+11xvA==
=nhC8
-----END PGP SIGNATURE-----

View File

@@ -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.dev0"
LE_AUTO_VERSION="1.12.0.dev0"
BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -1475,18 +1475,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==1.10.1 \
--hash=sha256:011ac980fa21b9f29e02c9b8d8b86e8a4bf4670b51b6ad91656e401e9d2d2231 \
--hash=sha256:0d9ee3fc09e0d03b2d1b1f1c4916e61ecfc6904b4216ddef4e6a5ca1424d9cb7
acme==1.10.1 \
--hash=sha256:752d598e54e98ad1e874de53fd50c61044f1b566d6deb790db5676ce9c573546 \
--hash=sha256:fcbb559aedc96b404edf593e78517dcd7291984d5a37036c3fc77f3c5c122fd8
certbot-apache==1.10.1 \
--hash=sha256:f077b4b7f166627ef5e0921fe7cde57700670fc86e9ad9dbdfaf2c573cc0f2fa \
--hash=sha256:97ed637b4c7b03820db6c69aa90145dc989933351d46a3d62baf6b71674f0a10
certbot-nginx==1.10.1 \
--hash=sha256:7c36459021f8a1ec3b6c062e4c4fc866bfaa1dbf26ccd29e043dd6848003be08 \
--hash=sha256:c0bbeccf85f46b728fd95e6bb8c2649d32d3383d7f47ea4b9c312d12bf04d2f0
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
UNLIKELY_EOF
# -------------------------------------------------------------------------

View File

@@ -1,12 +1,12 @@
certbot==1.10.1 \
--hash=sha256:011ac980fa21b9f29e02c9b8d8b86e8a4bf4670b51b6ad91656e401e9d2d2231 \
--hash=sha256:0d9ee3fc09e0d03b2d1b1f1c4916e61ecfc6904b4216ddef4e6a5ca1424d9cb7
acme==1.10.1 \
--hash=sha256:752d598e54e98ad1e874de53fd50c61044f1b566d6deb790db5676ce9c573546 \
--hash=sha256:fcbb559aedc96b404edf593e78517dcd7291984d5a37036c3fc77f3c5c122fd8
certbot-apache==1.10.1 \
--hash=sha256:f077b4b7f166627ef5e0921fe7cde57700670fc86e9ad9dbdfaf2c573cc0f2fa \
--hash=sha256:97ed637b4c7b03820db6c69aa90145dc989933351d46a3d62baf6b71674f0a10
certbot-nginx==1.10.1 \
--hash=sha256:7c36459021f8a1ec3b6c062e4c4fc866bfaa1dbf26ccd29e043dd6848003be08 \
--hash=sha256:c0bbeccf85f46b728fd95e6bb8c2649d32d3383d7f47ea4b9c312d12bf04d2f0
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

View File

@@ -1,76 +1,80 @@
# This file contains the oldest versions of our dependencies we say we require
# in our packages or versions we need to support to maintain compatibility with
# the versions included in the various Linux distros where we are packaged.
# This file contains the oldest versions of our dependencies we're trying to
# support. Usually these version numbers are taken from the packages of our
# dependencies available in popular LTS Linux distros. Keeping compatibility
# with those versions makes it much easier for OS maintainers to update their
# Certbot packages.
#
# When updating these dependencies, we should try to only update them to the
# oldest version of the package that is found in a non-EOL'd version of
# CentOS, Debian, or Ubuntu that has Certbot packages in their OS repositories
# using a version of Python we support. If the distro is EOL'd or using a
# version of Python we don't support, it can be ignored.
# CentOS/RHEL 7 EPEL constraints
cffi==1.6.0
# Some of these constraints may be stricter than necessary because they
# initially referred to the Python 2 packages in CentOS/RHEL 7 with EPEL.
cffi==1.9.1
chardet==2.2.1
configobj==4.7.2
ipaddress==1.0.16
mock==1.0.1
ndg-httpsclient==0.3.2
ply==3.4
pyOpenSSL==17.3.0
pyasn1==0.1.9
pycparser==2.14
pyRFC3339==1.0
python-augeas==0.5.0
oauth2client==4.0.0
six==1.9.0
# setuptools 0.9.8 is the actual version packaged, but some other dependencies
# in this file require setuptools>=1.0 and there are no relevant changes for us
# between these versions.
setuptools==1.0.0
urllib3==1.10.2
zope.component==4.1.0
zope.event==4.0.3
zope.interface==4.0.5
# Debian Jessie Backports constraints
# Debian Jessie has reached end of life. However:
# When it becomes necessary to upgrade any of these dependencies, you should only update them to the oldest version of the package found
# in a non-EOL'd version of CentOS, Debian, or Ubuntu that has Certbot packages in their OS repositories.
# Debian Jessie has reached end of life so these dependencies can probably be
# updated as needed or desired.
PyICU==1.8
colorama==0.3.2
enum34==1.0.3
html5lib==0.999
idna==2.0
pbr==1.8.0
pytz==2012rc0
# Debian Buster constraints
google-api-python-client==1.5.5
pyparsing==2.2.0
# Our setup.py constraints
apacheconfig==0.3.2
cloudflare==1.5.1
cryptography==1.2.3
parsedatetime==1.3
pyparsing==1.5.5
python-digitalocean==1.11
requests[security]==2.6.0
# Ubuntu Xenial constraints
# Ubuntu Xenial only has versions of Python which we do not support available
# so these dependencies can probably be updated as needed or desired.
ConfigArgParse==0.10.0
pyOpenSSL==0.15.1
funcsigs==0.4
zope.hookable==4.0.4
# Ubuntu Bionic constraints.
cryptography==2.1.4
distro==1.0.1
# Lexicon oldest constraint is overridden appropriately on relevant DNS provider plugins
# using their local-oldest-requirements.txt
dns-lexicon==2.2.1
httplib2==0.9.2
idna==2.6
setuptools==39.0.1
six==1.11.0
# Ubuntu Focal constraints
asn1crypto==0.24.0
configobj==5.0.6
parsedatetime==2.4
# Plugin constraints
# These aren't necessarily the oldest versions we need to support
# Tracking at https://github.com/certbot/certbot/issues/6473
boto3==1.4.7
botocore==1.7.41
# Old certbot[dev] constraints
# Old versions of certbot[dev] required ipdb and our normally pinned version of
# ipython which ipdb depends on doesn't support Python 2 so we pin an older
# version here to keep tests working while we have Python 2 support.
ipython==5.8.0
prompt-toolkit==1.0.18

View File

@@ -1,37 +0,0 @@
#!/bin/bash
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
pushd "${DIR}/../"
function cleanup() {
rm -f "${DOCKERFILE}"
popd
}
trap cleanup EXIT
DOCKERFILE=$(mktemp /tmp/Dockerfile.XXXXXX)
cat << "EOF" >> "${DOCKERFILE}"
FROM ubuntu:16.04
COPY letsencrypt-auto-source/pieces/dependency-requirements.txt /tmp/letsencrypt-auto-source/pieces/
COPY tools/ /tmp/tools/
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
python-dev python-pip python-setuptools \
gcc libaugeas0 libssl-dev libffi-dev \
git ca-certificates nginx-light openssl curl \
&& curl -fsSL https://get.docker.com | bash /dev/stdin \
&& python /tmp/tools/pipstrap.py \
&& python /tmp/tools/pip_install.py tox \
&& rm -rf /var/lib/apt/lists/*
EOF
docker build -f "${DOCKERFILE}" -t oldest-worker .
docker run --rm --network=host -w "${PWD}" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "${PWD}:${PWD}" -v /tmp:/tmp \
-e TOXENV -e ACME_SERVER -e PYTEST_ADDOPTS \
oldest-worker python -m tox

50
tox.ini
View File

@@ -77,49 +77,65 @@ setenv =
PYTEST_ADDOPTS = {env:PYTEST_ADDOPTS:--numprocesses auto}
PYTHONHASHSEED = 0
[testenv:py27-oldest]
[testenv:oldest]
# Setting basepython allows the tests to fail fast if that version of Python
# isn't available instead of potentially trying to use a newer version of
# Python which is unlikely to work.
basepython = python3.6
commands =
{[testenv]commands}
setenv =
{[testenv]setenv}
CERTBOT_OLDEST=1
[testenv:py27-acme-oldest]
[testenv:acme-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} acme[dev]
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:py27-apache-oldest]
[testenv:apache-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} certbot-apache
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:py27-apache-v2-oldest]
[testenv:apache-v2-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} certbot-apache[dev]
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:py27-certbot-oldest]
[testenv:certbot-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} certbot[dev]
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:py27-dns-oldest]
[testenv:dns-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} {[base]dns_packages}
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:py27-nginx-oldest]
[testenv:nginx-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]install_and_test} certbot-nginx
python tests/lock_test.py
setenv =
{[testenv:py27-oldest]setenv}
{[testenv:oldest]setenv}
[testenv:lint]
basepython = python3
@@ -238,22 +254,26 @@ commands =
passenv = DOCKER_*
[testenv:integration-certbot-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]pip_install} certbot
{[base]pip_install} certbot-ci
pytest certbot-ci/certbot_integration_tests/certbot_tests \
--acme-server={env:ACME_SERVER:pebble}
passenv = DOCKER_*
setenv = {[testenv:py27-oldest]setenv}
setenv = {[testenv:oldest]setenv}
[testenv:integration-nginx-oldest]
basepython =
{[testenv:oldest]basepython}
commands =
{[base]pip_install} certbot-nginx
{[base]pip_install} certbot-ci
pytest certbot-ci/certbot_integration_tests/nginx_tests \
--acme-server={env:ACME_SERVER:pebble}
passenv = DOCKER_*
setenv = {[testenv:py27-oldest]setenv}
setenv = {[testenv:oldest]setenv}
[testenv:test-farm-tests-base]
changedir = tests/letstest