]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add restore_volume_id in backup
authorLisaLi <xiaoyan.li@intel.com>
Thu, 24 Dec 2015 03:16:26 +0000 (11:16 +0800)
committerLisaLi <xiaoyan.li@intel.com>
Mon, 15 Feb 2016 02:00:31 +0000 (10:00 +0800)
This patch is to add restore_volume_id in backup object.
When restoring a volume from a backup, it saves the
volume in backup object.

Currently volume service and backup service are in same host.
When backup service starts, it does cleanup tasks on both
backups and volumes on current host.

But with bp scalable-backup-service, backup service and
volume services can run on different hosts. When doing cleanup
tasks, we need to find out backing-up and restoring volumes
related to the backups on current host. Backing-up volumes can
be found with field backup.volume_id. Restoring volumes are found
by new field backup.restore_volume_id.

Change-Id: I757be7a5e47fc366c181400587b5a61fe3709a0b
Partial-Implements: bp scalable-backup-service
Co-Authored-By: Tom Barron <tpb@dyncloud.net>
cinder/backup/api.py
cinder/db/sqlalchemy/migrate_repo/versions/064_add_restore_volume_id_to_backups.py [new file with mode: 0644]
cinder/db/sqlalchemy/models.py
cinder/objects/backup.py
cinder/objects/base.py
cinder/tests/unit/objects/test_backup.py
cinder/tests/unit/objects/test_objects.py
cinder/tests/unit/test_backup.py
cinder/tests/unit/test_db_api.py
cinder/tests/unit/test_migrations.py

index c3900422209370b661cee59f24110123c65554b3..3be3f69606b5ddfdceba0c4bd6b96b6a7fb01041 100644 (file)
@@ -365,8 +365,9 @@ class API(base.Base):
         # Setting the status here rather than setting at start and unrolling
         # for each error condition, it should be a very small window
         backup.status = fields.BackupStatus.RESTORING
+        backup.restore_volume_id = volume.id
         backup.save()
-        volume_host = volume_utils.extract_host(volume['host'], 'host')
+        volume_host = volume_utils.extract_host(volume.host, 'host')
         self.db.volume_update(context, volume_id, {'status':
                                                    'restoring-backup'})
 
diff --git a/cinder/db/sqlalchemy/migrate_repo/versions/064_add_restore_volume_id_to_backups.py b/cinder/db/sqlalchemy/migrate_repo/versions/064_add_restore_volume_id_to_backups.py
new file mode 100644 (file)
index 0000000..370a535
--- /dev/null
@@ -0,0 +1,26 @@
+# Copyright (c) 2015 Intel Corporation\r
+# All Rights Reserved.\r
+#\r
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+#    not use this file except in compliance with the License. You may obtain\r
+#    a copy of the License at\r
+#\r
+#         http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#    Unless required by applicable law or agreed to in writing, software\r
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+#    License for the specific language governing permissions and limitations\r
+#    under the License.\r
+\r
+from sqlalchemy import Column, MetaData, String, Table\r
+\r
+\r
+def upgrade(migrate_engine):\r
+    meta = MetaData()\r
+    meta.bind = migrate_engine\r
+\r
+    backups = Table('backups', meta, autoload=True)\r
+    restore_volume_id = Column('restore_volume_id', String(length=36))\r
+\r
+    backups.create_column(restore_volume_id)\r
index 6e42bf8f5b3edeb2f33d01df054ca0382652d925..aa182e020d6f65a80f4d16d704eeacdac4d745d6 100644 (file)
@@ -527,6 +527,7 @@ class Backup(BASE, CinderBase):
     num_dependent_backups = Column(Integer)
     snapshot_id = Column(String(36))
     data_timestamp = Column(DateTime)
+    restore_volume_id = Column(String(36))
 
     @validates('fail_reason')
     def validate_fail_reason(self, key, fail_reason):
