Hello community,

here is the log from the commit of package python-certbot for openSUSE:Factory 
checked in at 2020-10-07 14:18:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-certbot (Old)
 and      /work/SRC/openSUSE:Factory/.python-certbot.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-certbot"

Wed Oct  7 14:18:47 2020 rev:30 rq:839981 version:1.9.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-certbot/python-certbot.changes    
2020-08-21 19:13:15.760680074 +0200
+++ /work/SRC/openSUSE:Factory/.python-certbot.new.4249/python-certbot.changes  
2020-10-07 14:19:02.301512020 +0200
@@ -1,0 +2,36 @@
+Wed Oct  7 08:15:42 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- Update to version 1.9.0
+  * certbot-auto was deprecated on all systems except for those based on 
Debian or RHEL.
+  * Update the packaging instructions to promote usage of python -m pytest to 
test Certbot
+    instead of the deprecated python setup.py test setuptools approach.
+  * Reduced CLI logging when handling some kinds of errors.
+  * The minimum version of the acme library required by Certbot was corrected.
+    In the previous release, Certbot said it required acme>=1.6.0 when it
+    actually required acme>=1.8.0 to properly support removing contact
+    information from an ACME account.
+
+-------------------------------------------------------------------
+Mon Sep 28 13:57:39 UTC 2020 - Hans-Peter Jansen <[email protected]>
+
+- Update to version 1.8.0
+  + Added
+    * Added the ability to remove email and phone contact
+      information from an account
+    * using update_account --register-unsafely-without-email
+  + Changed
+    * Support for Python 3.5 has been removed.
+  + Fixed
+    * The problem causing the Apache plugin in the Certbot snap on
+      ARM systems to
+    * fail to load the Augeas library it depends on has been fixed.
+    * The acme library can now tell the ACME server to clear
+      contact information by passing an empty
+    * tuple to the contact field of a Registration message.
+    * Fixed the *** stack smashing detected *** error in the
+      Certbot snap on some systems.
+    * More details about these changes can be found on our GitHub
+      repo.
+- Add certbot keyring and hash file
+
+-------------------------------------------------------------------

Old:
----
  certbot-1.7.0.tar.gz

New:
----
  certbot-1.9.0.tar.gz
  certbot-1.9.0.tar.gz.asc
  python-certbot.keyring

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-certbot.spec ++++++
--- /var/tmp/diff_new_pack.O41QVt/_old  2020-10-07 14:19:03.157512701 +0200
+++ /var/tmp/diff_new_pack.O41QVt/_new  2020-10-07 14:19:03.157512701 +0200
@@ -19,13 +19,15 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-certbot
-Version:        1.7.0
+Version:        1.9.0
 Release:        0
 Summary:        ACME client
 License:        Apache-2.0
 URL:            https://github.com/certbot/certbot
-Source:         
https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz
-BuildRequires:  %{python_module acme >= 1.6.0}
+Source0:        
https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz
+Source1:        
https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz.asc
+Source2:        %{name}.keyring
+BuildRequires:  %{python_module acme >= 1.8.0}
 BuildRequires:  %{python_module configargparse >= 0.9.3}
 BuildRequires:  %{python_module configobj}
 BuildRequires:  %{python_module cryptography >= 1.2.3}

