mirror of
https://github.com/certbot/certbot.git
synced 2026-06-13 18:50:20 -04:00
Merge branch 'master' into fix-cryptography-ocsp
This commit is contained in:
commit
391d2f8f14
50 changed files with 520 additions and 427 deletions
29
CHANGELOG.md
29
CHANGELOG.md
|
|
@ -2,7 +2,34 @@
|
|||
|
||||
Certbot adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## 0.31.0 - master
|
||||
## 0.32.0 - master
|
||||
|
||||
### Added
|
||||
|
||||
*
|
||||
|
||||
### Changed
|
||||
|
||||
* Certbot and its acme module now depend on josepy>=1.1.0 to avoid printing the
|
||||
warnings described at https://github.com/certbot/josepy/issues/13.
|
||||
* Apache plugin now respects CERTBOT_DOCS environment variable when adding
|
||||
command line defaults.
|
||||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
|
||||
Despite us having broken lockstep, we are continuing to release new versions of
|
||||
all Certbot components during releases for the time being, however, the only
|
||||
package with changes other than its version number was:
|
||||
|
||||
* acme
|
||||
* certbot
|
||||
* certbot-apache
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
## 0.31.0 - 2019-02-07
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
|||
|
|
@ -739,8 +739,7 @@ class ClientV2(ClientBase):
|
|||
if body.error is not None:
|
||||
raise errors.IssuanceError(body.error)
|
||||
if body.certificate is not None:
|
||||
certificate_response = self._post_as_get(body.certificate,
|
||||
content_type=DER_CONTENT_TYPE).text
|
||||
certificate_response = self._post_as_get(body.certificate).text
|
||||
return orderr.update(body=body, fullchain_pem=certificate_response)
|
||||
raise errors.TimeoutError()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from setuptools import find_packages
|
|||
from setuptools.command.test import test as TestCommand
|
||||
import sys
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
@ -11,7 +11,9 @@ install_requires = [
|
|||
# rsa_recover_prime_factors (>=0.8)
|
||||
'cryptography>=1.2.3',
|
||||
# formerly known as acme.jose:
|
||||
'josepy>=1.0.0',
|
||||
# 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)
|
||||
'mock',
|
||||
'PyOpenSSL>=0.13.1',
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"""
|
||||
|
||||
description = "Apache Web Server plugin"
|
||||
if os.environ.get("CERTBOT_DOCS") == "1":
|
||||
description += ( # pragma: no cover
|
||||
" (Please note that the default values of the Apache plugin options"
|
||||
" change depending on the operating system Certbot is run on.)"
|
||||
)
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
server_root="/etc/apache2",
|
||||
|
|
@ -141,28 +146,36 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
# When adding, modifying or deleting command line arguments, be sure to
|
||||
# include the changes in the list used in method _prepare_options() to
|
||||
# ensure consistent behavior.
|
||||
add("enmod", default=cls.OS_DEFAULTS["enmod"],
|
||||
|
||||
# Respect CERTBOT_DOCS environment variable and use default values from
|
||||
# base class regardless of the underlying distribution (overrides).
|
||||
if os.environ.get("CERTBOT_DOCS") == "1":
|
||||
DEFAULTS = ApacheConfigurator.OS_DEFAULTS
|
||||
else:
|
||||
# cls.OS_DEFAULTS can be distribution specific, see override classes
|
||||
DEFAULTS = cls.OS_DEFAULTS
|
||||
add("enmod", default=DEFAULTS["enmod"],
|
||||
help="Path to the Apache 'a2enmod' binary")
|
||||
add("dismod", default=cls.OS_DEFAULTS["dismod"],
|
||||
add("dismod", default=DEFAULTS["dismod"],
|
||||
help="Path to the Apache 'a2dismod' binary")
|
||||
add("le-vhost-ext", default=cls.OS_DEFAULTS["le_vhost_ext"],
|
||||
add("le-vhost-ext", default=DEFAULTS["le_vhost_ext"],
|
||||
help="SSL vhost configuration extension")
|
||||
add("server-root", default=cls.OS_DEFAULTS["server_root"],
|
||||
add("server-root", default=DEFAULTS["server_root"],
|
||||
help="Apache server root directory")
|
||||
add("vhost-root", default=None,
|
||||
help="Apache server VirtualHost configuration root")
|
||||
add("logs-root", default=cls.OS_DEFAULTS["logs_root"],
|
||||
add("logs-root", default=DEFAULTS["logs_root"],
|
||||
help="Apache server logs directory")
|
||||
add("challenge-location",
|
||||
default=cls.OS_DEFAULTS["challenge_location"],
|
||||
default=DEFAULTS["challenge_location"],
|
||||
help="Directory path for challenge configuration")
|
||||
add("handle-modules", default=cls.OS_DEFAULTS["handle_modules"],
|
||||
add("handle-modules", default=DEFAULTS["handle_modules"],
|
||||
help="Let installer handle enabling required modules for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
add("handle-sites", default=cls.OS_DEFAULTS["handle_sites"],
|
||||
add("handle-sites", default=DEFAULTS["handle_sites"],
|
||||
help="Let installer handle enabling sites for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
add("ctl", default=cls.OS_DEFAULTS["ctl"],
|
||||
add("ctl", default=DEFAULTS["ctl"],
|
||||
help="Full path to Apache control script")
|
||||
util.add_deprecated_argument(
|
||||
add, argument_name="init-script", nargs=1)
|
||||
|
|
|
|||
|
|
@ -115,6 +115,37 @@ class MultipleVhostsTest(util.ApacheTest):
|
|||
# Weak test..
|
||||
ApacheConfigurator.add_parser_arguments(mock.MagicMock())
|
||||
|
||||
def test_docs_parser_arguments(self):
|
||||
os.environ["CERTBOT_DOCS"] = "1"
|
||||
from certbot_apache.configurator import ApacheConfigurator
|
||||
mock_add = mock.MagicMock()
|
||||
ApacheConfigurator.add_parser_arguments(mock_add)
|
||||
parserargs = ["server_root", "enmod", "dismod", "le_vhost_ext",
|
||||
"vhost_root", "logs_root", "challenge_location",
|
||||
"handle_modules", "handle_sites", "ctl"]
|
||||
exp = dict()
|
||||
|
||||
for k in ApacheConfigurator.OS_DEFAULTS:
|
||||
if k in parserargs:
|
||||
exp[k.replace("_", "-")] = ApacheConfigurator.OS_DEFAULTS[k]
|
||||
# Special cases
|
||||
exp["vhost-root"] = None
|
||||
exp["init-script"] = None
|
||||
|
||||
found = set()
|
||||
for call in mock_add.call_args_list:
|
||||
# init-script is a special case: deprecated argument
|
||||
if call[0][0] != "init-script":
|
||||
self.assertEqual(exp[call[0][0]], call[1]['default'])
|
||||
found.add(call[0][0])
|
||||
|
||||
# Make sure that all (and only) the expected values exist
|
||||
self.assertEqual(len(mock_add.call_args_list), len(found))
|
||||
for e in exp:
|
||||
self.assertTrue(e in found)
|
||||
|
||||
del os.environ["CERTBOT_DOCS"]
|
||||
|
||||
def test_add_parser_arguments_all_configurators(self): # pylint: disable=no-self-use
|
||||
from certbot_apache.entrypoint import OVERRIDE_CLASSES
|
||||
for cls in OVERRIDE_CLASSES.values():
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
84
certbot-auto
84
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="0.30.2"
|
||||
LE_AUTO_VERSION="0.31.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -333,63 +333,11 @@ BootstrapDebCommon() {
|
|||
fi
|
||||
|
||||
augeas_pkg="libaugeas0 augeas-lenses"
|
||||
AUGVERSION=`LC_ALL=C apt-cache show --no-all-versions libaugeas0 | grep ^Version: | cut -d" " -f2`
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
YES_FLAG="-y"
|
||||
fi
|
||||
|
||||
AddBackportRepo() {
|
||||
# ARGS:
|
||||
BACKPORT_NAME="$1"
|
||||
BACKPORT_SOURCELINE="$2"
|
||||
say "To use the Apache Certbot plugin, augeas needs to be installed from $BACKPORT_NAME."
|
||||
if ! grep -v -e ' *#' /etc/apt/sources.list | grep -q "$BACKPORT_NAME" ; then
|
||||
# This can theoretically error if sources.list.d is empty, but in that case we don't care.
|
||||
if ! grep -v -e ' *#' /etc/apt/sources.list.d/* 2>/dev/null | grep -q "$BACKPORT_NAME"; then
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
/bin/echo -n "Installing augeas from $BACKPORT_NAME in 3 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -ne "\e[0K\rInstalling augeas from $BACKPORT_NAME in 2 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -e "\e[0K\rInstalling augeas from $BACKPORT_NAME in 1 second ..."
|
||||
sleep 1s
|
||||
add_backports=1
|
||||
else
|
||||
read -p "Would you like to enable the $BACKPORT_NAME repository [Y/n]? " response
|
||||
case $response in
|
||||
[yY][eE][sS]|[yY]|"")
|
||||
add_backports=1;;
|
||||
*)
|
||||
add_backports=0;;
|
||||
esac
|
||||
fi
|
||||
if [ "$add_backports" = 1 ]; then
|
||||
sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list"
|
||||
apt-get $QUIET_FLAG update
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$add_backports" != 0 ]; then
|
||||
apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg
|
||||
augeas_pkg=
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if dpkg --compare-versions 1.0 gt "$AUGVERSION" ; then
|
||||
if lsb_release -a | grep -q wheezy ; then
|
||||
AddBackportRepo wheezy-backports "deb http://http.debian.net/debian wheezy-backports main"
|
||||
elif lsb_release -a | grep -q precise ; then
|
||||
# XXX add ARM case
|
||||
AddBackportRepo precise-backports "deb http://archive.ubuntu.com/ubuntu precise-backports main restricted universe multiverse"
|
||||
else
|
||||
echo "No libaugeas0 version is available that's new enough to run the"
|
||||
echo "Certbot apache plugin..."
|
||||
fi
|
||||
# XXX add a case for ubuntu PPAs
|
||||
fi
|
||||
|
||||
apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \
|
||||
python \
|
||||
python-dev \
|
||||
|
|
@ -1140,9 +1088,9 @@ parsedatetime==2.1 \
|
|||
pbr==1.8.1 \
|
||||
--hash=sha256:46c8db75ae75a056bd1cc07fa21734fe2e603d11a07833ecc1eeb74c35c72e0c \
|
||||
--hash=sha256:e2127626a91e6c885db89668976db31020f0af2da728924b56480fc7ccf09649
|
||||
pyOpenSSL==16.2.0 \
|
||||
--hash=sha256:26ca380ddf272f7556e48064bbcd5bd71f83dfc144f3583501c7ddbd9434ee17 \
|
||||
--hash=sha256:7779a3bbb74e79db234af6a08775568c6769b5821faecf6e2f4143edb227516e
|
||||
pyOpenSSL==18.0.0 \
|
||||
--hash=sha256:26ff56a6b5ecaf3a2a59f132681e2a80afcc76b4f902f612f518f92c2a1bf854 \
|
||||
--hash=sha256:6488f1423b00f73b7ad5167885312bb0ce410d3312eb212393795b53c8caa580
|
||||
pyparsing==2.1.8 \
|
||||
--hash=sha256:2f0f5ceb14eccd5aef809d6382e87df22ca1da583c79f6db01675ce7d7f49c18 \
|
||||
--hash=sha256:03a4869b9f3493807ee1f1cb405e6d576a1a2ca4d81a982677c0c1ad6177c56b \
|
||||
|
|
@ -1232,18 +1180,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.30.2 \
|
||||
--hash=sha256:e411b72fa86eec1018e6de28e649e8c9c71191a7431dcc77f207b57ca9484c11 \
|
||||
--hash=sha256:534487cb552ced8e47948ba3d2e7ca12c3a439133fc609485012b1a02fc7776e
|
||||
acme==0.30.2 \
|
||||
--hash=sha256:68982576492dfa99c7e2be0fce4371adc9344740b05420ce0ab53238d2bb9b3b \
|
||||
--hash=sha256:295a5b7fce9f908e6e5cff8c40be1a3daf3e1ebabd2e139a4c87274e68eeb8f2
|
||||
certbot-apache==0.30.2 \
|
||||
--hash=sha256:3b7fa4e59772da7c9975ef2a49ceff157c9d7cb31eb9475928b5986d89701a3a \
|
||||
--hash=sha256:32fa915a8a51810fdfe828ac1361da4425c231d7384891e49e6338e4741464b2
|
||||
certbot-nginx==0.30.2 \
|
||||
--hash=sha256:7dc785f6f0c0c57b19cea8d98f9ea8feef53945613967b52c9348c81327010e2 \
|
||||
--hash=sha256:6ba4dd772d0c7cdfb3383ca325b35639e01ac9e142e4baa6445cd85c7fb59552
|
||||
certbot==0.31.0 \
|
||||
--hash=sha256:1a1b4b2675daf5266cc2cf2a44ded44de1d83e9541ffa078913c0e4c3231a1c4 \
|
||||
--hash=sha256:0c3196f80a102c0f9d82d566ba859efe3b70e9ed4670520224c844fafd930473
|
||||
acme==0.31.0 \
|
||||
--hash=sha256:a0c851f6b7845a0faa3a47a3e871440eed9ec11b4ab949de0dc4a0fb1201cd24 \
|
||||
--hash=sha256:7e5c2d01986e0f34ca08fee58981892704c82c48435dcd3592b424c312d8b2bf
|
||||
certbot-apache==0.31.0 \
|
||||
--hash=sha256:740bb55dd71723a21eebabb16e6ee5d8883f8b8f8cf6956dd1d4873e0cccae21 \
|
||||
--hash=sha256:cc4b840b2a439a63e2dce809272c3c3cd4b1aeefc4053cd188935135be137edd
|
||||
certbot-nginx==0.31.0 \
|
||||
--hash=sha256:7a1ffda9d93dc7c2aaf89452ce190250de8932e624d31ebba8e4fa7d950025c5 \
|
||||
--hash=sha256:d450d75650384f74baccb7673c89e2f52468afa478ed354eb6d4b99aa33bf865
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.1.22',
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1',
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
dns-lexicon==2.7.14
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
-e acme[dev]
|
||||
-e .[dev]
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.31.0
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0.dev0',
|
||||
'certbot>=0.31.0.dev0',
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.31.0',
|
||||
'dns-lexicon>=2.1.23',
|
||||
'mock',
|
||||
'setuptools',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.31.0.dev0'
|
||||
version = '0.32.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Certbot client."""
|
||||
|
||||
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
|
||||
__version__ = '0.31.0.dev0'
|
||||
__version__ = '0.32.0.dev0'
|
||||
|
|
|
|||
|
|
@ -13,13 +13,6 @@ import stat
|
|||
|
||||
from certbot import errors
|
||||
|
||||
try:
|
||||
# Linux specific
|
||||
import fcntl # pylint: disable=import-error
|
||||
except ImportError:
|
||||
# Windows specific
|
||||
import msvcrt # pylint: disable=import-error
|
||||
|
||||
UNPRIVILEGED_SUBCOMMANDS_ALLOWED = [
|
||||
'certificates', 'enhance', 'revoke', 'delete',
|
||||
'register', 'unregister', 'config_changes', 'plugins']
|
||||
|
|
@ -118,55 +111,6 @@ def readline_with_timeout(timeout, prompt):
|
|||
return sys.stdin.readline()
|
||||
|
||||
|
||||
def lock_file(fd):
|
||||
"""
|
||||
Lock the file linked to the specified file descriptor.
|
||||
|
||||
:param int fd: The file descriptor of the file to lock.
|
||||
|
||||
"""
|
||||
if 'fcntl' in sys.modules:
|
||||
# Linux specific
|
||||
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
else:
|
||||
# Windows specific
|
||||
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
|
||||
|
||||
|
||||
def release_locked_file(fd, path):
|
||||
"""
|
||||
Remove, close, and release a lock file specified by its file descriptor and its path.
|
||||
|
||||
:param int fd: The file descriptor of the lock file.
|
||||
:param str path: The path of the lock file.
|
||||
|
||||
"""
|
||||
# Linux specific
|
||||
#
|
||||
# It is important the lock file is removed before it's released,
|
||||
# otherwise:
|
||||
#
|
||||
# process A: open lock file
|
||||
# process B: release lock file
|
||||
# process A: lock file
|
||||
# process A: check device and inode
|
||||
# process B: delete file
|
||||
# process C: open and lock a different file at the same path
|
||||
try:
|
||||
os.remove(path)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EACCES:
|
||||
# Windows specific
|
||||
# We will not be able to remove a file before closing it.
|
||||
# To avoid race conditions described for Linux, we will not delete the lockfile,
|
||||
# just close it to be reused on the next Certbot call.
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
|
||||
def compare_file_modes(mode1, mode2):
|
||||
"""Return true if the two modes can be considered as equals for this platform"""
|
||||
if os.name != 'nt':
|
||||
|
|
|
|||
213
certbot/lock.py
213
certbot/lock.py
|
|
@ -1,15 +1,23 @@
|
|||
"""Implements file locks for locking files and directories in UNIX."""
|
||||
"""Implements file locks compatible with Linux and Windows for locking files and directories."""
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
try:
|
||||
import fcntl # pylint: disable=import-error
|
||||
except ImportError:
|
||||
import msvcrt # pylint: disable=import-error
|
||||
POSIX_MODE = False
|
||||
else:
|
||||
POSIX_MODE = True
|
||||
|
||||
from certbot import compat
|
||||
from certbot import errors
|
||||
from acme.magic_typing import Optional, Callable # pylint: disable=unused-import, no-name-in-module
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def lock_dir(dir_path):
|
||||
# type: (str) -> LockFile
|
||||
"""Place a lock file on the directory at dir_path.
|
||||
|
||||
The lock file is placed in the root of dir_path with the name
|
||||
|
|
@ -27,34 +35,99 @@ def lock_dir(dir_path):
|
|||
|
||||
|
||||
class LockFile(object):
|
||||
"""A UNIX lock file.
|
||||
|
||||
This lock file is released when the locked file is closed or the
|
||||
process exits. It cannot be used to provide synchronization between
|
||||
threads. It is based on the lock_file package by Martin Horcicka.
|
||||
|
||||
"""
|
||||
Platform independent file lock system.
|
||||
LockFile accepts a parameter, the path to a file acting as a lock. Once the LockFile,
|
||||
instance is created, the associated file is 'locked from the point of view of the OS,
|
||||
meaning that if another instance of Certbot try at the same time to acquire the same lock,
|
||||
it will raise an Exception. Calling release method will release the lock, and make it
|
||||
available to every other instance.
|
||||
Upon exit, Certbot will also release all the locks.
|
||||
This allows us to protect a file or directory from being concurrently accessed
|
||||
or modified by two Certbot instances.
|
||||
LockFile is platform independent: it will proceed to the appropriate OS lock mechanism
|
||||
depending on Linux or Windows.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
"""Initialize and acquire the lock file.
|
||||
|
||||
:param str path: path to the file to lock
|
||||
|
||||
:raises errors.LockError: if unable to acquire the lock
|
||||
|
||||
# type: (str) -> None
|
||||
"""
|
||||
Create a LockFile instance on the given file path, and acquire lock.
|
||||
:param str path: the path to the file that will hold a lock
|
||||
"""
|
||||
super(LockFile, self).__init__()
|
||||
self._path = path
|
||||
self._fd = None
|
||||
mechanism = _UnixLockMechanism if POSIX_MODE else _WindowsLockMechanism
|
||||
self._lock_mechanism = mechanism(path)
|
||||
|
||||
self.acquire()
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
repr_str = '{0}({1}) <'.format(self.__class__.__name__, self._path)
|
||||
if self.is_locked():
|
||||
repr_str += 'acquired>'
|
||||
else:
|
||||
repr_str += 'released>'
|
||||
return repr_str
|
||||
|
||||
def acquire(self):
|
||||
"""Acquire the lock file.
|
||||
|
||||
:raises errors.LockError: if lock is already held
|
||||
:raises OSError: if unable to open or stat the lock file
|
||||
|
||||
# type: () -> None
|
||||
"""
|
||||
Acquire the lock on the file, forbidding any other Certbot instance to acquire it.
|
||||
:raises errors.LockError: if unable to acquire the lock
|
||||
"""
|
||||
self._lock_mechanism.acquire()
|
||||
|
||||
def release(self):
|
||||
# type: () -> None
|
||||
"""
|
||||
Release the lock on the file, allowing any other Certbot instance to acquire it.
|
||||
"""
|
||||
self._lock_mechanism.release()
|
||||
|
||||
def is_locked(self):
|
||||
# type: () -> bool
|
||||
"""
|
||||
Check if the file is currently locked.
|
||||
:return: True if the file is locked, False otherwise
|
||||
"""
|
||||
return self._lock_mechanism.is_locked()
|
||||
|
||||
|
||||
class _BaseLockMechanism(object):
|
||||
def __init__(self, path):
|
||||
# type: (str) -> None
|
||||
"""
|
||||
Create a lock file mechanism for Unix.
|
||||
:param str path: the path to the lock file
|
||||
"""
|
||||
self._path = path
|
||||
self._fd = None # type: Optional[int]
|
||||
|
||||
def is_locked(self):
|
||||
# type: () -> bool
|
||||
"""Check if lock file is currently locked.
|
||||
:return: True if the lock file is locked
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._fd is not None
|
||||
|
||||
def acquire(self): # pylint: disable=missing-docstring
|
||||
pass # pragma: no cover
|
||||
|
||||
def release(self): # pylint: disable=missing-docstring
|
||||
pass # pragma: no cover
|
||||
|
||||
|
||||
class _UnixLockMechanism(_BaseLockMechanism):
|
||||
"""
|
||||
A UNIX lock file mechanism.
|
||||
This lock file is released when the locked file is closed or the
|
||||
process exits. It cannot be used to provide synchronization between
|
||||
threads. It is based on the lock_file package by Martin Horcicka.
|
||||
"""
|
||||
def acquire(self):
|
||||
# type: () -> None
|
||||
"""Acquire the lock."""
|
||||
while self._fd is None:
|
||||
# Open the file
|
||||
fd = os.open(self._path, os.O_CREAT | os.O_WRONLY, 0o600)
|
||||
|
|
@ -68,33 +141,29 @@ class LockFile(object):
|
|||
os.close(fd)
|
||||
|
||||
def _try_lock(self, fd):
|
||||
"""Try to acquire the lock file without blocking.
|
||||
|
||||
# type: (int) -> None
|
||||
"""
|
||||
Try to acquire the lock file without blocking.
|
||||
:param int fd: file descriptor of the opened file to lock
|
||||
|
||||
"""
|
||||
try:
|
||||
compat.lock_file(fd)
|
||||
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except IOError as err:
|
||||
if err.errno in (errno.EACCES, errno.EAGAIN):
|
||||
logger.debug(
|
||||
"A lock on %s is held by another process.", self._path)
|
||||
raise errors.LockError(
|
||||
"Another instance of Certbot is already running.")
|
||||
logger.debug('A lock on %s is held by another process.', self._path)
|
||||
raise errors.LockError('Another instance of Certbot is already running.')
|
||||
raise
|
||||
|
||||
def _lock_success(self, fd):
|
||||
"""Did we successfully grab the lock?
|
||||
|
||||
# type: (int) -> bool
|
||||
"""
|
||||
Did we successfully grab the lock?
|
||||
Because this class deletes the locked file when the lock is
|
||||
released, it is possible another process removed and recreated
|
||||
the file between us opening the file and acquiring the lock.
|
||||
|
||||
:param int fd: file descriptor of the opened file to lock
|
||||
|
||||
:returns: True if the lock was successfully acquired
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
try:
|
||||
stat1 = os.stat(self._path)
|
||||
|
|
@ -108,17 +177,75 @@ class LockFile(object):
|
|||
# the same device and inode, they're the same file.
|
||||
return stat1.st_dev == stat2.st_dev and stat1.st_ino == stat2.st_ino
|
||||
|
||||
def __repr__(self):
|
||||
repr_str = '{0}({1}) <'.format(self.__class__.__name__, self._path)
|
||||
if self._fd is None:
|
||||
repr_str += 'released>'
|
||||
else:
|
||||
repr_str += 'acquired>'
|
||||
return repr_str
|
||||
def release(self):
|
||||
# type: () -> None
|
||||
"""Remove, close, and release the lock file."""
|
||||
# It is important the lock file is removed before it's released,
|
||||
# otherwise:
|
||||
#
|
||||
# process A: open lock file
|
||||
# process B: release lock file
|
||||
# process A: lock file
|
||||
# process A: check device and inode
|
||||
# process B: delete file
|
||||
# process C: open and lock a different file at the same path
|
||||
try:
|
||||
os.remove(self._path)
|
||||
finally:
|
||||
# Following check is done to make mypy happy: it ensure that self._fd, marked
|
||||
# as Optional[int] is effectively int to make it compatible with os.close signature.
|
||||
if self._fd is None: # pragma: no cover
|
||||
raise TypeError('Error, self._fd is None.')
|
||||
try:
|
||||
os.close(self._fd)
|
||||
finally:
|
||||
self._fd = None
|
||||
|
||||
|
||||
class _WindowsLockMechanism(_BaseLockMechanism):
|
||||
"""
|
||||
A Windows lock file mechanism.
|
||||
By default on Windows, acquiring a file handler gives exclusive access to the process
|
||||
and results in an effective lock. However, it is possible to explicitly acquire the
|
||||
file handler in shared access in terms of read and write, and this is done by os.open
|
||||
and io.open in Python. So an explicit lock needs to be done through the call of
|
||||
msvcrt.locking, that will lock the first byte of the file. In theory, it is also
|
||||
possible to access a file in shared delete access, allowing other processes to delete an
|
||||
opened file. But this needs also to be done explicitly by all processes using the Windows
|
||||
low level APIs, and Python does not do it. As of Python 3.7 and below, Python developers
|
||||
state that deleting a file opened by a process from another process is not possible with
|
||||
os.open and io.open.
|
||||
Consequently, mscvrt.locking is sufficient to obtain an effective lock, and the race
|
||||
condition encountered on Linux is not possible on Windows, leading to a simpler workflow.
|
||||
"""
|
||||
def acquire(self):
|
||||
"""Acquire the lock"""
|
||||
open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
|
||||
|
||||
fd = os.open(self._path, open_mode, 0o600)
|
||||
try:
|
||||
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
|
||||
except (IOError, OSError) as err:
|
||||
os.close(fd)
|
||||
# Anything except EACCES is unexpected. Raise directly the error in that case.
|
||||
if err.errno != errno.EACCES:
|
||||
raise
|
||||
logger.debug('A lock on %s is held by another process.', self._path)
|
||||
raise errors.LockError('Another instance of Certbot is already running.')
|
||||
|
||||
self._fd = fd
|
||||
|
||||
def release(self):
|
||||
"""Remove, close, and release the lock file."""
|
||||
"""Release the lock."""
|
||||
try:
|
||||
compat.release_locked_file(self._fd, self._path)
|
||||
msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1)
|
||||
os.close(self._fd)
|
||||
|
||||
try:
|
||||
os.remove(self._path)
|
||||
except OSError as e:
|
||||
# If the lock file cannot be removed, it is not a big deal.
|
||||
# Likely another instance is acquiring the lock we just released.
|
||||
logger.debug(str(e))
|
||||
finally:
|
||||
self._fd = None
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import functools
|
|||
import multiprocessing
|
||||
import os
|
||||
import unittest
|
||||
try:
|
||||
import fcntl # pylint: disable=import-error,unused-import
|
||||
except ImportError:
|
||||
POSIX_MODE = False
|
||||
else:
|
||||
POSIX_MODE = True
|
||||
|
||||
import mock
|
||||
|
||||
|
|
@ -10,7 +16,6 @@ from certbot import errors
|
|||
from certbot.tests import util as test_util
|
||||
|
||||
|
||||
@test_util.broken_on_windows
|
||||
class LockDirTest(test_util.TempDirTestCase):
|
||||
"""Tests for certbot.lock.lock_dir."""
|
||||
@classmethod
|
||||
|
|
@ -25,7 +30,6 @@ class LockDirTest(test_util.TempDirTestCase):
|
|||
test_util.lock_and_call(assert_raises, lock_path)
|
||||
|
||||
|
||||
@test_util.broken_on_windows
|
||||
class LockFileTest(test_util.TempDirTestCase):
|
||||
"""Tests for certbot.lock.LockFile."""
|
||||
@classmethod
|
||||
|
|
@ -71,6 +75,8 @@ class LockFileTest(test_util.TempDirTestCase):
|
|||
self.assertTrue(lock_file.__class__.__name__ in lock_repr)
|
||||
self.assertTrue(self.lock_path in lock_repr)
|
||||
|
||||
@test_util.skip_on_windows(
|
||||
'Race conditions on lock are specific to the non-blocking file access approach on Linux.')
|
||||
def test_race(self):
|
||||
should_delete = [True, False]
|
||||
stat = os.stat
|
||||
|
|
@ -91,27 +97,36 @@ class LockFileTest(test_util.TempDirTestCase):
|
|||
lock_file.release()
|
||||
self.assertFalse(os.path.exists(self.lock_path))
|
||||
|
||||
@mock.patch('certbot.compat.fcntl.lockf')
|
||||
def test_unexpected_lockf_err(self, mock_lockf):
|
||||
def test_unexpected_lockf_or_locking_err(self):
|
||||
if POSIX_MODE:
|
||||
mocked_function = 'certbot.lock.fcntl.lockf'
|
||||
else:
|
||||
mocked_function = 'certbot.lock.msvcrt.locking'
|
||||
msg = 'hi there'
|
||||
mock_lockf.side_effect = IOError(msg)
|
||||
try:
|
||||
self._call(self.lock_path)
|
||||
except IOError as err:
|
||||
self.assertTrue(msg in str(err))
|
||||
else: # pragma: no cover
|
||||
self.fail('IOError not raised')
|
||||
with mock.patch(mocked_function) as mock_lock:
|
||||
mock_lock.side_effect = IOError(msg)
|
||||
try:
|
||||
self._call(self.lock_path)
|
||||
except IOError as err:
|
||||
self.assertTrue(msg in str(err))
|
||||
else: # pragma: no cover
|
||||
self.fail('IOError not raised')
|
||||
|
||||
@mock.patch('certbot.lock.os.stat')
|
||||
def test_unexpected_stat_err(self, mock_stat):
|
||||
def test_unexpected_os_err(self):
|
||||
if POSIX_MODE:
|
||||
mock_function = 'certbot.lock.os.stat'
|
||||
else:
|
||||
mock_function = 'certbot.lock.msvcrt.locking'
|
||||
# The only expected errno are ENOENT and EACCES in lock module.
|
||||
msg = 'hi there'
|
||||
mock_stat.side_effect = OSError(msg)
|
||||
try:
|
||||
self._call(self.lock_path)
|
||||
except OSError as err:
|
||||
self.assertTrue(msg in str(err))
|
||||
else: # pragma: no cover
|
||||
self.fail('OSError not raised')
|
||||
with mock.patch(mock_function) as mock_os:
|
||||
mock_os.side_effect = OSError(msg)
|
||||
try:
|
||||
self._call(self.lock_path)
|
||||
except OSError as err:
|
||||
self.assertTrue(msg in str(err))
|
||||
else: # pragma: no cover
|
||||
self.fail('OSError not raised')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
.. warning:: This module is not part of the public API.
|
||||
|
||||
"""
|
||||
import multiprocessing
|
||||
import os
|
||||
import pkg_resources
|
||||
import shutil
|
||||
|
|
@ -11,6 +10,8 @@ import tempfile
|
|||
import unittest
|
||||
import sys
|
||||
import warnings
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
|
@ -23,8 +24,8 @@ from six.moves import reload_module # pylint: disable=import-error
|
|||
from certbot import constants
|
||||
from certbot import interfaces
|
||||
from certbot import storage
|
||||
from certbot import util
|
||||
from certbot import configuration
|
||||
from certbot import util
|
||||
|
||||
from certbot.display import util as display_util
|
||||
|
||||
|
|
@ -211,7 +212,7 @@ class FreezableMock(object):
|
|||
|
||||
"""
|
||||
def __init__(self, frozen=False, func=None, return_value=mock.sentinel.DEFAULT):
|
||||
self._frozen_set = set() if frozen else set(('freeze',))
|
||||
self._frozen_set = set() if frozen else {'freeze', }
|
||||
self._func = func
|
||||
self._mock = mock.MagicMock()
|
||||
if return_value != mock.sentinel.DEFAULT:
|
||||
|
|
@ -340,6 +341,7 @@ class TempDirTestCase(unittest.TestCase):
|
|||
warnings.warn(message)
|
||||
shutil.rmtree(self.tempdir, onerror=onerror_handler)
|
||||
|
||||
|
||||
class ConfigTestCase(TempDirTestCase):
|
||||
"""Test class which sets up a NamespaceConfig object.
|
||||
|
||||
|
|
@ -358,47 +360,58 @@ class ConfigTestCase(TempDirTestCase):
|
|||
self.config.chain_path = constants.CLI_DEFAULTS['auth_chain_path']
|
||||
self.config.server = "https://example.com"
|
||||
|
||||
def lock_and_call(func, lock_path):
|
||||
"""Grab a lock for lock_path and call func.
|
||||
|
||||
:param callable func: object to call after acquiring the lock
|
||||
:param str lock_path: path to file or directory to lock
|
||||
|
||||
def lock_and_call(callback, path_to_lock):
|
||||
"""Grab a lock on path_to_lock from a foreign process and call the callback.
|
||||
:param callable callback: object to call after acquiring the lock
|
||||
:param str path_to_lock: path to file or directory to lock
|
||||
"""
|
||||
# Reload module to reset internal _LOCKS dictionary
|
||||
script = """\
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from certbot import lock
|
||||
|
||||
path_to_lock = sys.argv[1]
|
||||
trigger = sys.argv[2]
|
||||
|
||||
if os.path.isdir(path_to_lock):
|
||||
my_lock = lock.lock_dir(path_to_lock)
|
||||
else:
|
||||
my_lock = lock.LockFile(path_to_lock)
|
||||
try:
|
||||
open(trigger, 'w').close()
|
||||
while os.path.exists(trigger):
|
||||
time.sleep(1)
|
||||
finally:
|
||||
my_lock.release()
|
||||
"""
|
||||
# Reload certbot.util module to reset internal _LOCKS dictionary.
|
||||
reload_module(util)
|
||||
|
||||
# start child and wait for it to grab the lock
|
||||
cv = multiprocessing.Condition()
|
||||
cv.acquire()
|
||||
child_args = (cv, lock_path,)
|
||||
child = multiprocessing.Process(target=hold_lock, args=child_args)
|
||||
child.start()
|
||||
cv.wait()
|
||||
workspace = tempfile.mkdtemp()
|
||||
try:
|
||||
tmp_script = os.path.join(workspace, 'test_script.py')
|
||||
with open(tmp_script, 'w') as file_handle:
|
||||
file_handle.write(script)
|
||||
|
||||
# call func and terminate the child
|
||||
func()
|
||||
cv.notify()
|
||||
cv.release()
|
||||
child.join()
|
||||
assert child.exitcode == 0
|
||||
# Trigger file is used to coordinate current process and its subprocess.
|
||||
trigger = os.path.join(workspace, 'trigger')
|
||||
process = subprocess.Popen([sys.executable, tmp_script, path_to_lock, trigger])
|
||||
try:
|
||||
# Poll and wait for the lock to be acquired, spotted by the trigger file creation.
|
||||
while not os.path.exists(trigger):
|
||||
time.sleep(1)
|
||||
# Then execute the callback.
|
||||
callback()
|
||||
finally:
|
||||
# This will trigger the lock release in subprocess.
|
||||
os.remove(trigger)
|
||||
process.communicate()
|
||||
assert process.returncode == 0
|
||||
finally:
|
||||
shutil.rmtree(workspace)
|
||||
|
||||
def hold_lock(cv, lock_path): # pragma: no cover
|
||||
"""Acquire a file lock at lock_path and wait to release it.
|
||||
|
||||
:param multiprocessing.Condition cv: condition for synchronization
|
||||
:param str lock_path: path to the file lock
|
||||
|
||||
"""
|
||||
from certbot import lock
|
||||
if os.path.isdir(lock_path):
|
||||
my_lock = lock.lock_dir(lock_path)
|
||||
else:
|
||||
my_lock = lock.LockFile(lock_path)
|
||||
cv.acquire()
|
||||
cv.notify()
|
||||
cv.wait()
|
||||
my_lock.release()
|
||||
|
||||
def skip_on_windows(reason):
|
||||
"""Decorator to skip permanently a test on Windows. A reason is required."""
|
||||
|
|
@ -407,6 +420,7 @@ def skip_on_windows(reason):
|
|||
return unittest.skipIf(sys.platform == 'win32', reason)(function)
|
||||
return wrapper
|
||||
|
||||
|
||||
def broken_on_windows(function):
|
||||
"""Decorator to skip temporarily a broken test on Windows."""
|
||||
reason = 'Test is broken and ignored on windows but should be fixed.'
|
||||
|
|
@ -415,9 +429,10 @@ def broken_on_windows(function):
|
|||
and os.environ.get('SKIP_BROKEN_TESTS_ON_WINDOWS', 'true') == 'true',
|
||||
reason)(function)
|
||||
|
||||
|
||||
def temp_join(path):
|
||||
"""
|
||||
Return the given path joined to the tempdir path for the current platform
|
||||
Eg.: 'cert' => /tmp/cert (Linux) or 'C:\\Users\\currentuser\\AppData\\Temp\\cert' (Windows)
|
||||
"""
|
||||
return os.path.join(tempfile.gettempdir(), path)
|
||||
return os.path.join(tempfile.gettempdir(), path)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
import argparse
|
||||
import errno
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
|
@ -88,7 +87,6 @@ class LockDirUntilExit(test_util.TempDirTestCase):
|
|||
import certbot.util
|
||||
reload_module(certbot.util)
|
||||
|
||||
@test_util.broken_on_windows
|
||||
@mock.patch('certbot.util.logger')
|
||||
@mock.patch('certbot.util.atexit_register')
|
||||
def test_it(self, mock_register, mock_logger):
|
||||
|
|
@ -100,11 +98,15 @@ class LockDirUntilExit(test_util.TempDirTestCase):
|
|||
|
||||
self.assertEqual(mock_register.call_count, 1)
|
||||
registered_func = mock_register.call_args[0][0]
|
||||
shutil.rmtree(subdir)
|
||||
registered_func() # exception not raised
|
||||
# logger.debug is only called once because the second call
|
||||
# to lock subdir was ignored because it was already locked
|
||||
self.assertEqual(mock_logger.debug.call_count, 1)
|
||||
|
||||
from certbot import util
|
||||
# Despite lock_dir_until_exit has been called twice to subdir, its lock should have been
|
||||
# added only once. So we expect to have two lock references: for self.tempdir and subdir
|
||||
self.assertTrue(len(util._LOCKS) == 2) # pylint: disable=protected-access
|
||||
registered_func() # Exception should not be raised
|
||||
# Logically, logger.debug, that would be invoked in case of unlock failure,
|
||||
# should never been called.
|
||||
self.assertEqual(mock_logger.debug.call_count, 0)
|
||||
|
||||
|
||||
class SetUpCoreDirTest(test_util.TempDirTestCase):
|
||||
|
|
|
|||
|
|
@ -113,7 +113,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/0.30.2
|
||||
"". (default: CertbotACMEClient/0.31.0
|
||||
(certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX
|
||||
Installer/YYY (SUBCOMMAND; flags: FLAGS)
|
||||
Py/major.minor.patchlevel). The flags encoded in the
|
||||
|
|
@ -351,8 +351,9 @@ revoke:
|
|||
Specify reason for revoking certificate. (default:
|
||||
unspecified)
|
||||
--delete-after-revoke
|
||||
Delete certificates after revoking them. (default:
|
||||
None)
|
||||
Delete certificates after revoking them, along with
|
||||
all previous and later versions of those certificates.
|
||||
(default: None)
|
||||
--no-delete-after-revoke
|
||||
Do not delete certificates after revoking them. This
|
||||
option should be used with caution because the 'renew'
|
||||
|
|
@ -479,10 +480,9 @@ apache:
|
|||
Apache Web Server plugin
|
||||
|
||||
--apache-enmod APACHE_ENMOD
|
||||
Path to the Apache 'a2enmod' binary (default: a2enmod)
|
||||
Path to the Apache 'a2enmod' binary (default: None)
|
||||
--apache-dismod APACHE_DISMOD
|
||||
Path to the Apache 'a2dismod' binary (default:
|
||||
a2dismod)
|
||||
Path to the Apache 'a2dismod' binary (default: None)
|
||||
--apache-le-vhost-ext APACHE_LE_VHOST_EXT
|
||||
SSL vhost configuration extension (default: -le-
|
||||
ssl.conf)
|
||||
|
|
@ -496,16 +496,16 @@ apache:
|
|||
/var/log/apache2)
|
||||
--apache-challenge-location APACHE_CHALLENGE_LOCATION
|
||||
Directory path for challenge configuration (default:
|
||||
/etc/apache2)
|
||||
/etc/apache2/other)
|
||||
--apache-handle-modules APACHE_HANDLE_MODULES
|
||||
Let installer handle enabling required modules for you
|
||||
(Only Ubuntu/Debian currently) (default: True)
|
||||
(Only Ubuntu/Debian currently) (default: False)
|
||||
--apache-handle-sites APACHE_HANDLE_SITES
|
||||
Let installer handle enabling sites for you (Only
|
||||
Ubuntu/Debian currently) (default: True)
|
||||
Ubuntu/Debian currently) (default: False)
|
||||
--apache-ctl APACHE_CTL
|
||||
Full path to Apache control script (default:
|
||||
apache2ctl)
|
||||
apachectl)
|
||||
|
||||
dns-cloudflare:
|
||||
Obtain certificates using a DNS TXT record (if you are using Cloudflare
|
||||
|
|
|
|||
|
|
@ -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="0.30.2"
|
||||
LE_AUTO_VERSION="0.31.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -333,63 +333,11 @@ BootstrapDebCommon() {
|
|||
fi
|
||||
|
||||
augeas_pkg="libaugeas0 augeas-lenses"
|
||||
AUGVERSION=`LC_ALL=C apt-cache show --no-all-versions libaugeas0 | grep ^Version: | cut -d" " -f2`
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
YES_FLAG="-y"
|
||||
fi
|
||||
|
||||
AddBackportRepo() {
|
||||
# ARGS:
|
||||
BACKPORT_NAME="$1"
|
||||
BACKPORT_SOURCELINE="$2"
|
||||
say "To use the Apache Certbot plugin, augeas needs to be installed from $BACKPORT_NAME."
|
||||
if ! grep -v -e ' *#' /etc/apt/sources.list | grep -q "$BACKPORT_NAME" ; then
|
||||
# This can theoretically error if sources.list.d is empty, but in that case we don't care.
|
||||
if ! grep -v -e ' *#' /etc/apt/sources.list.d/* 2>/dev/null | grep -q "$BACKPORT_NAME"; then
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
/bin/echo -n "Installing augeas from $BACKPORT_NAME in 3 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -ne "\e[0K\rInstalling augeas from $BACKPORT_NAME in 2 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -e "\e[0K\rInstalling augeas from $BACKPORT_NAME in 1 second ..."
|
||||
sleep 1s
|
||||
add_backports=1
|
||||
else
|
||||
read -p "Would you like to enable the $BACKPORT_NAME repository [Y/n]? " response
|
||||
case $response in
|
||||
[yY][eE][sS]|[yY]|"")
|
||||
add_backports=1;;
|
||||
*)
|
||||
add_backports=0;;
|
||||
esac
|
||||
fi
|
||||
if [ "$add_backports" = 1 ]; then
|
||||
sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list"
|
||||
apt-get $QUIET_FLAG update
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$add_backports" != 0 ]; then
|
||||
apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg
|
||||
augeas_pkg=
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if dpkg --compare-versions 1.0 gt "$AUGVERSION" ; then
|
||||
if lsb_release -a | grep -q wheezy ; then
|
||||
AddBackportRepo wheezy-backports "deb http://http.debian.net/debian wheezy-backports main"
|
||||
elif lsb_release -a | grep -q precise ; then
|
||||
# XXX add ARM case
|
||||
AddBackportRepo precise-backports "deb http://archive.ubuntu.com/ubuntu precise-backports main restricted universe multiverse"
|
||||
else
|
||||
echo "No libaugeas0 version is available that's new enough to run the"
|
||||
echo "Certbot apache plugin..."
|
||||
fi
|
||||
# XXX add a case for ubuntu PPAs
|
||||
fi
|
||||
|
||||
apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \
|
||||
python \
|
||||
python-dev \
|
||||
|
|
@ -1140,9 +1088,9 @@ parsedatetime==2.1 \
|
|||
pbr==1.8.1 \
|
||||
--hash=sha256:46c8db75ae75a056bd1cc07fa21734fe2e603d11a07833ecc1eeb74c35c72e0c \
|
||||
--hash=sha256:e2127626a91e6c885db89668976db31020f0af2da728924b56480fc7ccf09649
|
||||
pyOpenSSL==16.2.0 \
|
||||
--hash=sha256:26ca380ddf272f7556e48064bbcd5bd71f83dfc144f3583501c7ddbd9434ee17 \
|
||||
--hash=sha256:7779a3bbb74e79db234af6a08775568c6769b5821faecf6e2f4143edb227516e
|
||||
pyOpenSSL==18.0.0 \
|
||||
--hash=sha256:26ff56a6b5ecaf3a2a59f132681e2a80afcc76b4f902f612f518f92c2a1bf854 \
|
||||
--hash=sha256:6488f1423b00f73b7ad5167885312bb0ce410d3312eb212393795b53c8caa580
|
||||
pyparsing==2.1.8 \
|
||||
--hash=sha256:2f0f5ceb14eccd5aef809d6382e87df22ca1da583c79f6db01675ce7d7f49c18 \
|
||||
--hash=sha256:03a4869b9f3493807ee1f1cb405e6d576a1a2ca4d81a982677c0c1ad6177c56b \
|
||||
|
|
@ -1232,18 +1180,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.30.2 \
|
||||
--hash=sha256:e411b72fa86eec1018e6de28e649e8c9c71191a7431dcc77f207b57ca9484c11 \
|
||||
--hash=sha256:534487cb552ced8e47948ba3d2e7ca12c3a439133fc609485012b1a02fc7776e
|
||||
acme==0.30.2 \
|
||||
--hash=sha256:68982576492dfa99c7e2be0fce4371adc9344740b05420ce0ab53238d2bb9b3b \
|
||||
--hash=sha256:295a5b7fce9f908e6e5cff8c40be1a3daf3e1ebabd2e139a4c87274e68eeb8f2
|
||||
certbot-apache==0.30.2 \
|
||||
--hash=sha256:3b7fa4e59772da7c9975ef2a49ceff157c9d7cb31eb9475928b5986d89701a3a \
|
||||
--hash=sha256:32fa915a8a51810fdfe828ac1361da4425c231d7384891e49e6338e4741464b2
|
||||
certbot-nginx==0.30.2 \
|
||||
--hash=sha256:7dc785f6f0c0c57b19cea8d98f9ea8feef53945613967b52c9348c81327010e2 \
|
||||
--hash=sha256:6ba4dd772d0c7cdfb3383ca325b35639e01ac9e142e4baa6445cd85c7fb59552
|
||||
certbot==0.31.0 \
|
||||
--hash=sha256:1a1b4b2675daf5266cc2cf2a44ded44de1d83e9541ffa078913c0e4c3231a1c4 \
|
||||
--hash=sha256:0c3196f80a102c0f9d82d566ba859efe3b70e9ed4670520224c844fafd930473
|
||||
acme==0.31.0 \
|
||||
--hash=sha256:a0c851f6b7845a0faa3a47a3e871440eed9ec11b4ab949de0dc4a0fb1201cd24 \
|
||||
--hash=sha256:7e5c2d01986e0f34ca08fee58981892704c82c48435dcd3592b424c312d8b2bf
|
||||
certbot-apache==0.31.0 \
|
||||
--hash=sha256:740bb55dd71723a21eebabb16e6ee5d8883f8b8f8cf6956dd1d4873e0cccae21 \
|
||||
--hash=sha256:cc4b840b2a439a63e2dce809272c3c3cd4b1aeefc4053cd188935135be137edd
|
||||
certbot-nginx==0.31.0 \
|
||||
--hash=sha256:7a1ffda9d93dc7c2aaf89452ce190250de8932e624d31ebba8e4fa7d950025c5 \
|
||||
--hash=sha256:d450d75650384f74baccb7673c89e2f52468afa478ed354eb6d4b99aa33bf865
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAlxLcw8ACgkQTRfJlc2X
|
||||
dfK35gf+PoxtrJJIjvybNqd3lb8HOg2ntIVmXcYJGuuUo6m09fzai+XI6cOm5Dpu
|
||||
l2D5OrbLqmez8tYkCkEWHV0OfwyVWw+m8T3sXlcrv14eA1RfgMnZ+cmmlpDskzHU
|
||||
EOtaXo1/IkLDwBRrsl8IUbwD2XxbjuLsA2Sevoa59NlfTXJUApfAzohl3epRiJjB
|
||||
gugdqcsfjRRAqQqOz+iJCKBCWSTIrr/g6Y9aZu9V93t/WDSLRFjehxO1GQrLnCnX
|
||||
17JGlr0/AXd67jOKS1OWmORPPAFfLIXezUMtgrz5hE7T5UviaUu9ySV8UCxq1N79
|
||||
cfSBb/HIUxZ0wf1CkTUMRFQpA7cGtw==
|
||||
=cNcT
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAlxcop8ACgkQTRfJlc2X
|
||||
dfIbZwf/faKu7IjLi0qFQ+kw8zaAnV47JDgfWqbR5GSdwWPqld+QyHlcRfPgwYma
|
||||
fKj9+g/FvPNPSfjHRRCoFrYvpZ4lZ+f4HPN9+OjydfM77rdDhVDwzs8dbKIk02yU
|
||||
0IEJhXj5Q9hF3TSDZcyXAJdBU1lz51ohtVIXelMBPmzhYPCZF47iE9/k9pApQi86
|
||||
RTji7hxPcF/n7mzXrbyTvk+kDxSdDlE0Eg9syK7XaFDBTa2lqgG8wTnMPVqhc/hm
|
||||
WM/uwkzbYarjy05ffV1kM683nP0rECnHlYT38pYcT2puw2kn/QthwR5j/jB/DWSc
|
||||
94Kw7BeMH651V8EaNwYIiouylnVH3A==
|
||||
=U+Qh
|
||||
-----END PGP SIGNATURE-----
|
||||
|
|
|
|||
|
|
@ -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="0.31.0.dev0"
|
||||
LE_AUTO_VERSION="0.32.0.dev0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -1180,18 +1180,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.30.2 \
|
||||
--hash=sha256:e411b72fa86eec1018e6de28e649e8c9c71191a7431dcc77f207b57ca9484c11 \
|
||||
--hash=sha256:534487cb552ced8e47948ba3d2e7ca12c3a439133fc609485012b1a02fc7776e
|
||||
acme==0.30.2 \
|
||||
--hash=sha256:68982576492dfa99c7e2be0fce4371adc9344740b05420ce0ab53238d2bb9b3b \
|
||||
--hash=sha256:295a5b7fce9f908e6e5cff8c40be1a3daf3e1ebabd2e139a4c87274e68eeb8f2
|
||||
certbot-apache==0.30.2 \
|
||||
--hash=sha256:3b7fa4e59772da7c9975ef2a49ceff157c9d7cb31eb9475928b5986d89701a3a \
|
||||
--hash=sha256:32fa915a8a51810fdfe828ac1361da4425c231d7384891e49e6338e4741464b2
|
||||
certbot-nginx==0.30.2 \
|
||||
--hash=sha256:7dc785f6f0c0c57b19cea8d98f9ea8feef53945613967b52c9348c81327010e2 \
|
||||
--hash=sha256:6ba4dd772d0c7cdfb3383ca325b35639e01ac9e142e4baa6445cd85c7fb59552
|
||||
certbot==0.31.0 \
|
||||
--hash=sha256:1a1b4b2675daf5266cc2cf2a44ded44de1d83e9541ffa078913c0e4c3231a1c4 \
|
||||
--hash=sha256:0c3196f80a102c0f9d82d566ba859efe3b70e9ed4670520224c844fafd930473
|
||||
acme==0.31.0 \
|
||||
--hash=sha256:a0c851f6b7845a0faa3a47a3e871440eed9ec11b4ab949de0dc4a0fb1201cd24 \
|
||||
--hash=sha256:7e5c2d01986e0f34ca08fee58981892704c82c48435dcd3592b424c312d8b2bf
|
||||
certbot-apache==0.31.0 \
|
||||
--hash=sha256:740bb55dd71723a21eebabb16e6ee5d8883f8b8f8cf6956dd1d4873e0cccae21 \
|
||||
--hash=sha256:cc4b840b2a439a63e2dce809272c3c3cd4b1aeefc4053cd188935135be137edd
|
||||
certbot-nginx==0.31.0 \
|
||||
--hash=sha256:7a1ffda9d93dc7c2aaf89452ce190250de8932e624d31ebba8e4fa7d950025c5 \
|
||||
--hash=sha256:d450d75650384f74baccb7673c89e2f52468afa478ed354eb6d4b99aa33bf865
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,12 +1,12 @@
|
|||
certbot==0.30.2 \
|
||||
--hash=sha256:e411b72fa86eec1018e6de28e649e8c9c71191a7431dcc77f207b57ca9484c11 \
|
||||
--hash=sha256:534487cb552ced8e47948ba3d2e7ca12c3a439133fc609485012b1a02fc7776e
|
||||
acme==0.30.2 \
|
||||
--hash=sha256:68982576492dfa99c7e2be0fce4371adc9344740b05420ce0ab53238d2bb9b3b \
|
||||
--hash=sha256:295a5b7fce9f908e6e5cff8c40be1a3daf3e1ebabd2e139a4c87274e68eeb8f2
|
||||
certbot-apache==0.30.2 \
|
||||
--hash=sha256:3b7fa4e59772da7c9975ef2a49ceff157c9d7cb31eb9475928b5986d89701a3a \
|
||||
--hash=sha256:32fa915a8a51810fdfe828ac1361da4425c231d7384891e49e6338e4741464b2
|
||||
certbot-nginx==0.30.2 \
|
||||
--hash=sha256:7dc785f6f0c0c57b19cea8d98f9ea8feef53945613967b52c9348c81327010e2 \
|
||||
--hash=sha256:6ba4dd772d0c7cdfb3383ca325b35639e01ac9e142e4baa6445cd85c7fb59552
|
||||
certbot==0.31.0 \
|
||||
--hash=sha256:1a1b4b2675daf5266cc2cf2a44ded44de1d83e9541ffa078913c0e4c3231a1c4 \
|
||||
--hash=sha256:0c3196f80a102c0f9d82d566ba859efe3b70e9ed4670520224c844fafd930473
|
||||
acme==0.31.0 \
|
||||
--hash=sha256:a0c851f6b7845a0faa3a47a3e871440eed9ec11b4ab949de0dc4a0fb1201cd24 \
|
||||
--hash=sha256:7e5c2d01986e0f34ca08fee58981892704c82c48435dcd3592b424c312d8b2bf
|
||||
certbot-apache==0.31.0 \
|
||||
--hash=sha256:740bb55dd71723a21eebabb16e6ee5d8883f8b8f8cf6956dd1d4873e0cccae21 \
|
||||
--hash=sha256:cc4b840b2a439a63e2dce809272c3c3cd4b1aeefc4053cd188935135be137edd
|
||||
certbot-nginx==0.31.0 \
|
||||
--hash=sha256:7a1ffda9d93dc7c2aaf89452ce190250de8932e624d31ebba8e4fa7d950025c5 \
|
||||
--hash=sha256:d450d75650384f74baccb7673c89e2f52468afa478ed354eb6d4b99aa33bf865
|
||||
|
|
|
|||
4
setup.py
4
setup.py
|
|
@ -38,7 +38,9 @@ install_requires = [
|
|||
'ConfigArgParse>=0.9.3',
|
||||
'configobj',
|
||||
'cryptography>=1.2.3', # load_pem_x509_certificate
|
||||
'josepy',
|
||||
# 1.1.0+ is required to avoid the warnings described at
|
||||
# https://github.com/certbot/josepy/issues/13.
|
||||
'josepy>=1.1.0',
|
||||
'mock',
|
||||
'parsedatetime>=1.3', # Calendar.parseDT
|
||||
'pyrfc3339',
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fi
|
|||
# started failing on newer distros with newer versions of OpenSSL.
|
||||
INITIAL_VERSION="0.17.0"
|
||||
git checkout -f "v$INITIAL_VERSION" letsencrypt-auto
|
||||
if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | grep "$INITIAL_VERSION" ; then
|
||||
if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | tail -n1 | grep "^certbot $INITIAL_VERSION$" ; then
|
||||
echo initial installation appeared to fail
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -85,7 +85,7 @@ if [ $(python -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') -eq 26 ];
|
|||
fi
|
||||
# Create a 2nd venv at the new path to ensure we properly handle this case
|
||||
export VENV_PATH="/opt/eff.org/certbot/venv"
|
||||
if ! sudo -E ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | grep "$INITIAL_VERSION" ; then
|
||||
if ! sudo -E ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | tail -n1 | grep "^certbot $INITIAL_VERSION$" ; then
|
||||
echo second installation appeared to fail
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -98,7 +98,7 @@ if ./letsencrypt-auto -v --debug --version | grep "WARNING: couldn't find Python
|
|||
fi
|
||||
|
||||
EXPECTED_VERSION=$(grep -m1 LE_AUTO_VERSION certbot-auto | cut -d\" -f2)
|
||||
if ! /opt/eff.org/certbot/venv/bin/letsencrypt --version 2>&1 | grep "$EXPECTED_VERSION" ; then
|
||||
if ! /opt/eff.org/certbot/venv/bin/letsencrypt --version 2>&1 | tail -n1 | grep "^certbot $EXPECTED_VERSION$" ; then
|
||||
echo upgrade appeared to fail
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ export VENV_ARGS="-p $PYTHON"
|
|||
# setup venv
|
||||
tools/_venv_common.py --requirement letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
. ./venv/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
|
||||
|
||||
# build sdists
|
||||
for pkg_dir in acme . $PLUGINS; do
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
#!/bin/sh -xe
|
||||
|
||||
LE_AUTO="letsencrypt/letsencrypt-auto-source/letsencrypt-auto"
|
||||
REPO_ROOT="letsencrypt"
|
||||
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="$REPO_ROOT/tools/pip_install.py"
|
||||
VENV_NAME=venv
|
||||
|
||||
# *-auto respects VENV_PATH
|
||||
$LE_AUTO --os-packages-only
|
||||
LE_AUTO_SUDO="" VENV_PATH="$VENV_NAME" $LE_AUTO --no-bootstrap --version
|
||||
. $VENV_NAME/bin/activate
|
||||
"$PIP_INSTALL" pytest
|
||||
|
||||
# change to an empty directory to ensure CWD doesn't affect tests
|
||||
cd $(mktemp -d)
|
||||
pip install pytest==3.2.5
|
||||
|
||||
for module in $MODULES ; do
|
||||
echo testing $module
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Download and run Pebble instance for integration testing
|
||||
set -xe
|
||||
|
||||
PEBBLE_VERSION=2018-11-02
|
||||
PEBBLE_VERSION=v1.0.1
|
||||
|
||||
# We reuse the same GOPATH-style directory than for Boulder.
|
||||
# Pebble does not need it, but it will make the installation consistent with Boulder's one.
|
||||
|
|
@ -13,15 +13,32 @@ mkdir -p ${PEBBLEPATH}
|
|||
|
||||
cat << UNLIKELY_EOF > "$PEBBLEPATH/docker-compose.yml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
pebble:
|
||||
image: letsencrypt/pebble:${PEBBLE_VERSION}
|
||||
command: pebble -strict ${PEBBLE_STRICT:-false} -dnsserver 10.77.77.1
|
||||
ports:
|
||||
- 14000:14000
|
||||
environment:
|
||||
pebble:
|
||||
image: letsencrypt/pebble:${PEBBLE_VERSION}
|
||||
command: pebble -dnsserver 10.30.50.3:8053
|
||||
environment:
|
||||
- PEBBLE_VA_NOSLEEP=1
|
||||
ports:
|
||||
- 14000:14000
|
||||
networks:
|
||||
acmenet:
|
||||
ipv4_address: 10.30.50.2
|
||||
challtestsrv:
|
||||
image: letsencrypt/pebble-challtestsrv:${PEBBLE_VERSION}
|
||||
command: pebble-challtestsrv -defaultIPv6 "" -defaultIPv4 10.30.50.1
|
||||
ports:
|
||||
- 8055:8055
|
||||
networks:
|
||||
acmenet:
|
||||
ipv4_address: 10.30.50.3
|
||||
networks:
|
||||
acmenet:
|
||||
driver: bridge
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.30.50.0/24
|
||||
UNLIKELY_EOF
|
||||
|
||||
docker-compose -f "$PEBBLEPATH/docker-compose.yml" up -d pebble
|
||||
|
|
|
|||
1
tox.ini
1
tox.ini
|
|
@ -166,7 +166,6 @@ passenv =
|
|||
HOME
|
||||
GOPATH
|
||||
PEBBLEPATH
|
||||
PEBBLE_STRICT
|
||||
setenv =
|
||||
SERVER=https://localhost:14000/dir
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue