From 9744849712531f0385ca5b99cc1b9294e6d14b54 Mon Sep 17 00:00:00 2001 From: Ivan Kolodyazhny Date: Thu, 17 Sep 2020 19:14:22 +0300 Subject: [PATCH] Rollback volume status if backup service is unavailable We should not keep volume in 'backing-up' state if backup creation process failed. It should be reverted to the previous state. Change-Id: I33d4569df439fa59dec847f8dbc9f516a4839070 Closes-Bug: #1896087 --- cinder/scheduler/manager.py | 6 +++++- cinder/tests/unit/scheduler/test_scheduler.py | 12 ++++++++++-- ...6087-rollback-volume-status-bd04951f929bb88d.yaml | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/bug-1896087-rollback-volume-status-bd04951f929bb88d.yaml diff --git a/cinder/scheduler/manager.py b/cinder/scheduler/manager.py index 4a16696e86e..0832f387a51 100644 --- a/cinder/scheduler/manager.py +++ b/cinder/scheduler/manager.py @@ -629,13 +629,17 @@ class SchedulerManager(manager.CleanableManager, manager.Manager): return requested, not_requested def create_backup(self, context, backup): - volume = self.db.volume_get(context, backup.volume_id) + volume_id = backup.volume_id + volume = self.db.volume_get(context, volume_id) try: host = self.driver.get_backup_host(volume) backup.host = host backup.save() self.backup_api.create_backup(context, backup) except exception.ServiceNotFound: + self.db.volume_update(context, volume_id, + {'status': volume['previous_status'], + 'previous_status': volume['status']}) msg = "Service not found for creating backup." LOG.error(msg) vol_utils.update_backup_error(backup, msg) diff --git a/cinder/tests/unit/scheduler/test_scheduler.py b/cinder/tests/unit/scheduler/test_scheduler.py index 53b65662bc8..4036e7d59ab 100644 --- a/cinder/tests/unit/scheduler/test_scheduler.py +++ b/cinder/tests/unit/scheduler/test_scheduler.py @@ -605,9 +605,12 @@ class SchedulerManagerTestCase(test.TestCase): @mock.patch('cinder.volume.volume_utils.update_backup_error') @mock.patch('cinder.scheduler.driver.Scheduler.get_backup_host') @mock.patch('cinder.db.volume_get') - def test_create_backup_no_service(self, mock_volume_get, mock_host, - mock_error): + @mock.patch('cinder.db.volume_update') + def test_create_backup_no_service(self, mock_volume_update, + mock_volume_get, mock_host, mock_error): volume = fake_volume.fake_db_volume() + volume['status'] = 'backing-up' + volume['previous_status'] = 'available' mock_volume_get.return_value = volume mock_host.side_effect = exception.ServiceNotFound( service_id='cinder-volume') @@ -617,6 +620,11 @@ class SchedulerManagerTestCase(test.TestCase): mock_host.assert_called_once_with(volume) mock_volume_get.assert_called_once_with(self.context, backup.volume_id) + mock_volume_update.assert_called_once_with( + self.context, + backup.volume_id, + {'status': 'available', + 'previous_status': 'backing-up'}) mock_error.assert_called_once_with( backup, 'Service not found for creating backup.') diff --git a/releasenotes/notes/bug-1896087-rollback-volume-status-bd04951f929bb88d.yaml b/releasenotes/notes/bug-1896087-rollback-volume-status-bd04951f929bb88d.yaml new file mode 100644 index 00000000000..41700caf2cd --- /dev/null +++ b/releasenotes/notes/bug-1896087-rollback-volume-status-bd04951f929bb88d.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + `Bug #1896087 `_: + Volume status will be rolled back to the previous state if backup creation + fails when backup service is not available +