fix: dependencies and deprecated code (#390)

This commit is contained in:
Vincent Renaville
2022-11-04 14:34:29 +01:00
committed by GitHub
co-authored by GitHub
parent 14cab08024
commit dddd130e79
14 changed files with 224 additions and 111 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ env:
- TESTS="1" ODOO_REPO="odoo/odoo" EXCLUDE="cloud_platform,cloud_platform_ovh,cloud_platform_exoscale" - TESTS="1" ODOO_REPO="odoo/odoo" EXCLUDE="cloud_platform,cloud_platform_ovh,cloud_platform_exoscale"
- TESTS="1" ODOO_REPO="OCA/OCB" EXCLUDE="cloud_platform,cloud_platform_ovh,cloud_platform_exoscale" - TESTS="1" ODOO_REPO="OCA/OCB" EXCLUDE="cloud_platform,cloud_platform_ovh,cloud_platform_exoscale"
global: global:
- VERSION="15.0" LINT_CHECK="0" TESTS="0" - VERSION="16.0" LINT_CHECK="0" TESTS="0"
install: install:
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
@@ -5,7 +5,7 @@ import inspect
import logging import logging
import os import os
import time import time
from distutils.util import strtobool from .strtobool import strtobool
import psycopg2 import psycopg2
import odoo import odoo
@@ -0,0 +1,21 @@
_MAP = {
'y': True,
'yes': True,
't': True,
'true': True,
'on': True,
'1': True,
'n': False,
'no': False,
'f': False,
'false': False,
'off': False,
'0': False
}
def strtobool(value):
try:
return _MAP[str(value).lower()]
except KeyError:
raise ValueError('"{}" is not a valid bool value'.format(value))
+1 -1
View File
@@ -6,7 +6,7 @@ import os
import re import re
from collections import namedtuple from collections import namedtuple
from distutils.util import strtobool from .strtobool import strtobool
from odoo import api, models from odoo import api, models
from odoo.tools.config import config from odoo.tools.config import config
+21
View File
@@ -0,0 +1,21 @@
_MAP = {
'y': True,
'yes': True,
't': True,
'true': True,
'on': True,
'1': True,
'n': False,
'no': False,
'f': False,
'false': False,
'off': False,
'0': False
}
def strtobool(value):
try:
return _MAP[str(value).lower()]
except KeyError:
raise ValueError('"{}" is not a valid bool value'.format(value))
+10 -11
View File
@@ -6,7 +6,7 @@ import os
import threading import threading
import uuid import uuid
from distutils.util import strtobool from .strtobool import strtobool
from odoo import http from odoo import http
@@ -20,30 +20,29 @@ except ImportError:
def is_true(strval): def is_true(strval):
return bool(strtobool(strval or '0'.lower())) return bool(strtobool(strval or "0".lower()))
class OdooJsonFormatter(jsonlogger.JsonFormatter): class OdooJsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict): def add_fields(self, log_record, record, message_dict):
record.pid = os.getpid() record.pid = os.getpid()
record.dbname = getattr(threading.currentThread(), 'dbname', '?') record.dbname = getattr(threading.currentThread(), "dbname", "?")
record.request_id = getattr(threading.current_thread(), 'request_uuid', None) record.request_id = getattr(threading.current_thread(), "request_uuid", None)
record.uid = getattr(threading.current_thread(), 'uid', None) record.uid = getattr(threading.current_thread(), "uid", None)
_super = super(OdooJsonFormatter, self) _super = super(OdooJsonFormatter, self)
return _super.add_fields(log_record, record, message_dict) return _super.add_fields(log_record, record, message_dict)
if is_true(os.environ.get('ODOO_LOGGING_JSON')): if is_true(os.environ.get("ODOO_LOGGING_JSON")):
formatted_message = ( formatted_message = (
'%(asctime)s %(pid)s %(levelname)s %(dbname)s %(name)s: %(message)s' "%(asctime)s %(pid)s %(levelname)s %(dbname)s %(name)s: %(message)s"
) )
formatter = OdooJsonFormatter(formatted_message) formatter = OdooJsonFormatter(formatted_message)
logging.getLogger().handlers[0].formatter = formatter logging.getLogger().handlers[0].formatter = formatter
# monkey patch WebRequest constructor to store request_uuid # monkey patch Request constructor to store request_uuid
org_init = http.WebRequest.__init__ org_init = http.Request.__init__
def new_init(self, httprequest): def new_init(self, httprequest):
@@ -51,4 +50,4 @@ def new_init(self, httprequest):
threading.current_thread().request_uuid = uuid.uuid4() threading.current_thread().request_uuid = uuid.uuid4()
http.WebRequest.__init__ = new_init http.Request.__init__ = new_init
+21
View File
@@ -0,0 +1,21 @@
_MAP = {
'y': True,
'yes': True,
't': True,
'true': True,
'on': True,
'1': True,
'n': False,
'no': False,
'f': False,
'false': False,
'off': False,
'0': False
}
def strtobool(value):
try:
return _MAP[str(value).lower()]
except KeyError:
raise ValueError('"{}" is not a valid bool value'.format(value))
+42 -38
View File
@@ -10,27 +10,28 @@ from odoo.http import request as http_request
from odoo.tools.config import config from odoo.tools.config import config
_logger = logging.getLogger('monitoring.http.requests') _logger = logging.getLogger("monitoring.http.requests")
class IrHttp(models.AbstractModel): class IrHttp(models.AbstractModel):
_inherit = 'ir.http' _inherit = "ir.http"
@classmethod @classmethod
def _dispatch(cls): def _dispatch(cls, endpoint):
begin = time.time() begin = time.time()
response = super()._dispatch() response = super()._dispatch(endpoint)
end = time.time() end = time.time()
if (not cls._monitoring_blacklist(http_request) and if not cls._monitoring_blacklist(http_request) and cls._monitoring_filter(
cls._monitoring_filter(http_request)): http_request
):
info = cls._monitoring_info(http_request, response, begin, end) info = cls._monitoring_info(http_request, response, begin, end)
cls._monitoring_log(info) cls._monitoring_log(info)
return response return response
@classmethod @classmethod
def _monitoring_blacklist(cls, request): def _monitoring_blacklist(cls, request):
path_info = request.httprequest.environ.get('PATH_INFO') path_info = request.httprequest.environ.get("PATH_INFO")
if path_info.startswith('/longpolling/'): if path_info.startswith("/longpolling/"):
return True return True
return False return False
@@ -40,42 +41,45 @@ class IrHttp(models.AbstractModel):
@classmethod @classmethod
def _monitoring_info(cls, request, response, begin, end): def _monitoring_info(cls, request, response, begin, end):
path = request.httprequest.environ.get('PATH_INFO') path = request.httprequest.environ.get("PATH_INFO")
info = { info = {
# timing # timing
'start_time': time.strftime("%Y-%m-%d %H:%M:%S", "start_time": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(begin)),
time.gmtime(begin)), "duration": end - begin,
'duration': end - begin,
# HTTP things # HTTP things
'method': request.httprequest.method, "method": request.httprequest.method,
'url': request.httprequest.url, "url": request.httprequest.url,
'path': path, "path": path,
'content_type': request.httprequest.environ.get('CONTENT_TYPE'), "content_type": request.httprequest.environ.get("CONTENT_TYPE"),
'user_agent': request.httprequest.environ.get('HTTP_USER_AGENT'), "user_agent": request.httprequest.environ.get("HTTP_USER_AGENT"),
# Odoo things # Odoo things
'db': None, "db": None,
'uid': request.uid, "uid": request.uid,
'login': None, "login": None,
'server_environment': config.get('running_env'), "server_environment": config.get("running_env"),
'model': None, "model": None,
'model_method': None, "model_method": None,
'workflow_signal': None, "workflow_signal": None,
# response things # response things
'response_status_code': None, "response_status_code": None,
} }
if hasattr(request, 'status_code'): if hasattr(request, "status_code"):
info['status_code'] = response.status_code info["status_code"] = response.status_code
if hasattr(request, 'session'): if hasattr(request, "session"):
info.update({ info.update(
'login': request.session.get('login'), {
'db': request.session.get('db'), "login": request.session.get("login"),
}) "db": request.session.get("db"),
if hasattr(request, 'params'): }
info.update({ )
'model': request.params.get('model'), if hasattr(request, "params"):
'model_method': request.params.get('method'), info.update(
'workflow_signal': request.params.get('signal'), {
}) "model": request.params.get("model"),
"model_method": request.params.get("method"),
"workflow_signal": request.params.get("signal"),
}
)
return info return info
@classmethod @classmethod
+4 -4
View File
@@ -16,15 +16,15 @@ class IrHttp(models.AbstractModel):
_inherit = "ir.http" _inherit = "ir.http"
@classmethod @classmethod
def _dispatch(cls): def _dispatch(cls, endpoint):
path_info = request.httprequest.environ.get("PATH_INFO") path_info = request.httprequest.environ.get("PATH_INFO")
if path_info.startswith("/longpolling/"): if path_info.startswith("/longpolling/"):
LONGPOLLING_COUNT.inc() LONGPOLLING_COUNT.inc()
return super()._dispatch() return super()._dispatch(endpoint)
if path_info.startswith("/metrics"): if path_info.startswith("/metrics"):
return super()._dispatch() return super()._dispatch(endpoint)
if path_info.startswith("/web/static"): if path_info.startswith("/web/static"):
label = "assets" label = "assets"
@@ -35,6 +35,6 @@ class IrHttp(models.AbstractModel):
res = None res = None
with REQUEST_TIME.labels(label).time(): with REQUEST_TIME.labels(label).time():
res = super()._dispatch() res = super()._dispatch(endpoint)
return res return res
+4 -4
View File
@@ -11,13 +11,13 @@ class IrHttp(models.AbstractModel):
_inherit = 'ir.http' _inherit = 'ir.http'
@classmethod @classmethod
def _dispatch(cls): def _dispatch(cls, endpoint):
if not statsd: if not statsd:
return super()._dispatch() return super()._dispatch(endpoint)
path_info = request.httprequest.environ.get('PATH_INFO') path_info = request.httprequest.environ.get('PATH_INFO')
if path_info.startswith('/longpolling/'): if path_info.startswith('/longpolling/'):
return super()._dispatch() return super()._dispatch(endpoint)
parts = ['http', ] parts = ['http', ]
if path_info.startswith('/web/dataset/call_button'): if path_info.startswith('/web/dataset/call_button'):
@@ -38,4 +38,4 @@ class IrHttp(models.AbstractModel):
] ]
with statsd.timer('.'.join(parts)): with statsd.timer('.'.join(parts)):
return super()._dispatch() return super()._dispatch(endpoint)
+21
View File
@@ -0,0 +1,21 @@
_MAP = {
'y': True,
'yes': True,
't': True,
'true': True,
'on': True,
'1': True,
'n': False,
'no': False,
'f': False,
'false': False,
'off': False,
'0': False
}
def strtobool(value):
try:
return _MAP[str(value).lower()]
except KeyError:
raise ValueError('"{}" is not a valid bool value'.format(value))
+21 -24
View File
@@ -4,9 +4,7 @@
import logging import logging
import os import os
from distutils.util import strtobool from .strtobool import strtobool
from odoo.tools.config import config
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -14,40 +12,39 @@ try:
from statsd import defaults from statsd import defaults
from statsd.client import StatsClient from statsd.client import StatsClient
except ImportError: except ImportError:
_logger.warning('statds must be installed') _logger.warning("statds must be installed")
defaults = None # noqa defaults = None # noqa
StatsClient = None # noqa StatsClient = None # noqa
def is_true(strval): def is_true(strval):
return bool(strtobool(strval or '0'.lower())) return bool(strtobool(strval or "0".lower()))
statsd_active = is_true(os.environ.get('ODOO_STATSD')) statsd_active = is_true(os.environ.get("ODOO_STATSD"))
statsd = None statsd = None
customer = None customer = None
environment = None environment = None
if statsd_active and statsd is None and StatsClient is not None: if statsd_active and statsd is None and StatsClient is not None:
if not os.environ.get('STATSD_CUSTOMER'): if not os.environ.get("STATSD_CUSTOMER"):
raise Exception( raise Exception("STATSD_CUSTOMER must contain the name of the customer")
'STATSD_CUSTOMER must contain the name of the customer' customer = os.environ.get("STATSD_CUSTOMER")
) if os.environ.get("STATSD_ENVIRONMENT"):
customer = os.environ.get('STATSD_CUSTOMER') environment = os.environ["STATSD_ENVIRONMENT"]
if os.environ.get('STATSD_ENVIRONMENT'): elif config.get("running_env"):
environment = os.environ['STATSD_ENVIRONMENT'] environment = config["running_env"]
elif config.get('running_env'):
environment = config['running_env']
else: else:
raise Exception( raise Exception(
'Either STATSD_ENVIRONMENT or configuration option running_env ' "Either STATSD_ENVIRONMENT or configuration option running_env "
'must contain the environment (prod, integration, ...)' "must contain the environment (prod, integration, ...)"
) )
host = os.getenv('STATSD_HOST', defaults.HOST) host = os.getenv("STATSD_HOST", defaults.HOST)
port = int(os.getenv('STATSD_PORT', defaults.PORT)) port = int(os.getenv("STATSD_PORT", defaults.PORT))
prefix = os.getenv('STATSD_PREFIX', defaults.PREFIX) prefix = os.getenv("STATSD_PREFIX", defaults.PREFIX)
maxudpsize = int(os.getenv('STATSD_MAXUDPSIZE', defaults.MAXUDPSIZE)) maxudpsize = int(os.getenv("STATSD_MAXUDPSIZE", defaults.MAXUDPSIZE))
ipv6 = bool(int(os.getenv('STATSD_IPV6', defaults.IPV6))) ipv6 = bool(int(os.getenv("STATSD_IPV6", defaults.IPV6)))
statsd = StatsClient(host=host, port=port, prefix='odoo', statsd = StatsClient(
maxudpsize=maxudpsize, ipv6=ipv6) host=host, port=port, prefix="odoo", maxudpsize=maxudpsize, ipv6=ipv6
)
+35 -27
View File
@@ -4,7 +4,7 @@
import logging import logging
import os import os
from distutils.util import strtobool from .strtobool import strtobool
import odoo import odoo
from odoo import http from odoo import http
@@ -23,46 +23,46 @@ except ImportError:
def is_true(strval): def is_true(strval):
return bool(strtobool(strval or '0'.lower())) return bool(strtobool(strval or "0".lower()))
sentinel_host = os.environ.get('ODOO_SESSION_REDIS_SENTINEL_HOST') sentinel_host = os.environ.get("ODOO_SESSION_REDIS_SENTINEL_HOST")
sentinel_master_name = os.environ.get( sentinel_master_name = os.environ.get("ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME")
'ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME'
)
if sentinel_host and not sentinel_master_name: if sentinel_host and not sentinel_master_name:
raise Exception( raise Exception(
"ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME must be defined " "ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME must be defined "
"when using session_redis" "when using session_redis"
) )
sentinel_port = int(os.environ.get('ODOO_SESSION_REDIS_SENTINEL_PORT', 26379)) sentinel_port = int(os.environ.get("ODOO_SESSION_REDIS_SENTINEL_PORT", 26379))
host = os.environ.get('ODOO_SESSION_REDIS_HOST', 'localhost') host = os.environ.get("ODOO_SESSION_REDIS_HOST", "localhost")
port = int(os.environ.get('ODOO_SESSION_REDIS_PORT', 6379)) port = int(os.environ.get("ODOO_SESSION_REDIS_PORT", 6379))
prefix = os.environ.get('ODOO_SESSION_REDIS_PREFIX') prefix = os.environ.get("ODOO_SESSION_REDIS_PREFIX")
url = os.environ.get('ODOO_SESSION_REDIS_URL') url = os.environ.get("ODOO_SESSION_REDIS_URL")
password = os.environ.get('ODOO_SESSION_REDIS_PASSWORD') password = os.environ.get("ODOO_SESSION_REDIS_PASSWORD")
expiration = os.environ.get('ODOO_SESSION_REDIS_EXPIRATION') expiration = os.environ.get("ODOO_SESSION_REDIS_EXPIRATION")
anon_expiration = os.environ.get('ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS') anon_expiration = os.environ.get("ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS")
@lazy_property @lazy_property
def session_store(self): def session_store(self):
if sentinel_host: if sentinel_host:
sentinel = Sentinel([(sentinel_host, sentinel_port)], sentinel = Sentinel([(sentinel_host, sentinel_port)], password=password)
password=password)
redis_client = sentinel.master_for(sentinel_master_name) redis_client = sentinel.master_for(sentinel_master_name)
elif url: elif url:
redis_client = redis.from_url(url) redis_client = redis.from_url(url)
else: else:
redis_client = redis.Redis(host=host, port=port, password=password) redis_client = redis.Redis(host=host, port=port, password=password)
return RedisSessionStore(redis=redis_client, prefix=prefix, return RedisSessionStore(
expiration=expiration, redis=redis_client,
anon_expiration=anon_expiration, prefix=prefix,
session_class=http.OpenERPSession) expiration=expiration,
anon_expiration=anon_expiration,
session_class=http.OpenERPSession,
)
def session_gc(session_store): def session_gc(session_store):
""" Do not garbage collect the sessions """Do not garbage collect the sessions
Redis keys are automatically cleaned at the end of their Redis keys are automatically cleaned at the end of their
expiration. expiration.
@@ -79,14 +79,22 @@ def purge_fs_sessions(path):
pass pass
if is_true(os.environ.get('ODOO_SESSION_REDIS')): if is_true(os.environ.get("ODOO_SESSION_REDIS")):
if sentinel_host: if sentinel_host:
_logger.debug("HTTP sessions stored in Redis with prefix '%s'. " _logger.debug(
"Using Sentinel on %s:%s", "HTTP sessions stored in Redis with prefix '%s'. "
prefix or '', sentinel_host, sentinel_port) "Using Sentinel on %s:%s",
prefix or "",
sentinel_host,
sentinel_port,
)
else: else:
_logger.debug("HTTP sessions stored in Redis with prefix '%s' on " _logger.debug(
"%s:%s", prefix or '', host, port) "HTTP sessions stored in Redis with prefix '%s' on " "%s:%s",
prefix or "",
host,
port,
)
http.Root.session_store = session_store http.Root.session_store = session_store
http.session_gc = session_gc http.session_gc = session_gc
+21
View File
@@ -0,0 +1,21 @@
_MAP = {
'y': True,
'yes': True,
't': True,
'true': True,
'on': True,
'1': True,
'n': False,
'no': False,
'f': False,
'false': False,
'off': False,
'0': False
}
def strtobool(value):
try:
return _MAP[str(value).lower()]
except KeyError:
raise ValueError('"{}" is not a valid bool value'.format(value))