mirror of
https://github.com/certbot/certbot.git
synced 2026-06-05 06:42:10 -04:00
Merge branch 'master' into snap-build-timeout
This commit is contained in:
commit
ff18b86144
78 changed files with 439 additions and 1376 deletions
|
|
@ -79,8 +79,6 @@ jobs:
|
|||
IMAGE_NAME: ubuntu-18.04
|
||||
PYTHON_VERSION: 3.8
|
||||
TOXENV: integration-dns-rfc2136
|
||||
le-auto-oraclelinux6:
|
||||
TOXENV: le_auto_oraclelinux6
|
||||
docker-dev:
|
||||
TOXENV: docker_dev
|
||||
macos-farmtest-apache2:
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ jobs:
|
|||
apache-compat:
|
||||
IMAGE_NAME: ubuntu-18.04
|
||||
TOXENV: apache_compat
|
||||
le-auto-centos6:
|
||||
le-modification:
|
||||
IMAGE_NAME: ubuntu-18.04
|
||||
TOXENV: le_auto_centos6
|
||||
TOXENV: modification
|
||||
apacheconftest:
|
||||
IMAGE_NAME: ubuntu-18.04
|
||||
PYTHON_VERSION: 2.7
|
||||
|
|
|
|||
|
|
@ -20,3 +20,10 @@ for mod in list(sys.modules):
|
|||
# preserved (acme.jose.* is josepy.*)
|
||||
if mod == 'josepy' or mod.startswith('josepy.'):
|
||||
sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
warnings.warn(
|
||||
"Python 2 support will be dropped in the next release of acme. "
|
||||
"Please upgrade your Python version.",
|
||||
PendingDeprecationWarning,
|
||||
) # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -327,6 +327,9 @@ class ApacheConfigurator(common.Installer):
|
|||
if self.version < (2, 2):
|
||||
raise errors.NotSupportedError(
|
||||
"Apache Version {0} not supported.".format(str(self.version)))
|
||||
elif self.version < (2, 4):
|
||||
logger.warning('Support for Apache 2.2 is deprecated and will be removed in a '
|
||||
'future release.')
|
||||
|
||||
# Recover from previous crash before Augeas initialization to have the
|
||||
# correct parse tree from the get go.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
32
certbot-auto
32
certbot-auto
|
|
@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
|||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="1.9.0"
|
||||
LE_AUTO_VERSION="1.10.1"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -799,11 +799,7 @@ BootstrapMageiaCommon() {
|
|||
# that function. If Bootstrap is set to a function that doesn't install any
|
||||
# packages BOOTSTRAP_VERSION is not set.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "Debian-based OSes"
|
||||
BootstrapDebCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapDebCommon $BOOTSTRAP_DEB_COMMON_VERSION"
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/mageia-release ]; then
|
||||
# Mageia has both /etc/mageia-release and /etc/redhat-release
|
||||
DEPRECATED_OS=1
|
||||
|
|
@ -1497,18 +1493,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==1.9.0 \
|
||||
--hash=sha256:d5a804d32e471050921f7b39ed9859e2e9de02824176ed78f57266222036b53a \
|
||||
--hash=sha256:2ff9bf7d9af381c7efee22dec2dd6938d9d8fddcc9e11682b86e734164a30b57
|
||||
acme==1.9.0 \
|
||||
--hash=sha256:d8061b396a22b21782c9b23ff9a945b23e50fca2573909a42f845e11d5658ac5 \
|
||||
--hash=sha256:38a1630c98e144136c62eec4d2c545a1bdb1a3cd4eca82214be6b83a1f5a161f
|
||||
certbot-apache==1.9.0 \
|
||||
--hash=sha256:09528a820d57e54984d490100644cd8a6603db97bf5776f86e95795ecfacf23d \
|
||||
--hash=sha256:f47fb3f4a9bd927f4812121a0beefe56b163475a28f4db34c64dc838688d9e9e
|
||||
certbot-nginx==1.9.0 \
|
||||
--hash=sha256:bb2e3f7fe17f071f350a3efa48571b8ef40a8e4b6db9c6da72539206a20b70be \
|
||||
--hash=sha256:ab26a4f49d53b0e8bf0f903e58e2a840cda233fe1cbbc54c36ff17f973e57d65
|
||||
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
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""General purpose nginx test configuration generator."""
|
||||
import getpass
|
||||
|
||||
|
|
@ -42,6 +43,8 @@ events {{
|
|||
worker_connections 1024;
|
||||
}}
|
||||
|
||||
# “This comment contains valid Unicode”.
|
||||
|
||||
http {{
|
||||
# Set an array of temp, cache and log file options that will otherwise default to
|
||||
# restricted locations accessible only to root.
|
||||
|
|
@ -51,61 +54,61 @@ http {{
|
|||
#scgi_temp_path {nginx_root}/scgi_temp;
|
||||
#uwsgi_temp_path {nginx_root}/uwsgi_temp;
|
||||
access_log {nginx_root}/error.log;
|
||||
|
||||
|
||||
# This should be turned off in a Virtualbox VM, as it can cause some
|
||||
# interesting issues with data corruption in delivered files.
|
||||
sendfile off;
|
||||
|
||||
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
|
||||
#include /etc/nginx/mime.types;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] $status '
|
||||
'"$request" $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
|
||||
default_type application/octet-stream;
|
||||
|
||||
|
||||
server {{
|
||||
# IPv4.
|
||||
listen {http_port} {default_server};
|
||||
# IPv6.
|
||||
listen [::]:{http_port} {default_server};
|
||||
server_name nginx.{wtf_prefix}.wtf nginx2.{wtf_prefix}.wtf;
|
||||
|
||||
|
||||
root {nginx_webroot};
|
||||
|
||||
|
||||
location / {{
|
||||
# First attempt to serve request as file, then as directory, then fall
|
||||
# back to index.html.
|
||||
try_files $uri $uri/ /index.html;
|
||||
}}
|
||||
}}
|
||||
|
||||
|
||||
server {{
|
||||
listen {http_port};
|
||||
listen [::]:{http_port};
|
||||
server_name nginx3.{wtf_prefix}.wtf;
|
||||
|
||||
|
||||
root {nginx_webroot};
|
||||
|
||||
|
||||
location /.well-known/ {{
|
||||
return 404;
|
||||
}}
|
||||
|
||||
|
||||
return 301 https://$host$request_uri;
|
||||
}}
|
||||
|
||||
|
||||
server {{
|
||||
listen {other_port};
|
||||
listen [::]:{other_port};
|
||||
server_name nginx4.{wtf_prefix}.wtf nginx5.{wtf_prefix}.wtf;
|
||||
}}
|
||||
|
||||
|
||||
server {{
|
||||
listen {http_port};
|
||||
listen [::]:{http_port};
|
||||
|
|
|
|||
|
|
@ -149,10 +149,10 @@ class ACMEServer(object):
|
|||
[pebble_path, '-config', pebble_config_path, '-dnsserver', dns_server, '-strict'],
|
||||
env=environ)
|
||||
|
||||
# pebble_ocsp_server is imported here and not at the top of module in order to avoid a useless
|
||||
# ImportError, in the case where cryptography dependency is too old to support ocsp, but
|
||||
# Boulder is used instead of Pebble, so pebble_ocsp_server is not used. This is the typical
|
||||
# situation of integration-certbot-oldest tox testenv.
|
||||
# pebble_ocsp_server is imported here and not at the top of module in order to avoid a
|
||||
# useless ImportError, in the case where cryptography dependency is too old to support ocsp,
|
||||
# but Boulder is used instead of Pebble, so pebble_ocsp_server is not used. This is the
|
||||
# typical situation of integration-certbot-oldest tox testenv.
|
||||
from certbot_integration_tests.utils import pebble_ocsp_server
|
||||
self._launch_process([sys.executable, pebble_ocsp_server.__file__])
|
||||
|
||||
|
|
@ -178,11 +178,12 @@ class ACMEServer(object):
|
|||
|
||||
if self._dns_server:
|
||||
# Change Boulder config to use the provided DNS server
|
||||
with open(join(instance_path, 'test/config/va.json'), 'r') as file_h:
|
||||
config = json.loads(file_h.read())
|
||||
config['va']['dnsResolvers'] = [self._dns_server]
|
||||
with open(join(instance_path, 'test/config/va.json'), 'w') as file_h:
|
||||
file_h.write(json.dumps(config, indent=2, separators=(',', ': ')))
|
||||
for suffix in ["", "-remote-a", "-remote-b"]:
|
||||
with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'r') as f:
|
||||
config = json.loads(f.read())
|
||||
config['va']['dnsResolvers'] = [self._dns_server]
|
||||
with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'w') as f:
|
||||
f.write(json.dumps(config, indent=2, separators=(',', ': ')))
|
||||
|
||||
try:
|
||||
# Launch the Boulder server
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ def _prepare_args_env(certbot_args, directory_url, http_01_port, tls_alpn_01_por
|
|||
'--no-verify-ssl',
|
||||
'--http-01-port', str(http_01_port),
|
||||
'--https-port', str(tls_alpn_01_port),
|
||||
'--manual-public-ip-logging-ok',
|
||||
'--config-dir', config_dir,
|
||||
'--work-dir', os.path.join(workspace, 'work'),
|
||||
'--logs-dir', os.path.join(workspace, 'logs'),
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ See https://docs.pytest.org/en/latest/reference.html#hook-reference
|
|||
from __future__ import print_function
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -85,9 +85,13 @@ class _GoogleClient(object):
|
|||
|
||||
scopes = ['https://www.googleapis.com/auth/ndev.clouddns.readwrite']
|
||||
if account_json is not None:
|
||||
credentials = ServiceAccountCredentials.from_json_keyfile_name(account_json, scopes)
|
||||
with open(account_json) as account:
|
||||
self.project_id = json.load(account)['project_id']
|
||||
try:
|
||||
credentials = ServiceAccountCredentials.from_json_keyfile_name(account_json, scopes)
|
||||
with open(account_json) as account:
|
||||
self.project_id = json.load(account)['project_id']
|
||||
except Exception as e:
|
||||
raise errors.PluginError(
|
||||
"Error parsing credentials file '{}': {}".format(account_json, e))
|
||||
else:
|
||||
credentials = None
|
||||
self.project_id = self.get_project_id()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -107,6 +107,17 @@ class GoogleClientTest(unittest.TestCase):
|
|||
self.assertFalse(credential_mock.called)
|
||||
self.assertTrue(get_project_id_mock.called)
|
||||
|
||||
@mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name')
|
||||
def test_client_bad_credentials_file(self, credential_mock):
|
||||
credential_mock.side_effect = ValueError('Some exception buried in oauth2client')
|
||||
with self.assertRaises(errors.PluginError) as cm:
|
||||
self._setUp_client_with_mock([])
|
||||
self.assertEqual(
|
||||
str(cm.exception),
|
||||
"Error parsing credentials file '/not/a/real/path.json': "
|
||||
"Some exception buried in oauth2client"
|
||||
)
|
||||
|
||||
@mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name')
|
||||
@mock.patch('certbot_dns_google._internal.dns_google.open',
|
||||
mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""A class that performs HTTP-01 challenges for Nginx"""
|
||||
|
||||
import io
|
||||
import logging
|
||||
|
||||
from acme import challenges
|
||||
|
|
@ -102,7 +103,7 @@ class NginxHttp01(common.ChallengePerformer):
|
|||
self.configurator.reverter.register_file_creation(
|
||||
True, self.challenge_conf)
|
||||
|
||||
with open(self.challenge_conf, "w") as new_conf:
|
||||
with io.open(self.challenge_conf, "w", encoding="utf-8") as new_conf:
|
||||
nginxparser.dump(config, new_conf)
|
||||
|
||||
def _default_listen_addresses(self):
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from pyparsing import stringEnd
|
|||
from pyparsing import White
|
||||
from pyparsing import ZeroOrMore
|
||||
import six
|
||||
from acme.magic_typing import IO, Any # pylint: disable=unused-import
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -130,26 +131,27 @@ def load(_file):
|
|||
|
||||
|
||||
def dumps(blocks):
|
||||
"""Dump to a string.
|
||||
# type: (UnspacedList) -> six.text_type
|
||||
"""Dump to a Unicode string.
|
||||
|
||||
:param UnspacedList block: The parsed tree
|
||||
:param int indentation: The number of spaces to indent
|
||||
:rtype: str
|
||||
:rtype: six.text_type
|
||||
|
||||
"""
|
||||
return str(RawNginxDumper(blocks.spaced))
|
||||
return six.text_type(RawNginxDumper(blocks.spaced))
|
||||
|
||||
|
||||
def dump(blocks, _file):
|
||||
# type: (UnspacedList, IO[Any]) -> None
|
||||
"""Dump to a file.
|
||||
|
||||
:param UnspacedList block: The parsed tree
|
||||
:param file _file: The file to dump to
|
||||
:param int indentation: The number of spaces to indent
|
||||
:rtype: NoneType
|
||||
:param IO[Any] _file: The file stream to dump to. It must be opened with
|
||||
Unicode encoding.
|
||||
:rtype: None
|
||||
|
||||
"""
|
||||
return _file.write(dumps(blocks))
|
||||
_file.write(dumps(blocks))
|
||||
|
||||
|
||||
spacey = lambda x: (isinstance(x, six.string_types) and x.isspace()) or x == ''
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ class NginxParser(object):
|
|||
continue
|
||||
out = nginxparser.dumps(tree)
|
||||
logger.debug('Writing nginx conf tree to %s:\n%s', filename, out)
|
||||
with open(filename, 'w') as _file:
|
||||
with io.open(filename, 'w', encoding='utf-8') as _file:
|
||||
_file.write(out)
|
||||
|
||||
except IOError:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from setuptools import __version__ as setuptools_version
|
|||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.10.0.dev0'
|
||||
version = '1.11.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -492,6 +492,14 @@ class NginxParserTest(util.NginxTest):
|
|||
self.assertEqual(['server'], parsed[0][2][0])
|
||||
self.assertEqual(['listen', '80'], parsed[0][2][1][3])
|
||||
|
||||
def test_valid_unicode_roundtrip(self):
|
||||
"""This tests the parser's ability to load and save a config containing Unicode"""
|
||||
nparser = parser.NginxParser(self.config_path)
|
||||
nparser._parse_files(
|
||||
nparser.abs_path('valid_unicode_comments.conf')
|
||||
) # pylint: disable=protected-access
|
||||
nparser.filedump(lazy=False)
|
||||
|
||||
def test_invalid_unicode_characters(self):
|
||||
with self.assertLogs() as log:
|
||||
nparser = parser.NginxParser(self.config_path)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,38 @@
|
|||
|
||||
Certbot adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## 1.10.0 - master
|
||||
## 1.11.0 - master
|
||||
|
||||
### Added
|
||||
|
||||
*
|
||||
|
||||
### Changed
|
||||
|
||||
* We deprecated support for Python 2 in Certbot and its ACME library.
|
||||
Support for Python 2 will be removed in the next planned release of Certbot.
|
||||
* certbot-auto was deprecated on all systems.
|
||||
* We deprecated support for Apache 2.2 in the certbot-apache plugin and it will
|
||||
be removed in a future release of Certbot.
|
||||
|
||||
### Fixed
|
||||
|
||||
* The Certbot snap no longer loads packages installed via `pip install --user`. This
|
||||
was unintended and DNS plugins should be installed via `snap` instead.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
## 1.10.1 - 2020-12-03
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a bug in `certbot.util.add_deprecated_argument` that caused the
|
||||
deprecated `--manual-public-ip-logging-ok` flag to crash Certbot in some
|
||||
scenarios.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
## 1.10.0 - 2020-12-01
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -10,7 +41,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
* Confirmation when deleting certificates
|
||||
* CLI flag `--key-type` has been added to specify 'rsa' or 'ecdsa' (default 'rsa').
|
||||
* CLI flag `--elliptic-curve` has been added which takes an NIST/SECG elliptic curve. Any of
|
||||
`secp256r1`, `secp284r1` and `secp521r1` are accepted values.
|
||||
`secp256r1`, `secp384r1` and `secp521r1` are accepted values.
|
||||
* The command `certbot certficates` lists the which type of the private key that was used
|
||||
for the private key.
|
||||
* Support for Python 3.9 was added to Certbot and all of its components.
|
||||
|
|
@ -20,11 +51,10 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
* certbot-auto was deprecated on Debian based systems.
|
||||
* CLI flag `--manual-public-ip-logging-ok` is now a no-op, generates a
|
||||
deprecation warning, and will be removed in a future release.
|
||||
*
|
||||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
* Fixed a Unicode-related crash in the nginx plugin when running under Python 2.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ Current Features
|
|||
* Can get domain-validated (DV) certificates.
|
||||
* Can revoke certificates.
|
||||
* Adjustable RSA key bit-length (2048 (default), 4096, ...).
|
||||
* Adjustable [EC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)
|
||||
* Adjustable `EC <https://en.wikipedia.org/wiki/Elliptic-curve_cryptography>`_
|
||||
key (`secp256r1` (default), `secp384r1`, `secp521r1`).
|
||||
* Can optionally install a http -> https redirect, so your site effectively
|
||||
runs https only (Apache only)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
"""Certbot client."""
|
||||
import warnings
|
||||
import sys
|
||||
|
||||
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
|
||||
__version__ = '1.10.0.dev0'
|
||||
__version__ = '1.11.0.dev0'
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
warnings.warn(
|
||||
"Python 2 support will be dropped in the next release of Certbot. "
|
||||
"Please upgrade your Python version.",
|
||||
PendingDeprecationWarning,
|
||||
) # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
from __future__ import print_function
|
||||
import argparse
|
||||
import copy
|
||||
import functools
|
||||
import glob
|
||||
import sys
|
||||
|
||||
import configargparse
|
||||
import six
|
||||
import zope.component
|
||||
|
|
@ -356,6 +358,18 @@ class HelpfulArgumentParser(object):
|
|||
:param dict **kwargs: various argparse settings for this argument
|
||||
|
||||
"""
|
||||
action = kwargs.get("action")
|
||||
if action is util.DeprecatedArgumentAction:
|
||||
# If the argument is deprecated through
|
||||
# certbot.util.add_deprecated_argument, it is not shown in the help
|
||||
# output and any value given to the argument is thrown away during
|
||||
# argument parsing. Because of this, we handle this case early
|
||||
# skipping putting the argument in different help topics and
|
||||
# handling default detection since these actions aren't needed and
|
||||
# can cause bugs like
|
||||
# https://github.com/certbot/certbot/issues/8495.
|
||||
self.parser.add_argument(*args, **kwargs)
|
||||
return
|
||||
|
||||
if isinstance(topics, list):
|
||||
# if this flag can be listed in multiple sections, try to pick the one
|
||||
|
|
@ -410,8 +424,22 @@ class HelpfulArgumentParser(object):
|
|||
:param int nargs: Number of arguments the option takes.
|
||||
|
||||
"""
|
||||
util.add_deprecated_argument(
|
||||
self.parser.add_argument, argument_name, num_args)
|
||||
# certbot.util.add_deprecated_argument expects the normal add_argument
|
||||
# interface provided by argparse. This is what is given including when
|
||||
# certbot.util.add_deprecated_argument is used by plugins, however, in
|
||||
# that case the first argument to certbot.util.add_deprecated_argument
|
||||
# is certbot._internal.cli.HelpfulArgumentGroup.add_argument which
|
||||
# internally calls the add method of this class.
|
||||
#
|
||||
# The difference between the add method of this class and the standard
|
||||
# argparse add_argument method caused a bug in the past (see
|
||||
# https://github.com/certbot/certbot/issues/8495) so we use the same
|
||||
# code path here for consistency and to ensure it works. To do that, we
|
||||
# wrap the add method in a similar way to
|
||||
# HelpfulArgumentGroup.add_argument by providing a help topic (which in
|
||||
# this case is set to None).
|
||||
add_func = functools.partial(self.add, None)
|
||||
util.add_deprecated_argument(add_func, argument_name, num_args)
|
||||
|
||||
def add_group(self, topic, verbs=(), **kwargs):
|
||||
"""Create a new argument group.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import print_function
|
|||
import functools
|
||||
import logging.handlers
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import configobj
|
||||
import josepy as jose
|
||||
|
|
@ -1402,6 +1403,13 @@ def main(cli_args=None):
|
|||
if config.func != plugins_cmd: # pylint: disable=comparison-with-callable
|
||||
raise
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
warnings.warn(
|
||||
"Python 2 support will be dropped in the next release of Certbot. "
|
||||
"Please upgrade your Python version.",
|
||||
PendingDeprecationWarning,
|
||||
) # pragma: no cover
|
||||
|
||||
set_displayer(config)
|
||||
|
||||
# Reporter
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"""Null plugin."""
|
||||
import logging
|
||||
|
||||
import zope.component
|
||||
import zope.interface
|
||||
|
||||
from certbot import interfaces
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import zope.component
|
|||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Optional # pylint: disable=unused-import
|
||||
from certbot import crypto_util
|
||||
from certbot.display import util as display_util
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
|
|
@ -347,40 +348,42 @@ def report(msgs, category):
|
|||
|
||||
def _renew_describe_results(config, renew_successes, renew_failures,
|
||||
renew_skipped, parse_failures):
|
||||
# type: (interfaces.IConfig, List[str], List[str], List[str], List[str]) -> None
|
||||
"""
|
||||
Print a report to the terminal about the results of the renewal process.
|
||||
|
||||
out = [] # type: List[str]
|
||||
notify = out.append
|
||||
disp = zope.component.getUtility(interfaces.IDisplay)
|
||||
:param interfaces.IConfig config: Configuration
|
||||
:param list renew_successes: list of fullchain paths which were renewed
|
||||
:param list renew_failures: list of fullchain paths which failed to be renewed
|
||||
:param list renew_skipped: list of messages to print about skipped certificates
|
||||
:param list parse_failures: list of renewal parameter paths which had erorrs
|
||||
"""
|
||||
notify = display_util.notify
|
||||
notify_error = logger.error
|
||||
|
||||
def notify_error(err):
|
||||
"""Notify and log errors."""
|
||||
notify(str(err))
|
||||
logger.error(err)
|
||||
notify('\n{}'.format(display_util.SIDE_FRAME))
|
||||
|
||||
renewal_noun = "simulated renewal" if config.dry_run else "renewal"
|
||||
|
||||
if config.dry_run:
|
||||
notify("** DRY RUN: simulating 'certbot renew' close to cert expiry")
|
||||
notify("** (The test certificates below have not been saved.)")
|
||||
notify("")
|
||||
if renew_skipped:
|
||||
notify("The following certs are not due for renewal yet:")
|
||||
notify(report(renew_skipped, "skipped"))
|
||||
if not renew_successes and not renew_failures:
|
||||
notify("No renewals were attempted.")
|
||||
notify("No {renewal}s were attempted.".format(renewal=renewal_noun))
|
||||
if (config.pre_hook is not None or
|
||||
config.renew_hook is not None or config.post_hook is not None):
|
||||
notify("No hooks were run.")
|
||||
elif renew_successes and not renew_failures:
|
||||
notify("Congratulations, all renewals succeeded. The following certs "
|
||||
"have been renewed:")
|
||||
notify("Congratulations, all {renewal}s succeeded: ".format(renewal=renewal_noun))
|
||||
notify(report(renew_successes, "success"))
|
||||
elif renew_failures and not renew_successes:
|
||||
notify_error("All renewal attempts failed. The following certs could "
|
||||
"not be renewed:")
|
||||
notify_error("All %ss failed. The following certs could "
|
||||
"not be renewed:", renewal_noun)
|
||||
notify_error(report(renew_failures, "failure"))
|
||||
elif renew_failures and renew_successes:
|
||||
notify("The following certs were successfully renewed:")
|
||||
notify("The following {renewal}s succeeded:".format(renewal=renewal_noun))
|
||||
notify(report(renew_successes, "success") + "\n")
|
||||
notify_error("The following certs could not be renewed:")
|
||||
notify_error("The following %ss failed:", renewal_noun)
|
||||
notify_error(report(renew_failures, "failure"))
|
||||
|
||||
if parse_failures:
|
||||
|
|
@ -388,11 +391,7 @@ def _renew_describe_results(config, renew_successes, renew_failures,
|
|||
"were invalid: ")
|
||||
notify(report(parse_failures, "parsefail"))
|
||||
|
||||
if config.dry_run:
|
||||
notify("** DRY RUN: simulating 'certbot renew' close to cert expiry")
|
||||
notify("** (The test certificates above have not been saved.)")
|
||||
|
||||
disp.notification("\n".join(out), wrap=False)
|
||||
notify(display_util.SIDE_FRAME)
|
||||
|
||||
|
||||
def handle_renewal_request(config):
|
||||
|
|
@ -482,9 +481,10 @@ def handle_renewal_request(config):
|
|||
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
# obtain_cert (presumably) encountered an unanticipated problem.
|
||||
logger.warning("Attempting to renew cert (%s) from %s produced an "
|
||||
"unexpected error: %s. Skipping.", lineagename,
|
||||
renewal_file, e)
|
||||
logger.error(
|
||||
"Failed to renew cert %s with error: %s",
|
||||
lineagename, e
|
||||
)
|
||||
logger.debug("Traceback was:\n%s", traceback.format_exc())
|
||||
renew_failures.append(renewal_candidate.fullchain)
|
||||
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ def safe_email(email):
|
|||
return False
|
||||
|
||||
|
||||
class _ShowWarning(argparse.Action):
|
||||
class DeprecatedArgumentAction(argparse.Action):
|
||||
"""Action to log a warning when an argument is used."""
|
||||
def __call__(self, unused1, unused2, unused3, option_string=None):
|
||||
logger.warning("Use of %s is deprecated.", option_string)
|
||||
|
|
@ -458,16 +458,16 @@ def add_deprecated_argument(add_argument, argument_name, nargs):
|
|||
:param nargs: Value for nargs when adding the argument to argparse.
|
||||
|
||||
"""
|
||||
if _ShowWarning not in configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE:
|
||||
if DeprecatedArgumentAction not in configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE:
|
||||
# In version 0.12.0 ACTION_TYPES_THAT_DONT_NEED_A_VALUE was
|
||||
# changed from a set to a tuple.
|
||||
if isinstance(configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE, set):
|
||||
configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE.add(
|
||||
_ShowWarning)
|
||||
DeprecatedArgumentAction)
|
||||
else:
|
||||
configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE += (
|
||||
_ShowWarning,)
|
||||
add_argument(argument_name, action=_ShowWarning,
|
||||
DeprecatedArgumentAction,)
|
||||
add_argument(argument_name, action=DeprecatedArgumentAction,
|
||||
help=argparse.SUPPRESS, nargs=nargs)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
usage:
|
||||
usage:
|
||||
certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...
|
||||
|
||||
Certbot can obtain and install HTTPS/TLS/SSL certificates. By default,
|
||||
|
|
@ -118,12 +118,12 @@ 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.9.0 (certbot(-auto);
|
||||
OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY
|
||||
(SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel).
|
||||
The flags encoded in the user agent are: --duplicate,
|
||||
--force-renew, --allow-subset-of-names, -n, and
|
||||
whether any hooks are set.
|
||||
"". (default: CertbotACMEClient/1.10.1
|
||||
(certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX
|
||||
Installer/YYY (SUBCOMMAND; flags: FLAGS)
|
||||
Py/major.minor.patchlevel). The flags encoded in the
|
||||
user agent are: --duplicate, --force-renew, --allow-
|
||||
subset-of-names, -n, and whether any hooks are set.
|
||||
--user-agent-comment USER_AGENT_COMMENT
|
||||
Add a comment to the default user agent string. May be
|
||||
used when repackaging Certbot or calling it from
|
||||
|
|
@ -188,12 +188,12 @@ security:
|
|||
Security parameters & server settings
|
||||
|
||||
--rsa-key-size N Size of the RSA key. (default: 2048)
|
||||
--key-type type The type of algorithm to use for the the private key.
|
||||
Either ``rsa`` or ``ecdsa``. (default: ``rsa``).
|
||||
--elliptic-curve The elliptic curve to use when choosing ``ecdsa`` as the key
|
||||
type. Accepted values are SECG curve names as defined by
|
||||
the cryptography library. ``secp256r1``, ``secp384r1``,
|
||||
``secp521r1``. (default: secp256r1).
|
||||
--key-type {rsa,ecdsa}
|
||||
Type of generated private key(Only *ONE* per
|
||||
invocation can be provided at this time) (default:
|
||||
rsa)
|
||||
--elliptic-curve N The SECG elliptic curve name to use. Please see RFC
|
||||
8446 for supported values. (default: secp256r1)
|
||||
--must-staple Adds the OCSP Must Staple extension to the
|
||||
certificate. Autoconfigures OCSP Stapling for
|
||||
supported setups (Apache version >= 2.3.3 ). (default:
|
||||
|
|
@ -694,8 +694,6 @@ manual:
|
|||
--manual-cleanup-hook MANUAL_CLEANUP_HOOK
|
||||
Path or command to execute for the cleanup script
|
||||
(default: None)
|
||||
--manual-public-ip-logging-ok
|
||||
Automatically allows public IP logging (default: Ask)
|
||||
|
||||
nginx:
|
||||
Nginx Web Server plugin
|
||||
|
|
|
|||
|
|
@ -516,11 +516,13 @@ Steps:
|
|||
4. Run ``tox --skip-missing-interpreters`` to run the entire test suite
|
||||
including coverage. The ``--skip-missing-interpreters`` argument ignores
|
||||
missing versions of Python needed for running the tests. Fix any errors.
|
||||
5. Submit the PR. Once your PR is open, please do not force push to the branch
|
||||
5. If any documentation should be added or updated as part of the changes you
|
||||
have made, please include the documentation changes in your PR.
|
||||
6. Submit the PR. Once your PR is open, please do not force push to the branch
|
||||
containing your pull request to squash or amend commits. We use `squash
|
||||
merges <https://github.com/blog/2141-squash-your-commits>`_ on PRs and
|
||||
rewriting commits makes changes harder to track between reviews.
|
||||
6. Did your tests pass on Azure Pipelines? If they didn't, fix any errors.
|
||||
7. Did your tests pass on Azure Pipelines? If they didn't, fix any errors.
|
||||
|
||||
.. _ask for help:
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ except ImportError: # pragma: no cover
|
|||
from certbot import errors
|
||||
from certbot import util
|
||||
from certbot._internal import account
|
||||
from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
import certbot.tests.util as test_util
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"""Tests for certbot.compat.filesystem"""
|
||||
import contextlib
|
||||
import errno
|
||||
import stat
|
||||
import unittest
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
"""Tests for certbot.helpful_parser"""
|
||||
import unittest
|
||||
|
||||
try:
|
||||
import mock
|
||||
except ImportError: # pragma: no cover
|
||||
from unittest import mock
|
||||
|
||||
from certbot import errors
|
||||
from certbot._internal.cli import HelpfulArgumentParser
|
||||
from certbot._internal.cli import _DomainsAction
|
||||
|
|
@ -189,5 +194,16 @@ class TestParseArgsErrors(unittest.TestCase):
|
|||
arg_parser.parse_args()
|
||||
|
||||
|
||||
class TestAddDeprecatedArgument(unittest.TestCase):
|
||||
"""Tests for add_deprecated_argument method of HelpfulArgumentParser"""
|
||||
|
||||
@mock.patch.object(HelpfulArgumentParser, "modify_kwargs_for_default_detection")
|
||||
def test_no_default_detection_modifications(self, mock_modify):
|
||||
arg_parser = HelpfulArgumentParser(["run"], {}, detect_defaults=True)
|
||||
arg_parser.add_deprecated_argument("--foo", 0)
|
||||
arg_parser.parse_args()
|
||||
mock_modify.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -163,5 +163,70 @@ class RestoreRequiredConfigElementsTest(test_util.ConfigTestCase):
|
|||
self.assertEqual(self.config.server, constants.CLI_DEFAULTS['server'])
|
||||
|
||||
|
||||
class DescribeResultsTest(unittest.TestCase):
|
||||
"""Tests for certbot._internal.renewal._renew_describe_results."""
|
||||
def setUp(self):
|
||||
self.patchers = {
|
||||
'log_error': mock.patch('certbot._internal.renewal.logger.error'),
|
||||
'notify': mock.patch('certbot._internal.renewal.display_util.notify')}
|
||||
self.mock_notify = self.patchers['notify'].start()
|
||||
self.mock_error = self.patchers['log_error'].start()
|
||||
|
||||
def tearDown(self):
|
||||
for patch in self.patchers.values():
|
||||
patch.stop()
|
||||
|
||||
@classmethod
|
||||
def _call(cls, *args, **kwargs):
|
||||
from certbot._internal.renewal import _renew_describe_results
|
||||
_renew_describe_results(*args, **kwargs)
|
||||
|
||||
def _assert_success_output(self, lines):
|
||||
self.mock_notify.assert_has_calls([mock.call(l) for l in lines])
|
||||
|
||||
def test_no_renewal_attempts(self):
|
||||
self._call(mock.MagicMock(dry_run=True), [], [], [], [])
|
||||
self._assert_success_output(['No simulated renewals were attempted.'])
|
||||
|
||||
def test_successful_renewal(self):
|
||||
self._call(mock.MagicMock(dry_run=False), ['good.pem'], None, None, None)
|
||||
self._assert_success_output([
|
||||
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
'Congratulations, all renewals succeeded: ',
|
||||
' good.pem (success)',
|
||||
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
])
|
||||
|
||||
def test_failed_renewal(self):
|
||||
self._call(mock.MagicMock(dry_run=False), [], ['bad.pem'], [], [])
|
||||
self._assert_success_output([
|
||||
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
])
|
||||
self.mock_error.assert_has_calls([
|
||||
mock.call('All %ss failed. The following certs could not be renewed:', 'renewal'),
|
||||
mock.call(' bad.pem (failure)'),
|
||||
])
|
||||
|
||||
def test_all_renewal(self):
|
||||
self._call(mock.MagicMock(dry_run=True),
|
||||
['good.pem', 'good2.pem'], ['bad.pem', 'bad2.pem'],
|
||||
['foo.pem expires on 123'], ['errored.conf'])
|
||||
self._assert_success_output([
|
||||
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
'The following certs are not due for renewal yet:',
|
||||
' foo.pem expires on 123 (skipped)',
|
||||
'The following simulated renewals succeeded:',
|
||||
' good.pem (success)\n good2.pem (success)\n',
|
||||
'\nAdditionally, the following renewal configurations were invalid: ',
|
||||
' errored.conf (parsefail)',
|
||||
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
|
||||
])
|
||||
self.mock_error.assert_has_calls([
|
||||
mock.call('The following %ss failed:', 'simulated renewal'),
|
||||
mock.call(' bad.pem (failure)\n bad2.pem (failure)'),
|
||||
])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -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.9.0"
|
||||
LE_AUTO_VERSION="1.10.1"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -799,11 +799,7 @@ BootstrapMageiaCommon() {
|
|||
# that function. If Bootstrap is set to a function that doesn't install any
|
||||
# packages BOOTSTRAP_VERSION is not set.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "Debian-based OSes"
|
||||
BootstrapDebCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapDebCommon $BOOTSTRAP_DEB_COMMON_VERSION"
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/mageia-release ]; then
|
||||
# Mageia has both /etc/mageia-release and /etc/redhat-release
|
||||
DEPRECATED_OS=1
|
||||
|
|
@ -1497,18 +1493,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==1.9.0 \
|
||||
--hash=sha256:d5a804d32e471050921f7b39ed9859e2e9de02824176ed78f57266222036b53a \
|
||||
--hash=sha256:2ff9bf7d9af381c7efee22dec2dd6938d9d8fddcc9e11682b86e734164a30b57
|
||||
acme==1.9.0 \
|
||||
--hash=sha256:d8061b396a22b21782c9b23ff9a945b23e50fca2573909a42f845e11d5658ac5 \
|
||||
--hash=sha256:38a1630c98e144136c62eec4d2c545a1bdb1a3cd4eca82214be6b83a1f5a161f
|
||||
certbot-apache==1.9.0 \
|
||||
--hash=sha256:09528a820d57e54984d490100644cd8a6603db97bf5776f86e95795ecfacf23d \
|
||||
--hash=sha256:f47fb3f4a9bd927f4812121a0beefe56b163475a28f4db34c64dc838688d9e9e
|
||||
certbot-nginx==1.9.0 \
|
||||
--hash=sha256:bb2e3f7fe17f071f350a3efa48571b8ef40a8e4b6db9c6da72539206a20b70be \
|
||||
--hash=sha256:ab26a4f49d53b0e8bf0f903e58e2a840cda233fe1cbbc54c36ff17f973e57d65
|
||||
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
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
# For running tests, build a docker image with a passwordless sudo and a trust
|
||||
# store we can manipulate.
|
||||
|
||||
ARG REDHAT_DIST_FLAVOR
|
||||
FROM ${REDHAT_DIST_FLAVOR}:6
|
||||
|
||||
ARG REDHAT_DIST_FLAVOR
|
||||
|
||||
RUN curl -O https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm \
|
||||
&& rpm -ivh epel-release-latest-6.noarch.rpm
|
||||
|
||||
# Install pip and sudo:
|
||||
RUN yum install -y python-pip sudo
|
||||
# Update to a stable and tested version of pip.
|
||||
# We do not use pipstrap here because it no longer supports Python 2.6.
|
||||
RUN pip install pip==9.0.1 setuptools==29.0.1 wheel==0.29.0
|
||||
# Pin pytest version for increased stability
|
||||
RUN pip install pytest==3.2.5 six==1.10.0
|
||||
|
||||
# Add an unprivileged user:
|
||||
RUN useradd --create-home --home-dir /home/lea --shell /bin/bash --groups wheel --uid 1000 lea
|
||||
|
||||
# Let that user sudo:
|
||||
RUN sed -i.bkp -e \
|
||||
's/# %wheel\(NOPASSWD: ALL\)\?/%wheel/g' \
|
||||
/etc/sudoers
|
||||
|
||||
RUN mkdir -p /home/lea/certbot
|
||||
|
||||
# Install fake testing CA:
|
||||
COPY ./tests/certs/ca/my-root-ca.crt.pem /usr/local/share/ca-certificates/
|
||||
RUN update-ca-trust
|
||||
|
||||
# Copy current letsencrypt-auto:
|
||||
COPY . /home/lea/certbot/letsencrypt-auto-source
|
||||
|
||||
# Tweak uname binary for tests on fake 32bits
|
||||
COPY tests/uname_wrapper.sh /bin
|
||||
RUN mv /bin/uname /bin/uname_orig \
|
||||
&& mv /bin/uname_wrapper.sh /bin/uname \
|
||||
&& chmod +x /bin/uname
|
||||
|
||||
# Fetch previous letsencrypt-auto that was installing python 3.4
|
||||
RUN curl https://raw.githubusercontent.com/certbot/certbot/v0.38.0/letsencrypt-auto-source/letsencrypt-auto \
|
||||
-o /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34 \
|
||||
&& chmod +x /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34
|
||||
|
||||
RUN cp /home/lea/certbot/letsencrypt-auto-source/tests/${REDHAT_DIST_FLAVOR}6_tests.sh /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh \
|
||||
&& chmod +x /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh
|
||||
|
||||
USER lea
|
||||
WORKDIR /home/lea
|
||||
|
||||
CMD ["sudo", "certbot/letsencrypt-auto-source/tests/redhat6_tests.sh"]
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl98wk8ACgkQTRfJlc2X
|
||||
dfIctgf/TO83xXJJ8haqxke0ehHCwcmipX7ijPhwvaUTSqciMa56KnGJLNp1lAVz
|
||||
vv8sfHUf7NSvGlRg+5M0szWY25+JzveJDNzse3rOzFmxA1GNKUycE3/zE/IdBRwN
|
||||
fmxJHaUBrBL2erBZPHe8gFGTvlzopBoGSmQpWGY3hIufPWKBJohCbTscKbaa9hyz
|
||||
njmMvwRdeqzvLWVZ4jNDDsil9kKl2Emue3guzA/cvVxHe17DZyLDfqni7ysZIcTn
|
||||
wPAQzpLBKHyiqVRoVk+BJ6Z6wamW4NAxKbjXy9GrHy4txlfW8tGd3jXha8yWqJeH
|
||||
xEFK02Zp+T17+C5uqEW4o0cIofMjCw==
|
||||
=9UGf
|
||||
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
|
||||
-----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="1.10.0.dev0"
|
||||
LE_AUTO_VERSION="1.11.0.dev0"
|
||||
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.9.0 \
|
||||
--hash=sha256:d5a804d32e471050921f7b39ed9859e2e9de02824176ed78f57266222036b53a \
|
||||
--hash=sha256:2ff9bf7d9af381c7efee22dec2dd6938d9d8fddcc9e11682b86e734164a30b57
|
||||
acme==1.9.0 \
|
||||
--hash=sha256:d8061b396a22b21782c9b23ff9a945b23e50fca2573909a42f845e11d5658ac5 \
|
||||
--hash=sha256:38a1630c98e144136c62eec4d2c545a1bdb1a3cd4eca82214be6b83a1f5a161f
|
||||
certbot-apache==1.9.0 \
|
||||
--hash=sha256:09528a820d57e54984d490100644cd8a6603db97bf5776f86e95795ecfacf23d \
|
||||
--hash=sha256:f47fb3f4a9bd927f4812121a0beefe56b163475a28f4db34c64dc838688d9e9e
|
||||
certbot-nginx==1.9.0 \
|
||||
--hash=sha256:bb2e3f7fe17f071f350a3efa48571b8ef40a8e4b6db9c6da72539206a20b70be \
|
||||
--hash=sha256:ab26a4f49d53b0e8bf0f903e58e2a840cda233fe1cbbc54c36ff17f973e57d65
|
||||
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
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -326,6 +326,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.
|
||||
|
|
@ -358,12 +359,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
|
||||
|
|
@ -382,18 +378,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
|
||||
|
||||
|
|
@ -411,10 +396,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
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
certbot==1.9.0 \
|
||||
--hash=sha256:d5a804d32e471050921f7b39ed9859e2e9de02824176ed78f57266222036b53a \
|
||||
--hash=sha256:2ff9bf7d9af381c7efee22dec2dd6938d9d8fddcc9e11682b86e734164a30b57
|
||||
acme==1.9.0 \
|
||||
--hash=sha256:d8061b396a22b21782c9b23ff9a945b23e50fca2573909a42f845e11d5658ac5 \
|
||||
--hash=sha256:38a1630c98e144136c62eec4d2c545a1bdb1a3cd4eca82214be6b83a1f5a161f
|
||||
certbot-apache==1.9.0 \
|
||||
--hash=sha256:09528a820d57e54984d490100644cd8a6603db97bf5776f86e95795ecfacf23d \
|
||||
--hash=sha256:f47fb3f4a9bd927f4812121a0beefe56b163475a28f4db34c64dc838688d9e9e
|
||||
certbot-nginx==1.9.0 \
|
||||
--hash=sha256:bb2e3f7fe17f071f350a3efa48571b8ef40a8e4b6db9c6da72539206a20b70be \
|
||||
--hash=sha256:ab26a4f49d53b0e8bf0f903e58e2a840cda233fe1cbbc54c36ff17f973e57d65
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
"""Tests for letsencrypt-auto
|
||||
|
||||
Run these locally by saying... ::
|
||||
|
||||
./build.py && docker build -t lea . -f Dockerfile.<distro> && docker run --rm -t -i lea
|
||||
|
||||
"""
|
||||
|
|
@ -1,503 +0,0 @@
|
|||
"""Tests for letsencrypt-auto"""
|
||||
|
||||
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from json import dumps
|
||||
from os import chmod, environ, makedirs, stat
|
||||
from os.path import abspath, dirname, exists, join
|
||||
import re
|
||||
from shutil import copy, rmtree
|
||||
import socket
|
||||
import ssl
|
||||
from stat import S_IMODE, S_IRUSR, S_IWUSR, S_IXUSR, S_IWGRP, S_IWOTH
|
||||
from subprocess import CalledProcessError, Popen, PIPE
|
||||
import sys
|
||||
from tempfile import mkdtemp
|
||||
from threading import Thread
|
||||
from unittest import TestCase
|
||||
|
||||
from pytest import mark
|
||||
from six.moves import xrange # pylint: disable=redefined-builtin
|
||||
|
||||
|
||||
@mark.skip
|
||||
def tests_dir():
|
||||
"""Return a path to the "tests" directory."""
|
||||
return dirname(abspath(__file__))
|
||||
|
||||
|
||||
def copy_stable(src, dst):
|
||||
"""
|
||||
Copy letsencrypt-auto, and replace its current version to its equivalent stable one.
|
||||
This is needed to test correctly the self-upgrade functionality.
|
||||
"""
|
||||
copy(src, dst)
|
||||
with open(dst, 'r') as file:
|
||||
filedata = file.read()
|
||||
filedata = re.sub(r'LE_AUTO_VERSION="(.*)\.dev0"', r'LE_AUTO_VERSION="\1"', filedata)
|
||||
with open(dst, 'w') as file:
|
||||
file.write(filedata)
|
||||
|
||||
|
||||
sys.path.insert(0, dirname(tests_dir()))
|
||||
from build import build as build_le_auto
|
||||
|
||||
|
||||
BOOTSTRAP_FILENAME = 'certbot-auto-bootstrap-version.txt'
|
||||
"""Name of the file where certbot-auto saves its bootstrap version."""
|
||||
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
"""An HTTPS request handler which is quiet and serves a specific folder."""
|
||||
|
||||
def __init__(self, resources, *args, **kwargs):
|
||||
"""
|
||||
:arg resources: A dict of resource paths pointing to content bytes
|
||||
|
||||
"""
|
||||
self.resources = resources
|
||||
BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
"""Don't log each request to the terminal."""
|
||||
|
||||
def do_GET(self):
|
||||
"""Serve a GET request."""
|
||||
content = self.send_head()
|
||||
if content is not None:
|
||||
self.wfile.write(content)
|
||||
|
||||
def send_head(self):
|
||||
"""Common code for GET and HEAD commands
|
||||
|
||||
This sends the response code and MIME headers and returns either a
|
||||
bytestring of content or, if none is found, None.
|
||||
|
||||
"""
|
||||
path = self.path[1:] # Strip leading slash.
|
||||
content = self.resources.get(path)
|
||||
if content is None:
|
||||
self.send_error(404, 'Path "%s" not found in self.resources' % path)
|
||||
else:
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.send_header('Content-Length', str(len(content)))
|
||||
self.end_headers()
|
||||
return content
|
||||
|
||||
|
||||
def server_and_port(resources):
|
||||
"""Return an unstarted HTTPS server and the port it will use."""
|
||||
# Find a port, and bind to it. I can't get the OS to close the socket
|
||||
# promptly after we shut down the server, so we typically need to try
|
||||
# a couple ports after the first test case. Setting
|
||||
# TCPServer.allow_reuse_address = True seems to have nothing to do
|
||||
# with this behavior.
|
||||
worked = False
|
||||
for port in xrange(4443, 4543):
|
||||
try:
|
||||
server = HTTPServer(('localhost', port),
|
||||
partial(RequestHandler, resources))
|
||||
except socket.error:
|
||||
pass
|
||||
else:
|
||||
worked = True
|
||||
server.socket = ssl.wrap_socket(
|
||||
server.socket,
|
||||
certfile=join(tests_dir(), 'certs', 'localhost', 'server.pem'),
|
||||
server_side=True)
|
||||
break
|
||||
if not worked:
|
||||
raise RuntimeError("Couldn't find an unused socket for the testing HTTPS server.")
|
||||
return server, port
|
||||
|
||||
|
||||
@contextmanager
|
||||
def serving(resources):
|
||||
"""Spin up a local HTTPS server, and yield its base URL.
|
||||
|
||||
Use a self-signed cert generated as outlined by
|
||||
https://coolaj86.com/articles/create-your-own-certificate-authority-for-
|
||||
testing/.
|
||||
|
||||
"""
|
||||
server, port = server_and_port(resources)
|
||||
thread = Thread(target=server.serve_forever)
|
||||
try:
|
||||
thread.start()
|
||||
yield 'https://localhost:{port}/'.format(port=port)
|
||||
finally:
|
||||
server.shutdown()
|
||||
thread.join()
|
||||
|
||||
|
||||
LE_AUTO_PATH = join(dirname(tests_dir()), 'letsencrypt-auto')
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temp_paths():
|
||||
"""Creates and deletes paths for letsencrypt-auto and its venv."""
|
||||
dir = mkdtemp(prefix='le-test-')
|
||||
try:
|
||||
yield join(dir, 'letsencrypt-auto'), join(dir, 'venv')
|
||||
finally:
|
||||
rmtree(dir, ignore_errors=True)
|
||||
|
||||
|
||||
def out_and_err(command, input=None, shell=False, env=None):
|
||||
"""Run a shell command, and return stderr and stdout as string.
|
||||
|
||||
If the command returns nonzero, raise CalledProcessError.
|
||||
|
||||
:arg command: A list of commandline args
|
||||
:arg input: Data to pipe to stdin. Omit for none.
|
||||
|
||||
Remaining args have the same meaning as for Popen.
|
||||
|
||||
"""
|
||||
process = Popen(command,
|
||||
stdout=PIPE,
|
||||
stdin=PIPE,
|
||||
stderr=PIPE,
|
||||
shell=shell,
|
||||
env=env)
|
||||
out, err = process.communicate(input=input)
|
||||
status = process.poll() # same as in check_output(), though wait() sounds better
|
||||
if status:
|
||||
error = CalledProcessError(status, command)
|
||||
error.output = out
|
||||
print('stdout output was:')
|
||||
print(out)
|
||||
print('stderr output was:')
|
||||
print(err)
|
||||
raise error
|
||||
return out, err
|
||||
|
||||
|
||||
def signed(content, private_key_name='signing.key'):
|
||||
"""Return the signed SHA-256 hash of ``content``, using the given key file."""
|
||||
command = ['openssl', 'dgst', '-sha256', '-sign',
|
||||
join(tests_dir(), private_key_name)]
|
||||
out, err = out_and_err(command, input=content)
|
||||
return out
|
||||
|
||||
|
||||
def install_le_auto(contents, install_path):
|
||||
"""Install some given source code as the letsencrypt-auto script at the
|
||||
root level of a virtualenv.
|
||||
|
||||
:arg contents: The contents of the built letsencrypt-auto script
|
||||
:arg install_path: The path where to install the script
|
||||
|
||||
"""
|
||||
with open(install_path, 'w') as le_auto:
|
||||
le_auto.write(contents)
|
||||
chmod(install_path, S_IRUSR | S_IXUSR)
|
||||
|
||||
|
||||
def run_le_auto(le_auto_path, venv_dir, base_url=None, le_auto_args_str='--version', **kwargs):
|
||||
"""Run the prebuilt version of letsencrypt-auto, returning stdout and
|
||||
stderr strings.
|
||||
|
||||
If the command returns other than 0, raise CalledProcessError.
|
||||
|
||||
"""
|
||||
env = environ.copy()
|
||||
d = dict(VENV_PATH=venv_dir,
|
||||
NO_CERT_VERIFY='1',
|
||||
**kwargs)
|
||||
|
||||
if base_url is not None:
|
||||
# URL to PyPI-style JSON that tell us the latest released version
|
||||
# of LE:
|
||||
d['LE_AUTO_JSON_URL'] = base_url + 'certbot/json'
|
||||
# URL to dir containing letsencrypt-auto and letsencrypt-auto.sig:
|
||||
d['LE_AUTO_DIR_TEMPLATE'] = base_url + '%s/'
|
||||
# The public key corresponding to signing.key:
|
||||
d['LE_AUTO_PUBLIC_KEY'] = """-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMoSzLYQ7E1sdSOkwelg
|
||||
tzKIh2qi3bpXuYtcfFC0XrvWig071NwIj+dZiT0OLZ2hPispEH0B7ISuuWg1ll7G
|
||||
hFW0VdbxL6JdGzS2ShNWkX9hE9z+j8VqwDPOBn3ZHm03qwpYkBDwQib3KqOdYbTT
|
||||
uUtJmmGcuk3a9Aq/sCT6DdfmTSdP5asdQYwIcaQreDrOosaS84DTWI3IU+UYJVgl
|
||||
LsIVPBuy9IcgHidUQ96hJnoPsDCWsHwX62495QKEarauyKQrJzFes0EY95orDM47
|
||||
Z5o/NDiQB11m91yNB0MmPYY9QSbnOA9j7IaaC97AwRLuwXY+/R2ablTcxurWou68
|
||||
iQIDAQAB
|
||||
-----END PUBLIC KEY-----"""
|
||||
|
||||
env.update(d)
|
||||
|
||||
return out_and_err(
|
||||
le_auto_path + ' ' + le_auto_args_str,
|
||||
shell=True,
|
||||
env=env)
|
||||
|
||||
|
||||
def set_le_script_version(venv_dir, version):
|
||||
"""Tell the letsencrypt script to report a certain version.
|
||||
|
||||
We actually replace the script with a dummy version that knows only how to
|
||||
print its version.
|
||||
|
||||
"""
|
||||
letsencrypt_path = join(venv_dir, 'bin', 'letsencrypt')
|
||||
with open(letsencrypt_path, 'w') as script:
|
||||
script.write("#!/usr/bin/env python\n"
|
||||
"from sys import stderr\n"
|
||||
"stderr.write('letsencrypt %s\\n')" % version)
|
||||
chmod(letsencrypt_path, S_IRUSR | S_IXUSR)
|
||||
|
||||
|
||||
def sudo_chmod(path, mode):
|
||||
"""Runs `sudo chmod mode path`."""
|
||||
mode = oct(mode).replace('o', '')
|
||||
out_and_err(['sudo', 'chmod', mode, path])
|
||||
|
||||
|
||||
class AutoTests(TestCase):
|
||||
"""Test the major branch points of letsencrypt-auto:
|
||||
|
||||
* An le-auto upgrade is needed.
|
||||
* An le-auto upgrade is not needed.
|
||||
* There was an out-of-date LE script installed.
|
||||
* There was a current LE script installed.
|
||||
* There was no LE script installed (less important).
|
||||
* Pip hash-verification passes.
|
||||
* Pip has a hash mismatch.
|
||||
* The OpenSSL sig matches.
|
||||
* The OpenSSL sig mismatches.
|
||||
|
||||
For tests which get to the end, we run merely ``letsencrypt --version``.
|
||||
The functioning of the rest of the certbot script is covered by other
|
||||
test suites.
|
||||
|
||||
"""
|
||||
NEW_LE_AUTO = build_le_auto(
|
||||
version='99.9.9',
|
||||
requirements='letsencrypt==99.9.9 --hash=sha256:1cc14d61ab424cdee446f51e50f1123f8482ec740587fe78626c933bba2873a0')
|
||||
NEW_LE_AUTO_SIG = signed(NEW_LE_AUTO)
|
||||
|
||||
def test_successes(self):
|
||||
"""Exercise most branches of letsencrypt-auto.
|
||||
|
||||
They just happen to be the branches in which everything goes well.
|
||||
|
||||
I violate my usual rule of having small, decoupled tests, because...
|
||||
|
||||
1. We shouldn't need to run a Cartesian product of the branches: the
|
||||
phases run in separate shell processes, containing state leakage
|
||||
pretty effectively. The only shared state is FS state, and it's
|
||||
limited to a temp dir, assuming (if we dare) all functions properly.
|
||||
2. One combination of branches happens to set us up nicely for testing
|
||||
the next, saving code.
|
||||
|
||||
"""
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
# This serves a PyPI page with a higher version, a GitHub-alike
|
||||
# with a corresponding le-auto script, and a matching signature.
|
||||
resources = {'certbot/json': dumps({'releases': {'99.9.9': None}}),
|
||||
'v99.9.9/letsencrypt-auto': self.NEW_LE_AUTO,
|
||||
'v99.9.9/letsencrypt-auto.sig': self.NEW_LE_AUTO_SIG}
|
||||
with serving(resources) as base_url:
|
||||
run_letsencrypt_auto = partial(
|
||||
run_le_auto,
|
||||
le_auto_path,
|
||||
venv_dir,
|
||||
base_url,
|
||||
PIP_FIND_LINKS=join(tests_dir(),
|
||||
'fake-letsencrypt',
|
||||
'dist'))
|
||||
|
||||
# Test when a phase-1 upgrade is needed, there's no LE binary
|
||||
# installed, and pip hashes verify:
|
||||
install_le_auto(build_le_auto(version='50.0.0'), le_auto_path)
|
||||
out, err = run_letsencrypt_auto()
|
||||
self.assertTrue(re.match(r'letsencrypt \d+\.\d+\.\d+',
|
||||
err.strip().splitlines()[-1]))
|
||||
# Make a few assertions to test the validity of the next tests:
|
||||
self.assertTrue('Upgrading certbot-auto ' in out)
|
||||
self.assertTrue('Creating virtual environment...' in out)
|
||||
|
||||
# Now we have le-auto 99.9.9 and LE 99.9.9 installed. This
|
||||
# conveniently sets us up to test the next 2 cases.
|
||||
|
||||
# Test when neither phase-1 upgrade nor phase-2 upgrade is
|
||||
# needed (probably a common case):
|
||||
out, err = run_letsencrypt_auto()
|
||||
self.assertFalse('Upgrading certbot-auto ' in out)
|
||||
self.assertFalse('Creating virtual environment...' in out)
|
||||
|
||||
def test_phase2_upgrade(self):
|
||||
"""Test a phase-2 upgrade without a phase-1 upgrade."""
|
||||
resources = {'certbot/json': dumps({'releases': {'99.9.9': None}}),
|
||||
'v99.9.9/letsencrypt-auto': self.NEW_LE_AUTO,
|
||||
'v99.9.9/letsencrypt-auto.sig': self.NEW_LE_AUTO_SIG}
|
||||
with serving(resources) as base_url:
|
||||
pip_find_links=join(tests_dir(), 'fake-letsencrypt', 'dist')
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
install_le_auto(self.NEW_LE_AUTO, le_auto_path)
|
||||
|
||||
# Create venv saving the correct bootstrap script version
|
||||
out, err = run_le_auto(le_auto_path, venv_dir, base_url,
|
||||
PIP_FIND_LINKS=pip_find_links)
|
||||
self.assertFalse('Upgrading certbot-auto ' in out)
|
||||
self.assertTrue('Creating virtual environment...' in out)
|
||||
with open(join(venv_dir, BOOTSTRAP_FILENAME)) as f:
|
||||
bootstrap_version = f.read()
|
||||
|
||||
# Create a new venv with an old letsencrypt version
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
venv_bin = join(venv_dir, 'bin')
|
||||
makedirs(venv_bin)
|
||||
set_le_script_version(venv_dir, '0.0.1')
|
||||
with open(join(venv_dir, BOOTSTRAP_FILENAME), 'w') as f:
|
||||
f.write(bootstrap_version)
|
||||
|
||||
install_le_auto(self.NEW_LE_AUTO, le_auto_path)
|
||||
out, err = run_le_auto(le_auto_path, venv_dir, base_url,
|
||||
PIP_FIND_LINKS=pip_find_links)
|
||||
|
||||
self.assertFalse('Upgrading certbot-auto ' in out)
|
||||
self.assertTrue('Creating virtual environment...' in out)
|
||||
|
||||
def test_openssl_failure(self):
|
||||
"""Make sure we stop if the openssl signature check fails."""
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
# Serve an unrelated hash signed with the good key (easier than
|
||||
# making a bad key, and a mismatch is a mismatch):
|
||||
resources = {'': '<a href="certbot/">certbot/</a>',
|
||||
'certbot/json': dumps({'releases': {'99.9.9': None}}),
|
||||
'v99.9.9/letsencrypt-auto': build_le_auto(version='99.9.9'),
|
||||
'v99.9.9/letsencrypt-auto.sig': signed('something else')}
|
||||
with serving(resources) as base_url:
|
||||
copy_stable(LE_AUTO_PATH, le_auto_path)
|
||||
try:
|
||||
out, err = run_le_auto(le_auto_path, venv_dir, base_url)
|
||||
except CalledProcessError as exc:
|
||||
self.assertEqual(exc.returncode, 1)
|
||||
self.assertTrue("Couldn't verify signature of downloaded "
|
||||
"certbot-auto." in exc.output)
|
||||
else:
|
||||
print(out)
|
||||
self.fail('Signature check on certbot-auto erroneously passed.')
|
||||
|
||||
def test_pip_failure(self):
|
||||
"""Make sure pip stops us if there is a hash mismatch."""
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
resources = {'': '<a href="certbot/">certbot/</a>',
|
||||
'certbot/json': dumps({'releases': {'99.9.9': None}})}
|
||||
with serving(resources) as base_url:
|
||||
# Build a le-auto script embedding a bad requirements file:
|
||||
install_le_auto(
|
||||
build_le_auto(
|
||||
version='99.9.9',
|
||||
requirements='configobj==5.0.6 --hash=sha256:badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb'),
|
||||
le_auto_path)
|
||||
try:
|
||||
out, err = run_le_auto(le_auto_path, venv_dir, base_url)
|
||||
except CalledProcessError as exc:
|
||||
self.assertEqual(exc.returncode, 1)
|
||||
self.assertTrue("THESE PACKAGES DO NOT MATCH THE HASHES "
|
||||
"FROM THE REQUIREMENTS FILE" in exc.output)
|
||||
self.assertFalse(
|
||||
exists(venv_dir),
|
||||
msg="The virtualenv was left around, even though "
|
||||
"installation didn't succeed. We shouldn't do "
|
||||
"this, as it foils our detection of whether we "
|
||||
"need to recreate the virtualenv, which hinges "
|
||||
"on the presence of $VENV_BIN/letsencrypt.")
|
||||
else:
|
||||
self.fail("Pip didn't detect a bad hash and stop the "
|
||||
"installation.")
|
||||
|
||||
def test_permissions_warnings(self):
|
||||
"""Make sure letsencrypt-auto properly warns about permissions problems."""
|
||||
# This test assumes that only the parent of the directory containing
|
||||
# letsencrypt-auto (usually /tmp) may have permissions letsencrypt-auto
|
||||
# considers insecure.
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
le_auto_path = abspath(le_auto_path)
|
||||
le_auto_dir = dirname(le_auto_path)
|
||||
le_auto_dir_parent = dirname(le_auto_dir)
|
||||
install_le_auto(self.NEW_LE_AUTO, le_auto_path)
|
||||
|
||||
run_letsencrypt_auto = partial(
|
||||
run_le_auto, le_auto_path, venv_dir,
|
||||
le_auto_args_str='--install-only --no-self-upgrade',
|
||||
PIP_FIND_LINKS=join(tests_dir(), 'fake-letsencrypt', 'dist'))
|
||||
# Run letsencrypt-auto once with current permissions to avoid
|
||||
# potential problems when the script tries to write to temporary
|
||||
# directories.
|
||||
run_letsencrypt_auto()
|
||||
|
||||
le_auto_dir_mode = stat(le_auto_dir).st_mode
|
||||
le_auto_dir_parent_mode = S_IMODE(stat(le_auto_dir_parent).st_mode)
|
||||
try:
|
||||
# Make letsencrypt-auto happy with the current permissions
|
||||
chmod(le_auto_dir, S_IRUSR | S_IXUSR)
|
||||
sudo_chmod(le_auto_dir_parent, 0o755)
|
||||
|
||||
self._test_permissions_warnings_about_path(le_auto_path, run_letsencrypt_auto)
|
||||
self._test_permissions_warnings_about_path(le_auto_dir, run_letsencrypt_auto)
|
||||
finally:
|
||||
chmod(le_auto_dir, le_auto_dir_mode)
|
||||
sudo_chmod(le_auto_dir_parent, le_auto_dir_parent_mode)
|
||||
|
||||
def _test_permissions_warnings_about_path(self, path, run_le_auto_func):
|
||||
# Test that there are no problems with the current permissions
|
||||
out, _ = run_le_auto_func()
|
||||
self.assertFalse('insecure permissions' in out)
|
||||
|
||||
stat_result = stat(path)
|
||||
original_mode = stat_result.st_mode
|
||||
|
||||
# Test world permissions
|
||||
chmod(path, original_mode | S_IWOTH)
|
||||
out, _ = run_le_auto_func()
|
||||
self.assertTrue('insecure permissions' in out)
|
||||
|
||||
# Test group permissions
|
||||
if stat_result.st_gid >= 1000:
|
||||
chmod(path, original_mode | S_IWGRP)
|
||||
out, _ = run_le_auto_func()
|
||||
self.assertTrue('insecure permissions' in out)
|
||||
|
||||
# Test owner permissions
|
||||
if stat_result.st_uid >= 1000:
|
||||
chmod(path, original_mode | S_IWUSR)
|
||||
out, _ = run_le_auto_func()
|
||||
self.assertTrue('insecure permissions' in out)
|
||||
|
||||
# Test that permissions were properly restored
|
||||
chmod(path, original_mode)
|
||||
out, _ = run_le_auto_func()
|
||||
self.assertFalse('insecure permissions' in out)
|
||||
|
||||
def test_disabled_permissions_warnings(self):
|
||||
"""Make sure that letsencrypt-auto permissions warnings can be disabled."""
|
||||
with temp_paths() as (le_auto_path, venv_dir):
|
||||
le_auto_path = abspath(le_auto_path)
|
||||
install_le_auto(self.NEW_LE_AUTO, le_auto_path)
|
||||
|
||||
le_auto_args_str='--install-only --no-self-upgrade'
|
||||
pip_links=join(tests_dir(), 'fake-letsencrypt', 'dist')
|
||||
out, _ = run_le_auto(le_auto_path, venv_dir,
|
||||
le_auto_args_str=le_auto_args_str,
|
||||
PIP_FIND_LINKS=pip_links)
|
||||
self.assertTrue('insecure permissions' in out)
|
||||
|
||||
# Test that warnings are disabled when the script isn't run as
|
||||
# root.
|
||||
out, _ = run_le_auto(le_auto_path, venv_dir,
|
||||
le_auto_args_str=le_auto_args_str,
|
||||
LE_AUTO_SUDO='',
|
||||
PIP_FIND_LINKS=pip_links)
|
||||
self.assertFalse('insecure permissions' in out)
|
||||
|
||||
# Test that --no-permissions-check disables warnings.
|
||||
le_auto_args_str += ' --no-permissions-check'
|
||||
out, _ = run_le_auto(
|
||||
le_auto_path, venv_dir,
|
||||
le_auto_args_str=le_auto_args_str,
|
||||
PIP_FIND_LINKS=pip_links)
|
||||
self.assertFalse('insecure permissions' in out)
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
# Start by making sure your system is up-to-date:
|
||||
yum update -y >/dev/null
|
||||
yum install -y centos-release-scl >/dev/null
|
||||
yum install -y python27 >/dev/null 2>/dev/null
|
||||
|
||||
LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34"
|
||||
LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto"
|
||||
|
||||
# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users
|
||||
INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0"
|
||||
|
||||
# we're going to modify env variables, so do this in a subshell
|
||||
(
|
||||
# ensure CentOS6 32bits is not supported anymore, and so certbot is not installed
|
||||
export UNAME_FAKE_32BITS=true
|
||||
if ! "$LE_AUTO" 2>&1 | grep -q "Certbot cannot be installed."; then
|
||||
echo "ERROR: certbot-auto installed certbot on 32-bit CentOS."
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
echo "PASSED: On CentOS 6 32 bits, certbot-auto refused to install certbot."
|
||||
|
||||
# we're going to modify env variables, so do this in a subshell
|
||||
(
|
||||
. /opt/rh/python27/enable
|
||||
|
||||
# ensure python 3 isn't installed
|
||||
if python3 --version 2> /dev/null; then
|
||||
echo "ERROR: Python3 is already installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure python2.7 is available
|
||||
if ! python2.7 --version 2> /dev/null; then
|
||||
echo "ERROR: Python2.7 is not available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# bootstrap, but don't install python 3.
|
||||
"$LE_AUTO" --no-self-upgrade -n --version > /dev/null 2> /dev/null
|
||||
|
||||
# ensure python 3 isn't installed
|
||||
if python3 --version 2> /dev/null; then
|
||||
echo "ERROR: letsencrypt-auto installed Python3 even though Python2.7 is present."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Did not upgrade to Python3 when Python2.7 is present."
|
||||
)
|
||||
|
||||
# ensure python2.7 isn't available
|
||||
if python2.7 --version 2> /dev/null; then
|
||||
echo "ERROR: Python2.7 is still available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Skip self upgrade due to Python 3 not being available.
|
||||
if ! "$LE_AUTO" 2>&1 | grep -q "WARNING: couldn't find Python"; then
|
||||
echo "ERROR: Python upgrade failure warning not printed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# bootstrap from the old letsencrypt-auto, this time installing python3.4
|
||||
"$LE_AUTO_PY_34" --no-self-upgrade -n --version >/dev/null 2>/dev/null
|
||||
|
||||
# ensure python 3.4 is installed
|
||||
if ! python3.4 --version >/dev/null 2>/dev/null; then
|
||||
echo "ERROR: letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Successfully upgraded to Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present."
|
||||
|
||||
# As "certbot-auto" (so without implicit --non-interactive flag set), check that the script
|
||||
# refuses to install SCL Python 3.6 when run in a non interactive shell (simulated here
|
||||
# using | tee /dev/null) if --non-interactive flag is not provided.
|
||||
cp "$LE_AUTO" /tmp/certbot-auto
|
||||
# NB: Readline has an issue on all Python versions for CentOS 6, making `certbot --version`
|
||||
# output an unprintable ASCII character on a new line at the end.
|
||||
# So we take the second last line of the output.
|
||||
version=$(/tmp/certbot-auto --version 2>/dev/null | tee /dev/null | tail -2 | head -1)
|
||||
|
||||
if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then
|
||||
echo "ERROR: certbot-auto upgraded certbot in a non-interactive shell with --non-interactive flag not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: certbot-auto did not upgrade certbot in a non-interactive shell with --non-interactive flag not set."
|
||||
|
||||
if [ -f /opt/rh/rh-python36/enable ]; then
|
||||
echo "ERROR: certbot-auto installed Python3.6 in a non-interactive shell with --non-interactive flag not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: certbot-auto did not install Python3.6 in a non-interactive shell with --non-interactive flag not set."
|
||||
|
||||
# now bootstrap from current letsencrypt-auto, that will install python3.6 from SCL
|
||||
"$LE_AUTO" --no-self-upgrade -n --version >/dev/null 2>/dev/null
|
||||
|
||||
# Following test is executed in a subshell, to not leak any environment variable
|
||||
(
|
||||
# enable SCL rh-python36
|
||||
. /opt/rh/rh-python36/enable
|
||||
|
||||
# ensure python 3.6 is installed
|
||||
if ! python3.6 --version >/dev/null 2>/dev/null; then
|
||||
echo "ERROR: letsencrypt-auto failed to install Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Successfully upgraded to Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present."
|
||||
)
|
||||
|
||||
# Following test is executed in a subshell, to not leak any environment variable
|
||||
(
|
||||
export VENV_PATH=$(mktemp -d)
|
||||
"$LE_AUTO" -n --no-bootstrap --no-self-upgrade --version >/dev/null 2>&1
|
||||
if [ "$($VENV_PATH/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then
|
||||
echo "ERROR: Python 3.6 wasn't used with --no-bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
# Following test is executed in a subshell, to not leak any environment variable
|
||||
(
|
||||
# enable SCL rh-python36
|
||||
. /opt/rh/rh-python36/enable
|
||||
|
||||
# ensure everything works fine with certbot-auto bootstrap when python 3.6 is already enabled
|
||||
export VENV_PATH=$(mktemp -d)
|
||||
if ! "$LE_AUTO" --no-self-upgrade -n --version >/dev/null 2>/dev/null; then
|
||||
echo "ERROR: Certbot-auto broke when Python 3.6 SCL is already enabled."
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
# we're going to modify env variables, so do this in a subshell
|
||||
(
|
||||
# ensure CentOS6 32bits is not supported anymore, and so certbot
|
||||
# is not upgraded nor reinstalled.
|
||||
export UNAME_FAKE_32BITS=true
|
||||
OUTPUT=$("$LE_AUTO" --version 2>&1)
|
||||
if ! echo "$OUTPUT" | grep -q "Certbot will no longer receive updates."; then
|
||||
echo "ERROR: certbot-auto failed to run or upgraded pre-existing Certbot instance on 32-bit CentOS 6."
|
||||
exit 1
|
||||
fi
|
||||
if ! "$LE_AUTO" --install-only 2>&1 | grep -q "Certbot cannot be installed."; then
|
||||
echo "ERROR: certbot-auto reinstalled Certbot on 32-bit CentOS 6."
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
# we're going to modify env variables, so do this in a subshell
|
||||
(
|
||||
# Prepare a certbot installation in the old venv path
|
||||
rm -rf /opt/eff.org
|
||||
VENV_PATH=~/.local/share/letsencrypt "$LE_AUTO" --install-only > /dev/null 2> /dev/null
|
||||
# fake 32 bits mode
|
||||
export UNAME_FAKE_32BITS=true
|
||||
OUTPUT=$("$LE_AUTO" --version 2>&1)
|
||||
if ! echo "$OUTPUT" | grep -q "Certbot will no longer receive updates."; then
|
||||
echo "ERROR: certbot-auto failed to run or upgraded pre-existing Certbot instance in the old venv path on 32-bit CentOS 6."
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
echo "PASSED: certbot-auto refused to install/upgrade certbot on 32-bit CentOS 6."
|
||||
|
||||
# test using python3
|
||||
pytest -v -s certbot/letsencrypt-auto-source/tests
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIID5jCCAs6gAwIBAgIJAI1Qkfyw88REMA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRswGQYDVQQKExJNeSBCb2d1cyBS
|
||||
b290IENlcnQxFDASBgNVBAMTC2V4YW1wbGUuY29tMB4XDTE1MTIwNDIwNTIxNVoX
|
||||
DTQwMTIwMzIwNTIxNVowVTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3Rh
|
||||
dGUxGzAZBgNVBAoTEk15IEJvZ3VzIFJvb3QgQ2VydDEUMBIGA1UEAxMLZXhhbXBs
|
||||
ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQVQpQ2EH4gTJB
|
||||
NJP6+ocT3xJwT8mSXYUnvzjj6iv+JxZiXRGzAPziNzrrSRKY0yDHF+UiJwuOerLa
|
||||
n8laZkLb1Ogqzs2u64rKeb0xWv90Qp+eXG0J/1xb4dw+GExqe5QFo1JUJzO/eK7m
|
||||
1S04SeFkN1qV9mD5yJUy7DGiTUzDHgCxM2tXMLusXYqkxsQQ9+2EJ7BEOK4YJGEx
|
||||
Sign5FuSxb64PiNow6OA97CaLl7tV4INP4w195ueDRIaS4poeOep4s8U7IAdMjIZ
|
||||
EryJgKNCij50xK92vPBBJSj0NOitltBlwoEqkOZpQCOZamFd6nvt78LQ6W8Am+l6
|
||||
y6oCON5JAgMBAAGjgbgwgbUwHQYDVR0OBBYEFAlrdStDhaayLLj89Whe3Gc+HE8y
|
||||
MIGFBgNVHSMEfjB8gBQJa3UrQ4Wmsiy4/PVoXtxnPhxPMqFZpFcwVTELMAkGA1UE
|
||||
BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxGzAZBgNVBAoTEk15IEJvZ3VzIFJv
|
||||
b3QgQ2VydDEUMBIGA1UEAxMLZXhhbXBsZS5jb22CCQCNUJH8sPPERDAMBgNVHRME
|
||||
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQC7KAQfDTiNM3QO8Ic3x21CAPJUavkH
|
||||
zshifN+Ei0+nmseHDTCTgsGfGDOToLUpUEZ4PuiHnz08UwRfd9wotc3SgY9ZaXMe
|
||||
vRs8KUAF9EoyTvESzPyv2b6cS9NNMpj5y7KyXSyP17VoGbNavtiGQ4dwgEH6VgNl
|
||||
0RtBvcSBv/tqxIIx1tWzL74tVEm0Kbd9BAZsYpQNKL8e6WXP35/j0PvCCvtofGrA
|
||||
E8LTqMz4kCwnX+QaJIMJhBophRCsjXdAkvFbFxX0DGPztQtzIwBPcdMjsft7AFeE
|
||||
0XchhDDXxw8YsbpvPfCvrD8XiiVuBycbnB1zt0LLVwB/QsCzUW9ImpLC
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA0FUKUNhB+IEyQTST+vqHE98ScE/Jkl2FJ7844+or/icWYl0R
|
||||
swD84jc660kSmNMgxxflIicLjnqy2p/JWmZC29ToKs7NruuKynm9MVr/dEKfnlxt
|
||||
Cf9cW+HcPhhManuUBaNSVCczv3iu5tUtOEnhZDdalfZg+ciVMuwxok1Mwx4AsTNr
|
||||
VzC7rF2KpMbEEPfthCewRDiuGCRhMUooJ+RbksW+uD4jaMOjgPewmi5e7VeCDT+M
|
||||
Nfebng0SGkuKaHjnqeLPFOyAHTIyGRK8iYCjQoo+dMSvdrzwQSUo9DTorZbQZcKB
|
||||
KpDmaUAjmWphXep77e/C0OlvAJvpesuqAjjeSQIDAQABAoIBAH+qbVzneV3wxjwh
|
||||
HUHi/p3VyHXc3xh7iNq3mwRH/1eK2nPCttLsGwwBbnC64dOXJfH7maWZKcLRPAMv
|
||||
gfOM0RHn4bJB8tdrbizv91lke0DihvBDkWpb+1wvB4lh2Io0Wpwt3ojFUTfXm87G
|
||||
+iQRWjbQmQlm5zyKh6uiBDSCjDTQdb9omZEBMAwlGPTZwt8TRUEtWd8QgW8FCHoB
|
||||
iLER2WBwXdvn3PBtocI3VE6IYDSeZ81Xv+d7925RtVintT8Suk4toYwX+jfSz+wZ
|
||||
sgHd5V6PSv9a7GUlWoUihD99D9wqDZE8IvMDZ5ofSAUd1KfICDtmsEyugY7u2yYZ
|
||||
tYt49AECgYEA73f7ITMHg8JsUipqb6eG10gCRtRhkqrrO1g/TNeTBh3CTrQGb56e
|
||||
y6kmUivn5gK46t3T2N4Ht4IR8fpLcJcbPYPQNulSjmWm5y6WduafXW/VCW1NA9Lc
|
||||
FyGPkMxFCIVJTLFxfLFepBVvtUzLLDKGGtQxru/GNbBzjdtmVfDPIoECgYEA3rbM
|
||||
cTfvj+jWrV1YsRbphyjy+k3OJEIVx6KA4s5d7Tp12UfYQp/B3HPhXXm5wqeo1Nos
|
||||
UAEWZIMi1VoE8iu6jjeJ6uERtbKKQVed25Us/ff0jUPbxlXgiBOtRcllq9d9Srjm
|
||||
ybHUgfjLsZ2/xpIcOl+oI5pDM9JvD8Sq4ZCFR8kCgYBK/H0tFjeiML2OtS2DLShy
|
||||
PWBJIbQ0I0Vp3eZkf5TQc30m/ASP61G6YItZa9pAElYpZbEy1cQA2MAZz9DTvt2O
|
||||
07ndmA57/KTY+6OuM+Vvctd5DjrxmZPFwoKcSvrLAkHDvETXUQtbwkKquRNeEawg
|
||||
tpWgPAELSufEYhGXk8KpAQKBgBDCqPgMQZcO6rj5QWdyVfi5+C8mE9Fet8ziSdjH
|
||||
twHXWG8VnQzGgQxaHCewtW4Ut/vsv1D2A/1kcQalU6H18IArZdGrRm3qFcV9FoAj
|
||||
5dLnChxncu6mH9Odx3htA52/BcrNx3B+VYPCeXHQcVI8RKuP71NelJgdygXhwwpe
|
||||
mekhAoGBAOUovnqylciYa9HRqo+xZk59eyX+ehhnlV8SeJ2K0PwaQkzQ0KYtCmE7
|
||||
kdSdhcv8h/IQKGaFfc/LyFMM/a26PfAeY5bj41UjkT0K5hQrYuL/52xaT401YLcb
|
||||
Xo+bZz9K0hrdP7TdZFuTY/WxojXgjsVAuAN1NwnJumqxhzPh+hfl
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1 +0,0 @@
|
|||
D613482D0EF95DD0
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKjCCAhICCQDWE0gtDvld0DANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEbMBkGA1UEChMSTXkgQm9ndXMgUm9vdCBD
|
||||
ZXJ0MRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNTEyMDQyMDU0MzFaFw00MDEy
|
||||
MDMyMDU0MzFaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2Fs
|
||||
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2WIIi86Mis4UQH
|
||||
a5PrFbX2PBtQHbI3t3ekN1CewRsgQ/2X3lCeWhKmr3CJYXVgA7q/23PORQAiuV6y
|
||||
DG2dQIrjeahWCXaCptTi49ljfVRTW2IxrHke/iA8TkDuZbWGzVLb8TB83ipBOD41
|
||||
SjuomoN4A/ktnIfbNqRqgjjHs2wwJHDfxPiCQlwyOayjHmdlh8cqfVE8rWEm5/3T
|
||||
Iu0X1J53SammR1SbUmsLJNofxFYMK1ogHb0CaFEG9QuuUDPJl5K74Rr6InMQZKPn
|
||||
ne4W3cGoALxPHAca7yicpSMSmdsmd6pqylc2Fdua7o/wf0SwShxS4A1DqA/HWLEM
|
||||
V6MSEF8CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAz5sMAFG6W/ZEULZITkBTCU6P
|
||||
NttpGiKufnqyBW5HyNylaczfnHnClvQjr8f/84xvKVcfC3xP0lz+92aIQqo+5L/n
|
||||
v7gLhBFR4Vr2XwMt2qz2FpkaxmVwnhVAHaaC05WIKQ6W2gDwWT0u1K8YdTh+7mvN
|
||||
AT9FW4vDgtNZWq4W/PePh9QCiOOQhGOuBYj/7zqLtz4XPifhi66ILIRDHiu0kond
|
||||
3YMFcECIAf4MPT9vT0iNcWX+c8CfAixPt8nMD6bzOo3oTcfuZh/2enfgLbMqOlOi
|
||||
uk72FM5VVPXTWAckJvL/vVjqsvDuJQKqbr0oUc3bdWbS36xtWZUycp4IQLguAQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIICnjCCAYYCAQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
|
||||
ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAxMJbG9j
|
||||
YWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArZYgiLzoyKzh
|
||||
RAdrk+sVtfY8G1Adsje3d6Q3UJ7BGyBD/ZfeUJ5aEqavcIlhdWADur/bc85FACK5
|
||||
XrIMbZ1AiuN5qFYJdoKm1OLj2WN9VFNbYjGseR7+IDxOQO5ltYbNUtvxMHzeKkE4
|
||||
PjVKO6iag3gD+S2ch9s2pGqCOMezbDAkcN/E+IJCXDI5rKMeZ2WHxyp9UTytYSbn
|
||||
/dMi7RfUnndJqaZHVJtSawsk2h/EVgwrWiAdvQJoUQb1C65QM8mXkrvhGvoicxBk
|
||||
o+ed7hbdwagAvE8cBxrvKJylIxKZ2yZ3qmrKVzYV25ruj/B/RLBKHFLgDUOoD8dY
|
||||
sQxXoxIQXwIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAFbg3WrAokoPx7iAYG6z
|
||||
PqeDd4/XanXjeL4Ryxv6LoGhu69mmBAd3N5ILPyQJjnkWpIjEmJDzEcPMzhQjRh5
|
||||
GlWTyvKWO4zClYU840KZk7crVkpzNZ+HP0YeM/Agz6sab00ffRcq5m1wEF9MCvDE
|
||||
8FUXk1HBHRAb/6t9QV/7axsPOkGT8SjQ1v2SCaiB0HQL3sYChYLi5zu4dfmQNPGq
|
||||
ar9Xm5a0YqOQIFfmy8RSwxk0Q/ipNFTGN1uvlIRkgbT9zPnodxjWZsSI9BF+q5Af
|
||||
uiE/oAk7MxfJ0LyLfhOWB+T98bKIOVtFT3wMLS1IIgMogwqCEXFf30Q9p2iTEzqT
|
||||
6UE=
|
||||
-----END CERTIFICATE REQUEST-----
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEArZYgiLzoyKzhRAdrk+sVtfY8G1Adsje3d6Q3UJ7BGyBD/Zfe
|
||||
UJ5aEqavcIlhdWADur/bc85FACK5XrIMbZ1AiuN5qFYJdoKm1OLj2WN9VFNbYjGs
|
||||
eR7+IDxOQO5ltYbNUtvxMHzeKkE4PjVKO6iag3gD+S2ch9s2pGqCOMezbDAkcN/E
|
||||
+IJCXDI5rKMeZ2WHxyp9UTytYSbn/dMi7RfUnndJqaZHVJtSawsk2h/EVgwrWiAd
|
||||
vQJoUQb1C65QM8mXkrvhGvoicxBko+ed7hbdwagAvE8cBxrvKJylIxKZ2yZ3qmrK
|
||||
VzYV25ruj/B/RLBKHFLgDUOoD8dYsQxXoxIQXwIDAQABAoIBAG8bVJ+xKt6nqVg9
|
||||
16HKKw9ZGIfy888K0qgFuFImCzwtntdGycmYUdb2Uf0aMgNK/ZgfDXxGXuwDTdtK
|
||||
46GVsaY0i74vs8bjQZ2pzGVsxN+gqzFi0h6Es+w2LXBqJzfVnL6YgPykMB+jtzg6
|
||||
K9Wbyaq0uvZXN4XNzl/WvJtTV4i7Cff1MOd5EhKFdqxrZvB/SRBCr/SMMafRtB9P
|
||||
EvMneNKzhmlrutHAxuyxEKZR32Kkx7ydAdTjGgn+rE+NL5BweXfeWhLU4Bv14bn9
|
||||
Mkneu3w5o1ryJfE2YnVajUP//jeopUT0nTQ3MpEusBQCLBlvFXjjM9uCaFX+5+MP
|
||||
0H4xVcECgYEA1Q+wR3GHbk37vIGSlbENyUsri5WlMt8IVAHsDsTOpxAjYB0yyo+x
|
||||
h9RS+RJZQECJlA6H72peUl3GM7RgdWIcKOT3nZ12XqYKG57rr/N5zlUuxbdS8KBk
|
||||
JhyZeJdYjq/Jrno1ZP+OSmc7VvBLcM7irY7LHlvK0o8W1W0TNJ8jrZkCgYEA0JHX
|
||||
lJd+fiezcUS7g4moHtzJp0JKquQiXLX+c2urmpyhb3ZrTuQ8OUjSy6DlwHlgDx8K
|
||||
Hg2sdx/ZCuDaGjR4IY/Qs5RFt9WUqlK9gi9V3nYVrzBOQkdFOf/Ad3j4pQ8/aeCX
|
||||
nP6snHXz1WqPpbCXG6l6GzFGbQU473GfuKsDuLcCgYAWQaNKc0OQdDj9whNL68ji
|
||||
5CVSWXl+TOoTzHeaO1jS/s6TNbmei1AiPj3EovQL0DIO802j5tqfhAg2UntZB7yl
|
||||
UPXE0zQQQwv/QqSgJrDsqt1N7g6N8FNF3+rwO+8WSKqqvT1ipYd5ojsCo+tdh18K
|
||||
fkYdj70qLaRW+yPsdUtG0QKBgEYc8NqbvsML94+ZKmwCh4iwcf2PFGi0PjTqXTpR
|
||||
tKNKCh7dMR+ZLAGZ0HrxgKqeYsNSjOUjdZmqFB1LDyaGAuhNXzwvGOy+mLZVEC3G
|
||||
Wdhp28pDs9sl+EiSCBJhkTxzjr656F23YzFJmYlhxB5P6cw7wbeIbgNSIRylFqtO
|
||||
mfarAoGBAICsAEWypOctxtmtOcjxgJ7jMbOA7rrsGlXpiy1/WlwIwRGF5LMvIIFX
|
||||
qFAfiPcZn05ZgdAGzaFYowdjmQB10FW0jZbDf+nIHfOF5YmfmfWjsaweEGALJmqB
|
||||
okGu/lGNGf3XoYzy0/hC3WAqk3znSZtQLUq8jEWF7dLNUizUeUow
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEArZYgiLzoyKzhRAdrk+sVtfY8G1Adsje3d6Q3UJ7BGyBD/Zfe
|
||||
UJ5aEqavcIlhdWADur/bc85FACK5XrIMbZ1AiuN5qFYJdoKm1OLj2WN9VFNbYjGs
|
||||
eR7+IDxOQO5ltYbNUtvxMHzeKkE4PjVKO6iag3gD+S2ch9s2pGqCOMezbDAkcN/E
|
||||
+IJCXDI5rKMeZ2WHxyp9UTytYSbn/dMi7RfUnndJqaZHVJtSawsk2h/EVgwrWiAd
|
||||
vQJoUQb1C65QM8mXkrvhGvoicxBko+ed7hbdwagAvE8cBxrvKJylIxKZ2yZ3qmrK
|
||||
VzYV25ruj/B/RLBKHFLgDUOoD8dYsQxXoxIQXwIDAQABAoIBAG8bVJ+xKt6nqVg9
|
||||
16HKKw9ZGIfy888K0qgFuFImCzwtntdGycmYUdb2Uf0aMgNK/ZgfDXxGXuwDTdtK
|
||||
46GVsaY0i74vs8bjQZ2pzGVsxN+gqzFi0h6Es+w2LXBqJzfVnL6YgPykMB+jtzg6
|
||||
K9Wbyaq0uvZXN4XNzl/WvJtTV4i7Cff1MOd5EhKFdqxrZvB/SRBCr/SMMafRtB9P
|
||||
EvMneNKzhmlrutHAxuyxEKZR32Kkx7ydAdTjGgn+rE+NL5BweXfeWhLU4Bv14bn9
|
||||
Mkneu3w5o1ryJfE2YnVajUP//jeopUT0nTQ3MpEusBQCLBlvFXjjM9uCaFX+5+MP
|
||||
0H4xVcECgYEA1Q+wR3GHbk37vIGSlbENyUsri5WlMt8IVAHsDsTOpxAjYB0yyo+x
|
||||
h9RS+RJZQECJlA6H72peUl3GM7RgdWIcKOT3nZ12XqYKG57rr/N5zlUuxbdS8KBk
|
||||
JhyZeJdYjq/Jrno1ZP+OSmc7VvBLcM7irY7LHlvK0o8W1W0TNJ8jrZkCgYEA0JHX
|
||||
lJd+fiezcUS7g4moHtzJp0JKquQiXLX+c2urmpyhb3ZrTuQ8OUjSy6DlwHlgDx8K
|
||||
Hg2sdx/ZCuDaGjR4IY/Qs5RFt9WUqlK9gi9V3nYVrzBOQkdFOf/Ad3j4pQ8/aeCX
|
||||
nP6snHXz1WqPpbCXG6l6GzFGbQU473GfuKsDuLcCgYAWQaNKc0OQdDj9whNL68ji
|
||||
5CVSWXl+TOoTzHeaO1jS/s6TNbmei1AiPj3EovQL0DIO802j5tqfhAg2UntZB7yl
|
||||
UPXE0zQQQwv/QqSgJrDsqt1N7g6N8FNF3+rwO+8WSKqqvT1ipYd5ojsCo+tdh18K
|
||||
fkYdj70qLaRW+yPsdUtG0QKBgEYc8NqbvsML94+ZKmwCh4iwcf2PFGi0PjTqXTpR
|
||||
tKNKCh7dMR+ZLAGZ0HrxgKqeYsNSjOUjdZmqFB1LDyaGAuhNXzwvGOy+mLZVEC3G
|
||||
Wdhp28pDs9sl+EiSCBJhkTxzjr656F23YzFJmYlhxB5P6cw7wbeIbgNSIRylFqtO
|
||||
mfarAoGBAICsAEWypOctxtmtOcjxgJ7jMbOA7rrsGlXpiy1/WlwIwRGF5LMvIIFX
|
||||
qFAfiPcZn05ZgdAGzaFYowdjmQB10FW0jZbDf+nIHfOF5YmfmfWjsaweEGALJmqB
|
||||
okGu/lGNGf3XoYzy0/hC3WAqk3znSZtQLUq8jEWF7dLNUizUeUow
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKjCCAhICCQDWE0gtDvld0DANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEbMBkGA1UEChMSTXkgQm9ndXMgUm9vdCBD
|
||||
ZXJ0MRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNTEyMDQyMDU0MzFaFw00MDEy
|
||||
MDMyMDU0MzFaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2Fs
|
||||
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2WIIi86Mis4UQH
|
||||
a5PrFbX2PBtQHbI3t3ekN1CewRsgQ/2X3lCeWhKmr3CJYXVgA7q/23PORQAiuV6y
|
||||
DG2dQIrjeahWCXaCptTi49ljfVRTW2IxrHke/iA8TkDuZbWGzVLb8TB83ipBOD41
|
||||
SjuomoN4A/ktnIfbNqRqgjjHs2wwJHDfxPiCQlwyOayjHmdlh8cqfVE8rWEm5/3T
|
||||
Iu0X1J53SammR1SbUmsLJNofxFYMK1ogHb0CaFEG9QuuUDPJl5K74Rr6InMQZKPn
|
||||
ne4W3cGoALxPHAca7yicpSMSmdsmd6pqylc2Fdua7o/wf0SwShxS4A1DqA/HWLEM
|
||||
V6MSEF8CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAz5sMAFG6W/ZEULZITkBTCU6P
|
||||
NttpGiKufnqyBW5HyNylaczfnHnClvQjr8f/84xvKVcfC3xP0lz+92aIQqo+5L/n
|
||||
v7gLhBFR4Vr2XwMt2qz2FpkaxmVwnhVAHaaC05WIKQ6W2gDwWT0u1K8YdTh+7mvN
|
||||
AT9FW4vDgtNZWq4W/PePh9QCiOOQhGOuBYj/7zqLtz4XPifhi66ILIRDHiu0kond
|
||||
3YMFcECIAf4MPT9vT0iNcWX+c8CfAixPt8nMD6bzOo3oTcfuZh/2enfgLbMqOlOi
|
||||
uk72FM5VVPXTWAckJvL/vVjqsvDuJQKqbr0oUc3bdWbS36xtWZUycp4IQLguAQ==
|
||||
-----END CERTIFICATE-----
|
||||
Binary file not shown.
|
|
@ -1,8 +0,0 @@
|
|||
from sys import argv, stderr
|
||||
|
||||
|
||||
def main():
|
||||
"""Act like letsencrypt --version insofar as printing the version number to
|
||||
stderr."""
|
||||
if '--version' in argv:
|
||||
stderr.write('letsencrypt 99.9.9\n')
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from setuptools import setup
|
||||
|
||||
|
||||
setup(
|
||||
name='letsencrypt',
|
||||
version='99.9.9',
|
||||
description='A mock version of letsencrypt that just prints its version',
|
||||
py_modules=['letsencrypt'],
|
||||
entry_points={
|
||||
'console_scripts': ['letsencrypt = letsencrypt:main']
|
||||
}
|
||||
)
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
# Start by making sure your system is up-to-date:
|
||||
yum update -y >/dev/null
|
||||
|
||||
LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34"
|
||||
LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto"
|
||||
|
||||
# Apply installation instructions from official documentation:
|
||||
# https://certbot.eff.org/lets-encrypt/centosrhel6-other
|
||||
cp "$LE_AUTO" /usr/local/bin/certbot-auto
|
||||
chown root /usr/local/bin/certbot-auto
|
||||
chmod 0755 /usr/local/bin/certbot-auto
|
||||
LE_AUTO=/usr/local/bin/certbot-auto
|
||||
|
||||
# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users
|
||||
INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0"
|
||||
|
||||
# Check bootstrap from current certbot-auto will fail, because SCL is not enabled.
|
||||
set +o pipefail
|
||||
if ! "$LE_AUTO" -n 2>&1 | grep -q "Enable the SCL repository and try running Certbot again."; then
|
||||
echo "ERROR: Bootstrap was not aborted although SCL was not installed!"
|
||||
exit 1
|
||||
fi
|
||||
set -o pipefail
|
||||
|
||||
echo "PASSED: Bootstrap was aborted since SCL was not installed."
|
||||
|
||||
# Bootstrap from the old letsencrypt-auto, Python 3.4 will be installed from EPEL.
|
||||
"$LE_AUTO_PY_34" --no-self-upgrade -n --install-only >/dev/null 2>/dev/null
|
||||
|
||||
# Ensure Python 3.4 is installed
|
||||
if ! command -v python3.4 &>/dev/null; then
|
||||
echo "ERROR: old letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Bootstrap from old letsencrypt-auto succeeded and installed Python 3.4"
|
||||
|
||||
# Expect certbot-auto to skip rebootstrapping with a warning since SCL is not installed.
|
||||
if ! "$LE_AUTO" --non-interactive --version 2>&1 | grep -q "This requires manual user intervention"; then
|
||||
echo "FAILED: Script certbot-auto did not print a warning about needing manual intervention!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Script certbot-auto did not rebootstrap."
|
||||
|
||||
# NB: Readline has an issue on all Python versions for OL 6, making `certbot --version`
|
||||
# output an unprintable ASCII character on a new line at the end.
|
||||
# So we take the second last line of the output.
|
||||
version=$($LE_AUTO --version 2>/dev/null | tail -2 | head -1)
|
||||
|
||||
if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then
|
||||
echo "ERROR: Script certbot-auto upgraded certbot in a non-interactive shell while SCL was not enabled."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Script certbot-auto did not upgrade certbot but started it successfully while SCL was not enabled."
|
||||
|
||||
# Enable SCL
|
||||
yum install -y oracle-softwarecollection-release-el6 >/dev/null
|
||||
|
||||
# Expect certbot-auto to bootstrap successfully since SCL is available.
|
||||
"$LE_AUTO" -n --version &>/dev/null
|
||||
|
||||
if [ "$(/opt/eff.org/certbot/venv/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then
|
||||
echo "ERROR: Script certbot-auto failed to bootstrap and install Python 3.6 while SCL is available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! /opt/eff.org/certbot/venv/bin/certbot --version > /dev/null 2> /dev/null; then
|
||||
echo "ERROR: Script certbot-auto did not install certbot correctly while SCL is enabled."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Script certbot-auto correctly bootstraped Certbot using rh-python36 when SCL is available."
|
||||
|
||||
# Expect certbot-auto will be totally silent now that everything has been correctly boostraped.
|
||||
OUTPUT_LEN=$("$LE_AUTO" --install-only --no-self-upgrade --quiet 2>&1 | wc -c)
|
||||
if [ "$OUTPUT_LEN" != 0 ]; then
|
||||
echo certbot-auto produced unexpected output!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Script certbot-auto did not print anything in quiet mode."
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
uname_output=$(/bin/uname_orig "$@")
|
||||
|
||||
if [ "$UNAME_FAKE_32BITS" = true ]; then
|
||||
uname_output="${uname_output//x86_64/i686}"
|
||||
fi
|
||||
|
||||
echo "$uname_output"
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
## Pull Request Checklist
|
||||
|
||||
- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `master` section of `certbot/CHANGELOG.md` to include a description of the change being made.
|
||||
- [ ] Add or update any documentation as needed to support the changes in this PR.
|
||||
- [ ] Include your name in `AUTHORS.md` if you like.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
[pytest]
|
||||
# In general, all warnings are treated as errors. Here are the exceptions:
|
||||
# 1- decodestring: https://github.com/rthalley/dnspython/issues/338
|
||||
# 2- Python 2 deprecation: https://github.com/certbot/certbot/issues/8388
|
||||
# (to be removed with Certbot 1.12.0 and its drop of Python 2 support)
|
||||
# Warnings being triggered by our plugins using deprecated features in
|
||||
# acme/certbot should be fixed by having our plugins no longer using the
|
||||
# deprecated code rather than adding them to the list of ignored warnings here.
|
||||
|
|
@ -14,3 +16,4 @@
|
|||
filterwarnings =
|
||||
error
|
||||
ignore:decodestring:DeprecationWarning
|
||||
ignore:Python 2 support will be dropped:PendingDeprecationWarning
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ adopt-info: certbot
|
|||
|
||||
apps:
|
||||
certbot:
|
||||
command: bin/python3 $SNAP/bin/certbot
|
||||
command: bin/python3 -s $SNAP/bin/certbot
|
||||
environment:
|
||||
PATH: "$SNAP/bin:$SNAP/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
|
||||
AUGEAS_LENS_LIB: "$SNAP/usr/share/augeas/lenses/dist"
|
||||
CERTBOT_SNAPPED: "True"
|
||||
renew:
|
||||
command: bin/python3 $SNAP/bin/certbot -q renew
|
||||
command: bin/python3 -s $SNAP/bin/certbot -q renew
|
||||
daemon: oneshot
|
||||
environment:
|
||||
PATH: "$SNAP/bin:$SNAP/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
|
||||
|
|
@ -64,7 +64,6 @@ parts:
|
|||
- libpython3.8-stdlib
|
||||
- libpython3.8-minimal
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
- python3-wheel
|
||||
- python3-venv
|
||||
- python3-minimal
|
||||
|
|
@ -74,13 +73,16 @@ parts:
|
|||
# To build cryptography and cffi if needed
|
||||
build-packages: [gcc, libffi-dev, libssl-dev, git, libaugeas-dev, python3-dev]
|
||||
build-environment:
|
||||
- SNAPCRAFT_PYTHON_VENV_ARGS: --system-site-packages
|
||||
- SNAPCRAFT_PYTHON_VENV_ARGS: --upgrade
|
||||
- PIP_NO_BUILD_ISOLATION: "no"
|
||||
override-build: |
|
||||
python3 -m venv "${SNAPCRAFT_PART_INSTALL}"
|
||||
"${SNAPCRAFT_PART_INSTALL}"/bin/python3 "${SNAPCRAFT_PART_SRC}/tools/pipstrap.py"
|
||||
snapcraftctl build
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
cd $SNAPCRAFT_PART_SRC
|
||||
python3 tools/strip_hashes.py letsencrypt-auto-source/pieces/dependency-requirements.txt | grep -v python-augeas > snap-constraints.txt
|
||||
snapcraftctl set-version `grep -oP "__version__ = '\K.*(?=')" $SNAPCRAFT_PART_SRC/certbot/certbot/__init__.py`
|
||||
snapcraftctl pull
|
||||
python3 "${SNAPCRAFT_PART_SRC}/tools/strip_hashes.py" "${SNAPCRAFT_PART_SRC}/letsencrypt-auto-source/pieces/dependency-requirements.txt" | grep -v python-augeas > "${SNAPCRAFT_PART_SRC}/snap-constraints.txt"
|
||||
snapcraftctl set-version `grep -oP "__version__ = '\K.*(?=')" "${SNAPCRAFT_PART_SRC}/certbot/certbot/__init__.py"`
|
||||
shared-metadata:
|
||||
plugin: dump
|
||||
source: .
|
||||
|
|
|
|||
|
|
@ -56,17 +56,6 @@ targets:
|
|||
type: centos
|
||||
virt: hvm
|
||||
user: centos
|
||||
# centos6 requires EPEL repo added
|
||||
- ami: ami-1585c46a
|
||||
name: centos6
|
||||
type: centos
|
||||
virt: hvm
|
||||
user: centos
|
||||
userdata: |
|
||||
#cloud-config
|
||||
runcmd:
|
||||
- yum install -y epel-release
|
||||
- iptables -F
|
||||
- ami: ami-01ca03df4a6012157
|
||||
name: centos8
|
||||
type: centos
|
||||
|
|
|
|||
|
|
@ -105,15 +105,10 @@ if ./letsencrypt-auto -v --debug --version | grep "WARNING: couldn't find Python
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# On systems like Debian where certbot-auto is deprecated, we expect it to
|
||||
# leave existing Certbot installations unmodified so we check for the same
|
||||
# version that was initially installed below. Once certbot-auto is deprecated
|
||||
# on RHEL systems, we can unconditionally check for INITIAL_VERSION.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
EXPECTED_VERSION="$INITIAL_VERSION"
|
||||
else
|
||||
EXPECTED_VERSION=$(grep -m1 LE_AUTO_VERSION certbot-auto | cut -d\" -f2)
|
||||
fi
|
||||
# Since certbot-auto is deprecated, we expect it to leave existing Certbot
|
||||
# installations unmodified so we check for the same version that was initially
|
||||
# installed below.
|
||||
EXPECTED_VERSION="$INITIAL_VERSION"
|
||||
|
||||
if ! /opt/eff.org/certbot/venv/bin/letsencrypt --version 2>&1 | tail -n1 | grep "^certbot $EXPECTED_VERSION$" ; then
|
||||
echo unexpected certbot version found
|
||||
|
|
@ -124,22 +119,3 @@ if ! diff letsencrypt-auto letsencrypt-auto-source/letsencrypt-auto ; then
|
|||
echo letsencrypt-auto and letsencrypt-auto-source/letsencrypt-auto differ
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$RUN_RHEL6_TESTS" = 1 ]; then
|
||||
# Add the SCL python release to PATH in order to resolve python3 command
|
||||
PATH="/opt/rh/rh-python36/root/usr/bin:$PATH"
|
||||
if ! command -v python3; then
|
||||
echo "Python3 wasn't properly installed"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(/opt/eff.org/certbot/venv/bin/python -V 2>&1 | cut -d" " -f 2 | cut -d. -f1)" != 3 ]; then
|
||||
echo "Python3 wasn't used in venv!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$("$PYTHON_NAME" tools/readlink.py $OLD_VENV_PATH)" != "/opt/eff.org/certbot/venv" ]; then
|
||||
echo symlink from old venv path not properly created!
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo upgrade appeared to be successful
|
||||
|
|
|
|||
|
|
@ -16,58 +16,14 @@ sudo chown root "$LE_AUTO_PATH"
|
|||
sudo chmod 0755 "$LE_AUTO_PATH"
|
||||
export PATH="$LE_AUTO_DIR:$PATH"
|
||||
|
||||
# On systems like Debian where certbot-auto is deprecated, we expect
|
||||
# certbot-auto to error and refuse to install Certbot. Once certbot-auto is
|
||||
# deprecated on RHEL systems, we can unconditionally run this code.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
set +o pipefail
|
||||
if ! letsencrypt-auto --debug --version | grep "Certbot cannot be installed."; then
|
||||
echo "letsencrypt-auto didn't report being uninstallable."
|
||||
exit 1
|
||||
fi
|
||||
if [ ${PIPESTATUS[0]} != 1 ]; then
|
||||
echo "letsencrypt-auto didn't exit with status 1 as expected"
|
||||
exit 1
|
||||
fi
|
||||
# letsencrypt-auto is deprecated and cannot be installed on this system so
|
||||
# we cannot run the rest of this test.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
letsencrypt-auto --os-packages-only --debug --version
|
||||
|
||||
# This script sets the environment variables PYTHON_NAME, VENV_PATH, and
|
||||
# VENV_SCRIPT based on the version of Python available on the system. For
|
||||
# instance, Fedora uses Python 3 and Python 2 is not installed.
|
||||
. tests/letstest/scripts/set_python_envvars.sh
|
||||
|
||||
# Create a venv-like layout at the old virtual environment path to test that a
|
||||
# symlink is properly created when letsencrypt-auto runs.
|
||||
HOME=${HOME:-~root}
|
||||
XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share}
|
||||
OLD_VENV_BIN="$XDG_DATA_HOME/letsencrypt/bin"
|
||||
mkdir -p "$OLD_VENV_BIN"
|
||||
touch "$OLD_VENV_BIN/letsencrypt"
|
||||
|
||||
letsencrypt-auto certonly --no-self-upgrade -v --standalone --debug \
|
||||
--text --agree-tos \
|
||||
--renew-by-default --redirect \
|
||||
--register-unsafely-without-email \
|
||||
--domain $PUBLIC_HOSTNAME --server $BOULDER_URL
|
||||
|
||||
LINK_PATH=$("$PYTHON_NAME" tools/readlink.py ${XDG_DATA_HOME:-~/.local/share}/letsencrypt)
|
||||
if [ "$LINK_PATH" != "/opt/eff.org/certbot/venv" ]; then
|
||||
echo symlink from old venv path not properly created!
|
||||
# Since certbot-auto is deprecated, we expect certbot-auto to error and
|
||||
# refuse to install Certbot.
|
||||
set +o pipefail
|
||||
if ! letsencrypt-auto --debug --version | grep "Certbot cannot be installed."; then
|
||||
echo "letsencrypt-auto didn't report being uninstallable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! letsencrypt-auto --help --no-self-upgrade | grep -F "letsencrypt-auto [SUBCOMMAND]"; then
|
||||
echo "letsencrypt-auto not included in help output!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_LEN=$(letsencrypt-auto --install-only --no-self-upgrade --quiet 2>&1 | wc -c)
|
||||
if [ "$OUTPUT_LEN" != 0 ]; then
|
||||
echo letsencrypt-auto produced unexpected output!
|
||||
if [ ${PIPESTATUS[0]} != 1 ]; then
|
||||
echo "letsencrypt-auto didn't exit with status 1 as expected"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -52,17 +52,6 @@ targets:
|
|||
type: centos
|
||||
virt: hvm
|
||||
user: centos
|
||||
# centos6 requires EPEL repo added
|
||||
- ami: ami-1585c46a
|
||||
name: centos6
|
||||
type: centos
|
||||
virt: hvm
|
||||
user: centos
|
||||
userdata: |
|
||||
#cloud-config
|
||||
runcmd:
|
||||
- yum install -y epel-release
|
||||
- iptables -F
|
||||
- ami: ami-01ca03df4a6012157
|
||||
name: centos8
|
||||
type: centos
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Run:
|
|||
python tools/finish_release.py ~/.ssh/githubpat.txt
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import os.path
|
||||
import re
|
||||
|
|
@ -44,6 +45,34 @@ SNAPS = ['certbot'] + DNS_PLUGINS
|
|||
# for sanity checking.
|
||||
SNAP_ARCH_COUNT = 3
|
||||
|
||||
|
||||
def parse_args(args):
|
||||
"""Parse command line arguments.
|
||||
|
||||
:param args: command line arguments with the program name removed. This is
|
||||
usually taken from sys.argv[1:].
|
||||
:type args: `list` of `str`
|
||||
|
||||
:returns: parsed arguments
|
||||
:rtype: argparse.Namespace
|
||||
|
||||
"""
|
||||
# Use the file's docstring for the help text and don't let argparse reformat it.
|
||||
parser = argparse.ArgumentParser(description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('githubpat', help='path to your GitHub personal access token')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
# We use 'store_false' and a destination related to the other type of
|
||||
# artifact to cause the flag being set to disable publishing of the other
|
||||
# artifact. This makes using the parsed arguments later on a little simpler
|
||||
# and cleaner.
|
||||
group.add_argument('--snaps-only', action='store_false', dest='publish_windows',
|
||||
help='Skip publishing other artifacts and only publish the snaps')
|
||||
group.add_argument('--windows-only', action='store_false', dest='publish_snaps',
|
||||
help='Skip publishing other artifacts and only publish the Windows installer')
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def download_azure_artifacts(tempdir):
|
||||
"""Download and unzip build artifacts from Azure pipelines.
|
||||
|
||||
|
|
@ -181,8 +210,9 @@ def promote_snaps(version):
|
|||
|
||||
|
||||
def main(args):
|
||||
github_access_token_file = args[0]
|
||||
parsed_args = parse_args(args)
|
||||
|
||||
github_access_token_file = parsed_args.githubpat
|
||||
github_access_token = open(github_access_token_file, 'r').read().rstrip()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
|
|
@ -191,8 +221,10 @@ def main(args):
|
|||
# again fails. Publishing the snaps can be done multiple times though
|
||||
# so we do that first to make it easier to run the script again later
|
||||
# if something goes wrong.
|
||||
promote_snaps(version)
|
||||
create_github_release(github_access_token, tempdir, version)
|
||||
if parsed_args.publish_snaps:
|
||||
promote_snaps(version)
|
||||
if parsed_args.publish_windows:
|
||||
create_github_release(github_access_token, tempdir, version)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
29
tox.ini
29
tox.ini
|
|
@ -188,29 +188,6 @@ whitelist_externals =
|
|||
passenv =
|
||||
DOCKER_*
|
||||
|
||||
[testenv:le_auto_centos6]
|
||||
# At the moment, this tests under Python 2.6 only, as only that version is
|
||||
# readily available on the CentOS 6 Docker image.
|
||||
commands =
|
||||
python {toxinidir}/tests/modification-check.py
|
||||
docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=centos -t lea letsencrypt-auto-source
|
||||
docker run --rm -t lea
|
||||
whitelist_externals =
|
||||
docker
|
||||
passenv =
|
||||
DOCKER_*
|
||||
TARGET_BRANCH
|
||||
|
||||
[testenv:le_auto_oraclelinux6]
|
||||
# At the moment, this tests under Python 2.6 only, as only that version is
|
||||
# readily available on the Oracle Linux 6 Docker image.
|
||||
commands =
|
||||
docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=oraclelinux -t lea letsencrypt-auto-source
|
||||
docker run --rm -t lea
|
||||
whitelist_externals =
|
||||
docker
|
||||
passenv = DOCKER_*
|
||||
|
||||
[testenv:docker_dev]
|
||||
# tests the Dockerfile-dev file to ensure development with it works
|
||||
# as expected
|
||||
|
|
@ -245,7 +222,11 @@ commands =
|
|||
{[base]pip_install} acme certbot certbot-dns-rfc2136 certbot-ci
|
||||
pytest certbot-ci/certbot_integration_tests/rfc2136_tests \
|
||||
--acme-server=pebble --dns-server=bind \
|
||||
--numprocesses=1
|
||||
--numprocesses=1 \
|
||||
--cov=acme --cov=certbot --cov=certbot_dns_rfc2136 --cov-report= \
|
||||
--cov-config=certbot-ci/certbot_integration_tests/.coveragerc
|
||||
coverage report --include 'certbot/*' --show-missing --fail-under=45
|
||||
coverage report --include 'certbot-dns-rfc2136/*' --show-missing --fail-under=87
|
||||
|
||||
[testenv:integration-external]
|
||||
# Run integration tests with Certbot outside of tox's virtual environment.
|
||||
|
|
|
|||
Loading…
Reference in a new issue