mirror of
https://github.com/certbot/certbot.git
synced 2026-06-04 06:15:36 -04:00
Merge branch 'master' into separate-integration
This commit is contained in:
commit
172afb8500
69 changed files with 610 additions and 381 deletions
|
|
@ -34,7 +34,7 @@ matrix:
|
|||
- python: "3.5"
|
||||
env: TOXENV=mypy
|
||||
- python: "2.7"
|
||||
env: TOXENV='py27-{acme,apache,certbot,dns,nginx}-oldest'
|
||||
env: TOXENV='py27-{acme,apache,certbot,dns,nginx,postfix}-oldest'
|
||||
sudo: required
|
||||
services: docker
|
||||
- python: "3.4"
|
||||
|
|
@ -90,12 +90,12 @@ addons:
|
|||
- nginx-light
|
||||
- openssl
|
||||
|
||||
install: "travis_retry $(command -v pip || command -v pip3) install tox coveralls"
|
||||
install: "travis_retry $(command -v pip || command -v pip3) install codecov tox"
|
||||
script:
|
||||
- travis_retry tox
|
||||
- '[ -z "${BOULDER_INTEGRATION+x}" ] || (travis_retry tests/boulder-fetch.sh && tests/tox-boulder-integration.sh)'
|
||||
|
||||
after_success: '[ "$TOXENV" == "cover" ] && coveralls'
|
||||
after_success: '[ "$TOXENV" == "cover" ] && codecov'
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
|
|
|||
63
CHANGELOG.md
63
CHANGELOG.md
|
|
@ -2,6 +2,67 @@
|
|||
|
||||
Certbot adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 0.26.1 - 2018-07-17
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix a bug that was triggered when users who had previously manually set `--server` to get ACMEv2 certs tried to renew ACMEv1 certs.
|
||||
|
||||
Despite us having broken lockstep, we are continuing to release new versions of all Certbot components during releases for the time being, however, the only package with changes other than its version number was:
|
||||
|
||||
* certbot
|
||||
|
||||
More details about these changes can be found on our GitHub repo:
|
||||
https://github.com/certbot/certbot/milestone/58?closed=1
|
||||
|
||||
## 0.26.0 - 2018-07-11
|
||||
|
||||
### Added
|
||||
|
||||
* A new security enhancement which we're calling AutoHSTS has been added to
|
||||
Certbot's Apache plugin. This enhancement configures your webserver to send a
|
||||
HTTP Strict Transport Security header with a low max-age value that is slowly
|
||||
increased over time. The max-age value is not increased to a large value
|
||||
until you've successfully managed to renew your certificate. This enhancement
|
||||
can be requested with the --auto-hsts flag.
|
||||
* New official DNS plugins have been created for Gehirn Infrastracture Service,
|
||||
Linode, OVH, and Sakura Cloud. These plugins can be found on our Docker Hub
|
||||
page at https://hub.docker.com/u/certbot and on PyPI.
|
||||
* The ability to reuse ACME accounts from Let's Encrypt's ACMEv1 endpoint on
|
||||
Let's Encrypt's ACMEv2 endpoint has been added.
|
||||
* Certbot and its components now support Python 3.7.
|
||||
* Certbot's install subcommand now allows you to interactively choose which
|
||||
certificate to install from the list of certificates managed by Certbot.
|
||||
* Certbot now accepts the flag `--no-autorenew` which causes any obtained
|
||||
certificates to not be automatically renewed when it approaches expiration.
|
||||
* Support for parsing the TLS-ALPN-01 challenge has been added back to the acme
|
||||
library.
|
||||
|
||||
### Changed
|
||||
|
||||
* Certbot's default ACME server has been changed to Let's Encrypt's ACMEv2
|
||||
endpoint. By default, this server will now be used for both new certificate
|
||||
lineages and renewals.
|
||||
* The Nginx plugin is no longer marked labeled as an "Alpha" version.
|
||||
* The `prepare` method of Certbot's plugins is no longer called before running
|
||||
"Updater" enhancements that are run on every invocation of `certbot renew`.
|
||||
|
||||
Despite us having broken lockstep, we are continuing to release new versions of
|
||||
all Certbot components during releases for the time being, however, the only
|
||||
packages with functional changes were:
|
||||
|
||||
* acme
|
||||
* certbot
|
||||
* certbot-apache
|
||||
* certbot-dns-gehirn
|
||||
* certbot-dns-linode
|
||||
* certbot-dns-ovh
|
||||
* certbot-dns-sakuracloud
|
||||
* certbot-nginx
|
||||
|
||||
More details about these changes can be found on our GitHub repo:
|
||||
https://github.com/certbot/certbot/milestone/55?closed=1
|
||||
|
||||
## 0.25.1 - 2018-06-13
|
||||
|
||||
### Fixed
|
||||
|
|
@ -735,7 +796,7 @@ https://github.com/certbot/certbot/pulls?q=is%3Apr%20milestone%3A0.11.1%20is%3Ac
|
|||
|
||||
### Added
|
||||
|
||||
* When using the standalone plugin while running Certbot interactively
|
||||
* When using the standalone plugin while running Certbot interactively
|
||||
and a required port is bound by another process, Certbot will give you
|
||||
the option to retry to grab the port rather than immediately exiting.
|
||||
* You are now able to deactivate your account with the Let's Encrypt
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ ACME working area in github: https://github.com/ietf-wg-acme/acme
|
|||
:target: https://travis-ci.org/certbot/certbot
|
||||
:alt: Travis CI status
|
||||
|
||||
.. |coverage| image:: https://coveralls.io/repos/certbot/certbot/badge.svg?branch=master
|
||||
:target: https://coveralls.io/r/certbot/certbot
|
||||
.. |coverage| image:: https://codecov.io/gh/certbot/certbot/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/certbot/certbot
|
||||
:alt: Coverage status
|
||||
|
||||
.. |docs| image:: https://readthedocs.org/projects/letsencrypt/badge/
|
||||
|
|
|
|||
|
|
@ -577,16 +577,33 @@ class ClientV2(ClientBase):
|
|||
|
||||
:param .NewRegistration new_account:
|
||||
|
||||
:raises .ConflictError: in case the account already exists
|
||||
|
||||
:returns: Registration Resource.
|
||||
:rtype: `.RegistrationResource`
|
||||
"""
|
||||
response = self._post(self.directory['newAccount'], new_account)
|
||||
# if account already exists
|
||||
if response.status_code == 200 and 'Location' in response.headers:
|
||||
raise errors.ConflictError(response.headers.get('Location'))
|
||||
# "Instance of 'Field' has no key/contact member" bug:
|
||||
# pylint: disable=no-member
|
||||
regr = self._regr_from_response(response)
|
||||
self.net.account = regr
|
||||
return regr
|
||||
|
||||
def query_registration(self, regr):
|
||||
"""Query server about registration.
|
||||
|
||||
:param messages.RegistrationResource: Existing Registration
|
||||
Resource.
|
||||
|
||||
"""
|
||||
self.net.account = regr
|
||||
updated_regr = super(ClientV2, self).query_registration(regr)
|
||||
self.net.account = updated_regr
|
||||
return updated_regr
|
||||
|
||||
def update_registration(self, regr, update=None):
|
||||
"""Update registration.
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,12 @@ class BackwardsCompatibleClientV2Test(ClientTestBase):
|
|||
client = self._init()
|
||||
self.assertEqual(client.acme_version, 2)
|
||||
|
||||
def test_query_registration_client_v2(self):
|
||||
self.response.json.return_value = DIRECTORY_V2.to_json()
|
||||
client = self._init()
|
||||
self.response.json.return_value = self.regr.body.to_json()
|
||||
self.assertEqual(self.regr, client.query_registration(self.regr))
|
||||
|
||||
def test_forwarding(self):
|
||||
self.response.json.return_value = DIRECTORY_V1.to_json()
|
||||
client = self._init()
|
||||
|
|
@ -706,6 +712,11 @@ class ClientV2Test(ClientTestBase):
|
|||
|
||||
self.assertEqual(self.regr, self.client.new_account(self.new_reg))
|
||||
|
||||
def test_new_account_conflict(self):
|
||||
self.response.status_code = http_client.OK
|
||||
self.response.headers['Location'] = self.regr.uri
|
||||
self.assertRaises(errors.ConflictError, self.client.new_account, self.new_reg)
|
||||
|
||||
def test_new_order(self):
|
||||
order_response = copy.deepcopy(self.response)
|
||||
order_response.status_code = http_client.CREATED
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ class ConflictError(ClientError):
|
|||
|
||||
In the version of ACME implemented by Boulder, this is used to find an
|
||||
account if you only have the private key, but don't know the account URL.
|
||||
|
||||
Also used in V2 of the ACME client for the same purpose.
|
||||
"""
|
||||
def __init__(self, location):
|
||||
self.location = location
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from setuptools import find_packages
|
|||
from setuptools.command.test import test as TestCommand
|
||||
import sys
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Apache Configuration based off of Augeas Configurator."""
|
||||
# pylint: disable=too-many-lines
|
||||
import copy
|
||||
import fnmatch
|
||||
import logging
|
||||
import os
|
||||
|
|
@ -97,48 +98,72 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
vhost_root="/etc/apache2/sites-available",
|
||||
vhost_files="*",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
apache_cmd="apache2ctl",
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=False,
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
"certbot_apache", "options-ssl-apache.conf")
|
||||
)
|
||||
|
||||
def constant(self, key):
|
||||
"""Get constant for OS_DEFAULTS"""
|
||||
return self.OS_DEFAULTS.get(key)
|
||||
def option(self, key):
|
||||
"""Get a value from options"""
|
||||
return self.options.get(key)
|
||||
|
||||
def _prepare_options(self):
|
||||
"""
|
||||
Set the values possibly changed by command line parameters to
|
||||
OS_DEFAULTS constant dictionary
|
||||
"""
|
||||
opts = ["enmod", "dismod", "le_vhost_ext", "server_root", "vhost_root",
|
||||
"logs_root", "challenge_location", "handle_modules", "handle_sites",
|
||||
"ctl"]
|
||||
for o in opts:
|
||||
# Config options use dashes instead of underscores
|
||||
if self.conf(o.replace("_", "-")) is not None:
|
||||
self.options[o] = self.conf(o.replace("_", "-"))
|
||||
else:
|
||||
self.options[o] = self.OS_DEFAULTS[o]
|
||||
|
||||
# Special cases
|
||||
self.options["version_cmd"][0] = self.option("ctl")
|
||||
self.options["restart_cmd"][0] = self.option("ctl")
|
||||
self.options["conftest_cmd"][0] = self.option("ctl")
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add):
|
||||
# When adding, modifying or deleting command line arguments, be sure to
|
||||
# include the changes in the list used in method _prepare_options() to
|
||||
# ensure consistent behavior.
|
||||
add("enmod", default=cls.OS_DEFAULTS["enmod"],
|
||||
help="Path to the Apache 'a2enmod' binary.")
|
||||
help="Path to the Apache 'a2enmod' binary")
|
||||
add("dismod", default=cls.OS_DEFAULTS["dismod"],
|
||||
help="Path to the Apache 'a2dismod' binary.")
|
||||
help="Path to the Apache 'a2dismod' binary")
|
||||
add("le-vhost-ext", default=cls.OS_DEFAULTS["le_vhost_ext"],
|
||||
help="SSL vhost configuration extension.")
|
||||
help="SSL vhost configuration extension")
|
||||
add("server-root", default=cls.OS_DEFAULTS["server_root"],
|
||||
help="Apache server root directory.")
|
||||
help="Apache server root directory")
|
||||
add("vhost-root", default=None,
|
||||
help="Apache server VirtualHost configuration root")
|
||||
add("logs-root", default=cls.OS_DEFAULTS["logs_root"],
|
||||
help="Apache server logs directory")
|
||||
add("challenge-location",
|
||||
default=cls.OS_DEFAULTS["challenge_location"],
|
||||
help="Directory path for challenge configuration.")
|
||||
add("handle-modules", default=cls.OS_DEFAULTS["handle_mods"],
|
||||
help="Let installer handle enabling required modules for you. " +
|
||||
help="Directory path for challenge configuration")
|
||||
add("handle-modules", default=cls.OS_DEFAULTS["handle_modules"],
|
||||
help="Let installer handle enabling required modules for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
add("handle-sites", default=cls.OS_DEFAULTS["handle_sites"],
|
||||
help="Let installer handle enabling sites for you. " +
|
||||
help="Let installer handle enabling sites for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
util.add_deprecated_argument(add, argument_name="ctl", nargs=1)
|
||||
add("ctl", default=cls.OS_DEFAULTS["ctl"],
|
||||
help="Full path to Apache control script")
|
||||
util.add_deprecated_argument(
|
||||
add, argument_name="init-script", nargs=1)
|
||||
|
||||
|
|
@ -169,7 +194,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
self.parser = None
|
||||
self.version = version
|
||||
self.vhosts = None
|
||||
self.vhostroot = None
|
||||
self.options = copy.deepcopy(self.OS_DEFAULTS)
|
||||
self._enhance_func = {"redirect": self._enable_redirect,
|
||||
"ensure-http-header": self._set_http_header,
|
||||
"staple-ocsp": self._enable_ocsp_stapling}
|
||||
|
|
@ -201,12 +226,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
except ImportError:
|
||||
raise errors.NoInstallationError("Problem in Augeas installation")
|
||||
|
||||
self._prepare_options()
|
||||
|
||||
# Verify Apache is installed
|
||||
restart_cmd = self.constant("restart_cmd")[0]
|
||||
if not util.exe_exists(restart_cmd):
|
||||
if not path_surgery(restart_cmd):
|
||||
raise errors.NoInstallationError(
|
||||
'Cannot find Apache control command {0}'.format(restart_cmd))
|
||||
self._verify_exe_availability(self.option("ctl"))
|
||||
|
||||
# Make sure configuration is valid
|
||||
self.config_test()
|
||||
|
|
@ -226,12 +249,6 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"version 1.2.0 or higher, please make sure you have you have "
|
||||
"those installed.")
|
||||
|
||||
# Parse vhost-root if defined on cli
|
||||
if not self.conf("vhost-root"):
|
||||
self.vhostroot = self.constant("vhost_root")
|
||||
else:
|
||||
self.vhostroot = os.path.abspath(self.conf("vhost-root"))
|
||||
|
||||
self.parser = self.get_parser()
|
||||
|
||||
# Check for errors in parsing files with Augeas
|
||||
|
|
@ -245,13 +262,20 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
# Prevent two Apache plugins from modifying a config at once
|
||||
try:
|
||||
util.lock_dir_until_exit(self.conf("server-root"))
|
||||
util.lock_dir_until_exit(self.option("server_root"))
|
||||
except (OSError, errors.LockError):
|
||||
logger.debug("Encountered error:", exc_info=True)
|
||||
raise errors.PluginError(
|
||||
"Unable to lock %s", self.conf("server-root"))
|
||||
"Unable to lock %s", self.option("server_root"))
|
||||
self._prepared = True
|
||||
|
||||
def _verify_exe_availability(self, exe):
|
||||
"""Checks availability of Apache executable"""
|
||||
if not util.exe_exists(exe):
|
||||
if not path_surgery(exe):
|
||||
raise errors.NoInstallationError(
|
||||
'Cannot find Apache executable {0}'.format(exe))
|
||||
|
||||
def _check_aug_version(self):
|
||||
""" Checks that we have recent enough version of libaugeas.
|
||||
If augeas version is recent enough, it will support case insensitive
|
||||
|
|
@ -269,8 +293,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
# If user provided vhost_root value in command line, use it
|
||||
return parser.ApacheParser(
|
||||
self.aug, self.conf("server-root"), self.conf("vhost-root"),
|
||||
self.aug, self.option("server_root"), self.conf("vhost-root"),
|
||||
self.version, configurator=self)
|
||||
|
||||
def _wildcard_domain(self, domain):
|
||||
|
|
@ -1037,7 +1062,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
:param boolean temp: If the change is temporary
|
||||
"""
|
||||
|
||||
if self.conf("handle-modules"):
|
||||
if self.option("handle_modules"):
|
||||
if self.version >= (2, 4) and ("socache_shmcb_module" not in
|
||||
self.parser.modules):
|
||||
self.enable_mod("socache_shmcb", temp=temp)
|
||||
|
|
@ -1066,7 +1091,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
Duplicates vhost and adds default ssl options
|
||||
New vhost will reside as (nonssl_vhost.path) +
|
||||
``self.constant("le_vhost_ext")``
|
||||
``self.option("le_vhost_ext")``
|
||||
|
||||
.. note:: This function saves the configuration
|
||||
|
||||
|
|
@ -1165,18 +1190,16 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"""
|
||||
|
||||
if self.conf("vhost-root") and os.path.exists(self.conf("vhost-root")):
|
||||
# Defined by user on CLI
|
||||
|
||||
fp = os.path.join(os.path.realpath(self.vhostroot),
|
||||
fp = os.path.join(os.path.realpath(self.option("vhost_root")),
|
||||
os.path.basename(non_ssl_vh_fp))
|
||||
else:
|
||||
# Use non-ssl filepath
|
||||
fp = os.path.realpath(non_ssl_vh_fp)
|
||||
|
||||
if fp.endswith(".conf"):
|
||||
return fp[:-(len(".conf"))] + self.conf("le_vhost_ext")
|
||||
return fp[:-(len(".conf"))] + self.option("le_vhost_ext")
|
||||
else:
|
||||
return fp + self.conf("le_vhost_ext")
|
||||
return fp + self.option("le_vhost_ext")
|
||||
|
||||
def _sift_rewrite_rule(self, line):
|
||||
"""Decides whether a line should be copied to a SSL vhost.
|
||||
|
|
@ -2025,7 +2048,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
addr in self._get_proposed_addrs(ssl_vhost)),
|
||||
servername, serveralias,
|
||||
" ".join(rewrite_rule_args),
|
||||
self.conf("logs-root")))
|
||||
self.option("logs_root")))
|
||||
|
||||
def _write_out_redirect(self, ssl_vhost, text):
|
||||
# This is the default name
|
||||
|
|
@ -2037,7 +2060,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
if len(ssl_vhost.name) < (255 - (len(redirect_filename) + 1)):
|
||||
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.name
|
||||
|
||||
redirect_filepath = os.path.join(self.vhostroot,
|
||||
redirect_filepath = os.path.join(self.option("vhost_root"),
|
||||
redirect_filename)
|
||||
|
||||
# Register the new file that will be created
|
||||
|
|
@ -2158,18 +2181,18 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"""
|
||||
error = ""
|
||||
try:
|
||||
util.run_script(self.constant("restart_cmd"))
|
||||
util.run_script(self.option("restart_cmd"))
|
||||
except errors.SubprocessError as err:
|
||||
logger.info("Unable to restart apache using %s",
|
||||
self.constant("restart_cmd"))
|
||||
alt_restart = self.constant("restart_cmd_alt")
|
||||
self.option("restart_cmd"))
|
||||
alt_restart = self.option("restart_cmd_alt")
|
||||
if alt_restart:
|
||||
logger.debug("Trying alternative restart command: %s",
|
||||
alt_restart)
|
||||
# There is an alternative restart command available
|
||||
# This usually is "restart" verb while original is "graceful"
|
||||
try:
|
||||
util.run_script(self.constant(
|
||||
util.run_script(self.option(
|
||||
"restart_cmd_alt"))
|
||||
return
|
||||
except errors.SubprocessError as secerr:
|
||||
|
|
@ -2185,7 +2208,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
"""
|
||||
try:
|
||||
util.run_script(self.constant("conftest_cmd"))
|
||||
util.run_script(self.option("conftest_cmd"))
|
||||
except errors.SubprocessError as err:
|
||||
raise errors.MisconfigurationError(str(err))
|
||||
|
||||
|
|
@ -2201,11 +2224,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
"""
|
||||
try:
|
||||
stdout, _ = util.run_script(self.constant("version_cmd"))
|
||||
stdout, _ = util.run_script(self.option("version_cmd"))
|
||||
except errors.SubprocessError:
|
||||
raise errors.PluginError(
|
||||
"Unable to run %s -v" %
|
||||
self.constant("version_cmd"))
|
||||
self.option("version_cmd"))
|
||||
|
||||
regex = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE)
|
||||
matches = regex.findall(stdout)
|
||||
|
|
@ -2295,7 +2318,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
# certbot for unprivileged users via setuid), this function will need
|
||||
# to be modified.
|
||||
return common.install_version_controlled_file(options_ssl, options_ssl_digest,
|
||||
self.constant("MOD_SSL_CONF_SRC"), constants.ALL_SSL_OPTIONS_HASHES)
|
||||
self.option("MOD_SSL_CONF_SRC"), constants.ALL_SSL_OPTIONS_HASHES)
|
||||
|
||||
def enable_autohsts(self, _unused_lineage, domains):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -113,8 +113,7 @@ def _vhost_menu(domain, vhosts):
|
|||
code, tag = zope.component.getUtility(interfaces.IDisplay).menu(
|
||||
"We were unable to find a vhost with a ServerName "
|
||||
"or Address of {0}.{1}Which virtual host would you "
|
||||
"like to choose?\n(note: conf files with multiple "
|
||||
"vhosts are not yet supported)".format(domain, os.linesep),
|
||||
"like to choose?".format(domain, os.linesep),
|
||||
choices, force_interactive=True)
|
||||
except errors.MissingCommandlineFlag:
|
||||
msg = (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-m
|
|||
from certbot import errors
|
||||
from certbot.plugins import common
|
||||
from certbot_apache.obj import VirtualHost # pylint: disable=unused-import
|
||||
from certbot_apache.parser import get_aug_path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -172,4 +173,9 @@ class ApacheHttp01(common.TLSSNI01):
|
|||
self.configurator.parser.add_dir(
|
||||
vhost.path, "Include", self.challenge_conf_post)
|
||||
|
||||
if not vhost.enabled:
|
||||
self.configurator.parser.add_dir(
|
||||
get_aug_path(self.configurator.parser.loc["default"]),
|
||||
"Include", vhost.filep)
|
||||
|
||||
self.moded_vhosts.add(vhost)
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ class ArchConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/httpd/conf",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/httpd",
|
||||
ctl="apachectl",
|
||||
version_cmd=['apachectl', '-v'],
|
||||
apache_cmd="apachectl",
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=False,
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
|
|
|
|||
|
|
@ -18,25 +18,33 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/httpd/conf.d",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/httpd",
|
||||
ctl="apachectl",
|
||||
version_cmd=['apachectl', '-v'],
|
||||
apache_cmd="apachectl",
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
restart_cmd_alt=['apachectl', 'restart'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=False,
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf.d",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
"certbot_apache", "centos-options-ssl-apache.conf")
|
||||
)
|
||||
|
||||
def _prepare_options(self):
|
||||
"""
|
||||
Override the options dictionary initialization in order to support
|
||||
alternative restart cmd used in CentOS.
|
||||
"""
|
||||
super(CentOSConfigurator, self)._prepare_options()
|
||||
self.options["restart_cmd_alt"][0] = self.option("ctl")
|
||||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
return CentOSParser(
|
||||
self.aug, self.conf("server-root"), self.conf("vhost-root"),
|
||||
self.aug, self.option("server_root"), self.option("vhost_root"),
|
||||
self.version, configurator=self)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ class DarwinConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/apache2/other",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
version_cmd=['/usr/sbin/httpd', '-v'],
|
||||
apache_cmd="/usr/sbin/httpd",
|
||||
ctl="apachectl",
|
||||
version_cmd=['apachectl', '-v'],
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=False,
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2/other",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ class DebianConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/apache2/sites-available",
|
||||
vhost_files="*",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
apache_cmd="apache2ctl",
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod="a2enmod",
|
||||
dismod="a2dismod",
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=True,
|
||||
handle_modules=True,
|
||||
handle_sites=True,
|
||||
challenge_location="/etc/apache2",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
|
|
@ -134,11 +134,11 @@ class DebianConfigurator(configurator.ApacheConfigurator):
|
|||
# Generate reversal command.
|
||||
# Try to be safe here... check that we can probably reverse before
|
||||
# applying enmod command
|
||||
if not util.exe_exists(self.conf("dismod")):
|
||||
if not util.exe_exists(self.option("dismod")):
|
||||
raise errors.MisconfigurationError(
|
||||
"Unable to find a2dismod, please make sure a2enmod and "
|
||||
"a2dismod are configured correctly for certbot.")
|
||||
|
||||
self.reverter.register_undo_command(
|
||||
temp, [self.conf("dismod"), "-f", mod_name])
|
||||
util.run_script([self.conf("enmod"), mod_name])
|
||||
temp, [self.option("dismod"), "-f", mod_name])
|
||||
util.run_script([self.option("enmod"), mod_name])
|
||||
|
|
|
|||
|
|
@ -18,25 +18,33 @@ class GentooConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/apache2/vhosts.d",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
version_cmd=['/usr/sbin/apache2', '-v'],
|
||||
apache_cmd="apache2ctl",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
restart_cmd_alt=['apache2ctl', 'restart'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_mods=False,
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2/vhosts.d",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
"certbot_apache", "options-ssl-apache.conf")
|
||||
)
|
||||
|
||||
def _prepare_options(self):
|
||||
"""
|
||||
Override the options dictionary initialization in order to support
|
||||
alternative restart cmd used in Gentoo.
|
||||
"""
|
||||
super(GentooConfigurator, self)._prepare_options()
|
||||
self.options["restart_cmd_alt"][0] = self.option("ctl")
|
||||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
return GentooParser(
|
||||
self.aug, self.conf("server-root"), self.conf("vhost-root"),
|
||||
self.aug, self.option("server_root"), self.option("vhost_root"),
|
||||
self.version, configurator=self)
|
||||
|
||||
|
||||
|
|
@ -61,7 +69,7 @@ class GentooParser(parser.ApacheParser):
|
|||
|
||||
def update_modules(self):
|
||||
"""Get loaded modules from httpd process, and add them to DOM"""
|
||||
mod_cmd = [self.configurator.constant("apache_cmd"), "modules"]
|
||||
mod_cmd = [self.configurator.option("ctl"), "modules"]
|
||||
matches = self.parse_from_subprocess(mod_cmd, r"(.*)_module")
|
||||
for mod in matches:
|
||||
self.add_mod(mod.strip())
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ class OpenSUSEConfigurator(configurator.ApacheConfigurator):
|
|||
vhost_root="/etc/apache2/vhosts.d",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
apache_cmd="apache2ctl",
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod="a2enmod",
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class ApacheParser(object):
|
|||
# Must also attempt to parse additional virtual host root
|
||||
if vhostroot:
|
||||
self.parse_file(os.path.abspath(vhostroot) + "/" +
|
||||
self.configurator.constant("vhost_files"))
|
||||
self.configurator.option("vhost_files"))
|
||||
|
||||
# check to see if there were unparsed define statements
|
||||
if version < (2, 4):
|
||||
|
|
@ -152,7 +152,7 @@ class ApacheParser(object):
|
|||
"""Get Defines from httpd process"""
|
||||
|
||||
variables = dict()
|
||||
define_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
|
||||
define_cmd = [self.configurator.option("ctl"), "-t", "-D",
|
||||
"DUMP_RUN_CFG"]
|
||||
matches = self.parse_from_subprocess(define_cmd, r"Define: ([^ \n]*)")
|
||||
try:
|
||||
|
|
@ -179,7 +179,7 @@ class ApacheParser(object):
|
|||
# configuration files
|
||||
_ = self.find_dir("Include")
|
||||
|
||||
inc_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
|
||||
inc_cmd = [self.configurator.option("ctl"), "-t", "-D",
|
||||
"DUMP_INCLUDES"]
|
||||
matches = self.parse_from_subprocess(inc_cmd, r"\(.*\) (.*)")
|
||||
if matches:
|
||||
|
|
@ -190,7 +190,7 @@ class ApacheParser(object):
|
|||
def update_modules(self):
|
||||
"""Get loaded modules from httpd process, and add them to DOM"""
|
||||
|
||||
mod_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
|
||||
mod_cmd = [self.configurator.option("ctl"), "-t", "-D",
|
||||
"DUMP_MODULES"]
|
||||
matches = self.parse_from_subprocess(mod_cmd, r"(.*)_module")
|
||||
for mod in matches:
|
||||
|
|
|
|||
|
|
@ -119,6 +119,9 @@ class AutoHSTSTest(util.ApacheTest):
|
|||
cur_val = maxage.format(constants.AUTOHSTS_STEPS[i+1])
|
||||
self.assertEquals(self.get_autohsts_value(self.vh_truth[7].path),
|
||||
cur_val)
|
||||
# Ensure that the value is raised to max
|
||||
self.assertEquals(self.get_autohsts_value(self.vh_truth[7].path),
|
||||
maxage.format(constants.AUTOHSTS_STEPS[-1]))
|
||||
# Make permanent
|
||||
self.config.deploy_autohsts(mock_lineage)
|
||||
self.assertEquals(self.get_autohsts_value(self.vh_truth[7].path),
|
||||
|
|
|
|||
|
|
@ -135,5 +135,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest):
|
|||
errors.SubprocessError,
|
||||
errors.SubprocessError]
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -116,8 +116,9 @@ class MultipleVhostsTest(util.ApacheTest):
|
|||
ApacheConfigurator.add_parser_arguments(mock.MagicMock())
|
||||
|
||||
def test_constant(self):
|
||||
self.assertEqual(self.config.constant("server_root"), "/etc/apache2")
|
||||
self.assertEqual(self.config.constant("nonexistent"), None)
|
||||
self.assertTrue("debian_apache_2_4/multiple_vhosts/apache" in
|
||||
self.config.option("server_root"))
|
||||
self.assertEqual(self.config.option("nonexistent"), None)
|
||||
|
||||
@certbot_util.patch_get_utility()
|
||||
def test_get_all_names(self, mock_getutility):
|
||||
|
|
@ -651,22 +652,10 @@ class MultipleVhostsTest(util.ApacheTest):
|
|||
self.assertEqual(ssl_vhost_slink.name, "nonsym.link")
|
||||
|
||||
def test_make_vhost_ssl_nonexistent_vhost_path(self):
|
||||
def conf_side_effect(arg):
|
||||
""" Mock function for ApacheConfigurator.conf """
|
||||
confvars = {
|
||||
"vhost-root": "/tmp/nonexistent",
|
||||
"le_vhost_ext": "-le-ssl.conf",
|
||||
"handle-sites": True}
|
||||
return confvars[arg]
|
||||
|
||||
with mock.patch(
|
||||
"certbot_apache.configurator.ApacheConfigurator.conf"
|
||||
) as mock_conf:
|
||||
mock_conf.side_effect = conf_side_effect
|
||||
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[1])
|
||||
self.assertEqual(os.path.dirname(ssl_vhost.filep),
|
||||
os.path.dirname(os.path.realpath(
|
||||
self.vh_truth[1].filep)))
|
||||
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[1])
|
||||
self.assertEqual(os.path.dirname(ssl_vhost.filep),
|
||||
os.path.dirname(os.path.realpath(
|
||||
self.vh_truth[1].filep)))
|
||||
|
||||
def test_make_vhost_ssl(self):
|
||||
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
|
||||
|
|
@ -1583,7 +1572,7 @@ class AugeasVhostsTest(util.ApacheTest):
|
|||
broken_vhost)
|
||||
|
||||
class MultiVhostsTest(util.ApacheTest):
|
||||
"""Test vhosts with illegal names dependent on augeas version."""
|
||||
"""Test configuration with multiple virtualhosts in a single file."""
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
|
|
@ -1703,7 +1692,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
|||
self.config.updated_mod_ssl_conf_digest)
|
||||
|
||||
def _current_ssl_options_hash(self):
|
||||
return crypto_util.sha256sum(self.config.constant("MOD_SSL_CONF_SRC"))
|
||||
return crypto_util.sha256sum(self.config.option("MOD_SSL_CONF_SRC"))
|
||||
|
||||
def _assert_current_file(self):
|
||||
self.assertTrue(os.path.isfile(self.config.mod_ssl_conf))
|
||||
|
|
@ -1739,7 +1728,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
|||
self.assertFalse(mock_logger.warning.called)
|
||||
self.assertTrue(os.path.isfile(self.config.mod_ssl_conf))
|
||||
self.assertEqual(crypto_util.sha256sum(
|
||||
self.config.constant("MOD_SSL_CONF_SRC")),
|
||||
self.config.option("MOD_SSL_CONF_SRC")),
|
||||
self._current_ssl_options_hash())
|
||||
self.assertNotEqual(crypto_util.sha256sum(self.config.mod_ssl_conf),
|
||||
self._current_ssl_options_hash())
|
||||
|
|
@ -1755,7 +1744,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
|||
"%s has been manually modified; updated file "
|
||||
"saved to %s. We recommend updating %s for security purposes.")
|
||||
self.assertEqual(crypto_util.sha256sum(
|
||||
self.config.constant("MOD_SSL_CONF_SRC")),
|
||||
self.config.option("MOD_SSL_CONF_SRC")),
|
||||
self._current_ssl_options_hash())
|
||||
# only print warning once
|
||||
with mock.patch("certbot.plugins.common.logger") as mock_logger:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class MultipleVhostsTestDebian(util.ApacheTest):
|
|||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(MultipleVhostsTestDebian, self).setUp()
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, None, self.config_dir, self.work_dir,
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
os_info="debian")
|
||||
self.config = self.mock_deploy_cert(self.config)
|
||||
self.vh_truth = util.get_vh_truth(self.temp_dir,
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class MultipleVhostsTestGentoo(util.ApacheTest):
|
|||
self.config.parser.modules = set()
|
||||
|
||||
with mock.patch("certbot.util.get_os_info") as mock_osi:
|
||||
# Make sure we have the have the CentOS httpd constants
|
||||
# Make sure we have the have the Gentoo httpd constants
|
||||
mock_osi.return_value = ("gentoo", "123")
|
||||
self.config.parser.update_runtime_variables()
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from certbot import achallenges
|
|||
from certbot import errors
|
||||
|
||||
from certbot.tests import acme_util
|
||||
from certbot_apache.parser import get_aug_path
|
||||
from certbot_apache.tests import util
|
||||
|
||||
|
||||
|
|
@ -134,6 +135,21 @@ class ApacheHttp01Test(util.ApacheTest):
|
|||
def test_perform_3_achall_apache_2_4(self):
|
||||
self.combinations_perform_test(num_achalls=3, minor_version=4)
|
||||
|
||||
def test_activate_disabled_vhost(self):
|
||||
vhosts = [v for v in self.config.vhosts if v.name == "certbot.demo"]
|
||||
achalls = [
|
||||
achallenges.KeyAuthorizationAnnotatedChallenge(
|
||||
challb=acme_util.chall_to_challb(
|
||||
challenges.HTTP01(token=((b'a' * 16))),
|
||||
"pending"),
|
||||
domain="certbot.demo", account_key=self.account_key)]
|
||||
vhosts[0].enabled = False
|
||||
self.common_perform_test(achalls, vhosts)
|
||||
matches = self.config.parser.find_dir(
|
||||
"Include", vhosts[0].filep,
|
||||
get_aug_path(self.config.parser.loc["default"]))
|
||||
self.assertEqual(len(matches), 1)
|
||||
|
||||
def combinations_perform_test(self, num_achalls, minor_version):
|
||||
"""Test perform with the given achall count and Apache version."""
|
||||
achalls = self.achalls[:num_achalls]
|
||||
|
|
|
|||
|
|
@ -282,11 +282,11 @@ class BasicParserTest(util.ParserTest):
|
|||
self.assertRaises(
|
||||
errors.PluginError, self.parser.update_runtime_variables)
|
||||
|
||||
@mock.patch("certbot_apache.configurator.ApacheConfigurator.constant")
|
||||
@mock.patch("certbot_apache.configurator.ApacheConfigurator.option")
|
||||
@mock.patch("certbot_apache.parser.subprocess.Popen")
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_popen, mock_const):
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_popen, mock_opt):
|
||||
mock_popen.side_effect = OSError
|
||||
mock_const.return_value = "nonexistent"
|
||||
mock_opt.return_value = "nonexistent"
|
||||
self.assertRaises(
|
||||
errors.MisconfigurationError,
|
||||
self.parser.update_runtime_variables)
|
||||
|
|
|
|||
|
|
@ -97,9 +97,10 @@ def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-loc
|
|||
backups = os.path.join(work_dir, "backups")
|
||||
mock_le_config = mock.MagicMock(
|
||||
apache_server_root=config_path,
|
||||
apache_vhost_root=conf_vhost_path,
|
||||
apache_vhost_root=None,
|
||||
apache_le_vhost_ext="-le-ssl.conf",
|
||||
apache_challenge_location=config_path,
|
||||
apache_enmod=None,
|
||||
backup_dir=backups,
|
||||
config_dir=config_dir,
|
||||
http01_port=80,
|
||||
|
|
@ -107,33 +108,25 @@ def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-loc
|
|||
in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
|
||||
work_dir=work_dir)
|
||||
|
||||
orig_os_constant = configurator.ApacheConfigurator(mock_le_config,
|
||||
name="apache",
|
||||
version=version).constant
|
||||
|
||||
def mock_os_constant(key, vhost_path=vhost_path):
|
||||
"""Mock default vhost path"""
|
||||
if key == "vhost_root":
|
||||
return vhost_path
|
||||
else:
|
||||
return orig_os_constant(key)
|
||||
|
||||
with mock.patch("certbot_apache.configurator.ApacheConfigurator.constant") as mock_cons:
|
||||
mock_cons.side_effect = mock_os_constant
|
||||
with mock.patch("certbot_apache.configurator.util.run_script"):
|
||||
with mock.patch("certbot_apache.configurator.util."
|
||||
"exe_exists") as mock_exe_exists:
|
||||
mock_exe_exists.return_value = True
|
||||
with mock.patch("certbot_apache.parser.ApacheParser."
|
||||
"update_runtime_variables"):
|
||||
try:
|
||||
config_class = entrypoint.OVERRIDE_CLASSES[os_info]
|
||||
except KeyError:
|
||||
config_class = configurator.ApacheConfigurator
|
||||
config = config_class(config=mock_le_config, name="apache",
|
||||
version=version)
|
||||
|
||||
config.prepare()
|
||||
with mock.patch("certbot_apache.configurator.util.run_script"):
|
||||
with mock.patch("certbot_apache.configurator.util."
|
||||
"exe_exists") as mock_exe_exists:
|
||||
mock_exe_exists.return_value = True
|
||||
with mock.patch("certbot_apache.parser.ApacheParser."
|
||||
"update_runtime_variables"):
|
||||
try:
|
||||
config_class = entrypoint.OVERRIDE_CLASSES[os_info]
|
||||
except KeyError:
|
||||
config_class = configurator.ApacheConfigurator
|
||||
config = config_class(config=mock_le_config, name="apache",
|
||||
version=version)
|
||||
if not conf_vhost_path:
|
||||
config_class.OS_DEFAULTS["vhost_root"] = vhost_path
|
||||
else:
|
||||
# Custom virtualhost path was requested
|
||||
config.config.apache_vhost_root = conf_vhost_path
|
||||
config.config.apache_ctl = config_class.OS_DEFAULTS["ctl"]
|
||||
config.prepare()
|
||||
return config
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.25.0',
|
||||
'certbot>=0.26.0.dev0',
|
||||
'certbot>=0.26.0',
|
||||
'mock',
|
||||
'python-augeas',
|
||||
'setuptools',
|
||||
|
|
|
|||
83
certbot-auto
83
certbot-auto
|
|
@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
|||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.25.1"
|
||||
LE_AUTO_VERSION="0.26.1"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -1060,37 +1060,26 @@ ConfigArgParse==0.12.0 \
|
|||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 \
|
||||
--no-binary configobj
|
||||
cryptography==2.0.2 \
|
||||
--hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \
|
||||
--hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \
|
||||
--hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \
|
||||
--hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \
|
||||
--hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \
|
||||
--hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \
|
||||
--hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \
|
||||
--hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \
|
||||
--hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \
|
||||
--hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \
|
||||
--hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \
|
||||
--hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \
|
||||
--hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \
|
||||
--hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \
|
||||
--hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \
|
||||
--hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \
|
||||
--hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \
|
||||
--hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \
|
||||
--hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \
|
||||
--hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \
|
||||
--hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \
|
||||
--hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \
|
||||
--hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \
|
||||
--hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \
|
||||
--hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \
|
||||
--hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \
|
||||
--hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \
|
||||
--hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \
|
||||
--hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \
|
||||
--hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab
|
||||
cryptography==2.2.2 \
|
||||
--hash=sha256:3f3b65d5a16e6b52fba63dc860b62ca9832f51f1a2ae5083c78b6840275f12dd \
|
||||
--hash=sha256:5251e7de0de66810833606439ca65c9b9e45da62196b0c88bfadf27740aac09f \
|
||||
--hash=sha256:551a3abfe0c8c6833df4192a63371aa2ff43afd8f570ed345d31f251d78e7e04 \
|
||||
--hash=sha256:5cb990056b7cadcca26813311187ad751ea644712022a3976443691168781b6f \
|
||||
--hash=sha256:60bda7f12ecb828358be53095fc9c6edda7de8f1ef571f96c00b2363643fa3cd \
|
||||
--hash=sha256:64b5c67acc9a7c83fbb4b69166f3105a0ab722d27934fac2cb26456718eec2ba \
|
||||
--hash=sha256:6fef51ec447fe9f8351894024e94736862900d3a9aa2961528e602eb65c92bdb \
|
||||
--hash=sha256:77d0ad229d47a6e0272d00f6bf8ac06ce14715a9fd02c9a97f5a2869aab3ccb2 \
|
||||
--hash=sha256:808fe471b1a6b777f026f7dc7bd9a4959da4bfab64972f2bbe91e22527c1c037 \
|
||||
--hash=sha256:9b62fb4d18529c84b961efd9187fecbb48e89aa1a0f9f4161c61b7fc42a101bd \
|
||||
--hash=sha256:9e5bed45ec6b4f828866ac6a6bedf08388ffcfa68abe9e94b34bb40977aba531 \
|
||||
--hash=sha256:9fc295bf69130a342e7a19a39d7bbeb15c0bcaabc7382ec33ef3b2b7d18d2f63 \
|
||||
--hash=sha256:abd070b5849ed64e6d349199bef955ee0ad99aefbad792f0c587f8effa681a5e \
|
||||
--hash=sha256:ba6a774749b6e510cffc2fb98535f717e0e5fd91c7c99a61d223293df79ab351 \
|
||||
--hash=sha256:c332118647f084c983c6a3e1dba0f3bcb051f69d12baccac68db8d62d177eb8a \
|
||||
--hash=sha256:d6f46e862ee36df81e6342c2177ba84e70f722d9dc9c6c394f9f1f434c4a5563 \
|
||||
--hash=sha256:db6013746f73bf8edd9c3d1d3f94db635b9422f503db3fc5ef105233d4c011ab \
|
||||
--hash=sha256:f57008eaff597c69cf692c3518f6d4800f0309253bb138b526a37fe9ef0c7471 \
|
||||
--hash=sha256:f6c821ac253c19f2ad4c8691633ae1d1a17f120d5b01ea1d256d7b602bc59887
|
||||
enum34==1.1.2 ; python_version < '3.4' \
|
||||
--hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \
|
||||
--hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501
|
||||
|
|
@ -1103,9 +1092,9 @@ idna==2.5 \
|
|||
ipaddress==1.0.16 \
|
||||
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
||||
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
||||
josepy==1.0.1 \
|
||||
--hash=sha256:354a3513038a38bbcd27c97b7c68a8f3dfaff0a135b20a92c6db4cc4ea72915e \
|
||||
--hash=sha256:9f48b88ca37f0244238b1cc77723989f7c54f7b90b2eee6294390bacfe870acc
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
linecache2==1.0.0 \
|
||||
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
||||
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
||||
|
|
@ -1208,18 +1197,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.25.1 \
|
||||
--hash=sha256:01689015364685fef3f1e1fb7832ba84eb3b0aa85bc5a71c96661f6d4c59981f \
|
||||
--hash=sha256:5c23e5186133bb1afd805be5e0cd2fb7b95862a8b0459c9ecad4ae60f933e54e
|
||||
acme==0.25.1 \
|
||||
--hash=sha256:26e641a01536705fe5f12d856703b8ef06e5a07981a7b6379d2771dcdb69a742 \
|
||||
--hash=sha256:47b5f3f73d69b7b1d13f918aa2cd75a8093069a68becf4af38e428e4613b2734
|
||||
certbot-apache==0.25.1 \
|
||||
--hash=sha256:a28b7c152cc11474bef5b5e7967aaea42b2c0aaf86fd82ee4082713d33cee5a9 \
|
||||
--hash=sha256:ed012465617073a0f1057fe854dc8d1eb6d2dd7ede1fb2eee765129fed2a095a
|
||||
certbot-nginx==0.25.1 \
|
||||
--hash=sha256:83f82c3ba08c0b1d4bf449ac24018e8e7dd34a6248d35466f2de7da1cd312e15 \
|
||||
--hash=sha256:68f98b41c54e0bf4218ef293079597176617bee3837ae3aa6528ce2ff0bf4f9c
|
||||
certbot==0.26.1 \
|
||||
--hash=sha256:4e2ffdeebb7f5097600bcb1ca19131441fa021f952b443ca7454a279337af609 \
|
||||
--hash=sha256:4983513d63f7f36e24a07873ca2d6ea1c0101aa6cb1cd825cda02ed520f6ca66
|
||||
acme==0.26.1 \
|
||||
--hash=sha256:d47841e66adc1336ecca2f0d41a247c1b62307c981be6d07996bbf3f95af1dc5 \
|
||||
--hash=sha256:86e7b5f4654cb19215f16c0e6225750db7421f68ef6a0a040a61796f24e690be
|
||||
certbot-apache==0.26.1 \
|
||||
--hash=sha256:c16acb49bd4f84fff25bcbb7eaf74412145efe9b68ce46e1803be538894f2ce3 \
|
||||
--hash=sha256:b7fa327e987b892d64163e7519bdeaf9723d78275ef6c438272848894ace6d87
|
||||
certbot-nginx==0.26.1 \
|
||||
--hash=sha256:c0048dc83672dc90805a8ddf513be3e48c841d6e91607e91e8657c1785d65660 \
|
||||
--hash=sha256:d0c95a32625e0f1612d7fcf9021e6e050ba3d879823489d1edd2478a78ae6624
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -59,9 +59,6 @@ class Proxy(configurators_common.Proxy):
|
|||
setattr(self.le_config, "apache_" + k,
|
||||
entrypoint.ENTRYPOINT.OS_DEFAULTS[k])
|
||||
|
||||
# An alias
|
||||
self.le_config.apache_handle_modules = self.le_config.apache_handle_mods
|
||||
|
||||
self._configurator = entrypoint.ENTRYPOINT(
|
||||
config=configuration.NamespaceConfig(self.le_config),
|
||||
name="apache")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.25.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Credentials
|
|||
|
||||
Use of this plugin requires a configuration file containing Linode API
|
||||
credentials, obtained from your Linode account's `Applications & API
|
||||
Tokens page <https://cloud.linode.com/settings/api/tokens>`_.
|
||||
Tokens page <https://manager.linode.com/profile/api>`_.
|
||||
|
||||
.. code-block:: ini
|
||||
:name: credentials.ini
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import sys
|
|||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.25.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
@ -13,9 +13,7 @@ install_requires = [
|
|||
'certbot>=0.21.1',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
# For pkg_resources. >=1.0 so pip resolves it to a version cryptography
|
||||
# will tolerate; see #2599:
|
||||
'setuptools>=1.0',
|
||||
'setuptools',
|
||||
'zope.interface',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
|||
self.auth._get_sakuracloud_client = mock.MagicMock(return_value=self.mock_client)
|
||||
|
||||
|
||||
class NS1LexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexiconClientTest):
|
||||
class SakuraCloudLexiconClientTest(unittest.TestCase,
|
||||
dns_test_common_lexicon.BaseLexiconClientTest):
|
||||
DOMAIN_NOT_FOUND = HTTPError('404 Client Error: Not Found for url: {0}.'.format(DOMAIN))
|
||||
LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: {0}.'.format(DOMAIN))
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.25.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
acme[dev]==0.25.0
|
||||
acme[dev]==0.26.0
|
||||
-e .[dev]
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.26.0.dev0'
|
||||
version = '0.27.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.25.0',
|
||||
'acme>=0.26.0',
|
||||
'certbot>=0.22.0',
|
||||
'mock',
|
||||
'PyOpenSSL',
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ class InstallerTest(certbot_test_util.ConfigTestCase):
|
|||
fake_set.reset_mock()
|
||||
installer.deploy_cert("example.com", "cert_path", "key_path",
|
||||
"chain_path", "fullchain_path")
|
||||
fake_set.assert_not_called()
|
||||
self.assertFalse(fake_set.called)
|
||||
|
||||
@certbot_test_util.patch_get_utility()
|
||||
def test_deploy_already_secure(self, mock_util):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Certbot client."""
|
||||
|
||||
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
|
||||
__version__ = '0.26.0.dev0'
|
||||
__version__ = '0.27.0.dev0'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Creates ACME accounts for server."""
|
||||
import datetime
|
||||
import functools
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
|
|
@ -191,6 +192,11 @@ class AccountFileStorage(interfaces.AccountStorage):
|
|||
def find_all(self):
|
||||
return self._find_all_for_server_path(self.config.server_path)
|
||||
|
||||
def _symlink_to_account_dir(self, prev_server_path, server_path, account_id):
|
||||
prev_account_dir = self._account_dir_path_for_server_path(account_id, prev_server_path)
|
||||
new_account_dir = self._account_dir_path_for_server_path(account_id, server_path)
|
||||
os.symlink(prev_account_dir, new_account_dir)
|
||||
|
||||
def _symlink_to_accounts_dir(self, prev_server_path, server_path):
|
||||
accounts_dir = self.config.accounts_dir_for_server_path(server_path)
|
||||
if os.path.islink(accounts_dir):
|
||||
|
|
@ -207,7 +213,12 @@ class AccountFileStorage(interfaces.AccountStorage):
|
|||
prev_server_path = constants.LE_REUSE_SERVERS[server_path]
|
||||
prev_loaded_account = self._load_for_server_path(account_id, prev_server_path)
|
||||
# we didn't error so we found something, so create a symlink to that
|
||||
self._symlink_to_accounts_dir(prev_server_path, server_path)
|
||||
accounts_dir = self.config.accounts_dir_for_server_path(server_path)
|
||||
# If accounts_dir isn't empty, make an account specific symlink
|
||||
if os.listdir(accounts_dir):
|
||||
self._symlink_to_account_dir(prev_server_path, server_path, account_id)
|
||||
else:
|
||||
self._symlink_to_accounts_dir(prev_server_path, server_path)
|
||||
return prev_loaded_account
|
||||
else:
|
||||
raise errors.AccountNotFound(
|
||||
|
|
@ -250,49 +261,65 @@ class AccountFileStorage(interfaces.AccountStorage):
|
|||
:param account_id: id of account which should be deleted
|
||||
|
||||
"""
|
||||
# Step 1: remove the account itself
|
||||
account_dir_path = self._account_dir_path(account_id)
|
||||
if not os.path.isdir(account_dir_path):
|
||||
raise errors.AccountNotFound(
|
||||
"Account at %s does not exist" % account_dir_path)
|
||||
shutil.rmtree(account_dir_path)
|
||||
# Step 1: Delete account specific links and the directory
|
||||
self._delete_account_dir_for_server_path(account_id, self.config.server_path)
|
||||
|
||||
# Step 2: remove the directory if it's empty, and linked directories
|
||||
# Step 2: Remove any accounts links and directories that are now empty
|
||||
if not os.listdir(self.config.accounts_dir):
|
||||
self._delete_accounts_dir_for_server_path(self.config.server_path)
|
||||
|
||||
def _delete_account_dir_for_server_path(self, account_id, server_path):
|
||||
link_func = functools.partial(self._account_dir_path_for_server_path, account_id)
|
||||
nonsymlinked_dir = self._delete_links_and_find_target_dir(server_path, link_func)
|
||||
shutil.rmtree(nonsymlinked_dir)
|
||||
|
||||
def _delete_accounts_dir_for_server_path(self, server_path):
|
||||
accounts_dir_path = self.config.accounts_dir_for_server_path(server_path)
|
||||
link_func = self.config.accounts_dir_for_server_path
|
||||
nonsymlinked_dir = self._delete_links_and_find_target_dir(server_path, link_func)
|
||||
os.rmdir(nonsymlinked_dir)
|
||||
|
||||
def _delete_links_and_find_target_dir(self, server_path, link_func):
|
||||
"""Delete symlinks and return the nonsymlinked directory path.
|
||||
|
||||
:param str server_path: file path based on server
|
||||
:param callable link_func: callable that returns possible links
|
||||
given a server_path
|
||||
|
||||
:returns: the final, non-symlinked target
|
||||
:rtype: str
|
||||
|
||||
"""
|
||||
dir_path = link_func(server_path)
|
||||
|
||||
# does an appropriate directory link to me? if so, make sure that's gone
|
||||
reused_servers = {}
|
||||
for k in constants.LE_REUSE_SERVERS:
|
||||
reused_servers[constants.LE_REUSE_SERVERS[k]] = k
|
||||
|
||||
# is there a next one up? call that and be done
|
||||
if server_path in reused_servers:
|
||||
next_server_path = reused_servers[server_path]
|
||||
next_accounts_dir_path = self.config.accounts_dir_for_server_path(next_server_path)
|
||||
if os.path.islink(next_accounts_dir_path) \
|
||||
and os.readlink(next_accounts_dir_path) == accounts_dir_path:
|
||||
self._delete_accounts_dir_for_server_path(next_server_path)
|
||||
return
|
||||
# is there a next one up?
|
||||
possible_next_link = True
|
||||
while possible_next_link:
|
||||
possible_next_link = False
|
||||
if server_path in reused_servers:
|
||||
next_server_path = reused_servers[server_path]
|
||||
next_dir_path = link_func(next_server_path)
|
||||
if os.path.islink(next_dir_path) and os.readlink(next_dir_path) == dir_path:
|
||||
possible_next_link = True
|
||||
server_path = next_server_path
|
||||
dir_path = next_dir_path
|
||||
|
||||
# if there's not a next one up to delete, then delete me
|
||||
# and whatever I link to if applicable
|
||||
if os.path.islink(accounts_dir_path):
|
||||
# save my info then delete me
|
||||
target = os.readlink(accounts_dir_path)
|
||||
os.unlink(accounts_dir_path)
|
||||
# then delete whatever I linked to, if appropriate
|
||||
if server_path in constants.LE_REUSE_SERVERS:
|
||||
prev_server_path = constants.LE_REUSE_SERVERS[server_path]
|
||||
prev_accounts_dir_path = self.config.accounts_dir_for_server_path(prev_server_path)
|
||||
if target == prev_accounts_dir_path:
|
||||
self._delete_accounts_dir_for_server_path(prev_server_path)
|
||||
else:
|
||||
# just delete me
|
||||
os.rmdir(accounts_dir_path)
|
||||
# and whatever I link to
|
||||
while os.path.islink(dir_path):
|
||||
target = os.readlink(dir_path)
|
||||
os.unlink(dir_path)
|
||||
dir_path = target
|
||||
|
||||
return dir_path
|
||||
|
||||
def _save(self, account, acme, regr_only):
|
||||
account_dir_path = self._account_dir_path(account.id)
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ def _describe_certs(config, parsed_certs, parse_failures):
|
|||
notify("Found the following {0}certs:".format(match))
|
||||
notify(_report_human_readable(config, parsed_certs))
|
||||
if parse_failures:
|
||||
notify("\nThe following renewal configuration files "
|
||||
notify("\nThe following renewal configurations "
|
||||
"were invalid:")
|
||||
notify(_report_lines(parse_failures))
|
||||
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ def _renew_describe_results(config, renew_successes, renew_failures,
|
|||
notify_error(report(renew_failures, "failure"))
|
||||
|
||||
if parse_failures:
|
||||
notify("\nAdditionally, the following renewal configuration files "
|
||||
notify("\nAdditionally, the following renewal configurations "
|
||||
"were invalid: ")
|
||||
notify(report(parse_failures, "parsefail"))
|
||||
|
||||
|
|
|
|||
|
|
@ -249,6 +249,14 @@ class AccountFileStorageTest(test_util.ConfigTestCase):
|
|||
account = self.storage.load(self.acc.id)
|
||||
self.assertEqual(prev_account, account)
|
||||
|
||||
def test_upgrade_load_single_account(self):
|
||||
self._set_server('https://acme-staging.api.letsencrypt.org/directory')
|
||||
self.storage.save(self.acc, self.mock_client)
|
||||
prev_account = self.storage.load(self.acc.id)
|
||||
self._set_server_and_stop_symlink('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
account = self.storage.load(self.acc.id)
|
||||
self.assertEqual(prev_account, account)
|
||||
|
||||
def test_load_ioerror(self):
|
||||
self.storage.save(self.acc, self.mock_client)
|
||||
mock_open = mock.mock_open()
|
||||
|
|
@ -287,7 +295,7 @@ class AccountFileStorageTest(test_util.ConfigTestCase):
|
|||
self._set_server('https://acme-staging.api.letsencrypt.org/directory')
|
||||
self.storage.save(self.acc, self.mock_client)
|
||||
self._set_server('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
self.storage.find_all()
|
||||
self.storage.load(self.acc.id)
|
||||
|
||||
# delete starting at given server_url
|
||||
self._set_server(server_url)
|
||||
|
|
@ -307,6 +315,18 @@ class AccountFileStorageTest(test_util.ConfigTestCase):
|
|||
self._test_delete_folders('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
self._assert_symlinked_account_removed()
|
||||
|
||||
def _set_server_and_stop_symlink(self, server_path):
|
||||
self._set_server(server_path)
|
||||
with open(os.path.join(self.config.accounts_dir, 'foo'), 'w') as f:
|
||||
f.write('bar')
|
||||
|
||||
def test_delete_shared_account_up(self):
|
||||
self._set_server_and_stop_symlink('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
self._test_delete_folders('https://acme-staging.api.letsencrypt.org/directory')
|
||||
|
||||
def test_delete_shared_account_down(self):
|
||||
self._set_server_and_stop_symlink('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
self._test_delete_folders('https://acme-staging-v02.api.letsencrypt.org/directory')
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ optional arguments:
|
|||
case, and to know when to deprecate support for past
|
||||
Python versions and flags. If you wish to hide this
|
||||
information from the Let's Encrypt server, set this to
|
||||
"". (default: CertbotACMEClient/0.25.1
|
||||
"". (default: CertbotACMEClient/0.26.1
|
||||
(certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX
|
||||
Installer/YYY (SUBCOMMAND; flags: FLAGS)
|
||||
Py/major.minor.patchlevel). The flags encoded in the
|
||||
|
|
@ -196,6 +196,8 @@ security:
|
|||
--strict-permissions Require that all configuration files are owned by the
|
||||
current user; only needed if your config is somewhere
|
||||
unsafe like /tmp/ (default: False)
|
||||
--auto-hsts Gradually increasing max-age value for HTTP Strict
|
||||
Transport Security security header (default: False)
|
||||
|
||||
testing:
|
||||
The following flags are meant for testing and integration purposes only.
|
||||
|
|
@ -249,7 +251,7 @@ paths:
|
|||
--work-dir WORK_DIR Working directory. (default: /var/lib/letsencrypt)
|
||||
--logs-dir LOGS_DIR Logs directory. (default: /var/log/letsencrypt)
|
||||
--server SERVER ACME Directory Resource URI. (default:
|
||||
https://acme-v01.api.letsencrypt.org/directory)
|
||||
https://acme-v02.api.letsencrypt.org/directory)
|
||||
|
||||
manage:
|
||||
Various subcommands and flags are available for managing your
|
||||
|
|
@ -328,6 +330,7 @@ renew:
|
|||
renew", regardless of if the certificate is renewed.
|
||||
This setting does not apply to important TLS
|
||||
configuration updates. (default: False)
|
||||
--no-autorenew Disable auto renewal of certificates. (default: True)
|
||||
|
||||
certificates:
|
||||
List certificates managed by Certbot
|
||||
|
|
@ -448,8 +451,13 @@ plugins:
|
|||
using DNSimple for DNS). (default: False)
|
||||
--dns-dnsmadeeasy Obtain certificates using a DNS TXT record (if you
|
||||
areusing DNS Made Easy for DNS). (default: False)
|
||||
--dns-gehirn Obtain certificates using a DNS TXT record (if you are
|
||||
using Gehirn Infrastracture Service for DNS).
|
||||
(default: False)
|
||||
--dns-google Obtain certificates using a DNS TXT record (if you are
|
||||
using Google Cloud DNS). (default: False)
|
||||
--dns-linode Obtain certificates using a DNS TXT record (if you are
|
||||
using Linode for DNS). (default: False)
|
||||
--dns-luadns Obtain certificates using a DNS TXT record (if you are
|
||||
using LuaDNS for DNS). (default: False)
|
||||
--dns-nsone Obtain certificates using a DNS TXT record (if you are
|
||||
|
|
@ -460,14 +468,18 @@ plugins:
|
|||
using BIND for DNS). (default: False)
|
||||
--dns-route53 Obtain certificates using a DNS TXT record (if you are
|
||||
using Route53 for DNS). (default: False)
|
||||
--dns-sakuracloud Obtain certificates using a DNS TXT record (if you are
|
||||
using Sakura Cloud for DNS). (default: False)
|
||||
|
||||
apache:
|
||||
Apache Web Server plugin - Beta
|
||||
|
||||
--apache-enmod APACHE_ENMOD
|
||||
Path to the Apache 'a2enmod' binary. (default: None)
|
||||
Path to the Apache 'a2enmod' binary. (default:
|
||||
a2enmod)
|
||||
--apache-dismod APACHE_DISMOD
|
||||
Path to the Apache 'a2dismod' binary. (default: None)
|
||||
Path to the Apache 'a2dismod' binary. (default:
|
||||
a2dismod)
|
||||
--apache-le-vhost-ext APACHE_LE_VHOST_EXT
|
||||
SSL vhost configuration extension. (default: -le-
|
||||
ssl.conf)
|
||||
|
|
@ -481,13 +493,13 @@ apache:
|
|||
/var/log/apache2)
|
||||
--apache-challenge-location APACHE_CHALLENGE_LOCATION
|
||||
Directory path for challenge configuration. (default:
|
||||
/etc/apache2/other)
|
||||
/etc/apache2)
|
||||
--apache-handle-modules APACHE_HANDLE_MODULES
|
||||
Let installer handle enabling required modules for
|
||||
you. (Only Ubuntu/Debian currently) (default: False)
|
||||
you. (Only Ubuntu/Debian currently) (default: True)
|
||||
--apache-handle-sites APACHE_HANDLE_SITES
|
||||
Let installer handle enabling sites for you. (Only
|
||||
Ubuntu/Debian currently) (default: False)
|
||||
Ubuntu/Debian currently) (default: True)
|
||||
|
||||
certbot-route53:auth:
|
||||
Obtain certificates using a DNS TXT record (if you are using AWS Route53
|
||||
|
|
@ -553,6 +565,18 @@ dns-dnsmadeeasy:
|
|||
--dns-dnsmadeeasy-credentials DNS_DNSMADEEASY_CREDENTIALS
|
||||
DNS Made Easy credentials INI file. (default: None)
|
||||
|
||||
dns-gehirn:
|
||||
Obtain certificates using a DNS TXT record (if you are using Gehirn
|
||||
Infrastracture Service for DNS).
|
||||
|
||||
--dns-gehirn-propagation-seconds DNS_GEHIRN_PROPAGATION_SECONDS
|
||||
The number of seconds to wait for DNS to propagate
|
||||
before asking the ACME server to verify the DNS
|
||||
record. (default: 30)
|
||||
--dns-gehirn-credentials DNS_GEHIRN_CREDENTIALS
|
||||
Gehirn Infrastracture Service credentials file.
|
||||
(default: None)
|
||||
|
||||
dns-google:
|
||||
Obtain certificates using a DNS TXT record (if you are using Google Cloud
|
||||
DNS for DNS).
|
||||
|
|
@ -570,6 +594,16 @@ dns-google:
|
|||
control#permissions_and_roles for information about
|
||||
therequired permissions.) (default: None)
|
||||
|
||||
dns-linode:
|
||||
Obtain certs using a DNS TXT record (if you are using Linode for DNS).
|
||||
|
||||
--dns-linode-propagation-seconds DNS_LINODE_PROPAGATION_SECONDS
|
||||
The number of seconds to wait for DNS to propagate
|
||||
before asking the ACME server to verify the DNS
|
||||
record. (default: 960)
|
||||
--dns-linode-credentials DNS_LINODE_CREDENTIALS
|
||||
Linode credentials INI file. (default: None)
|
||||
|
||||
dns-luadns:
|
||||
Obtain certificates using a DNS TXT record (if you are using LuaDNS for
|
||||
DNS).
|
||||
|
|
@ -599,7 +633,7 @@ dns-ovh:
|
|||
before asking the ACME server to verify the DNS
|
||||
record. (default: 30)
|
||||
--dns-ovh-credentials DNS_OVH_CREDENTIALS
|
||||
OVH credentials file. (default: None)
|
||||
OVH credentials INI file. (default: None)
|
||||
|
||||
dns-rfc2136:
|
||||
Obtain certificates using a DNS TXT record (if you are using BIND for
|
||||
|
|
@ -621,6 +655,17 @@ dns-route53:
|
|||
before asking the ACME server to verify the DNS
|
||||
record. (default: 10)
|
||||
|
||||
dns-sakuracloud:
|
||||
Obtain certificates using a DNS TXT record (if you are using Sakura Cloud
|
||||
for DNS).
|
||||
|
||||
--dns-sakuracloud-propagation-seconds DNS_SAKURACLOUD_PROPAGATION_SECONDS
|
||||
The number of seconds to wait for DNS to propagate
|
||||
before asking the ACME server to verify the DNS
|
||||
record. (default: 90)
|
||||
--dns-sakuracloud-credentials DNS_SAKURACLOUD_CREDENTIALS
|
||||
Sakura Cloud credentials file. (default: None)
|
||||
|
||||
manual:
|
||||
Authenticate through manual configuration or custom shell scripts. When
|
||||
using shell scripts, an authenticator script must be provided. The
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ needs_sphinx = '1.0'
|
|||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.imgconverter',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.coverage',
|
||||
|
|
|
|||
|
|
@ -40,11 +40,17 @@ supports
|
|||
<https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/constants.py>`_
|
||||
modern OSes based on Debian, Fedora, SUSE, Gentoo and Darwin.
|
||||
|
||||
|
||||
Additional integrity verification of certbot-auto script can be done by verifying its digital signature.
|
||||
This requires a local installation of gpg2, which comes packaged in many Linux distributions under name gnupg or gnupg2.
|
||||
|
||||
|
||||
Installing with ``certbot-auto`` requires 512MB of RAM in order to build some
|
||||
of the dependencies. Installing from pre-built OS packages avoids this
|
||||
requirement. You can also temporarily set a swap file. See "Problems with
|
||||
Python virtual environment" below for details.
|
||||
|
||||
|
||||
Alternate installation methods
|
||||
================================
|
||||
|
||||
|
|
@ -64,12 +70,30 @@ download and run it as follows::
|
|||
user@webserver:~$ chmod a+x ./certbot-auto
|
||||
user@webserver:~$ ./certbot-auto --help
|
||||
|
||||
.. hint:: The certbot-auto download is protected by HTTPS, which is pretty good, but if you'd like to
|
||||
double check the integrity of the ``certbot-auto`` script, you can use these steps for verification before running it::
|
||||
To check the integrity of the ``certbot-auto`` script,
|
||||
you can use these steps::
|
||||
|
||||
|
||||
user@webserver:~$ wget -N https://dl.eff.org/certbot-auto.asc
|
||||
user@webserver:~$ gpg2 --keyserver pool.sks-keyservers.net --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2
|
||||
user@webserver:~$ gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc certbot-auto
|
||||
|
||||
|
||||
|
||||
The output of the last command should look something like::
|
||||
|
||||
|
||||
gpg: Signature made Wed 02 May 2018 05:29:12 AM IST
|
||||
gpg: using RSA key A2CFB51FA275A7286234E7B24D17C995CD9775F2
|
||||
gpg: key 4D17C995CD9775F2 marked as ultimately trusted
|
||||
gpg: checking the trustdb
|
||||
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||
gpg: depth: 0 valid: 2 signed: 2 trust: 0-, 0q, 0n, 0m, 0f, 2u
|
||||
gpg: depth: 1 valid: 2 signed: 0 trust: 2-, 0q, 0n, 0m, 0f, 0u
|
||||
gpg: next trustdb check due at 2027-11-22
|
||||
gpg: Good signature from "Let's Encrypt Client Team <letsencrypt-client@eff.org>" [ultimate]
|
||||
|
||||
|
||||
user@server:~$ wget -N https://dl.eff.org/certbot-auto.asc
|
||||
user@server:~$ gpg2 --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2
|
||||
user@server:~$ gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc certbot-auto
|
||||
|
||||
The ``certbot-auto`` command updates to the latest client release automatically.
|
||||
Since ``certbot-auto`` is a wrapper to ``certbot``, it accepts exactly
|
||||
|
|
|
|||
|
|
@ -65,10 +65,8 @@ From our official releases:
|
|||
- https://www.archlinux.org/packages/community/any/certbot-dns-dnsimple
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-dnsmadeeasy
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-google
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-linode
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-luadns
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-nsone
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-ovh
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-rfc2136
|
||||
- https://www.archlinux.org/packages/community/any/certbot-dns-route53
|
||||
|
||||
|
|
@ -95,7 +93,6 @@ In Fedora 23+.
|
|||
- https://apps.fedoraproject.org/packages/python-certbot-dns-dnsimple
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-dnsmadeeasy
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-google
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-linode
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-luadns
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-nsone
|
||||
- https://apps.fedoraproject.org/packages/python-certbot-dns-rfc2136
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
|||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.25.1"
|
||||
LE_AUTO_VERSION="0.26.1"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -1060,37 +1060,26 @@ ConfigArgParse==0.12.0 \
|
|||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 \
|
||||
--no-binary configobj
|
||||
cryptography==2.0.2 \
|
||||
--hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \
|
||||
--hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \
|
||||
--hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \
|
||||
--hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \
|
||||
--hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \
|
||||
--hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \
|
||||
--hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \
|
||||
--hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \
|
||||
--hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \
|
||||
--hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \
|
||||
--hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \
|
||||
--hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \
|
||||
--hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \
|
||||
--hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \
|
||||
--hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \
|
||||
--hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \
|
||||
--hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \
|
||||
--hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \
|
||||
--hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \
|
||||
--hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \
|
||||
--hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \
|
||||
--hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \
|
||||
--hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \
|
||||
--hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \
|
||||
--hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \
|
||||
--hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \
|
||||
--hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \
|
||||
--hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \
|
||||
--hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \
|
||||
--hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab
|
||||
cryptography==2.2.2 \
|
||||
--hash=sha256:3f3b65d5a16e6b52fba63dc860b62ca9832f51f1a2ae5083c78b6840275f12dd \
|
||||
--hash=sha256:5251e7de0de66810833606439ca65c9b9e45da62196b0c88bfadf27740aac09f \
|
||||
--hash=sha256:551a3abfe0c8c6833df4192a63371aa2ff43afd8f570ed345d31f251d78e7e04 \
|
||||
--hash=sha256:5cb990056b7cadcca26813311187ad751ea644712022a3976443691168781b6f \
|
||||
--hash=sha256:60bda7f12ecb828358be53095fc9c6edda7de8f1ef571f96c00b2363643fa3cd \
|
||||
--hash=sha256:64b5c67acc9a7c83fbb4b69166f3105a0ab722d27934fac2cb26456718eec2ba \
|
||||
--hash=sha256:6fef51ec447fe9f8351894024e94736862900d3a9aa2961528e602eb65c92bdb \
|
||||
--hash=sha256:77d0ad229d47a6e0272d00f6bf8ac06ce14715a9fd02c9a97f5a2869aab3ccb2 \
|
||||
--hash=sha256:808fe471b1a6b777f026f7dc7bd9a4959da4bfab64972f2bbe91e22527c1c037 \
|
||||
--hash=sha256:9b62fb4d18529c84b961efd9187fecbb48e89aa1a0f9f4161c61b7fc42a101bd \
|
||||
--hash=sha256:9e5bed45ec6b4f828866ac6a6bedf08388ffcfa68abe9e94b34bb40977aba531 \
|
||||
--hash=sha256:9fc295bf69130a342e7a19a39d7bbeb15c0bcaabc7382ec33ef3b2b7d18d2f63 \
|
||||
--hash=sha256:abd070b5849ed64e6d349199bef955ee0ad99aefbad792f0c587f8effa681a5e \
|
||||
--hash=sha256:ba6a774749b6e510cffc2fb98535f717e0e5fd91c7c99a61d223293df79ab351 \
|
||||
--hash=sha256:c332118647f084c983c6a3e1dba0f3bcb051f69d12baccac68db8d62d177eb8a \
|
||||
--hash=sha256:d6f46e862ee36df81e6342c2177ba84e70f722d9dc9c6c394f9f1f434c4a5563 \
|
||||
--hash=sha256:db6013746f73bf8edd9c3d1d3f94db635b9422f503db3fc5ef105233d4c011ab \
|
||||
--hash=sha256:f57008eaff597c69cf692c3518f6d4800f0309253bb138b526a37fe9ef0c7471 \
|
||||
--hash=sha256:f6c821ac253c19f2ad4c8691633ae1d1a17f120d5b01ea1d256d7b602bc59887
|
||||
enum34==1.1.2 ; python_version < '3.4' \
|
||||
--hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \
|
||||
--hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501
|
||||
|
|
@ -1103,9 +1092,9 @@ idna==2.5 \
|
|||
ipaddress==1.0.16 \
|
||||
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
||||
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
||||
josepy==1.0.1 \
|
||||
--hash=sha256:354a3513038a38bbcd27c97b7c68a8f3dfaff0a135b20a92c6db4cc4ea72915e \
|
||||
--hash=sha256:9f48b88ca37f0244238b1cc77723989f7c54f7b90b2eee6294390bacfe870acc
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
linecache2==1.0.0 \
|
||||
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
||||
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
||||
|
|
@ -1208,18 +1197,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.25.1 \
|
||||
--hash=sha256:01689015364685fef3f1e1fb7832ba84eb3b0aa85bc5a71c96661f6d4c59981f \
|
||||
--hash=sha256:5c23e5186133bb1afd805be5e0cd2fb7b95862a8b0459c9ecad4ae60f933e54e
|
||||
acme==0.25.1 \
|
||||
--hash=sha256:26e641a01536705fe5f12d856703b8ef06e5a07981a7b6379d2771dcdb69a742 \
|
||||
--hash=sha256:47b5f3f73d69b7b1d13f918aa2cd75a8093069a68becf4af38e428e4613b2734
|
||||
certbot-apache==0.25.1 \
|
||||
--hash=sha256:a28b7c152cc11474bef5b5e7967aaea42b2c0aaf86fd82ee4082713d33cee5a9 \
|
||||
--hash=sha256:ed012465617073a0f1057fe854dc8d1eb6d2dd7ede1fb2eee765129fed2a095a
|
||||
certbot-nginx==0.25.1 \
|
||||
--hash=sha256:83f82c3ba08c0b1d4bf449ac24018e8e7dd34a6248d35466f2de7da1cd312e15 \
|
||||
--hash=sha256:68f98b41c54e0bf4218ef293079597176617bee3837ae3aa6528ce2ff0bf4f9c
|
||||
certbot==0.26.1 \
|
||||
--hash=sha256:4e2ffdeebb7f5097600bcb1ca19131441fa021f952b443ca7454a279337af609 \
|
||||
--hash=sha256:4983513d63f7f36e24a07873ca2d6ea1c0101aa6cb1cd825cda02ed520f6ca66
|
||||
acme==0.26.1 \
|
||||
--hash=sha256:d47841e66adc1336ecca2f0d41a247c1b62307c981be6d07996bbf3f95af1dc5 \
|
||||
--hash=sha256:86e7b5f4654cb19215f16c0e6225750db7421f68ef6a0a040a61796f24e690be
|
||||
certbot-apache==0.26.1 \
|
||||
--hash=sha256:c16acb49bd4f84fff25bcbb7eaf74412145efe9b68ce46e1803be538894f2ce3 \
|
||||
--hash=sha256:b7fa327e987b892d64163e7519bdeaf9723d78275ef6c438272848894ace6d87
|
||||
certbot-nginx==0.26.1 \
|
||||
--hash=sha256:c0048dc83672dc90805a8ddf513be3e48c841d6e91607e91e8657c1785d65660 \
|
||||
--hash=sha256:d0c95a32625e0f1612d7fcf9021e6e050ba3d879823489d1edd2478a78ae6624
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2
|
||||
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAlsgc/cACgkQTRfJlc2X
|
||||
dfLjBgf/bHZn/q+Dqn34uBXHymRSce7UxQn17izcKAt7hZBl4j4sebQ9+0jjuNur
|
||||
zrW8b0XJ0PsI10GG9qHR3ajC+04pWfRritnK1g4Ycb/pDcUkWo+8uRwr7skAVcvC
|
||||
oa8ToBS3iUbd3csFl1mu1BGACUHLvVs2cYdDtMuJj8wjsVZ7KnWBGKULAskwmU4Z
|
||||
VVUxeUrG9f+2kT35meEJUk91FS+4tmqNIVsVlBzf0Q0ZU1iQnV56dMwTqFRzdDJ2
|
||||
DBecE0GwuYnKXo2I7kIYaqACQmk9YFh55Sh0K9PbQxyv7YEZXZtkcdqFqyhxy3Nh
|
||||
EJ2kurFaM3/VmLljc/rW8QW8B3QNbw==
|
||||
=pkDz
|
||||
iQEcBAABCAAGBQJbTSv8AAoJEE0XyZXNl3Xy12sH/1FgV3SDVG0T1jgKQOYEUwrq
|
||||
cmpjdav8YPgFOSQDOcyFZG0DNcRfTskZt45IMkBLLnXq2PuPvkppc1+akP81vMoK
|
||||
NXHHS+PXDMjnBW4NFkexoM06KRF1SyHnvqsOg13w7UW2CjsAgtazGF5BucNCnjPH
|
||||
XJTwUf4uhKxeUb0Xkva1OPH++oTWz8+SYgWr/iMggkBrK8y04QUUJ6lyCO6MZgcE
|
||||
3JcECG7CwMK+hW0gCUkCSNZ0NzOBALCd9wCxNGszgkeJXrrW73oUpZmGC5BxIwYY
|
||||
o6lcF0qo7Jb92t4B3+7JhulMC5JoVoG4lpiXpKQFFCT0P4pZKotIomKNMATmnB4=
|
||||
=hzUL
|
||||
-----END PGP SIGNATURE-----
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
|||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.26.0.dev0"
|
||||
LE_AUTO_VERSION="0.27.0.dev0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
|
|
@ -1197,18 +1197,18 @@ letsencrypt==0.7.0 \
|
|||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.25.1 \
|
||||
--hash=sha256:01689015364685fef3f1e1fb7832ba84eb3b0aa85bc5a71c96661f6d4c59981f \
|
||||
--hash=sha256:5c23e5186133bb1afd805be5e0cd2fb7b95862a8b0459c9ecad4ae60f933e54e
|
||||
acme==0.25.1 \
|
||||
--hash=sha256:26e641a01536705fe5f12d856703b8ef06e5a07981a7b6379d2771dcdb69a742 \
|
||||
--hash=sha256:47b5f3f73d69b7b1d13f918aa2cd75a8093069a68becf4af38e428e4613b2734
|
||||
certbot-apache==0.25.1 \
|
||||
--hash=sha256:a28b7c152cc11474bef5b5e7967aaea42b2c0aaf86fd82ee4082713d33cee5a9 \
|
||||
--hash=sha256:ed012465617073a0f1057fe854dc8d1eb6d2dd7ede1fb2eee765129fed2a095a
|
||||
certbot-nginx==0.25.1 \
|
||||
--hash=sha256:83f82c3ba08c0b1d4bf449ac24018e8e7dd34a6248d35466f2de7da1cd312e15 \
|
||||
--hash=sha256:68f98b41c54e0bf4218ef293079597176617bee3837ae3aa6528ce2ff0bf4f9c
|
||||
certbot==0.26.1 \
|
||||
--hash=sha256:4e2ffdeebb7f5097600bcb1ca19131441fa021f952b443ca7454a279337af609 \
|
||||
--hash=sha256:4983513d63f7f36e24a07873ca2d6ea1c0101aa6cb1cd825cda02ed520f6ca66
|
||||
acme==0.26.1 \
|
||||
--hash=sha256:d47841e66adc1336ecca2f0d41a247c1b62307c981be6d07996bbf3f95af1dc5 \
|
||||
--hash=sha256:86e7b5f4654cb19215f16c0e6225750db7421f68ef6a0a040a61796f24e690be
|
||||
certbot-apache==0.26.1 \
|
||||
--hash=sha256:c16acb49bd4f84fff25bcbb7eaf74412145efe9b68ce46e1803be538894f2ce3 \
|
||||
--hash=sha256:b7fa327e987b892d64163e7519bdeaf9723d78275ef6c438272848894ace6d87
|
||||
certbot-nginx==0.26.1 \
|
||||
--hash=sha256:c0048dc83672dc90805a8ddf513be3e48c841d6e91607e91e8657c1785d65660 \
|
||||
--hash=sha256:d0c95a32625e0f1612d7fcf9021e6e050ba3d879823489d1edd2478a78ae6624
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
ŒkľùŠea[1Ûxyꥥ=È.Üî«<C3AE>s4V’ôS? OÓD¨àSÆÌðÝ 9™äžÎ"òÉÄL©%Ø9ïÿšü-¢ H£ÄÝJ<EFBFBD>ù<ñ´mUëLŒuÊò»€k2ÂHÒÎ]ÎØw€šWá!;³ÕêÕ<C3AA>pëBÀÔ†ù›æÅþ¡þª|МXU»½lñE<C3B1>®ÿaJÎfÁ!¸ÉǬhŒh&ZšXró¾b¦'î_>%¾¾´¬Wƒ¢¨»—:¿;']ÝyRS¯7ˆuM̸¤d³µÆÈ“¿sX;apŒ‚>,™c5ñëî¨tb
|
||||
ÍÅ3pºŽàùSÄjÍ»¾´¼—²øö«ø~Ô@F-¢ä*6](Ý"üø<C3BC>²A‹,“8èß<C3A8><C39F>…ñ=äsO²cô{â…ŽE•B—\ä,üIJå1Ï
|
||||
»Â»Zï*¤ƒO/Æ+³k<C2B3>+}¦¥ùƒä«~ld‚?]ŒŽfÚ(r?JÐ2Ô”ò †4=¿
K+K<EFBFBD>¾è#Ó@š_›[)4ºV8;Õ Ž-øKö<10>WørÝýp…ý¤¤wߊ2»Û®x,g§Ú§w·áê×ù8½0;£uC^Ì“ÚÓB¯§€yI<79>ÚÄùX/b<EFBFBD>£øºìÏ
|
||||
¸®s‹Z¢ö€¥S
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
certbot==0.25.1 \
|
||||
--hash=sha256:01689015364685fef3f1e1fb7832ba84eb3b0aa85bc5a71c96661f6d4c59981f \
|
||||
--hash=sha256:5c23e5186133bb1afd805be5e0cd2fb7b95862a8b0459c9ecad4ae60f933e54e
|
||||
acme==0.25.1 \
|
||||
--hash=sha256:26e641a01536705fe5f12d856703b8ef06e5a07981a7b6379d2771dcdb69a742 \
|
||||
--hash=sha256:47b5f3f73d69b7b1d13f918aa2cd75a8093069a68becf4af38e428e4613b2734
|
||||
certbot-apache==0.25.1 \
|
||||
--hash=sha256:a28b7c152cc11474bef5b5e7967aaea42b2c0aaf86fd82ee4082713d33cee5a9 \
|
||||
--hash=sha256:ed012465617073a0f1057fe854dc8d1eb6d2dd7ede1fb2eee765129fed2a095a
|
||||
certbot-nginx==0.25.1 \
|
||||
--hash=sha256:83f82c3ba08c0b1d4bf449ac24018e8e7dd34a6248d35466f2de7da1cd312e15 \
|
||||
--hash=sha256:68f98b41c54e0bf4218ef293079597176617bee3837ae3aa6528ce2ff0bf4f9c
|
||||
certbot==0.26.1 \
|
||||
--hash=sha256:4e2ffdeebb7f5097600bcb1ca19131441fa021f952b443ca7454a279337af609 \
|
||||
--hash=sha256:4983513d63f7f36e24a07873ca2d6ea1c0101aa6cb1cd825cda02ed520f6ca66
|
||||
acme==0.26.1 \
|
||||
--hash=sha256:d47841e66adc1336ecca2f0d41a247c1b62307c981be6d07996bbf3f95af1dc5 \
|
||||
--hash=sha256:86e7b5f4654cb19215f16c0e6225750db7421f68ef6a0a040a61796f24e690be
|
||||
certbot-apache==0.26.1 \
|
||||
--hash=sha256:c16acb49bd4f84fff25bcbb7eaf74412145efe9b68ce46e1803be538894f2ce3 \
|
||||
--hash=sha256:b7fa327e987b892d64163e7519bdeaf9723d78275ef6c438272848894ace6d87
|
||||
certbot-nginx==0.26.1 \
|
||||
--hash=sha256:c0048dc83672dc90805a8ddf513be3e48c841d6e91607e91e8657c1785d65660 \
|
||||
--hash=sha256:d0c95a32625e0f1612d7fcf9021e6e050ba3d879823489d1edd2478a78ae6624
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
acme[dev]==0.25.0
|
||||
acme[dev]==0.26.0
|
||||
|
|
|
|||
6
setup.py
6
setup.py
|
|
@ -32,7 +32,7 @@ version = meta['version']
|
|||
# specified here to avoid masking the more specific request requirements in
|
||||
# acme. See https://github.com/pypa/pip/issues/988 for more info.
|
||||
install_requires = [
|
||||
'acme>=0.25.0',
|
||||
'acme>=0.26.0',
|
||||
# We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but
|
||||
# saying so here causes a runtime error against our temporary fork of 0.9.3
|
||||
# in which we added 2.6 support (see #2243), so we relax the requirement.
|
||||
|
|
@ -70,8 +70,8 @@ dev3_extras = [
|
|||
|
||||
docs_extras = [
|
||||
'repoze.sphinx.autointerface',
|
||||
# autodoc_member_order = 'bysource', autodoc_default_flags, and #4686
|
||||
'Sphinx >=1.0,<=1.5.6',
|
||||
# sphinx.ext.imgconverter
|
||||
'Sphinx >=1.6',
|
||||
'sphinx_rtd_theme',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ def make_instance(instance_name,
|
|||
userdata=""): #userdata contains bash or cloud-init script
|
||||
|
||||
new_instance = EC2.create_instances(
|
||||
BlockDeviceMappings=_get_block_device_mappings(ami_id),
|
||||
ImageId=ami_id,
|
||||
SecurityGroups=security_groups,
|
||||
KeyName=keyname,
|
||||
|
|
@ -151,38 +152,21 @@ def make_instance(instance_name,
|
|||
raise
|
||||
return new_instance
|
||||
|
||||
def terminate_and_clean(instances):
|
||||
def _get_block_device_mappings(ami_id):
|
||||
"""Returns the list of block device mappings to ensure cleanup.
|
||||
|
||||
This list sets connected EBS volumes to be deleted when the EC2
|
||||
instance is terminated.
|
||||
|
||||
"""
|
||||
Some AMIs specify EBS stores that won't delete on instance termination.
|
||||
These must be manually deleted after shutdown.
|
||||
"""
|
||||
volumes_to_delete = []
|
||||
for instance in instances:
|
||||
for bdmap in instance.block_device_mappings:
|
||||
if 'Ebs' in bdmap.keys():
|
||||
if not bdmap['Ebs']['DeleteOnTermination']:
|
||||
volumes_to_delete.append(bdmap['Ebs']['VolumeId'])
|
||||
|
||||
for instance in instances:
|
||||
instance.terminate()
|
||||
|
||||
# can't delete volumes until all attaching instances are terminated
|
||||
_ids = [instance.id for instance in instances]
|
||||
all_terminated = False
|
||||
while not all_terminated:
|
||||
all_terminated = True
|
||||
for _id in _ids:
|
||||
# necessary to reinit object for boto3 to get true state
|
||||
inst = EC2.Instance(id=_id)
|
||||
if inst.state['Name'] != 'terminated':
|
||||
all_terminated = False
|
||||
time.sleep(5)
|
||||
|
||||
for vol_id in volumes_to_delete:
|
||||
volume = EC2.Volume(id=vol_id)
|
||||
volume.delete()
|
||||
|
||||
return volumes_to_delete
|
||||
# Not all devices use EBS, but the default value for DeleteOnTermination
|
||||
# when the device does use EBS is true. See:
|
||||
# * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html
|
||||
# * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html
|
||||
return [{'DeviceName': mapping['DeviceName'],
|
||||
'Ebs': {'DeleteOnTermination': True}}
|
||||
for mapping in EC2.Image(ami_id).block_device_mappings
|
||||
if not mapping.get('Ebs', {}).get('DeleteOnTermination', True)]
|
||||
|
||||
|
||||
# Helper Routines
|
||||
|
|
@ -370,10 +354,11 @@ def test_client_process(inqueue, outqueue):
|
|||
def cleanup(cl_args, instances, targetlist):
|
||||
print('Logs in ', LOGDIR)
|
||||
if not cl_args.saveinstances:
|
||||
print('Terminating EC2 Instances and Cleaning Dangling EBS Volumes')
|
||||
print('Terminating EC2 Instances')
|
||||
if cl_args.killboulder:
|
||||
boulder_server.terminate()
|
||||
terminate_and_clean(instances)
|
||||
for instance in instances:
|
||||
instance.terminate()
|
||||
else:
|
||||
# print login information for the boxes for debugging
|
||||
for ii, target in enumerate(targetlist):
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ pylint==1.4.2
|
|||
pytest==3.2.5
|
||||
pytest-cov==2.5.1
|
||||
pytest-forked==0.2
|
||||
pytest-xdist==1.20.1
|
||||
pytest-xdist==1.22.5
|
||||
python-dateutil==2.6.1
|
||||
python-digitalocean==1.11
|
||||
PyYAML==3.13
|
||||
|
|
@ -60,8 +60,9 @@ s3transfer==0.1.11
|
|||
scandir==1.6
|
||||
simplegeneric==0.8.1
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==1.5.6
|
||||
Sphinx==1.7.5
|
||||
sphinx-rtd-theme==0.2.4
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
tldextract==2.2.0
|
||||
tox==2.9.1
|
||||
tqdm==4.19.4
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ fi
|
|||
-e certbot-dns-luadns \
|
||||
-e certbot-dns-nsone \
|
||||
-e certbot-dns-ovh \
|
||||
-e certbot-dns-rfc2136 \
|
||||
-e certbot-dns-route53 \
|
||||
-e certbot-dns-sakuracloud \
|
||||
-e certbot-nginx \
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# generate separate stats for each package. It should be removed once
|
||||
# those packages are moved to separate repo.
|
||||
#
|
||||
# -e makes sure we fail fast and don't submit coveralls submit
|
||||
# -e makes sure we fail fast and don't submit to codecov
|
||||
|
||||
if [ "xxx$1" = "xxx" ]; then
|
||||
pkgs="certbot acme certbot_apache certbot_dns_cloudflare certbot_dns_cloudxns certbot_dns_digitalocean certbot_dns_dnsimple certbot_dns_dnsmadeeasy certbot_dns_gehirn certbot_dns_google certbot_dns_linode certbot_dns_luadns certbot_dns_nsone certbot_dns_ovh certbot_dns_rfc2136 certbot_dns_route53 certbot_dns_sakuracloud certbot_nginx certbot_postfix letshelp_certbot"
|
||||
|
|
@ -61,7 +61,7 @@ cover () {
|
|||
fi
|
||||
|
||||
pkg_dir=$(echo "$1" | tr _ -)
|
||||
pytest --cov "$pkg_dir" --cov-append --cov-report= --numprocesses auto --pyargs "$1"
|
||||
pytest --cov "$pkg_dir" --cov-append --cov-report= --numprocesses "auto" --pyargs "$1"
|
||||
coverage report --fail-under="$min" --include="$pkg_dir/*" --show-missing
|
||||
}
|
||||
|
||||
|
|
|
|||
20
tox.ini
20
tox.ini
|
|
@ -64,6 +64,7 @@ source_paths =
|
|||
tests/lock_test.py
|
||||
|
||||
[testenv]
|
||||
passenv = TRAVIS
|
||||
commands =
|
||||
{[base]install_and_test} {[base]all_packages}
|
||||
python tests/lock_test.py
|
||||
|
|
@ -108,6 +109,12 @@ commands =
|
|||
setenv =
|
||||
{[testenv:py27-oldest]setenv}
|
||||
|
||||
[testenv:py27-postfix-oldest]
|
||||
commands =
|
||||
{[base]install_and_test} certbot-postfix
|
||||
setenv =
|
||||
{[testenv:py27-oldest]setenv}
|
||||
|
||||
[testenv:py27_install]
|
||||
basepython = python2.7
|
||||
commands =
|
||||
|
|
@ -159,7 +166,9 @@ commands =
|
|||
docker run --rm -it apache-compat -c apache.tar.gz -vvvv
|
||||
whitelist_externals =
|
||||
docker
|
||||
passenv = DOCKER_*
|
||||
passenv =
|
||||
DOCKER_*
|
||||
TRAVIS
|
||||
|
||||
[testenv:nginx_compat]
|
||||
commands =
|
||||
|
|
@ -168,7 +177,9 @@ commands =
|
|||
docker run --rm -it nginx-compat -c nginx.tar.gz -vv -aie
|
||||
whitelist_externals =
|
||||
docker
|
||||
passenv = DOCKER_*
|
||||
passenv =
|
||||
DOCKER_*
|
||||
TRAVIS
|
||||
|
||||
[testenv:le_auto_precise]
|
||||
# At the moment, this tests under Python 2.7 only, as only that version is
|
||||
|
|
@ -178,7 +189,9 @@ commands =
|
|||
docker run --rm -t -i lea
|
||||
whitelist_externals =
|
||||
docker
|
||||
passenv = DOCKER_*
|
||||
passenv =
|
||||
DOCKER_*
|
||||
TRAVIS
|
||||
|
||||
[testenv:le_auto_trusty]
|
||||
# At the moment, this tests under Python 2.7 only, as only that version is
|
||||
|
|
@ -191,6 +204,7 @@ whitelist_externals =
|
|||
docker
|
||||
passenv =
|
||||
DOCKER_*
|
||||
TRAVIS
|
||||
TRAVIS_BRANCH
|
||||
|
||||
[testenv:le_auto_wheezy]
|
||||
|
|
|
|||
Loading…
Reference in a new issue