From ccd58dea5bebd095fcd04030d296448af195b11d Mon Sep 17 00:00:00 2001 From: Peter Eckersley Date: Tue, 2 Feb 2016 16:47:42 -0800 Subject: [PATCH] More helpful error when renewing with standalone --- letsencrypt/plugins/standalone.py | 3 ++- letsencrypt/plugins/standalone_test.py | 2 +- letsencrypt/plugins/util.py | 11 +++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/letsencrypt/plugins/standalone.py b/letsencrypt/plugins/standalone.py index cde7041d8..6f4f4f6a7 100644 --- a/letsencrypt/plugins/standalone.py +++ b/letsencrypt/plugins/standalone.py @@ -200,7 +200,8 @@ class Authenticator(common.Plugin): return self.supported_challenges def perform(self, achalls): # pylint: disable=missing-docstring - if any(util.already_listening(port) for port in self._necessary_ports): + renewer = self.config.verb == "renew" + if any(util.already_listening(port, renewer) for port in self._necessary_ports): raise errors.MisconfigurationError( "At least one of the (possibly) required ports is " "already taken.") diff --git a/letsencrypt/plugins/standalone_test.py b/letsencrypt/plugins/standalone_test.py index 1e39dee57..80f9c8a74 100644 --- a/letsencrypt/plugins/standalone_test.py +++ b/letsencrypt/plugins/standalone_test.py @@ -125,7 +125,7 @@ class AuthenticatorTest(unittest.TestCase): self.config.standalone_supported_challenges = chall self.assertRaises( errors.MisconfigurationError, self.auth.perform, []) - mock_util.already_listening.assert_called_once_with(port) + mock_util.already_listening.assert_called_once_with(port, False) mock_util.already_listening.reset_mock() @mock.patch("letsencrypt.plugins.standalone.zope.component.getUtility") diff --git a/letsencrypt/plugins/util.py b/letsencrypt/plugins/util.py index d50c7d61c..53d2f439a 100644 --- a/letsencrypt/plugins/util.py +++ b/letsencrypt/plugins/util.py @@ -11,7 +11,7 @@ from letsencrypt import interfaces logger = logging.getLogger(__name__) -def already_listening(port): +def already_listening(port, renewer=False): """Check if a process is already listening on the port. If so, also tell the user via a display notification. @@ -49,11 +49,18 @@ def already_listening(port): pid = listeners[0] name = psutil.Process(pid).name() display = zope.component.getUtility(interfaces.IDisplay) + extra = "" + if renewer: + extra = (" For automated renewal, you may want to use a script that stops" + " and starts your webserver. You can find an example at" + " https://letsencrypt.org/howitworks/#writing-your-own-renewal-script" + ". Alternatively you can use the webroot plugin to renew without" + " needing to stop and start your webserver.") display.notification( "The program {0} (process ID {1}) is already listening " "on TCP port {2}. This will prevent us from binding to " "that port. Please stop the {0} program temporarily " - "and then try again.".format(name, pid, port)) + "and then try again.{3}".format(name, pid, port, extra)) return True except (psutil.NoSuchProcess, psutil.AccessDenied): # Perhaps the result of a race where the process could have