From: Nizamudeen A Date: Mon, 4 Nov 2024 05:42:32 +0000 (+0530) Subject: mgr/dashboard: remove cherrypy_backports.py X-Git-Tag: v17.2.8~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=c2fe94869854e74e055a6f0c52ad351b1620c02e;p=ceph.git mgr/dashboard: remove cherrypy_backports.py since its mostly used only for older cherrypy versions which we don't support anymore in any of our recent upstream releases, we could remove it completely Fixes: https://tracker.ceph.com/issues/68802 Signed-off-by: Nizamudeen A (cherry picked from commit 7ae56f4f561999898a7411840f94e742981ca6bc) Conflicts: src/pybind/mgr/prometheus/module.py - resolve conflicting import by just removing the version import (cherry picked from commit 8713c8c2266c5075d6a0eb8da6e77152cda44c11) --- diff --git a/src/pybind/mgr/dashboard/cherrypy_backports.py b/src/pybind/mgr/dashboard/cherrypy_backports.py deleted file mode 100644 index 8871004fed2df..0000000000000 --- a/src/pybind/mgr/dashboard/cherrypy_backports.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright © 2004-2019, CherryPy Team (team@cherrypy.org) - -All rights reserved. - -* * * - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of CherryPy nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from pkg_resources import parse_version - -# The SSL code in CherryPy 3.5.0 is buggy. It was fixed long ago, -# but 3.5.0 is still shipping in major linux distributions -# (Fedora 27, Ubuntu Xenial), so we must monkey patch it to get SSL working. - - -def patch_http_connection_init(v): - # It was fixed in 3.7.0. Exact lower bound version is probably earlier, - # but 3.5.0 is what this monkey patch is tested on. - if parse_version("3.5.0") <= v < parse_version("3.7.0"): - from cherrypy.wsgiserver.wsgiserver2 import CP_fileobject, HTTPConnection - - def fixed_init(hc_self, server, sock, makefile=CP_fileobject): - hc_self.server = server - hc_self.socket = sock - hc_self.rfile = makefile(sock, "rb", hc_self.rbufsize) - hc_self.wfile = makefile(sock, "wb", hc_self.wbufsize) - hc_self.requests_seen = 0 - - HTTPConnection.__init__ = fixed_init - - -# When the CherryPy server in 3.2.2 (and later) starts it attempts to verify -# that the ports its listening on are in fact bound. When using the any address -# "::" it tries both ipv4 and ipv6, and in some environments (e.g. kubernetes) -# ipv6 isn't yet configured / supported and CherryPy throws an uncaught -# exception. -def skip_wait_for_occupied_port(v): - # the issue was fixed in 3.2.3. it's present in 3.2.2 (current version on - # centos:7) and back to at least 3.0.0. - if parse_version("3.1.2") <= v < parse_version("3.2.3"): - # https://github.com/cherrypy/cherrypy/issues/1100 - from cherrypy.process import servers - servers.wait_for_occupied_port = lambda host, port: None - - -# cherrypy.wsgiserver was extracted wsgiserver into cheroot in cherrypy v9.0.0 -def patch_builtin_ssl_wrap(v, new_wrap): - if v < parse_version("9.0.0"): - from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter as builtin_ssl - else: - from cheroot.ssl.builtin import BuiltinSSLAdapter as builtin_ssl # type: ignore - builtin_ssl.wrap = new_wrap(builtin_ssl.wrap) - - -def accept_exceptions_from_builtin_ssl(v): - # the fix was included by cheroot v5.2.0, which was included by cherrypy - # 10.2.0. - if v < parse_version("10.2.0"): - # see https://github.com/cherrypy/cheroot/pull/4 - import ssl - - def accept_ssl_errors(func): - def wrapper(self, sock): - try: - return func(self, sock) - except ssl.SSLError as e: - if e.errno == ssl.SSL_ERROR_SSL: - # Check if it's one of the known errors - # Errors that are caught by PyOpenSSL, but thrown by - # built-in ssl - _block_errors = ('unknown protocol', 'unknown ca', 'unknown_ca', - 'unknown error', - 'https proxy request', 'inappropriate fallback', - 'wrong version number', - 'no shared cipher', 'certificate unknown', - 'ccs received early', - 'certificate verify failed', # client cert w/o trusted CA - 'version too low', # caused by SSL3 connections - 'unsupported protocol', # caused by TLS1 connections - 'sslv3 alert bad certificate') - for error_text in _block_errors: - if error_text in e.args[1].lower(): - # Accepted error, let's pass - return None, {} - raise - return wrapper - patch_builtin_ssl_wrap(v, accept_ssl_errors) - - -def accept_socket_error_0(v): - # see https://github.com/cherrypy/cherrypy/issues/1618 - try: - import cheroot - cheroot_version = parse_version(cheroot.__version__) - except ImportError: - pass - - if v < parse_version("9.0.0") or cheroot_version < parse_version("6.5.5"): - generic_socket_error = OSError - - def accept_socket_error_0(func): - def wrapper(self, sock): - try: - return func(self, sock) - except generic_socket_error as e: - """It is unclear why exactly this happens. - - It's reproducible only with openssl>1.0 and stdlib ``ssl`` wrapper. - In CherryPy it's triggered by Checker plugin, which connects - to the app listening to the socket port in TLS mode via plain - HTTP during startup (from the same process). - - Ref: https://github.com/cherrypy/cherrypy/issues/1618 - """ - import ssl - is_error0 = e.args == (0, 'Error') - IS_ABOVE_OPENSSL10 = ssl.OPENSSL_VERSION_INFO >= (1, 1) - del ssl - if is_error0 and IS_ABOVE_OPENSSL10: - return None, {} - raise - return wrapper - patch_builtin_ssl_wrap(v, accept_socket_error_0) - - -def patch_request_unique_id(v): - """ - Older versions of cherrypy don't include request.unique_id field (a lazily - calculated UUID4). - - Monkey-patching is preferred over alternatives as inheritance, as it'd break - type checks (cherrypy/lib/cgtools.py: `isinstance(obj, _cprequest.Request)`) - """ - if v < parse_version('11.1.0'): - import uuid - from functools import update_wrapper - - from cherrypy._cprequest import Request - - class LazyUUID4(object): - def __str__(self): - """Return UUID4 and keep it for future calls.""" - return str(self.uuid4) - - @property - def uuid4(self): - """Provide unique id on per-request basis using UUID4. - It's evaluated lazily on render. - """ - try: - self._uuid4 # type: ignore - except AttributeError: - # evaluate on first access - self._uuid4 = uuid.uuid4() - - return self._uuid4 - - old_init = Request.__init__ - - def init_with_unique_id(self, *args, **kwargs): - old_init(self, *args, **kwargs) - self.unique_id = LazyUUID4() - - Request.__init__ = update_wrapper(init_with_unique_id, old_init) - - -def patch_cherrypy(v): - ver = parse_version(v) - patch_http_connection_init(ver) - skip_wait_for_occupied_port(ver) - accept_exceptions_from_builtin_ssl(ver) - accept_socket_error_0(ver) - patch_request_unique_id(ver) diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 68725be6e3559..3482663dbfa14 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -46,10 +46,6 @@ except ImportError: from .services.sso import load_sso_db -if cherrypy is not None: - from .cherrypy_backports import patch_cherrypy - patch_cherrypy(cherrypy.__version__) - # pylint: disable=wrong-import-position from .plugins import PLUGIN_MANAGER, debug, feature_toggles, motd # isort:skip # noqa E501 # pylint: disable=unused-import diff --git a/src/pybind/mgr/prometheus/module.py b/src/pybind/mgr/prometheus/module.py index 25cae41c304f1..0b04359d9e7a9 100644 --- a/src/pybind/mgr/prometheus/module.py +++ b/src/pybind/mgr/prometheus/module.py @@ -7,7 +7,6 @@ import re import threading import time import enum -from packaging import version # type: ignore from mgr_module import CLIReadCommand, MgrModule, MgrStandbyModule, PG_STATES, Option, ServiceInfoT, HandleCommandResult, CLIWriteCommand from mgr_util import get_default_addr, profile_method, build_url @@ -27,21 +26,6 @@ MetricValue = Dict[LabelValues, Number] DEFAULT_PORT = 9283 -# When the CherryPy server in 3.2.2 (and later) starts it attempts to verify -# that the ports its listening on are in fact bound. When using the any address -# "::" it tries both ipv4 and ipv6, and in some environments (e.g. kubernetes) -# ipv6 isn't yet configured / supported and CherryPy throws an uncaught -# exception. -if cherrypy is not None: - Version = version.Version - v = Version(cherrypy.__version__) - # the issue was fixed in 3.2.3. it's present in 3.2.2 (current version on - # centos:7) and back to at least 3.0.0. - if Version("3.1.2") <= v < Version("3.2.3"): - # https://github.com/cherrypy/cherrypy/issues/1100 - from cherrypy.process import servers - servers.wait_for_occupied_port = lambda host, port: None - # cherrypy likes to sys.exit on error. don't let it take us down too! def os_exit_noop(status: int) -> None: