Fix json to_primitive when using IO OBjects
Currently, using Cinder's backup service with RBD the
backup-create operation gets stuck when logging
('use_json=True' must be set in the config file).
The oslo.log JSONFormatter gets stuck when passing an
RBDVolumeIOWrapper from os-brick. This happens via os-brick's
utils.trace() method which passes a connector containing
{'path': RBDVolumeIOWrapper}.
The oslo.log JSONFormatter format() method calls
oslo_serialization's jsonutils.to_primitive and passes in
this RBDVolumeIOWrapper object.
Therefore the to_primitive method eventually calls
RBDVolumeIOWrapper.read(). In order to fix this the current
path avoids mapping io.IOBase objects and fallback the wrapper
RBD volume object.
Co-authored-by: Eric Harney <eharney@redhat.com>
Closes-Bug: #1908607
Change-Id: I3c416e855cb5f0dc32d14b2749ba92aba8964574
(cherry picked from commit 02037330d8)
This commit is contained in:
committed by
Hervé Beraud
parent
57fd9dd9e0
commit
fcd737e2b1
@@ -33,6 +33,7 @@ import codecs
|
||||
import datetime
|
||||
import functools
|
||||
import inspect
|
||||
import io
|
||||
import itertools
|
||||
import json
|
||||
import uuid
|
||||
@@ -161,7 +162,7 @@ def to_primitive(value, convert_instances=False, convert_datetime=True,
|
||||
# Python 3 does not have iteritems
|
||||
elif hasattr(value, 'items'):
|
||||
return recursive(dict(value.items()), level=level + 1)
|
||||
elif hasattr(value, '__iter__'):
|
||||
elif hasattr(value, '__iter__') and not isinstance(value, io.IOBase):
|
||||
return list(map(recursive, value))
|
||||
elif convert_instances and hasattr(value, '__dict__'):
|
||||
# Likely an instance of something. Watch for cycles.
|
||||
|
||||
@@ -401,6 +401,16 @@ class ToPrimitiveTestCase(test_base.BaseTestCase):
|
||||
ret = jsonutils.to_primitive(obj, fallback=lambda _: 'fallback')
|
||||
self.assertEqual('fallback', ret)
|
||||
|
||||
def test_fallback_typeerror_IO_object(self):
|
||||
# IO Objects are not callable, cause a TypeError in to_primitive()
|
||||
obj = io.IOBase
|
||||
|
||||
ret = jsonutils.to_primitive(obj)
|
||||
self.assertEqual(str(obj), ret)
|
||||
|
||||
ret = jsonutils.to_primitive(obj, fallback=lambda _: 'fallback')
|
||||
self.assertEqual('fallback', ret)
|
||||
|
||||
def test_exception(self):
|
||||
self.assertIn(jsonutils.to_primitive(ValueError("an exception")),
|
||||
["ValueError('an exception',)",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
`Bug #1908607 <https://bugs.launchpad.net/cinder/+bug/1908607>`_: Fix
|
||||
json to_primitive when using IO OBjects.
|
||||
Reference in New Issue
Block a user