diff --git a/karbor/services/protection/protection_plugins/image/image_plugin_schemas.py b/karbor/services/protection/protection_plugins/image/image_plugin_schemas.py index 38635a66..70da2ef9 100644 --- a/karbor/services/protection/protection_plugins/image/image_plugin_schemas.py +++ b/karbor/services/protection/protection_plugins/image/image_plugin_schemas.py @@ -37,6 +37,12 @@ RESTORE_SCHEMA = { "required": ["backup_name"] } +VERIFY_SCHEMA = { + "title": "Image Protection Verify", + "type": "object", + "properties": {} +} + # TODO(hurong) SAVED_INFO_SCHEMA = { "title": "Image Protection Saved Info", diff --git a/karbor/services/protection/protection_plugins/image/image_protection_plugin.py b/karbor/services/protection/protection_plugins/image/image_protection_plugin.py index 17ebb794..3d1e70f5 100644 --- a/karbor/services/protection/protection_plugins/image/image_protection_plugin.py +++ b/karbor/services/protection/protection_plugins/image/image_protection_plugin.py @@ -209,6 +209,36 @@ class RestoreOperation(protection_plugin.Operation): original_image_id) +class VerifyOperation(protection_plugin.Operation): + def __init__(self): + super(VerifyOperation, self).__init__() + + def on_main(self, checkpoint, resource, context, parameters, **kwargs): + original_image_id = resource.id + bank_section = checkpoint.get_resource_bank_section( + original_image_id) + LOG.info('Verifying the image backup, server_id: %s', + original_image_id) + + update_method = partial( + utils.update_resource_verify_result, + kwargs.get('verify'), resource.type, original_image_id) + + backup_status = bank_section.get_object("status") + + if backup_status == constants.RESOURCE_STATUS_AVAILABLE: + update_method(constants.RESOURCE_STATUS_AVAILABLE) + else: + reason = ('The status of image backup status is %s.' + % backup_status) + update_method(backup_status, reason) + raise exception.VerifyResourceFailed( + name="Image backup", + reason=reason, + resource_id=original_image_id, + resource_type=resource.type) + + class GlanceProtectionPlugin(protection_plugin.ProtectionPlugin): _SUPPORT_RESOURCE_TYPES = [constants.IMAGE_RESOURCE_TYPE] @@ -239,6 +269,10 @@ class GlanceProtectionPlugin(protection_plugin.ProtectionPlugin): def get_restore_schema(cls, resources_type): return image_schemas.RESTORE_SCHEMA + @classmethod + def get_verify_schema(cls, resources_type): + return image_schemas.VERIFY_SCHEMA + @classmethod def get_saved_info_schema(cls, resources_type): return image_schemas.SAVED_INFO_SCHEMA @@ -254,5 +288,8 @@ class GlanceProtectionPlugin(protection_plugin.ProtectionPlugin): def get_restore_operation(self, resource): return RestoreOperation(self._poll_interval) + def get_verify_operation(self, resource): + return VerifyOperation() + def get_delete_operation(self, resource): return DeleteOperation() diff --git a/karbor/tests/unit/protection/test_glance_protection_plugin.py b/karbor/tests/unit/protection/test_glance_protection_plugin.py index e329f836..1a08ab0b 100644 --- a/karbor/tests/unit/protection/test_glance_protection_plugin.py +++ b/karbor/tests/unit/protection/test_glance_protection_plugin.py @@ -169,6 +169,22 @@ class GlanceProtectionPluginTest(base.TestCase): call_hooks(delete_operation, self.checkpoint, resource, self.cntxt, {}) + @mock.patch('karbor.services.protection.protection_plugins.utils.' + 'update_resource_verify_result') + def test_verify_backup(self, mock_update_verify): + resource = Resource(id="123", + type=constants.IMAGE_RESOURCE_TYPE, + name='fake') + + fake_bank_section.get_object = mock.MagicMock() + fake_bank_section.get_object.return_value = 'available' + + verify_operation = self.plugin.get_verify_operation(resource) + call_hooks(verify_operation, self.checkpoint, resource, self.cntxt, + {}) + mock_update_verify.assert_called_with( + None, resource.type, resource.id, 'available') + def test_get_supported_resources_types(self): types = self.plugin.get_supported_resources_types() self.assertEqual([constants.IMAGE_RESOURCE_TYPE], types)