summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ripton <dripton@redhat.com>2013-05-08 14:20:29 -0400
committerDavid Ripton <dripton@redhat.com>2013-05-08 22:18:39 -0400
commit188a94c898bcf07f9fe42ef2f3b5ee4aa8859b49 (patch)
tree9bc5c7cb5621017d2f87fc37757f14bc4167307b
parentbaa4109ed6b846661f4d6c0bab39754b7e574a8e (diff)
downloadnova-188a94c898bcf07f9fe42ef2f3b5ee4aa8859b49.tar.gz
nova-188a94c898bcf07f9fe42ef2f3b5ee4aa8859b49.tar.xz
nova-188a94c898bcf07f9fe42ef2f3b5ee4aa8859b49.zip
Remove invalid block_device_mapping volume_size of ''
Fixes bug #1171190 Parsing block_device_mapping from strings sometimes results in volume_size being set to '' or u''. This causes a problem when inserting into PostgreSQL, which insists that integer columns actually contain integers. Remove invalid device_size before inserting or updating block_device_mapping database records. Change-Id: If9132a96604b5b0e3a6df96624e565e016d5c9a3
-rw-r--r--nova/db/sqlalchemy/api.py13
-rw-r--r--nova/tests/test_db_api.py17
2 files changed, 30 insertions, 0 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 9213b36b3..52d25293a 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -3018,8 +3018,19 @@ def _block_device_mapping_get_query(context, session=None):
return model_query(context, models.BlockDeviceMapping, session=session)
+def _scrub_empty_str_values(dct, keys_to_scrub):
+ """
+ Remove any keys found in sequence keys_to_scrub from the dict
+ if they have the value ''.
+ """
+ for key in keys_to_scrub:
+ if key in dct and dct[key] == '':
+ del dct[key]
+
+
@require_context
def block_device_mapping_create(context, values):
+ _scrub_empty_str_values(values, ['volume_size'])
bdm_ref = models.BlockDeviceMapping()
bdm_ref.update(values)
bdm_ref.save()
@@ -3027,6 +3038,7 @@ def block_device_mapping_create(context, values):
@require_context
def block_device_mapping_update(context, bdm_id, values):
+ _scrub_empty_str_values(values, ['volume_size'])
_block_device_mapping_get_query(context).\
filter_by(id=bdm_id).\
update(values)
@@ -3034,6 +3046,7 @@ def block_device_mapping_update(context, bdm_id, values):
@require_context
def block_device_mapping_update_or_create(context, values):
+ _scrub_empty_str_values(values, ['volume_size'])
session = get_session()
with session.begin():
result = _block_device_mapping_get_query(context, session=session).\
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index e298b7e03..a3317b218 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -19,6 +19,7 @@
"""Unit tests for the DB API."""
+import copy
import datetime
import types
import uuid as stdlib_uuid
@@ -3344,6 +3345,22 @@ class BlockDeviceMappingTestCase(test.TestCase):
if bdm['device_name'] == values['device_name']:
return bdm
+ def test_scrub_empty_str_values_no_effect(self):
+ values = {'volume_size': 5}
+ expected = copy.copy(values)
+ sqlalchemy_api._scrub_empty_str_values(values, ['volume_size'])
+ self.assertEqual(values, expected)
+
+ def test_scrub_empty_str_values_empty_string(self):
+ values = {'volume_size': ''}
+ sqlalchemy_api._scrub_empty_str_values(values, ['volume_size'])
+ self.assertEqual(values, {})
+
+ def test_scrub_empty_str_values_empty_unicode(self):
+ values = {'volume_size': u''}
+ sqlalchemy_api._scrub_empty_str_values(values, ['volume_size'])
+ self.assertEqual(values, {})
+
def test_block_device_mapping_create(self):
bdm = self._create_bdm({})
self.assertFalse(bdm is None)