Merge "Add instance.share_detach notification"

This commit is contained in:
Zuul
2024-12-08 04:07:34 +00:00
committed by Gerrit Code Review
7 changed files with 225 additions and 10 deletions
@@ -0,0 +1,8 @@
{
"event_type": "instance.share_detach.end",
"payload": {
"$ref": "common_payloads/InstanceActionSharePayload.json#"
},
"priority": "INFO",
"publisher_id": "nova-api:compute"
}
@@ -0,0 +1,8 @@
{
"event_type": "instance.share_detach.start",
"payload": {
"$ref": "common_payloads/InstanceActionSharePayload.json#"
},
"priority": "INFO",
"publisher_id": "nova-api:compute"
}
+18
View File
@@ -4831,8 +4831,26 @@ class ComputeManager(manager.Manager):
# remove from manila, so we can still detach the share.
share_mapping.delete()
compute_utils.notify_about_share_attach_detach(
context,
instance,
instance.host,
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping.share_id
)
_deny_share(context, instance, share_mapping)
compute_utils.notify_about_share_attach_detach(
context,
instance,
instance.host,
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping.share_id
)
@wrap_exception()
def _mount_all_shares(self, context, instance, share_info):
for share_mapping in share_info:
+2
View File
@@ -626,6 +626,8 @@ class InstanceActionVolumeNotification(base.NotificationBase):
@base.notification_sample('instance-share_attach-start.json')
@base.notification_sample('instance-share_attach-end.json')
@base.notification_sample('instance-share_detach-start.json')
@base.notification_sample('instance-share_detach-end.json')
@nova_base.NovaObjectRegistry.register_notification
class InstanceActionShareNotification(base.NotificationBase):
# Version 1.0: Initial version
@@ -390,6 +390,7 @@ class TestInstanceNotificationSample(
self._test_lock_unlock_instance,
self._test_lock_unlock_instance_with_reason,
self._test_share_attach,
self._test_share_detach,
]
for action in actions:
@@ -1732,6 +1733,38 @@ class TestInstanceNotificationSample(
self.api.post_server_action(server['id'], {'os-start': {}})
self._wait_for_state_change(server, expected_status='ACTIVE')
def _test_share_detach(self, server):
self.api.post_server_action(server['id'], {'os-stop': {}})
self._wait_for_state_change(server, expected_status='SHUTOFF')
self.notifier.reset()
# Detach share
self._detach_share(server, 'e8debdc0-447a-4376-a10a-4cd9122d7986')
self.assertEqual(2, len(self.notifier.versioned_notifications),
self.notifier.versioned_notifications)
self._verify_notification(
'instance-share_detach-start',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id'],
'state': 'stopped',
'power_state': 'shutdown'},
actual=self.notifier.versioned_notifications[0])
self._verify_notification(
'instance-share_detach-end',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id'],
'state': 'stopped',
'power_state': 'shutdown',
},
actual=self.notifier.versioned_notifications[1])
# Restart server
self.api.post_server_action(server['id'], {'os-start': {}})
self._wait_for_state_change(server, expected_status='ACTIVE')
def _test_rescue_unrescue_server(self, server):
# Both "rescue" and "unrescue" notification asserts are made here
# rescue notification asserts
+147 -10
View File
@@ -2704,12 +2704,17 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_allow.assert_called_once_with(
mock.ANY, share_mapping.share_id, 'ip', compute_ip, 'rw')
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we can deny the instance share.
"""
@@ -2735,13 +2740,36 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_deny.assert_called_once_with(
mock.ANY, share_mapping.share_id, 'ip', compute_ip)
mock_db_delete.assert_called_once()
mock_notifications.assert_has_calls([
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping.share_id
),
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping.share_id
),
])
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_in_use(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we cannot deny a share used by an instance.
"""
@@ -2760,13 +2788,36 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
self.compute.deny_share(self.context, instance, share_mapping)
mock_deny.assert_not_called()
mock_db_delete.assert_called_once()
mock_notifications.assert_has_calls([
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping.share_id
),
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping.share_id
),
])
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_in_error(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we can deny a share in error on the instance detaching the
share.
@@ -2794,13 +2845,36 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_deny.assert_called_once_with(
mock.ANY, share_mapping.share_id, 'ip', compute_ip)
mock_db_delete.assert_called_once()
mock_notifications.assert_has_calls([
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping.share_id
),
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping.share_id
),
])
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_access_not_found_in_manila(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we can deny a share even if access is not found in manila.
"""
@@ -2825,12 +2899,17 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock.ANY, share_mapping.share_id, 'ip', compute_ip)
mock_db_delete.assert_called_once()
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_not_found_in_manila(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we can deny a share even if the share is not found in manila.
"""
@@ -2855,6 +2934,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock.ANY, share_mapping.share_id, 'ip', compute_ip)
mock_db_delete.assert_called_once()
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.save')
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@@ -2862,7 +2945,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_fails_access_removal_error(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_db_save
mock_db_save, mock_notifications
):
"""Ensure we have an exception if the access cannot be removed
by manila.
@@ -2893,6 +2976,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_db_delete.assert_not_called()
self.assertEqual(share_mapping.status, 'error')
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.save')
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@@ -2900,7 +2987,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_fails_keystone_unauthorized(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_db_save
mock_db_save, mock_notifications
):
"""Ensure we have an exception if the access cannot be removed
by manila.
@@ -2930,6 +3017,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_db_delete.assert_not_called()
self.assertEqual(share_mapping.status, 'error')
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.save')
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@@ -2937,7 +3028,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_fails_protocol_not_supported(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_db_save
mock_db_save, mock_notifications
):
"""Ensure we have an exception if the access cannot be removed
by manila.
@@ -2967,12 +3058,17 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
mock_db_delete.assert_not_called()
self.assertEqual(share_mapping.status, 'error')
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_in_use_by_another_instance(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we do not deny a share used by another instance.
"""
@@ -2993,13 +3089,36 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
self.compute.deny_share(self.context, instance, share_mapping1)
mock_deny.assert_not_called()
mock_db_delete.assert_called_once()
mock_notifications.assert_has_calls([
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping1.share_id
),
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping1.share_id
),
])
@mock.patch(
'nova.compute.utils.notify_about_share_attach_detach',
return_value=None
)
@mock.patch('nova.objects.share_mapping.ShareMapping.delete')
@mock.patch('nova.share.manila.API.deny')
@mock.patch('nova.share.manila.API.get_access')
@mock.patch('nova.objects.share_mapping.ShareMappingList.get_by_share_id')
def test_deny_share_in_error_on_another_instance(
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete
self, mock_db_get_share, mock_get_access, mock_deny, mock_db_delete,
mock_notifications
):
"""Ensure we cannot deny a share in error state on another instance.
If the other instance is hard rebooted, it might need the share.
@@ -3022,6 +3141,24 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
self.compute.deny_share(self.context, instance, share_mapping1)
mock_deny.assert_not_called()
mock_db_delete.assert_called_once()
mock_notifications.assert_has_calls([
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.START,
share_id=share_mapping1.share_id
),
mock.call(
mock.ANY,
instance,
"fake-host",
action=fields.NotificationAction.SHARE_DETACH,
phase=fields.NotificationPhase.END,
share_id=share_mapping1.share_id
),
])
@mock.patch('nova.objects.share_mapping.ShareMapping.save')
@mock.patch('nova.virt.fake.FakeDriver.mount_share')
@@ -0,0 +1,9 @@
---
features:
- |
The following share attach and share detach versioned notifications have
been added to the nova-compute service:
* instance.share_attach.start
* instance.share_attach.end
* instance.share_detach.start
* instance.share_detach.end