From c007350c500d31a38f709f8aae719dce067ebc65 Mon Sep 17 00:00:00 2001 From: Vipin Balachandran Date: Thu, 9 Oct 2014 19:35:46 +0530 Subject: [PATCH] Truncate fail_reason to column length During create_backup failure handling, backup_update fails with DataError ("Data too long for column") if the fail_reason is greater than 255 characters. As a result, backup status is stuck in 'creating' state. This patch avoids the problem by truncating fail_reason to 255 characters before update. Closes-Bug: #1376199 Change-Id: If0d616b81d3869f7ea110caab8cf4140cf5c5c9e (cherry picked from commit 82716b4ac836024b968c76db75be8a92ede0e226) --- cinder/db/sqlalchemy/models.py | 6 +++++- cinder/tests/test_db_api.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cinder/db/sqlalchemy/models.py b/cinder/db/sqlalchemy/models.py index e5b26c8ca87..6ae1505bcd9 100644 --- a/cinder/db/sqlalchemy/models.py +++ b/cinder/db/sqlalchemy/models.py @@ -24,7 +24,7 @@ from oslo.db.sqlalchemy import models from sqlalchemy import Column, Integer, String, Text, schema from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ForeignKey, DateTime, Boolean -from sqlalchemy.orm import relationship, backref +from sqlalchemy.orm import relationship, backref, validates from cinder.openstack.common import timeutils @@ -478,6 +478,10 @@ class Backup(BASE, CinderBase): size = Column(Integer) object_count = Column(Integer) + @validates('fail_reason') + def validate_fail_reason(self, key, fail_reason): + return fail_reason and fail_reason[:255] or '' + class Encryption(BASE, CinderBase): """Represents encryption requirement for a volume type. diff --git a/cinder/tests/test_db_api.py b/cinder/tests/test_db_api.py index 00ee51b414b..899a4bc1358 100644 --- a/cinder/tests/test_db_api.py +++ b/cinder/tests/test_db_api.py @@ -1237,6 +1237,19 @@ class DBAPIBackupTestCase(BaseTest): self._assertEqualObjects(updated_values, updated_backup, self._ignored_keys) + def test_backup_update_with_fail_reason_truncation(self): + updated_values = self._get_values(one=True) + fail_reason = '0' * 512 + updated_values['fail_reason'] = fail_reason + + update_id = self.created[1]['id'] + updated_backup = db.backup_update(self.ctxt, update_id, + updated_values) + + updated_values['fail_reason'] = fail_reason[:255] + self._assertEqualObjects(updated_values, updated_backup, + self._ignored_keys) + def test_backup_destroy(self): for backup in self.created: db.backup_destroy(self.ctxt, backup['id'])