From 01cb398019e4e0050eea24b7be1a28186d042919 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sun, 27 Oct 2019 10:57:20 +0800 Subject: [PATCH] mgr/dashboard: extract monkey patches for cherrypy out so they are less distracting to the dashboard developers. and probably less scaring. Signed-off-by: Kefu Chai --- .../mgr/dashboard/cherrypy_backports.py | 43 +++++++++++++++++++ src/pybind/mgr/dashboard/module.py | 35 +-------------- 2 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 src/pybind/mgr/dashboard/cherrypy_backports.py diff --git a/src/pybind/mgr/dashboard/cherrypy_backports.py b/src/pybind/mgr/dashboard/cherrypy_backports.py new file mode 100644 index 0000000000000..d5c6602b648d6 --- /dev/null +++ b/src/pybind/mgr/dashboard/cherrypy_backports.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +from distutils.version import StrictVersion + +# 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 StrictVersion("3.5.0") <= v < StrictVersion("3.7.0"): + from cherrypy.wsgiserver.wsgiserver2 import \ + HTTPConnection, CP_fileobject + + 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 StrictVersion("3.1.2") <= v < StrictVersion("3.2.3"): + # https://github.com/cherrypy/cherrypy/issues/1100 + from cherrypy.process import servers + servers.wait_for_occupied_port = lambda host, port: None + +def patch_cherrypy(v): + patch_http_connection_init(v) + skip_wait_for_occupied_port(v) + diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 5e3c810f677b8..f24a6f7c3d48a 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -6,7 +6,6 @@ from __future__ import absolute_import import collections import errno -from distutils.version import StrictVersion import os import socket import tempfile @@ -26,39 +25,9 @@ except ImportError: from .services.sso import load_sso_db -# 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. if cherrypy is not None: - v = StrictVersion(cherrypy.__version__) - # 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 StrictVersion("3.5.0") <= v < StrictVersion("3.7.0"): - from cherrypy.wsgiserver.wsgiserver2 import HTTPConnection,\ - CP_fileobject - - 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. -if cherrypy is not None: - v = StrictVersion(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 StrictVersion("3.1.2") <= v < StrictVersion("3.2.3"): - # https://github.com/cherrypy/cherrypy/issues/1100 - from cherrypy.process import servers - servers.wait_for_occupied_port = lambda host, port: None + from .cherrypy_backports import patch_cherrypy + patch_cherrypy(cherrypy.__version__) if 'COVERAGE_ENABLED' in os.environ: import coverage -- 2.39.5