Coerce booleans to integer values in paginate_query

(Grabbed from oslo.db's I4b90f1873 which fixes the same
issue.)

This fixes a failed request when a volume listing is requested
with sorting by bootable:asc and with a marker id specified.

It looks like we are due to replace our paginate_query() method
with the one from oslo.db, as noted in the comments above
the method.

Closes-Bug: #2027532
Change-Id: Idf75e9cc8be6d9f0be320f8109e45b9b9f93dacf
This commit is contained in:
Eric Harney 2023-07-12 16:04:59 +00:00
parent 26847ddeed
commit 6d60a6b1ae
3 changed files with 32 additions and 4 deletions

View File

@ -35,7 +35,8 @@ _TYPE_SCHEMA = {
'datetime': datetime.datetime(1900, 1, 1),
'big_integer': 0,
'integer': 0,
'string': ''
'string': '',
'boolean': False,
}
@ -155,6 +156,8 @@ def paginate_query(query, model, limit, sort_keys, marker=None,
*[(model_attr.isnot(None), model_attr)],
else_=default,
)
if isinstance(model_attr.type, sqlalchemy.Boolean):
marker_values[i] = int(marker_values[i])
if sort_dirs[i] == 'desc':
crit_attrs.append((attr < marker_values[i]))
elif sort_dirs[i] == 'asc':

View File

@ -192,14 +192,17 @@ class VolumeApiTest(test.TestCase):
# Create volumes in project 1
db.volume_create(self.ctxt, {'display_name': 'test1',
'project_id': fake.PROJECT_ID,
'volume_type_id': fake.VOLUME_TYPE_ID})
'volume_type_id': fake.VOLUME_TYPE_ID,
'id': fake.VOLUME_ID})
db.volume_create(self.ctxt, {'display_name': 'test2',
'project_id': fake.PROJECT_ID,
'volume_type_id': fake.VOLUME_TYPE_ID})
'volume_type_id': fake.VOLUME_TYPE_ID,
'id': fake.VOLUME2_ID})
# Create volume in project 2
db.volume_create(self.ctxt, {'display_name': 'test3',
'project_id': fake.PROJECT2_ID,
'volume_type_id': fake.VOLUME_TYPE_ID})
'volume_type_id': fake.VOLUME_TYPE_ID,
'id': fake.VOLUME3_ID})
def test_volume_index_filter_by_glance_metadata(self):
vols = self._create_volume_with_glance_metadata()
@ -332,6 +335,22 @@ class VolumeApiTest(test.TestCase):
self.assertEqual(1, len(res_dict['volumes']))
self.assertEqual(metadata, res_dict['volumes'][0]['metadata'])
def test_list_volume_with_filter_and_paginate(self):
self._create_multiple_volumes_with_different_project()
test_utils.create_volume(self.ctxt)
self.mock_object(ViewBuilder, '_get_volume_type',
v2_fakes.fake_volume_type_name_get)
req = fakes.HTTPRequest.blank(
"/v3/volumes/detail?all_tenants=1"
"&sort=bootable:asc&with_count=True&limit=5"
"&marker=" + fake.VOLUME_ID)
ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False)
req.environ['cinder.context'] = ctxt
res_dict = self.controller._get_volumes(req, is_detail=True)
self.assertEqual(2, len(res_dict['volumes']))
def test_volume_index_filter_by_group_id_in_unsupport_version(self):
self._create_volume_with_group()
req = fakes.HTTPRequest.blank(("/v3/volumes?group_id=%s") %

View File

@ -0,0 +1,6 @@
---
fixes:
- |
`Bug #2027532 <https://bugs.launchpad.net/cinder/+bug/2027532>`_:
Fixed Cinder API HTTP 500 when issuing a volume list and sorting by a
boolean field (i.e. "bootable").