index 6193d118aea5d6011ee7ad1364f08ba6e3fea394..826388280b1add3bdfb18eeded5be3a050ef4986 100644 (file)
@@ -38,7 +38,8 @@ class Backup(base.CinderPersistentObject, base.CinderObject,
     #              is_incremental and has_dependent_backups.
     # Version 1.2: Add new field snapshot_id and data_timestamp.
     # Version 1.3: Changed 'status' field to use BackupStatusField
-    VERSION = '1.3'
+    # Version 1.4: Add restore_volume_id
+    VERSION = '1.4'
 
     fields = {
         'id': fields.UUIDField(),
@@ -70,6 +71,7 @@ class Backup(base.CinderPersistentObject, base.CinderObject,
         'num_dependent_backups': fields.IntegerField(),
         'snapshot_id': fields.StringField(nullable=True),
         'data_timestamp': fields.DateTimeField(nullable=True),
+        'restore_volume_id': fields.StringField(nullable=True),
     }
 
     obj_extra_fields = ['name', 'is_incremental', 'has_dependent_backups']
index 24f775a1d5631554bd714ebdf83e043d1d176aba..90174fb6dee5dfd4e5bfbe921d718ec4edf3d3b1 100644 (file)
@@ -97,6 +97,7 @@ OBJ_VERSIONS.add('1.0', {'Backup': '1.3', 'BackupImport': '1.3',
                          'ConsistencyGroupList': '1.1', 'Service': '1.1',
                          'Volume': '1.3', 'VolumeTypeList': '1.1'})
 OBJ_VERSIONS.add('1.1', {'Service': '1.2', 'ServiceList': '1.1'})
+OBJ_VERSIONS.add('1.2', {'Backup': '1.4', 'BackupImport': '1.4'})
 
 
 class CinderObjectRegistry(base.VersionedObjectRegistry):
index 4b9a48bc7d519ea426379d23f10e0fe7f01df427..808f553fea301db4be0867e72b7e5ad3728d7991 100644 (file)
@@ -37,6 +37,7 @@ fake_backup = {
     'temp_snapshot_id': None,
     'snapshot_id': None,
     'data_timestamp': None,
+    'restore_volume_id': None,
 }
 
 
@@ -94,6 +95,11 @@ class TestBackup(test_objects.BaseObjectsTestCase):
                                 snapshot_id='2')
         self.assertEqual('2', backup.snapshot_id)
 
+    def test_obj_field_restore_volume_id(self):
+        backup = objects.Backup(context=self.context,
+                                restore_volume_id='2')
+        self.assertEqual('2', backup.restore_volume_id)
+
     def test_import_record(self):
         utils.replace_obj_loader(self, objects.Backup)
         backup = objects.Backup(context=self.context, id=1, parent_id=None,
index a5b89e0106ca82e342a850f99d7fe553c48d1f69..15ddd9e55ccbf20e8dad66df3fc10720d764f962 100644 (file)
@@ -21,8 +21,8 @@ from cinder import test
 # NOTE: The hashes in this list should only be changed if they come with a
 # corresponding version bump in the affected objects.
 object_data = {
-    'Backup': '1.3-2e63492190bbbc85c0e5bea328cd38f7',
-    'BackupImport': '1.3-2e63492190bbbc85c0e5bea328cd38f7',
+    'Backup': '1.4-1002c50b6e31938583c95c4c4889286c',
+    'BackupImport': '1.4-1002c50b6e31938583c95c4c4889286c',
     'BackupList': '1.0-24591dabe26d920ce0756fe64cd5f3aa',
     'CGSnapshot': '1.0-190da2a2aa9457edc771d888f7d225c4',
     'CGSnapshotList': '1.0-e8c3f4078cd0ee23487b34d173eec776',
index 707fc59bed0368900f5d3357fd5f6e0f7ff5b84a..d6661dfb480d5ceb8e849be3dab29d3a631d4e53 100644 (file)
@@ -1283,3 +1283,15 @@ class BackupAPITestCase(BaseBackupTest):
                           description="test backup description",
                           volume_id=volume_id,
                           container='volumebackups')
+
+    @mock.patch('cinder.backup.rpcapi.BackupAPI.restore_backup')
+    def test_restore_volume(self,
+                            mock_rpcapi_restore):
+        ctxt = context.RequestContext('fake', 'fake')
+        volume_id = self._create_volume_db_entry(status='available',
+                                                 size=1)
+        backup = self._create_backup_db_entry(size=1,
+                                              status='available')
+        self.api.restore(ctxt, backup.id, volume_id)
+        backup = objects.Backup.get_by_id(ctxt, backup.id)
+        self.assertEqual(volume_id, backup.restore_volume_id)
index ed321537856ac8f753d7c07163c73b0c392f3cf0..1a3e92bbabac6fafdb0663ca1cb8ec44b5fbd3ba 100644 (file)
@@ -1903,7 +1903,8 @@ class DBAPIBackupTestCase(BaseTest):
             'temp_volume_id': 'temp_volume_id',
             'temp_snapshot_id': 'temp_snapshot_id',
             'num_dependent_backups': 0,
-            'snapshot_id': 'snapshot_id', }
+            'snapshot_id': 'snapshot_id',
+            'restore_volume_id': 'restore_volume_id'}
         if one:
             return base_values
 
index ac692a00bd1c194b7c217eb97d6362006e00eefc..253c45f17dcdc14ffea69a3192083f96e602b778 100644 (file)
@@ -725,6 +725,11 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
         self.assertIsInstance(volume_type_projects.c.id.type,
                               self.INTEGER_TYPE)
 
+    def _check_064(self, engine, data):
+        backups = db_utils.get_table(engine, 'backups')
+        self.assertIsInstance(backups.c.restore_volume_id.type,
+                              self.VARCHAR_TYPE)
+
     def test_walk_versions(self):
         self.walk_versions(False, False)