++++++ certbot-1.7.0.tar.gz -> certbot-1.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/CHANGELOG.md 
new/certbot-1.9.0/CHANGELOG.md
--- old/certbot-1.7.0/CHANGELOG.md      2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/CHANGELOG.md      2020-10-06 20:39:49.000000000 +0200
@@ -2,6 +2,55 @@
 
 Certbot adheres to [Semantic Versioning](https://semver.org/).
 
+## 1.9.0 - 2020-10-06
+
+### Added
+
+* `--preconfigured-renewal` flag, for packager use only.
+  See the [packaging guide](https://certbot.eff.org/docs/packaging.html).
+
+### Changed
+
+* certbot-auto was deprecated on all systems except for those based on Debian 
or RHEL.
+* Update the packaging instructions to promote usage of `python -m pytest` to 
test Certbot
+  instead of the deprecated `python setup.py test` setuptools approach.
+* Reduced CLI logging when reloading nginx, if it is not running.
+* Reduced CLI logging when handling some kinds of errors.
+
+### Fixed
+
+* Fixed `server_name` case-sensitivity in the nginx plugin.
+* The minimum version of the `acme` library required by Certbot was corrected.
+  In the previous release, Certbot said it required `acme>=1.6.0` when it
+  actually required `acme>=1.8.0` to properly support removing contact
+  information from an ACME account.
+* Upgraded the version of httplib2 used in our snaps and Docker images to add
+  support for proxy environment variables and fix the plugin for Google Cloud
+  DNS.
+
+More details about these changes can be found on our GitHub repo.
+
+## 1.8.0 - 2020-09-08
+
+### Added
+
+* Added the ability to remove email and phone contact information from an 
account 
+  using `update_account --register-unsafely-without-email`
+
+### Changed
+
+* Support for Python 3.5 has been removed.
+
+### Fixed
+
+* The problem causing the Apache plugin in the Certbot snap on ARM systems to
+  fail to load the Augeas library it depends on has been fixed.
+* The `acme` library can now tell the ACME server to clear contact information 
by passing an empty
+  `tuple` to the `contact` field of a `Registration` message. 
+* Fixed the `*** stack smashing detected ***` error in the Certbot snap on 
some systems.
+
+More details about these changes can be found on our GitHub repo.
+
 ## 1.7.0 - 2020-08-04
 
 ### Added
@@ -20,7 +69,6 @@
 
 ### Fixed
 
-*
 
 More details about these changes can be found on our GitHub repo.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/PKG-INFO new/certbot-1.9.0/PKG-INFO
--- old/certbot-1.7.0/PKG-INFO  2020-08-04 20:20:16.638172000 +0200
+++ new/certbot-1.9.0/PKG-INFO  2020-10-06 20:39:50.532854600 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: certbot
-Version: 1.7.0
+Version: 1.9.0
 Summary: ACME client
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
@@ -75,9 +75,9 @@
         
         Community: https://community.letsencrypt.org
         
-        ACME spec: http://ietf-wg-acme.github.io/acme/
+        ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_
         
-        ACME working area in github: https://github.com/ietf-wg-acme/acme
+        ACME working area in github (archived): 
https://github.com/ietf-wg-acme/acme
         
         |build-status|
         
@@ -137,7 +137,6 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
@@ -147,7 +146,7 @@
 Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
 Provides-Extra: dev
 Provides-Extra: dev3
 Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/README.rst new/certbot-1.9.0/README.rst
--- old/certbot-1.7.0/README.rst        2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/README.rst        2020-10-06 20:39:49.000000000 +0200
@@ -67,9 +67,9 @@
 
 Community: https://community.letsencrypt.org
 
-ACME spec: http://ietf-wg-acme.github.io/acme/
+ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_
 
-ACME working area in github: https://github.com/ietf-wg-acme/acme
+ACME working area in github (archived): https://github.com/ietf-wg-acme/acme
 
 |build-status|
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/__init__.py 
new/certbot-1.9.0/certbot/__init__.py
--- old/certbot-1.7.0/certbot/__init__.py       2020-08-04 20:20:16.000000000 
+0200
+++ new/certbot-1.9.0/certbot/__init__.py       2020-10-06 20:39:50.000000000 
+0200
@@ -1,13 +1,4 @@
 """Certbot client."""
-import warnings
-import sys
 
 # version number like 1.2.3a0, must have at least 2 parts, like 1.2
-__version__ = '1.7.0'
-
-if sys.version_info[:2] == (3, 5):
-    warnings.warn(
-            "Python 3.5 support will be dropped in the next release of "
-            "certbot. Please upgrade your Python version.",
-            PendingDeprecationWarning,
-    )  # pragma: no cover
+__version__ = '1.9.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/cli/__init__.py 
new/certbot-1.9.0/certbot/_internal/cli/__init__.py
--- old/certbot-1.7.0/certbot/_internal/cli/__init__.py 2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/cli/__init__.py 2020-10-06 
20:39:49.000000000 +0200
@@ -101,6 +101,11 @@
              "flag to 0 disables log rotation entirely, causing "
              "Certbot to always append to the same log file.")
     helpful.add(
+        None, "--preconfigured-renewal", dest="preconfigured_renewal",
+        action="store_true", default=flag_default("preconfigured_renewal"),
+        help=argparse.SUPPRESS
+    )
+    helpful.add(
         [None, "automation", "run", "certonly", "enhance"],
         "-n", "--non-interactive", "--noninteractive",
         dest="noninteractive_mode", action="store_true",
@@ -171,13 +176,10 @@
         ["register", "automation"], "--register-unsafely-without-email", 
action="store_true",
         default=flag_default("register_unsafely_without_email"),
         help="Specifying this flag enables registering an account with no "
-             "email address. This is strongly discouraged, because in the "
-             "event of key loss or account compromise you will irrevocably "
-             "lose access to your account. You will also be unable to receive "
-             "notice about impending expiration or revocation of your "
-             "certificates. Updates to the Subscriber Agreement will still "
-             "affect you, and will be effective 14 days after posting an "
-             "update to the web site.")
+             "email address. This is strongly discouraged, because you will be 
"
+             "unable to receive notice about impending expiration or "
+             "revocation of your certificates or problems with your Certbot "
+             "installation that will lead to failure to renew.")
     helpful.add(
         ["register", "update_account", "unregister", "automation"], "-m", 
"--email",
         default=flag_default("email"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/cli/helpful.py 
new/certbot-1.9.0/certbot/_internal/cli/helpful.py
--- old/certbot-1.7.0/certbot/_internal/cli/helpful.py  2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/cli/helpful.py  2020-10-06 
20:39:49.000000000 +0200
@@ -192,8 +192,8 @@
         if self.detect_defaults:
             return parsed_args
 
-        self.defaults = dict((key, copy.deepcopy(self.parser.get_default(key)))
-                             for key in vars(parsed_args))
+        self.defaults = {key: copy.deepcopy(self.parser.get_default(key))
+                             for key in vars(parsed_args)}
 
         # Do any post-parsing homework here
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/constants.py 
new/certbot-1.9.0/certbot/_internal/constants.py
--- old/certbot-1.7.0/certbot/_internal/constants.py    2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/constants.py    2020-10-06 
20:39:49.000000000 +0200
@@ -16,7 +16,7 @@
 CLI_DEFAULTS = dict(
     config_files=[
         os.path.join(misc.get_default_folder('config'), 'cli.ini'),
-        # http://freedesktop.org/wiki/Software/xdg-user-dirs/
+        # https://freedesktop.org/wiki/Software/xdg-user-dirs/
         os.path.join(os.environ.get("XDG_CONFIG_HOME", "~/.config"),
                      "letsencrypt", "cli.ini"),
     ],
@@ -25,6 +25,7 @@
     verbose_count=-int(logging.INFO / 10),
     text_mode=False,
     max_log_backups=1000,
+    preconfigured_renewal=False,
     noninteractive_mode=False,
     force_interactive=False,
     domains=[],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/error_handler.py 
new/certbot-1.9.0/certbot/_internal/error_handler.py
--- old/certbot-1.7.0/certbot/_internal/error_handler.py        2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/error_handler.py        2020-10-06 
20:39:49.000000000 +0200
@@ -123,8 +123,10 @@
         while self.funcs:
             try:
                 self.funcs[-1]()
-            except Exception:  # pylint: disable=broad-except
-                logger.error("Encountered exception during recovery: ", 
exc_info=True)
+            except Exception as exc:  # pylint: disable=broad-except
+                output = traceback.format_exception_only(type(exc), exc)
+                logger.error("Encountered exception during recovery: %s",
+                             ''.join(output).rstrip())
             self.funcs.pop()
 
     def _set_signal_handlers(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/log.py 
new/certbot-1.9.0/certbot/_internal/log.py
--- old/certbot-1.7.0/certbot/_internal/log.py  2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/certbot/_internal/log.py  2020-10-06 20:39:49.000000000 
+0200
@@ -319,6 +319,9 @@
     # logger.DEBUG should be used
     if debug or not issubclass(exc_type, Exception):
         assert constants.QUIET_LOGGING_LEVEL <= logging.ERROR
+        if exc_type is KeyboardInterrupt:
+            logger.error('Exiting due to user request.')
+            sys.exit(1)
         logger.error('Exiting abnormally:', exc_info=exc_info)
     else:
         logger.debug('Exiting abnormally:', exc_info=exc_info)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/main.py 
new/certbot-1.9.0/certbot/_internal/main.py
--- old/certbot-1.7.0/certbot/_internal/main.py 2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/certbot/_internal/main.py 2020-10-06 20:39:49.000000000 
+0200
@@ -11,7 +11,7 @@
 import zope.component
 
 from acme import errors as acme_errors
-from acme.magic_typing import Union
+from acme.magic_typing import Union, Iterable, Optional  # pylint: 
disable=unused-import
 import certbot
 from certbot import crypto_util
 from certbot import errors
@@ -28,6 +28,7 @@
 from certbot._internal import log
 from certbot._internal import renewal
 from certbot._internal import reporter
+from certbot._internal import snap_config
 from certbot._internal import storage
 from certbot._internal import updater
 from certbot._internal.plugins import disco as plugins_disco
@@ -590,7 +591,7 @@
     :type config: interfaces.IConfig
 
     :param authenticator: Acme authentication handler
-    :type authenticator: interfaces.IAuthenticator
+    :type authenticator: Optional[interfaces.IAuthenticator]
     :param installer: Installer object
     :type installer: interfaces.IInstaller
 
@@ -703,17 +704,17 @@
 
     if not accounts:
         return "Could not find an existing account to update."
-    if config.email is None:
-        if config.register_unsafely_without_email:
-            return ("--register-unsafely-without-email provided, however, a "
-                    "new e-mail address must\ncurrently be provided when "
-                    "updating a registration.")
+    if config.email is None and not config.register_unsafely_without_email:
         config.email = display_ops.get_email(optional=False)
 
     acc, acme = _determine_account(config)
     cb_client = client.Client(config, acc, None, None, acme=acme)
+    # Empty list of contacts in case the user is removing all emails
+
+    acc_contacts = () # type: Iterable[str]
+    if config.email:
+        acc_contacts = ['mailto:' + email for email in config.email.split(',')]
     # We rely on an exception to interrupt this process if it didn't work.
-    acc_contacts = ['mailto:' + email for email in config.email.split(',')]
     prev_regr_uri = acc.regr.uri
     acc.regr = cb_client.acme.update_registration(acc.regr.update(
         body=acc.regr.body.update(contact=acc_contacts)))
@@ -722,8 +723,13 @@
     # so that we can also continue to use the account object with acmev1.
     acc.regr = acc.regr.update(uri=prev_regr_uri)
     account_storage.update_regr(acc, cb_client.acme)
-    eff.prepare_subscription(config, acc)
-    add_msg("Your e-mail address was updated to {0}.".format(config.email))
+
+    if config.email is None:
+        add_msg("Any contact information associated with this account has been 
removed.")
+    else:
+        eff.prepare_subscription(config, acc)
+        add_msg("Your e-mail address was updated to {0}.".format(config.email))
+
     return None
 
 
@@ -1320,6 +1326,9 @@
 
     log.pre_arg_parse_setup()
 
+    if os.environ.get('CERTBOT_SNAPPED') == 'True':
+        cli_args = snap_config.prepare_env(cli_args)
+
     plugins = plugins_disco.PluginsRegistry.find_all()
     logger.debug("certbot version: %s", certbot.__version__)
     # do not log `config`, as it contains sensitive data (e.g. revoke --key)!
@@ -1343,10 +1352,6 @@
         if config.func != plugins_cmd:  # pylint: 
disable=comparison-with-callable
             raise
 
-    if sys.version_info[:2] == (3, 5):
-        logger.warning("Python 3.5 support will be dropped in the next release 
"
-                       "of Certbot - please upgrade your Python version.")
-
     set_displayer(config)
 
     # Reporter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/plugins/disco.py 
new/certbot-1.9.0/certbot/_internal/plugins/disco.py
--- old/certbot-1.7.0/certbot/_internal/plugins/disco.py        2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/plugins/disco.py        2020-10-06 
20:39:49.000000000 +0200
@@ -277,8 +277,8 @@
 
     def filter(self, pred):
         """Filter plugins based on predicate."""
-        return type(self)(dict((name, plugin_ep) for name, plugin_ep
-                               in six.iteritems(self._plugins) if 
pred(plugin_ep)))
+        return type(self)({name: plugin_ep for name, plugin_ep
+                               in six.iteritems(self._plugins) if 
pred(plugin_ep)})
 
     def visible(self):
         """Filter plugins based on visibility."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/renewal.py 
new/certbot-1.9.0/certbot/_internal/renewal.py
--- old/certbot-1.7.0/certbot/_internal/renewal.py      2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/renewal.py      2020-10-06 
20:39:49.000000000 +0200
@@ -9,16 +9,21 @@
 import time
 import traceback
 
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.hazmat.primitives.serialization import load_pem_private_key
 import OpenSSL
 import six
 import zope.component
 
 from acme.magic_typing import List
+from acme.magic_typing import Optional  # pylint: disable=unused-import
 from certbot import crypto_util
 from certbot import errors
 from certbot import interfaces
 from certbot import util
 from certbot._internal import cli
+from certbot._internal import client  # pylint: disable=unused-import
 from certbot._internal import constants
 from certbot._internal import hooks
 from certbot._internal import storage
@@ -308,7 +313,8 @@
 
 
 def renew_cert(config, domains, le_client, lineage):
-    "Renew a certificate lineage."
+    # type: (interfaces.IConfig, Optional[List[str]], client.Client, 
storage.RenewableCert) -> None
+    """Renew a certificate lineage."""
     renewal_params = lineage.configuration["renewalparams"]
     original_server = renewal_params.get("server", cli.flag_default("server"))
     _avoid_invalidating_lineage(config, lineage, original_server)
@@ -316,11 +322,14 @@
         domains = lineage.names()
     # The private key is the existing lineage private key if reuse_key is set.
     # Otherwise, generate a fresh private key by passing None.
-    new_key = os.path.normpath(lineage.privkey) if config.reuse_key else None
+    if config.reuse_key:
+        new_key = os.path.normpath(lineage.privkey)
+        _update_renewal_params_from_key(new_key, config)
+    else:
+        new_key = None
     new_cert, new_chain, new_key, _ = le_client.obtain_certificate(domains, 
new_key)
     if config.dry_run:
-        logger.debug("Dry run: skipping updating lineage at %s",
-                    os.path.dirname(lineage.cert))
+        logger.debug("Dry run: skipping updating lineage at %s", 
os.path.dirname(lineage.cert))
     else:
         prior_version = lineage.latest_common_version()
         # TODO: Check return value of save_successor
@@ -335,6 +344,7 @@
     lines = ("%s (%s)" % (m, category) for m in msgs)
     return "  " + "\n  ".join(lines)
 
+
 def _renew_describe_results(config, renew_successes, renew_failures,
                             renew_skipped, parse_failures):
 
@@ -489,3 +499,13 @@
     # Windows installer integration tests rely on handle_renewal_request 
behavior here.
     # If the text below changes, these tests will need to be updated 
accordingly.
     logger.debug("no renewal failures")
+
+
+def _update_renewal_params_from_key(key_path, config):
+    # type: (str, interfaces.IConfig) -> None
+    with open(key_path, 'rb') as file_h:
+        key = load_pem_private_key(file_h.read(), password=None, 
backend=default_backend())
+    if isinstance(key, rsa.RSAPrivateKey):
+        config.rsa_key_size = key.key_size
+    else:
+        raise errors.Error('Key at {0} is of an unsupported type: 
{1}.'.format(key_path, type(key)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/snap_config.py 
new/certbot-1.9.0/certbot/_internal/snap_config.py
--- old/certbot-1.7.0/certbot/_internal/snap_config.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/certbot-1.9.0/certbot/_internal/snap_config.py  2020-10-06 
20:39:49.000000000 +0200
@@ -0,0 +1,102 @@
+"""Module configuring Certbot in a snap environment"""
+import logging
+import socket
+
+from requests import Session
+from requests.adapters import HTTPAdapter
+from requests.exceptions import HTTPError
+from requests.exceptions import RequestException
+
+from acme.magic_typing import List
+from certbot.compat import os
+from certbot.errors import Error
+
+try:
+    from urllib3.connection import HTTPConnection
+    from urllib3.connectionpool import HTTPConnectionPool
+except ImportError:
+    # Stub imports for oldest requirements, that will never be used in snaps.
+    HTTPConnection = object
+    HTTPConnectionPool = object
+
+
+_ARCH_TRIPLET_MAP = {
+    'arm64': 'aarch64-linux-gnu',
+    'armhf': 'arm-linux-gnueabihf',
+    'i386': 'i386-linux-gnu',
+    'ppc64el': 'powerpc64le-linux-gnu',
+    'powerpc': 'powerpc-linux-gnu',
+    'amd64': 'x86_64-linux-gnu',
+    's390x': 's390x-linux-gnu',
+}
+
+LOGGER = logging.getLogger(__name__)
+
+
+def prepare_env(cli_args):
+    # type: (List[str]) -> List[str]
+    """
+    Prepare runtime environment for a certbot execution in snap.
+    :param list cli_args: List of command line arguments
+    :return: Update list of command line arguments
+    :rtype: list
+    """
+    snap_arch = os.environ.get('SNAP_ARCH')
+
+    if snap_arch not in _ARCH_TRIPLET_MAP:
+        raise Error('Unrecognized value of SNAP_ARCH: {0}'.format(snap_arch))
+
+    os.environ['CERTBOT_AUGEAS_PATH'] = 
'{0}/usr/lib/{1}/libaugeas.so.0'.format(
+        os.environ.get('SNAP'), _ARCH_TRIPLET_MAP[snap_arch])
+
+    session = Session()
+    session.mount('http://snapd/', _SnapdAdapter())
+
+    try:
+        response = 
session.get('http://snapd/v2/connections?snap=certbot&interface=content')
+        response.raise_for_status()
+    except RequestException as e:
+        if isinstance(e, HTTPError) and e.response.status_code == 404:
+            LOGGER.error('An error occurred while fetching Certbot snap 
plugins: '
+                         'your version of snapd is outdated.')
+            LOGGER.error('Please run "sudo snap install core; sudo snap 
refresh core" '
+                         'in your terminal and try again.')
+        else:
+            LOGGER.error('An error occurred while fetching Certbot snap 
plugins: '
+                         'make sure the snapd service is running.')
+        raise e
+
+    data = response.json()
+    connections = 
['/snap/{0}/current/lib/python3.8/site-packages/'.format(item['slot']['snap'])
+                   for item in data.get('result', {}).get('established', [])
+                   if item.get('plug', {}).get('plug') == 'plugin'
+                   and item.get('plug-attrs', {}).get('content') == 
'certbot-1']
+
+    os.environ['CERTBOT_PLUGIN_PATH'] = ':'.join(connections)
+
+    cli_args.append('--preconfigured-renewal')
+
+    return cli_args
+
+
+class _SnapdConnection(HTTPConnection):
+    def __init__(self):
+        super(_SnapdConnection, self).__init__("localhost")
+        self.sock = None
+
+    def connect(self):
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect("/run/snapd.socket")
+
+
+class _SnapdConnectionPool(HTTPConnectionPool):
+    def __init__(self):
+        super(_SnapdConnectionPool, self).__init__("localhost")
+
+    def _new_conn(self):
+        return _SnapdConnection()
+
+
+class _SnapdAdapter(HTTPAdapter):
+    def get_connection(self, url, proxies=None):
+        return _SnapdConnectionPool()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/storage.py 
new/certbot-1.9.0/certbot/_internal/storage.py
--- old/certbot-1.7.0/certbot/_internal/storage.py      2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/_internal/storage.py      2020-10-06 
20:39:49.000000000 +0200
@@ -127,7 +127,7 @@
 
     config["renewalparams"].update(relevant_data)
 
-    for k in config["renewalparams"].keys():
+    for k in config["renewalparams"]:
         if k not in relevant_data:
             del config["renewalparams"][k]
 
@@ -1126,7 +1126,7 @@
             logger.debug("Writing full chain to %s.", target["fullchain"])
             f.write(new_cert + new_chain)
 
-        symlinks = dict((kind, self.configuration[kind]) for kind in ALL_FOUR)
+        symlinks = {kind: self.configuration[kind] for kind in ALL_FOUR}
         # Update renewal config file
         self.configfile = update_configuration(
             self.lineagename, self.archive_dir, symlinks, cli_config)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/compat/filesystem.py 
new/certbot-1.9.0/certbot/compat/filesystem.py
--- old/certbot-1.7.0/certbot/compat/filesystem.py      2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/compat/filesystem.py      2020-10-06 
20:39:49.000000000 +0200
@@ -340,8 +340,9 @@
     :param str dst: The new file path.
     """
     if hasattr(os, 'replace'):
-        # Use replace if possible. On Windows, only Python >= 3.5 is supported
-        # so we can assume that os.replace() is always available for this 
platform.
+        # Use replace if possible. Since we don't support Python 2 on Windows
+        # and os.replace() was added in Python 3.3, we can assume that
+        # os.replace() is always available on Windows.
         getattr(os, 'replace')(src, dst)
     else:
         # Otherwise, use os.rename() that behaves like os.replace() on Linux.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/compat/os.py 
new/certbot-1.9.0/certbot/compat/os.py
--- old/certbot-1.7.0/certbot/compat/os.py      2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/certbot/compat/os.py      2020-10-06 20:39:49.000000000 
+0200
@@ -3,8 +3,11 @@
 (e.g. chown, chmod, getuid) that would be harmful to the Windows file security 
model of Certbot.
 This module is intended to replace standard os module throughout certbot 
projects (except acme).
 
-isort:skip_file
+This module has the same API as the os module in the Python standard library
+except for the functions defined below.
+
 """
+# isort:skip_file
 # pylint: disable=function-redefined
 from __future__ import absolute_import
 
@@ -21,12 +24,15 @@
 import sys as std_sys
 
 ourselves = std_sys.modules[__name__]
-for attribute in dir(std_os):
-    # Check if the attribute does not already exist in our module. It could be 
internal attributes
-    # of the module (__name__, __doc__), or attributes from standard os 
already imported with
-    # `from os import *`.
-    if not hasattr(ourselves, attribute):
-        setattr(ourselves, attribute, getattr(std_os, attribute))
+# Adding all of stdlib os to this module confuses Sphinx so we skip this when
+# building the documentation.
+if not std_os.environ.get("CERTBOT_DOCS") == "1":
+    for attribute in dir(std_os):
+        # Check if the attribute does not already exist in our module. It could
+        # be internal attributes of the module (__name__, __doc__), or
+        # attributes from standard os already imported with `from os import *`.
+        if not hasattr(ourselves, attribute):
+            setattr(ourselves, attribute, getattr(std_os, attribute))
 
 # Import our internal path module, then allow certbot.compat.os.path
 # to behave as a module (similarly to os.path).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/display/ops.py 
new/certbot-1.9.0/certbot/display/ops.py
--- old/certbot-1.7.0/certbot/display/ops.py    2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/certbot/display/ops.py    2020-10-06 20:39:49.000000000 
+0200
@@ -6,7 +6,6 @@
 from certbot import errors
 from certbot import interfaces
 from certbot import util
-from certbot.compat import misc
 from certbot.compat import os
 from certbot.display import util as display_util
 
@@ -33,9 +32,10 @@
     msg = "Enter email address (used for urgent renewal and security 
notices)\n"
     unsafe_suggestion = ("\n\nIf you really want to skip this, you can run "
                          "the client with --register-unsafely-without-email "
-                         "but make sure you then backup your account key from "
-                         "{0}\n\n".format(os.path.join(
-                             misc.get_default_folder('config'), 'accounts')))
+                         "but you will then be unable to receive notice about "
+                         "impending expiration or revocation of your "
+                         "certificates or problems with your Certbot "
+                         "installation that will lead to failure to 
renew.\n\n")
     if optional:
         if invalid:
             msg += unsafe_suggestion
@@ -275,15 +275,6 @@
         pause=False)
 
 
-def _gen_ssl_lab_urls(domains):
-    """Returns a list of urls.
-
-    :param list domains: Each domain is a 'str'
-
-    """
-    return ["https://www.ssllabs.com/ssltest/analyze.html?d=%s"; % dom for dom 
in domains]
-
-
 def _gen_https_names(domains):
     """Returns a string of the https domains.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/plugins/storage.py 
new/certbot-1.9.0/certbot/plugins/storage.py
--- old/certbot-1.7.0/certbot/plugins/storage.py        2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/certbot/plugins/storage.py        2020-10-06 
20:39:49.000000000 +0200
@@ -106,7 +106,7 @@
         if not self._initialized:
             self._initialize_storage()
 
-        if not self._classkey in self._data.keys():
+        if self._classkey not in self._data:
             self._data[self._classkey] = {}
         self._data[self._classkey][key] = value
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot/reverter.py 
new/certbot-1.9.0/certbot/reverter.py
--- old/certbot-1.7.0/certbot/reverter.py       2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/certbot/reverter.py       2020-10-06 20:39:49.000000000 
+0200
@@ -180,7 +180,7 @@
                     shutil.copy2(filename, os.path.join(
                         cp_dir, os.path.basename(filename) + "_" + str(idx)))
                     op_fd.write('{0}\n'.format(filename))
-                # 
http://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2
+                # 
https://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2
                 except IOError:
                     op_fd.close()
                     logger.error(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/PKG-INFO 
new/certbot-1.9.0/certbot.egg-info/PKG-INFO
--- old/certbot-1.7.0/certbot.egg-info/PKG-INFO 2020-08-04 20:20:16.000000000 
+0200
+++ new/certbot-1.9.0/certbot.egg-info/PKG-INFO 2020-10-06 20:39:50.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: certbot
-Version: 1.7.0
+Version: 1.9.0
 Summary: ACME client
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
@@ -75,9 +75,9 @@
         
         Community: https://community.letsencrypt.org
         
-        ACME spec: http://ietf-wg-acme.github.io/acme/
+        ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_
         
-        ACME working area in github: https://github.com/ietf-wg-acme/acme
+        ACME working area in github (archived): 
https://github.com/ietf-wg-acme/acme
         
         |build-status|
         
@@ -137,7 +137,6 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
@@ -147,7 +146,7 @@
 Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
 Provides-Extra: dev
 Provides-Extra: dev3
 Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/SOURCES.txt 
new/certbot-1.9.0/certbot.egg-info/SOURCES.txt
--- old/certbot-1.7.0/certbot.egg-info/SOURCES.txt      2020-08-04 
20:20:16.000000000 +0200
+++ new/certbot-1.9.0/certbot.egg-info/SOURCES.txt      2020-10-06 
20:39:50.000000000 +0200
@@ -35,6 +35,7 @@
 certbot/_internal/main.py
 certbot/_internal/renewal.py
 certbot/_internal/reporter.py
+certbot/_internal/snap_config.py
 certbot/_internal/storage.py
 certbot/_internal/updater.py
 certbot/_internal/cli/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/requires.txt 
new/certbot-1.9.0/certbot.egg-info/requires.txt
--- old/certbot-1.7.0/certbot.egg-info/requires.txt     2020-08-04 
20:20:16.000000000 +0200
+++ new/certbot-1.9.0/certbot.egg-info/requires.txt     2020-10-06 
20:39:50.000000000 +0200
@@ -1,4 +1,4 @@
-acme>=1.6.0
+acme>=1.8.0
 ConfigArgParse>=0.9.3
 configobj
 cryptography>=1.2.3
@@ -28,8 +28,10 @@
 
 [dev3]
 astroid
+azure-devops
 ipdb
 mypy
+PyGithub
 pylint
 
 [docs]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/Makefile 
new/certbot-1.9.0/docs/Makefile
--- old/certbot-1.7.0/docs/Makefile     2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/Makefile     2020-10-06 20:39:49.000000000 +0200
@@ -9,7 +9,7 @@
 
 # User-friendly check for sphinx-build
 ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx 
installed, then set the SPHINXBUILD environment variable to point to the full 
path of the '$(SPHINXBUILD)' executable. Alternatively you can add the 
directory with the executable to your PATH. If you don't have Sphinx installed, 
grab it from http://sphinx-doc.org/)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx 
installed, then set the SPHINXBUILD environment variable to point to the full 
path of the '$(SPHINXBUILD)' executable. Alternatively you can add the 
directory with the executable to your PATH. If you don't have Sphinx installed, 
grab it from https://www.sphinx-doc.org/)
 endif
 
 # Internal variables.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/_templates/footer.html 
new/certbot-1.9.0/docs/_templates/footer.html
--- old/certbot-1.7.0/docs/_templates/footer.html       2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/_templates/footer.html       2020-10-06 
20:39:49.000000000 +0200
@@ -44,7 +44,7 @@
   </div>
 
   {%- if show_sphinx %}
-  {% trans %}Built with <a href="http://sphinx-doc.org/";>Sphinx</a> using a <a 
href="https://github.com/snide/sphinx_rtd_theme";>theme</a> provided by <a 
href="https://readthedocs.org";>Read the Docs</a>{% endtrans %}.
+  {% trans %}Built with <a href="https://www.sphinx-doc.org/";>Sphinx</a> using 
a <a href="https://github.com/snide/sphinx_rtd_theme";>theme</a> provided by <a 
href="https://readthedocs.org";>Read the Docs</a>{% endtrans %}.
   {%- endif %}
 
   {%- block extrafooter %} {% endblock %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/ciphers.rst 
new/certbot-1.9.0/docs/ciphers.rst
--- old/certbot-1.7.0/docs/ciphers.rst  2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/ciphers.rst  2020-10-06 20:39:49.000000000 +0200
@@ -208,17 +208,17 @@
 
 Damien Giry collects recommendations by academic researchers and standards 
organizations about keylengths for particular cryptoperiods, years, or security 
levels.  The keylength recommendations of the various sources are summarized in 
a chart.  This site has been updated over time and includes expert guidance 
from eight sources published between 2000 and 2017.
 
-http://www.keylength.com/
+https://www.keylength.com/
 
 NIST
 ~~~~
-NISA published its "NIST Special Publication 800-52 Revision 1: Guidelines for 
the Selection, Configuration, and Use of Transport Layer Security (TLS) 
Implementations"
+NIST published its "NIST Special Publication 800-52 Revision 2: Guidelines for 
the Selection, Configuration, and Use of Transport Layer Security (TLS) 
Implementations"
 
-http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf
 
-and its "NIST Special Publication 800-57: Recommendation for Key Management – 
Part 1: General (Revision 3)"
+and its "NIST Special Publication 800-57: Recommendation for Key Management – 
Part 1: General (Revision 5)"
 
-http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf
+https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf
 
 ENISA
 ~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/cli-help.txt 
new/certbot-1.9.0/docs/cli-help.txt
--- old/certbot-1.7.0/docs/cli-help.txt 2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/cli-help.txt 2020-10-06 20:39:49.000000000 +0200
@@ -118,7 +118,7 @@
                         case, and to know when to deprecate support for past
                         Python versions and flags. If you wish to hide this
                         information from the Let's Encrypt server, set this to
-                        "". (default: CertbotACMEClient/1.6.0 (certbot(-auto);
+                        "". (default: CertbotACMEClient/1.8.0 (certbot(-auto);
                         OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY
                         (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel).
                         The flags encoded in the user agent are: --duplicate,
@@ -373,13 +373,11 @@
   --register-unsafely-without-email
                         Specifying this flag enables registering an account
                         with no email address. This is strongly discouraged,
-                        because in the event of key loss or account compromise
-                        you will irrevocably lose access to your account. You
-                        will also be unable to receive notice about impending
-                        expiration or revocation of your certificates. Updates
-                        to the Subscriber Agreement will still affect you, and
-                        will be effective 14 days after posting an update to
-                        the web site. (default: False)
+                        because you will be unable to receive notice about
+                        impending expiration or revocation of your
+                        certificates or problems with your Certbot
+                        installation that will lead to failure to renew.
+                        (default: False)
   -m EMAIL, --email EMAIL
                         Email used for registration and recovery contact. Use
                         comma to register multiple emails, ex:
@@ -602,7 +600,7 @@
   --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: 1200)
+                        record. (default: 120)
   --dns-linode-credentials DNS_LINODE_CREDENTIALS
                         Linode credentials INI file. (default: None)
 
@@ -702,6 +700,9 @@
   --nginx-ctl NGINX_CTL
                         Path to the 'nginx' binary, used for 'configtest' and
                         retrieving nginx version number. (default: nginx)
+  --nginx-sleep-seconds NGINX_SLEEP_SECONDS
+                        Number of seconds to wait for nginx configuration
+                        changes to apply when reloading. (default: 1)
 
 null:
   Null Installer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/conf.py 
new/certbot-1.9.0/docs/conf.py
--- old/certbot-1.7.0/docs/conf.py      2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/conf.py      2020-10-06 20:39:49.000000000 +0200
@@ -131,7 +131,7 @@
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 
-# 
http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs
+# 
https://docs.readthedocs.io/en/stable/faq.html#i-want-to-use-the-read-the-docs-theme-locally
 # on_rtd is whether we are on readthedocs.org
 on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
 if not on_rtd:  # only import and set the theme if we're building docs locally
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/contributing.rst 
new/certbot-1.9.0/docs/contributing.rst
--- old/certbot-1.7.0/docs/contributing.rst     2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/docs/contributing.rst     2020-10-06 20:39:49.000000000 
+0200
@@ -18,6 +18,7 @@
 and continue with these instructions on that UNIX-like OS.
 
 .. _local copy:
+.. _prerequisites:
 
 Running a local copy of the client
 ----------------------------------
@@ -346,7 +347,7 @@
 starting reference for how to do this.
 
 .. _`setuptools entry points`:
-    http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
+    https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
 
 .. _coding-style:
 
@@ -377,7 +378,7 @@
 
 .. _Google Python Style Guide:
   https://google.github.io/styleguide/pyguide.html
-.. _Sphinx-style: http://sphinx-doc.org/
+.. _Sphinx-style: https://www.sphinx-doc.org/
 .. _PEP 8 - Style Guide for Python Code:
   https://www.python.org/dev/peps/pep-0008
 
@@ -578,33 +579,3 @@
 Now running the check for linting errors described above is as easy as::
 
   tox -e lint
-
-.. _prerequisites:
-
-Notes on OS dependencies
-========================
-
-OS-level dependencies can be installed like so:
-
-.. code-block:: shell
-
-   ./certbot-auto --debug --os-packages-only
-
-In general...
-
-* ``sudo`` is required as a suggested way of running privileged process
-* `Python`_ 2.7 or 3.5+ is required
-* `Augeas`_ is required for the Python bindings
-* ``virtualenv`` is used for managing other Python library dependencies
-
-.. _Python: https://wiki.python.org/moin/BeginnersGuide/Download
-.. _Augeas: http://augeas.net/
-.. _Virtualenv: https://virtualenv.pypa.io
-
-
-FreeBSD
--------
-
-FreeBSD by default uses ``tcsh``. In order to activate virtualenv (see
-above), you will need a compatible shell, e.g. ``pkg install bash &&
-bash``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/install.rst 
new/certbot-1.9.0/docs/install.rst
--- old/certbot-1.7.0/docs/install.rst  2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/install.rst  2020-10-06 20:39:49.000000000 +0200
@@ -18,7 +18,7 @@
 certbot.eff.org_, where you will also find the correct installation 
instructions for
 your system.
 
-.. Note:: Unless you have very specific requirements, we kindly suggest that 
you use the Certbot packages provided by your package manager (see 
certbot.eff.org_). If such packages are not available, we recommend using 
``certbot-auto``, which automates the process of installing Certbot on your 
system.
+.. Note:: Unless you have very specific requirements, we kindly suggest that 
you use the installation instructions for your system found at certbot.eff.org_.
 
 .. _certbot.eff.org: https://certbot.eff.org
 
@@ -28,7 +28,7 @@
 System Requirements
 ===================
 
-Certbot currently requires Python 2.7 or 3.5+ running on a UNIX-like operating
+Certbot currently requires Python 2.7 or 3.6+ running on a UNIX-like operating
 system. By default, it requires root access in order to write to
 ``/etc/letsencrypt``, ``/var/log/letsencrypt``, ``/var/lib/letsencrypt``; to
 bind to port 80 (if you use the ``standalone`` plugin) and to read and
@@ -156,18 +156,17 @@
 certificates or configure your webserver, because our installer
 plugins cannot reach your webserver from inside the Docker container.
 
-Most users should use the operating system packages (see instructions at
-certbot.eff.org_) or, as a fallback, ``certbot-auto``. You should only
-use Docker if you are sure you know what you are doing and have a
-good reason to do so.
+Most users should use the instructions at certbot.eff.org_. You should only use
+Docker if you are sure you know what you are doing and have a good reason to do
+so.
 
 You should definitely read the :ref:`where-certs` section, in order to
 know how to manage the certs
 manually. `Our ciphersuites page <ciphers.html>`__
 provides some information about recommended ciphersuites. If none of
-these make much sense to you, you should definitely use the
-certbot-auto_ method, which enables you to use installer plugins
-that cover both of those hard topics.
+these make much sense to you, you should definitely use the installation method
+recommended for your system at certbot.eff.org_, which enables you to use
+installer plugins that cover both of those hard topics.
 
 If you're still not convinced and have decided to use this method, from
 the server that the domain you're requesting a certficate for resolves
@@ -197,10 +196,7 @@
 you'd use ``certbot/dns-route53``. You may also need to add flags to
 Certbot and/or mount additional directories to provide access to your
 DNS API credentials as specified in the :ref:`DNS plugin documentation
-<dns_plugins>`. If you would like to obtain a wildcard certificate from
-Let's Encrypt's ACMEv2 server, you'll need to include ``--server
-https://acme-v02.api.letsencrypt.org/directory`` on the command line as
-well.
+<dns_plugins>`.
 
 For more information about the layout
 of the ``/etc/letsencrypt`` directory, see :ref:`where-certs`.
@@ -250,9 +246,6 @@
 They can be installed by running the same installation command above but
 replacing ``certbot`` with the name of the desired package.
 
-There are no Certbot packages available for Debian Jessie and Jessie users
-should instead use certbot-auto_.
-
 **Ubuntu**
 
 If you run Ubuntu Trusty, Xenial, or Bionic, certbot is available through the 
official PPA,
@@ -291,39 +284,19 @@
 
 **Gentoo**
 
-The official Certbot client is available in Gentoo Portage. If you
-want to use the Apache plugin, it has to be installed separately:
+The official Certbot client is available in Gentoo Portage. From the 
+official Certbot plugins, three of them are also available in Portage. 
+They need to be installed separately if you require their functionality.
 
 .. code-block:: shell
 
    emerge -av app-crypt/certbot
    emerge -av app-crypt/certbot-apache
+   emerge -av app-crypt/certbot-nginx
+   emerge -av app-crypt/certbot-dns-nsone
 
-When using the Apache plugin, you will run into a "cannot find an
-SSLCertificateFile directive" or "cannot find an SSLCertificateKeyFile
-directive for certificate" error if you're sporting the default Gentoo
-``httpd.conf``. You can fix this by commenting out two lines in
-``/etc/apache2/httpd.conf`` as follows:
-
-Change
-
-.. code-block:: shell
-
-   <IfDefine SSL>
-   LoadModule ssl_module modules/mod_ssl.so
-   </IfDefine>
-
-to
-
-.. code-block:: shell
-
-   #<IfDefine SSL>
-   LoadModule ssl_module modules/mod_ssl.so
-   #</IfDefine>
-
-For the time being, this is the only way for the Apache plugin to recognise
-the appropriate directives when installing the certificate.
-Note: this change is not required for the other plugins.
+.. Note:: The ``app-crypt/certbot-dns-nsone`` package has a different 
+   maintainer than the other packages and can lag behind in version.
 
 **NetBSD**
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/make.bat 
new/certbot-1.9.0/docs/make.bat
--- old/certbot-1.7.0/docs/make.bat     2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/make.bat     2020-10-06 20:39:49.000000000 +0200
@@ -65,7 +65,7 @@
        echo.may add the Sphinx directory to PATH.
        echo.
        echo.If you don't have Sphinx installed, grab it from
-       echo.http://sphinx-doc.org/
+       echo.https://www.sphinx-doc.org/
        exit /b 1
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/packaging.rst 
new/certbot-1.9.0/docs/packaging.rst
--- old/certbot-1.7.0/docs/packaging.rst        2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/docs/packaging.rst        2020-10-06 20:39:49.000000000 
+0200
@@ -31,7 +31,7 @@
 We use git tags to identify releases, using `Semantic Versioning`_. For
 example: `v0.11.1`.
 
-.. _`Semantic Versioning`: http://semver.org/
+.. _`Semantic Versioning`: https://semver.org/
 
 Our packages are cryptographically signed and their signature can be verified
 using the PGP key ``A2CFB51FA275A7286234E7B24D17C995CD9775F2``. This key can be
@@ -44,9 +44,13 @@
 
 1. Do not package ``certbot-compatibility-test`` as it's only used internally.
 
-2. To run tests on our packages, you should use ``python setup.py test``. 
Doing things like running ``pytest`` directly on our package files may not work 
because Certbot relies on setuptools to register and find its plugins.
+2. To run tests on our packages, you should use pytest by running the command 
``python -m pytest``. Running ``pytest`` directly may not work because 
PYTHONPATH is not handled the same way and local modules may not be found by 
the test runner.
 
-3. If you'd like to include automated renewal in your package ``certbot renew 
-q`` should be added to crontab or systemd timer. Additionally you should 
include a random per-machine time offset to avoid having a large number of your 
clients hit Let's Encrypt's servers simultaneously.
+3. If you'd like to include automated renewal in your package:
+
+  - ``certbot renew -q`` should be added to crontab or systemd timer.
+  - A random per-machine time offset should be included to avoid having a 
large number of your clients hit Let's Encrypt's servers simultaneously.
+  - ``--preconfigured-renewal`` should be included on the CLI or in 
``cli.ini`` for all invocations of Certbot, so that it can adjust its 
interactive output regarding automated renewal (Certbot >= 1.9.0).
 
 4. ``jws`` is an internal script for ``acme`` module and it doesn't have to be 
packaged - it's mostly for debugging: you can use it as ``echo foo | jws sign | 
jws verify``.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/docs/using.rst 
new/certbot-1.9.0/docs/using.rst
--- old/certbot-1.7.0/docs/using.rst    2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/docs/using.rst    2020-10-06 20:39:49.000000000 +0200
@@ -287,7 +287,7 @@
 .. _haproxy: https://github.com/greenhost/certbot-haproxy
 .. _s3front: https://github.com/dlapiduz/letsencrypt-s3front
 .. _gandi: https://github.com/obynio/certbot-plugin-gandi
-.. _varnish: http://git.sesse.net/?p=letsencrypt-varnish-plugin
+.. _varnish: https://git.sesse.net/?p=letsencrypt-varnish-plugin
 .. _pritunl: https://github.com/kharkevich/letsencrypt-pritunl
 .. _proxmox: https://github.com/kharkevich/letsencrypt-proxmox
 .. _external-auth: https://github.com/EnigmaBridge/certbot-external-auth
@@ -392,7 +392,7 @@
 .. _changing:
 
 Changing a Certificate's Domains
-================================
+--------------------------------
 
 The ``--cert-name`` flag can also be used to modify the domains a certificate 
contains,
 by specifying new domains using the ``-d`` or ``--domains`` flag. If 
certificate ``example.com``
@@ -631,7 +631,6 @@
    :header: "Distribution Name", "Distribution Version", "Automation Method"
 
    "CentOS", "EPEL 7", "systemd"
-   "Debian", "jessie", "cron, systemd"
    "Debian", "stretch", "cron, systemd"
    "Debian", "testing/sid", "cron, systemd"
    "Fedora", "26", "systemd"
@@ -685,7 +684,7 @@
   This is what Apache needs for `SSLCertificateKeyFile
   <https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatekeyfile>`_,
   and Nginx for `ssl_certificate_key
-  
<http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key>`_.
+  
<https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key>`_.
 
 ``fullchain.pem``
   All certificates, **including** server certificate (aka leaf certificate or
@@ -695,7 +694,7 @@
   This is what Apache >= 2.4.8 needs for `SSLCertificateFile
   <https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatefile>`_,
   and what Nginx needs for `ssl_certificate
-  <http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate>`_.
+  <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate>`_.
 
 ``cert.pem`` and ``chain.pem`` (less common)
   ``cert.pem`` contains the server certificate by itself, and
@@ -714,7 +713,7 @@
 
   If you're using OCSP stapling with Nginx >= 1.3.7, ``chain.pem`` should be
   provided as the `ssl_trusted_certificate
-  
<http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate>`_
+  
<https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate>`_
   to validate OCSP responses.
 
 .. note:: All files are PEM-encoded.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/setup.py new/certbot-1.9.0/setup.py
--- old/certbot-1.7.0/setup.py  2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/setup.py  2020-10-06 20:39:49.000000000 +0200
@@ -7,10 +7,9 @@
 from setuptools import __version__ as setuptools_version
 from setuptools import find_packages
 from setuptools import setup
-from setuptools.command.test import test as TestCommand
 
-# Workaround for http://bugs.python.org/issue8876, see
-# http://bugs.python.org/issue8876#msg208792
+# Workaround for https://bugs.python.org/issue8876, see
+# https://bugs.python.org/issue8876#msg208792
 # This can be removed when using Python 2.7.9 or later:
 # https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS
 if os.path.abspath(__file__).split(os.path.sep)[1] == 'vagrant':
@@ -36,7 +35,7 @@
 # specified here to avoid masking the more specific request requirements in
 # acme. See https://github.com/pypa/pip/issues/988 for more info.
 install_requires = [
-    'acme>=1.6.0',
+    'acme>=1.8.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.
@@ -93,8 +92,10 @@
 
 dev3_extras = [
     'astroid',
+    'azure-devops',
     'ipdb',
     'mypy',
+    'PyGithub',
     'pylint',
 ]
 
@@ -106,22 +107,6 @@
     'sphinx_rtd_theme',
 ]
 
-
-class PyTest(TestCommand):
-    user_options = []
-
-    def initialize_options(self):
-        TestCommand.initialize_options(self)
-        self.pytest_args = ''
-
-    def run_tests(self):
-        import shlex
-        # import here, cause outside the eggs aren't loaded
-        import pytest
-        errno = pytest.main(shlex.split(self.pytest_args))
-        sys.exit(errno)
-
-
 setup(
     name='certbot',
     version=version,
@@ -131,7 +116,7 @@
     author="Certbot Project",
     author_email='[email protected]',
     license='Apache License 2.0',
-    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
+    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, 
!=3.5.*',
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Environment :: Console',
@@ -143,7 +128,6 @@
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
@@ -165,10 +149,6 @@
         'docs': docs_extras,
     },
 
-    test_suite='certbot',
-    tests_require=["pytest"],
-    cmdclass={"test": PyTest},
-
     entry_points={
         'console_scripts': [
             'certbot = certbot.main:main',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/cert_manager_test.py 
new/certbot-1.9.0/tests/cert_manager_test.py
--- old/certbot-1.7.0/tests/cert_manager_test.py        2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/tests/cert_manager_test.py        2020-10-06 
20:39:49.000000000 +0200
@@ -35,8 +35,8 @@
             "example.org": None,
             "other.com": os.path.join(self.config.config_dir, "specialarchive")
         }
-        self.config_files = dict((domain, self._set_up_config(domain, 
self.domains[domain]))
-            for domain in self.domains)
+        self.config_files = {domain: self._set_up_config(domain, 
self.domains[domain])
+            for domain in self.domains}
 
         # We also create a file that isn't a renewal config in the same
         # location to test that logic that reads in all-and-only renewal
@@ -80,8 +80,8 @@
                 archive_dir_path = custom_archive
             else:
                 archive_dir_path = 
os.path.join(self.config.default_archive_dir, domain)
-            archive_paths[domain] = dict((kind,
-                os.path.join(archive_dir_path, kind + "1.pem")) for kind in 
ALL_FOUR)
+            archive_paths[domain] = {kind:
+                os.path.join(archive_dir_path, kind + "1.pem") for kind in 
ALL_FOUR}
             for kind in ALL_FOUR:
                 live_path = self.config_files[domain][kind]
                 archive_path = archive_paths[domain][kind]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/client_test.py 
new/certbot-1.9.0/tests/client_test.py
--- old/certbot-1.7.0/tests/client_test.py      2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/tests/client_test.py      2020-10-06 20:39:49.000000000 
+0200
@@ -483,7 +483,6 @@
     def test_save_certificate(self, mock_parser):
         certs = ["cert_512.pem", "cert-san_512.pem"]
         tmp_path = tempfile.mkdtemp()
-        filesystem.chmod(tmp_path, 0o755)  # TODO: really??
 
         cert_pem = test_util.load_vector(certs[0])
         chain_pem = (test_util.load_vector(certs[0]) + 
test_util.load_vector(certs[1]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/crypto_util_test.py 
new/certbot-1.9.0/tests/crypto_util_test.py
--- old/certbot-1.7.0/tests/crypto_util_test.py 2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/tests/crypto_util_test.py 2020-10-06 20:39:49.000000000 
+0200
@@ -185,8 +185,6 @@
     """Refactoring for verification tests."""
 
     def setUp(self):
-        super(VerifyCertSetup, self).setUp()
-
         self.renewable_cert = mock.MagicMock()
         self.renewable_cert.cert_path = SS_CERT_PATH
         self.renewable_cert.chain_path = SS_CERT_PATH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/display/ops_test.py 
new/certbot-1.9.0/tests/display/ops_test.py
--- old/certbot-1.7.0/tests/display/ops_test.py 2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/tests/display/ops_test.py 2020-10-06 20:39:49.000000000 
+0200
@@ -131,26 +131,6 @@
         self.assertTrue(self._call([self.acc1, self.acc2]) is None)
 
 
-class GenSSLLabURLs(unittest.TestCase):
-    """Loose test of _gen_ssl_lab_urls. URL can change easily in the future."""
-    def setUp(self):
-        zope.component.provideUtility(display_util.FileDisplay(sys.stdout,
-                                                               False))
-
-    @classmethod
-    def _call(cls, domains):
-        from certbot.display.ops import _gen_ssl_lab_urls
-        return _gen_ssl_lab_urls(domains)
-
-    def test_zero(self):
-        self.assertEqual(self._call([]), [])
-
-    def test_two(self):
-        urls = self._call(["eff.org", "umich.edu"])
-        self.assertTrue("eff.org" in urls[0])
-        self.assertTrue("umich.edu" in urls[1])
-
-
 class GenHttpsNamesTest(unittest.TestCase):
     """Test _gen_https_names."""
     def setUp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/display/util_test.py 
new/certbot-1.9.0/tests/display/util_test.py
--- old/certbot-1.7.0/tests/display/util_test.py        2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/tests/display/util_test.py        2020-10-06 
20:39:49.000000000 +0200
@@ -326,7 +326,6 @@
 class NoninteractiveDisplayTest(unittest.TestCase):
     """Test non-interactive display. These tests are pretty easy!"""
     def setUp(self):
-        super(NoninteractiveDisplayTest, self).setUp()
         self.mock_stdout = mock.MagicMock()
         self.displayer = display_util.NoninteractiveDisplay(self.mock_stdout)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/error_handler_test.py 
new/certbot-1.9.0/tests/error_handler_test.py
--- old/certbot-1.7.0/tests/error_handler_test.py       2020-08-04 
20:20:15.000000000 +0200
+++ new/certbot-1.9.0/tests/error_handler_test.py       2020-10-06 
20:39:49.000000000 +0200
@@ -14,7 +14,7 @@
 
 def get_signals(signums):
     """Get the handlers for an iterable of signums."""
-    return dict((s, signal.getsignal(s)) for s in signums)
+    return {s: signal.getsignal(s) for s in signums}
 
 
 def set_signals(sig_handler_dict):
@@ -28,7 +28,7 @@
     """Context manager to catch signals"""
     signals = []
     prev_handlers = get_signals(signums)  # type: Dict[int, Union[int, None, 
Callable]]
-    set_signals(dict((s, lambda s, _: signals.append(s)) for s in signums))
+    set_signals({s: lambda s, _: signals.append(s) for s in signums})
     yield signals
     set_signals(prev_handlers)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/log_test.py 
new/certbot-1.9.0/tests/log_test.py
--- old/certbot-1.7.0/tests/log_test.py 2020-08-04 20:20:15.000000000 +0200
+++ new/certbot-1.9.0/tests/log_test.py 2020-10-06 20:39:49.000000000 +0200
@@ -306,7 +306,7 @@
         self.log_path = 'foo.log'
 
     def test_base_exception(self):
-        exc_type = KeyboardInterrupt
+        exc_type = BaseException
         mock_logger, output = self._test_common(exc_type, debug=False)
         self._assert_exception_logged(mock_logger.error, exc_type)
         self._assert_logfile_output(output)
@@ -342,6 +342,11 @@
         self._assert_exception_logged(mock_logger.debug, exc_type)
         self._assert_quiet_output(mock_logger, output)
 
+    def test_keyboardinterrupt(self):
+        exc_type = KeyboardInterrupt
+        mock_logger, output = self._test_common(exc_type, debug=False)
+        mock_logger.error.assert_called_once_with('Exiting due to user 
request.')
+
     def _test_common(self, error_type, debug):
         """Returns the mocked logger and stderr output."""
         mock_err = six.StringIO()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/main_test.py 
new/certbot-1.9.0/tests/main_test.py
--- old/certbot-1.7.0/tests/main_test.py        2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/tests/main_test.py        2020-10-06 20:39:49.000000000 
+0200
@@ -1404,6 +1404,43 @@
                  "[email protected]"])
             self.assertTrue("Could not find an existing account" in x[0])
 
+    @mock.patch('certbot._internal.main._determine_account')
+    @mock.patch('certbot._internal.eff.prepare_subscription')
+    @mock.patch('certbot._internal.main.account')
+    def test_update_account_remove_email(self, mocked_account_module, 
mock_prepare, mock_det_acc):
+        # Mock account storage and the account object returned
+        mocked_storage = mock.MagicMock()
+        mocked_account = mock.MagicMock()
+
+        mocked_account_module.AccountFileStorage.return_value = mocked_storage
+        mocked_storage.find_all.return_value = [mocked_account]
+        mock_det_acc.return_value = (mocked_account, "foo")
+
+        # Mock registration body to verify calls are made
+        mock_regr_body = mock.MagicMock()
+
+        # mocked_account.regr is overwritten in update, requiring an odd mock 
setup
+        mocked_account.regr.body = mock_regr_body
+
+        x = self._call(
+            ["update_account", "--register-unsafely-without-email"])
+
+
+        # When update succeeds, the return value of update_account() is None
+        self.assertTrue(x[0] is None)
+        # and we got supposedly did update the registration from
+        # the server
+        client_mock = x[3]
+        self.assertTrue(client_mock.Client().acme.update_registration.called)
+
+        self.assertTrue(mock_regr_body.update.called)
+        self.assertTrue('contact' in mock_regr_body.update.call_args[1])
+        self.assertEqual(mock_regr_body.update.call_args[1]['contact'], ())
+        # and we saved the updated registration on disk
+        self.assertTrue(mocked_storage.update_regr.called)
+        # ensure we didn't try to subscribe (no email to subscribe with)
+        self.assertFalse(mock_prepare.called)
+
     @mock.patch('certbot._internal.main.display_ops.get_email')
     @test_util.patch_get_utility()
     def test_update_account_with_email(self, mock_utility, mock_email):
@@ -1455,7 +1492,7 @@
             'account': mock.patch('certbot._internal.main.account'),
             'client': mock.patch('certbot._internal.main.client'),
             'get_utility': test_util.patch_get_utility()}
-        self.mocks = dict((k, v.start()) for k, v in self.patchers.items())
+        self.mocks = {k: v.start() for k, v in self.patchers.items()}
 
     def tearDown(self):
         for patch in self.patchers.values():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-1.7.0/tests/renewal_test.py 
new/certbot-1.9.0/tests/renewal_test.py
--- old/certbot-1.7.0/tests/renewal_test.py     2020-08-04 20:20:15.000000000 
+0200
+++ new/certbot-1.9.0/tests/renewal_test.py     2020-10-06 20:39:49.000000000 
+0200
@@ -3,7 +3,7 @@
 
 try:
     import mock
-except ImportError: # pragma: no cover
+except ImportError:  # pragma: no cover
     from unittest import mock
 
 from acme import challenges
@@ -54,6 +54,26 @@
         self.assertEqual(self.config.webroot_map, {})
         self.assertEqual(self.config.webroot_path, ['/var/www/test'])
 
+    def test_reuse_key_renewal_params(self):
+        self.config.rsa_key_size = 'INVALID_VALUE'
+        self.config.reuse_key = True
+        self.config.dry_run = True
+        config = configuration.NamespaceConfig(self.config)
+
+        rc_path = test_util.make_lineage(
+            self.config.config_dir, 'sample-renewal.conf')
+        lineage = storage.RenewableCert(rc_path, config)
+
+        le_client = mock.MagicMock()
+        le_client.obtain_certificate.return_value = (None, None, None, None)
+
+        from certbot._internal import renewal
+
+        with mock.patch('certbot._internal.renewal.hooks.renew_hook'):
+            renewal.renew_cert(self.config, None, le_client, lineage)
+
+        assert self.config.rsa_key_size == 2048
+
 
 class RestoreRequiredConfigElementsTest(test_util.ConfigTestCase):
     """Tests for certbot._internal.renewal.restore_required_config_elements."""


Reply via email to