[FIX] incorrect serialisation of log_handler

Saving log_handler to the config file is not currently special-cased,
the value is thus dumped as the repr() of the list, but not deserialized
with literal_eval. This means -s breaks log_handler and the
configuration file example is incorrect (it looks like a list).

Repeated -s further break the log_handler by interpreting the original
value as a string, putting it into a list, then reserialising that with
repr(), injecting a bunch of escaping backslash. The config file is soon
filled with backslashes and doubles in size with each new -s.

Furthermore for some reason the whole thing breaks --log-handler (and
aliases) entirely, once the wrong log_handler has been saved none of
them works anymore.

Fixes #4552
Closes #4157
This commit is contained in:
Xavier Morel 2014-12-11 09:18:05 +01:00
parent e9f0d79f85
commit 426bcf427c
1 changed files with 19 additions and 19 deletions

View File

@ -49,7 +49,9 @@ class MyOption (optparse.Option, object):
super(MyOption, self).__init__(*opts, **attrs)
def check_ssl():
DEFAULT_LOG_HANDLER = ':INFO'
def _check_ssl():
try:
from OpenSSL import SSL
import socket
@ -58,8 +60,6 @@ def check_ssl():
except:
return False
DEFAULT_LOG_HANDLER = ':INFO'
def _get_default_datadir():
home = os.path.expanduser('~')
if os.path.exists(home):
@ -72,6 +72,20 @@ def _get_default_datadir():
# No "version" kwarg as session and filestore paths are shared against series
return func(appname=release.product_name, appauthor=release.author)
def _deduplicate_loggers(loggers):
""" Avoid saving multiple logging levels for the same loggers to a save
file, that just takes space and the list can potentially grow unbounded
if for some odd reason people use :option`odoo.py --save`` all the time.
"""
# dict(iterable) -> the last item of iterable for any given key wins,
# which is what we want and expect. Output order should not matter as
# there are no duplicates within the output sequence
return (
'{}:{}'.format(logger, level)
for logger, level in dict(it.split(':') for it in loggers).iteritems()
)
class configmanager(object):
def __init__(self, fname=None):
"""Constructor.
@ -101,7 +115,7 @@ class configmanager(object):
self.misc = {}
self.config_file = fname
self.has_ssl = check_ssl()
self.has_ssl = _check_ssl()
self._LOGLEVELS = dict([
(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x))
@ -623,7 +637,7 @@ class configmanager(object):
if opt in ('log_level',):
p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt]))
elif opt == 'log_handler':
p.set('options', opt, ','.join(deduplicate_loggers(self.options[opt])))
p.set('options', opt, ','.join(_deduplicate_loggers(self.options[opt])))
else:
p.set('options', opt, self.options[opt])
@ -686,18 +700,4 @@ class configmanager(object):
config = configmanager()
def deduplicate_loggers(loggers):
""" Avoid saving multiple logging levels for the same loggers to a save
file, that just takes space and the list can potentially grow unbounded
if for some odd reason people use :option`odoo.py --save`` all the time.
"""
# dict(iterable) -> the last item of iterable for any given key wins,
# which is what we want and expect. Output order should not matter as
# there are no duplicates within the output sequence
return (
'{}:{}'.format(logger, level)
for logger, level in dict(it.split(':') for it in loggers).iteritems()
)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: