def test_volume_backup_create_get_detailed_list_restore_delete(self): # Create backup volume = self.create_volume() self.addCleanup(self.volumes_client.delete_volume, volume['id']) backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') create_backup = self.backups_client.create_backup backup = create_backup(volume_id=volume['id'], name=backup_name)['backup'] self.addCleanup(self.backups_client.delete_backup, backup['id']) self.assertEqual(backup_name, backup['name']) waiters.wait_for_volume_status(self.volumes_client, volume['id'], 'available') waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') # Get a given backup backup = self.backups_client.show_backup(backup['id'])['backup'] self.assertEqual(backup_name, backup['name']) # Get all backups with detail backups = self.backups_client.list_backups(detail=True)['backups'] self.assertIn((backup['name'], backup['id']), [(m['name'], m['id']) for m in backups]) # Restore backup restore = self.backups_client.restore_backup(backup['id'])['restore'] # Delete backup self.addCleanup(self.volumes_client.delete_volume, restore['volume_id']) self.assertEqual(backup['id'], restore['backup_id']) waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') waiters.wait_for_volume_status(self.volumes_client, restore['volume_id'], 'available')
def test_backup_create_attached_volume(self): """Test backup create using force flag. Cinder allows to create a volume backup, whether the volume status is "available" or "in-use". """ # Create a server volume = self.create_volume() self.addCleanup(self.volumes_client.delete_volume, volume['id']) server = self.create_server(wait_until='ACTIVE') # Attach volume to instance self.servers_client.attach_volume(server['id'], volumeId=volume['id']) waiters.wait_for_volume_status(self.volumes_client, volume['id'], 'in-use') self.addCleanup(waiters.wait_for_volume_status, self.volumes_client, volume['id'], 'available') self.addCleanup(self.servers_client.detach_volume, server['id'], volume['id']) # Create backup using force flag backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') backup = self.backups_client.create_backup(volume_id=volume['id'], name=backup_name, force=True)['backup'] self.addCleanup(self.backups_client.delete_backup, backup['id']) waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') self.assertEqual(backup_name, backup['name'])
def test_backup_create_attached_volume(self): """Test backup create using force flag. Cinder allows to create a volume backup, whether the volume status is "available" or "in-use". """ # Create a server volume = self.create_volume() self.addCleanup(self.volumes_client.delete_volume, volume['id']) server = self.create_server(wait_until='ACTIVE') # Attach volume to instance self.servers_client.attach_volume(server['id'], volumeId=volume['id']) waiters.wait_for_volume_status(self.volumes_client, volume['id'], 'in-use') self.addCleanup(waiters.wait_for_volume_status, self.volumes_client, volume['id'], 'available') self.addCleanup(self.servers_client.detach_volume, server['id'], volume['id']) # Create backup using force flag backup_name = data_utils.rand_name( self.__class__.__name__ + '-Backup') backup = self.backups_client.create_backup( volume_id=volume['id'], name=backup_name, force=True)['backup'] self.addCleanup(self.backups_client.delete_backup, backup['id']) waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') self.assertEqual(backup_name, backup['name'])
def create_backup(self, volume_id): backup = self.backups_client.create_backup( volume_id=volume_id, force=True)['backup'] waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') return backup['id']
def create_backup(self, volume_id, backup_client=None, **kwargs): """Wrapper utility that returns a test backup.""" if backup_client is None: backup_client = self.backups_client backup = backup_client.create_backup(volume_id=volume_id, **kwargs)['backup'] self.addCleanup(backup_client.delete_backup, backup['id']) waiters.wait_for_backup_status(backup_client, backup['id'], 'available') return backup
def create_backup(self, volume_id, backup_client=None, **kwargs): """Wrapper utility that returns a test backup.""" if backup_client is None: backup_client = self.backups_client backup = backup_client.create_backup( volume_id=volume_id, **kwargs)['backup'] self.addCleanup(backup_client.delete_backup, backup['id']) waiters.wait_for_backup_status(backup_client, backup['id'], 'available') return backup
def test_volume_backup_reset_status(self): # Create a volume volume = self.create_volume() # Create a backup backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') backup = self.create_backup(backup_client=self.admin_backups_client, volume_id=volume['id'], name=backup_name) self.assertEqual(backup_name, backup['name']) # Reset backup status to error self.admin_backups_client.reset_backup_status(backup_id=backup['id'], status="error") waiters.wait_for_backup_status(self.admin_backups_client, backup['id'], 'error')
def restore_backup(self, backup_id): # Restore a backup restored_volume = self.backups_client.restore_backup( backup_id)['restore'] # Delete backup self.addCleanup(self.volumes_client.delete_volume, restored_volume['volume_id']) self.assertEqual(backup_id, restored_volume['backup_id']) waiters.wait_for_backup_status(self.backups_client, backup_id, 'available') waiters.wait_for_volume_status(self.volumes_client, restored_volume['volume_id'], 'available') return restored_volume
def restore_backup(self, backup_id): # Restore a backup restored_volume = self.backups_client.restore_backup( backup_id)['restore'] # Delete backup self.addCleanup(self.volumes_client.delete_volume, restored_volume['volume_id']) self.assertEqual(backup_id, restored_volume['backup_id']) waiters.wait_for_backup_status(self.backups_client, backup_id, 'available') waiters.wait_for_volume_status(self.volumes_client, restored_volume['volume_id'], 'available') return restored_volume
def test_volume_backup_reset_status(self): # Create a backup backup_name = data_utils.rand_name( self.__class__.__name__ + '-Backup') backup = self.admin_backups_client.create_backup( volume_id=self.volume['id'], name=backup_name)['backup'] self.addCleanup(self.admin_backups_client.delete_backup, backup['id']) self.assertEqual(backup_name, backup['name']) waiters.wait_for_backup_status(self.admin_backups_client, backup['id'], 'available') # Reset backup status to error self.admin_backups_client.reset_backup_status(backup_id=backup['id'], status="error") waiters.wait_for_backup_status(self.admin_backups_client, backup['id'], 'error')
def test_backup_create_and_restore_to_an_existing_volume(self): """Test backup create and restore to an existing volume.""" # Create volume src_vol = self.create_volume() self.addCleanup(self.volumes_client.delete_volume, src_vol['id']) # Create backup backup = self.backups_client.create_backup( volume_id=src_vol['id'])['backup'] self.addCleanup(self.backups_client.delete_backup, backup['id']) waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') # Restore to existing volume restore = self.backups_client.restore_backup( backup_id=backup['id'], volume_id=src_vol['id'])['restore'] waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') waiters.wait_for_volume_status(self.volumes_client, src_vol['id'], 'available') self.assertEqual(src_vol['id'], restore['volume_id']) self.assertEqual(backup['id'], restore['backup_id'])
def test_volume_snapshot_backup(self): """Create backup from snapshot.""" volume = self.create_volume() # Create snapshot snapshot = self.create_snapshot(volume['id']) # Create backup backup = self.create_backup(volume_id=volume['id'], snapshot_id=snapshot['id']) # Get a given backup backup = self.backups_client.show_backup(backup['id'])['backup'] waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') self.assertEqual(volume['id'], backup['volume_id']) self.assertEqual(snapshot['id'], backup['snapshot_id']) self.snapshots_client.delete_snapshot(snapshot['id']) self.snapshots_client.wait_for_resource_deletion(snapshot['id']) self.volumes_client.delete_volume(volume['id']) self.volumes_client.wait_for_resource_deletion(volume['id'])
def test_volume_backup_create_get_detailed_list_restore_delete(self): # Create backup volume = self.create_volume() self.addCleanup(self.volumes_client.delete_volume, volume['id']) backup_name = data_utils.rand_name( self.__class__.__name__ + '-Backup') create_backup = self.backups_client.create_backup backup = create_backup(volume_id=volume['id'], name=backup_name)['backup'] self.addCleanup(self.backups_client.delete_backup, backup['id']) self.assertEqual(backup_name, backup['name']) waiters.wait_for_volume_status(self.volumes_client, volume['id'], 'available') waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') # Get a given backup backup = self.backups_client.show_backup(backup['id'])['backup'] self.assertEqual(backup_name, backup['name']) # Get all backups with detail backups = self.backups_client.list_backups( detail=True)['backups'] self.assertIn((backup['name'], backup['id']), [(m['name'], m['id']) for m in backups]) # Restore backup restore = self.backups_client.restore_backup( backup['id'])['restore'] # Delete backup self.addCleanup(self.volumes_client.delete_volume, restore['volume_id']) self.assertEqual(backup['id'], restore['backup_id']) waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') waiters.wait_for_volume_status(self.volumes_client, restore['volume_id'], 'available')
def test_incremental_backup(self): """Test create incremental backup.""" # Create volume from image volume = self.create_volume(size=CONF.volume.volume_size, imageRef=CONF.compute.image_ref) self.addCleanup(self.volumes_client.delete_volume, volume['id']) # Create backup backup = self.backups_client.create_backup( volume_id=volume['id'])['backup'] waiters.wait_for_backup_status(self.backups_client, backup['id'], 'available') # Create a server bd_map = [{'volume_id': volume['id'], 'delete_on_termination': '0'}] server_name = data_utils.rand_name('instance') server = self.create_server(name=server_name, block_device_mapping=bd_map, wait_until='ACTIVE') # Delete VM self.servers_client.delete_server(server['id']) # Create incremental backup waiters.wait_for_volume_status(self.volumes_client, volume['id'], 'available') backup_incr = self.backups_client.create_backup( volume_id=volume['id'], incremental=True)['backup'] waiters.wait_for_backup_status(self.backups_client, backup_incr['id'], 'available') is_incremental = self.backups_client.show_backup( backup_incr['id'])['backup']['is_incremental'] self.assertTrue(is_incremental) self.backups_client.delete_backup(backup_incr['id']) self.backups_client.wait_for_resource_deletion(backup_incr['id']) self.backups_client.delete_backup(backup['id']) self.backups_client.wait_for_resource_deletion(backup['id'])
def test_volume_backup_export_import(self): """Test backup export import functionality. Cinder allows exporting DB backup information through its API so it can be imported back in case of a DB loss. """ volume = self.create_volume() # Create backup backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') backup = (self.create_backup(backup_client=self.admin_backups_client, volume_id=volume['id'], name=backup_name)) self.assertEqual(backup_name, backup['name']) # Export Backup export_backup = (self.admin_backups_client.export_backup( backup['id'])['backup-record']) self.assertIn('backup_service', export_backup) self.assertIn('backup_url', export_backup) self.assertTrue(export_backup['backup_service'].startswith( 'cinder.backup.drivers')) self.assertIsNotNone(export_backup['backup_url']) # NOTE(geguileo): Backups are imported with the same backup id # (important for incremental backups among other things), so we cannot # import the exported backup information as it is, because that Backup # ID already exists. So we'll fake the data by changing the backup id # in the exported backup DB info we have retrieved before importing it # back. new_id = data_utils.rand_uuid() new_url = self._modify_backup_url(export_backup['backup_url'], {'id': new_id}) # Import Backup import_backup = self.admin_backups_client.import_backup( backup_service=export_backup['backup_service'], backup_url=new_url)['backup'] # NOTE(geguileo): We delete both backups, but only one of those # deletions will delete data from the backup back-end because they # were both pointing to the same backend data. self.addCleanup(self._delete_backup, new_id) self.assertIn("id", import_backup) self.assertEqual(new_id, import_backup['id']) waiters.wait_for_backup_status(self.admin_backups_client, import_backup['id'], 'available') # Verify Import Backup backups = self.admin_backups_client.list_backups( detail=True)['backups'] self.assertIn(new_id, [b['id'] for b in backups]) # Restore backup restore = self.admin_backups_client.restore_backup( backup['id'])['restore'] self.addCleanup(self.admin_volume_client.delete_volume, restore['volume_id']) self.assertEqual(backup['id'], restore['backup_id']) waiters.wait_for_volume_status(self.admin_volume_client, restore['volume_id'], 'available') # Verify if restored volume is there in volume list volumes = self.admin_volume_client.list_volumes()['volumes'] self.assertIn(restore['volume_id'], [v['id'] for v in volumes]) waiters.wait_for_backup_status(self.admin_backups_client, import_backup['id'], 'available')
def test_volume_backup_export_import(self): """Test backup export import functionality. Cinder allows exporting DB backup information through its API so it can be imported back in case of a DB loss. """ # Create backup backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') backup = (self.admin_backups_client.create_backup( volume_id=self.volume['id'], name=backup_name)['backup']) self.addCleanup(self._delete_backup, backup['id']) self.assertEqual(backup_name, backup['name']) waiters.wait_for_backup_status(self.admin_backups_client, backup['id'], 'available') # Export Backup export_backup = (self.admin_backups_client.export_backup(backup['id']) ['backup-record']) self.assertIn('backup_service', export_backup) self.assertIn('backup_url', export_backup) self.assertTrue(export_backup['backup_service'].startswith( 'cinder.backup.drivers')) self.assertIsNotNone(export_backup['backup_url']) # NOTE(geguileo): Backups are imported with the same backup id # (important for incremental backups among other things), so we cannot # import the exported backup information as it is, because that Backup # ID already exists. So we'll fake the data by changing the backup id # in the exported backup DB info we have retrieved before importing it # back. new_id = data_utils.rand_uuid() new_url = self._modify_backup_url( export_backup['backup_url'], {'id': new_id}) # Import Backup import_backup = self.admin_backups_client.import_backup( backup_service=export_backup['backup_service'], backup_url=new_url)['backup'] # NOTE(geguileo): We delete both backups, but only one of those # deletions will delete data from the backup back-end because they # were both pointing to the same backend data. self.addCleanup(self._delete_backup, new_id) self.assertIn("id", import_backup) self.assertEqual(new_id, import_backup['id']) waiters.wait_for_backup_status(self.admin_backups_client, import_backup['id'], 'available') # Verify Import Backup backups = self.admin_backups_client.list_backups( detail=True)['backups'] self.assertIn(new_id, [b['id'] for b in backups]) # Restore backup restore = self.admin_backups_client.restore_backup( backup['id'])['restore'] self.addCleanup(self.admin_volume_client.delete_volume, restore['volume_id']) self.assertEqual(backup['id'], restore['backup_id']) waiters.wait_for_volume_status(self.admin_volume_client, restore['volume_id'], 'available') # Verify if restored volume is there in volume list volumes = self.admin_volume_client.list_volumes()['volumes'] self.assertIn(restore['volume_id'], [v['id'] for v in volumes]) waiters.wait_for_backup_status(self.admin_backups_client, import_backup['id'], 'available')