diff --git a/manila/cmd/manage.py b/manila/cmd/manage.py index 3cdcb74d12..59bcb3aa33 100644 --- a/manila/cmd/manage.py +++ b/manila/cmd/manage.py @@ -82,6 +82,7 @@ SHARE_SERVERS_UPDATE_HELP = ("List of share servers to be updated, separated " "by commas.") SHARE_SERVERS_UPDATE_CAPABILITIES_HELP = ( "List of share server capabilities to be updated, separated by commas.") +SHARE_DELETE_HELP = ("Share ID to be deleted.") # Decorators for actions @@ -402,6 +403,30 @@ class ShareCommands(object): } print(msg % msg_args) + @args('--share_id', required=True, help=SHARE_DELETE_HELP) + def delete(self, share_id): + """Delete manila share from the database. + + This command is useful after a share's manager service + has been decommissioned. + """ + ctxt = context.get_admin_context() + share = db.share_get(ctxt, share_id) + + active_replicas = [] + # We delete "active" replicas at the end + for share_instance in share['instances']: + if share_instance['replica_state'] == "active": + active_replicas.append(share_instance) + else: + db.share_instance_delete(ctxt, share_instance['id']) + for share_instance in active_replicas: + db.share_instance_delete(ctxt, share_instance['id']) + print("Deleted share instance %s" % share_instance['id']) + + # finally, clean up the share + print("Deleted share %s" % share_id) + class ShareServerCommands(object): @args('--share_servers', required=True, diff --git a/manila/tests/cmd/test_manage.py b/manila/tests/cmd/test_manage.py index 7d6020c6e0..b784e975cc 100644 --- a/manila/tests/cmd/test_manage.py +++ b/manila/tests/cmd/test_manage.py @@ -439,6 +439,33 @@ class ManilaCmdManageTestCase(test.TestCase): db.share_resources_host_update.assert_called_once_with( 'admin_ctxt', current_host, new_host) + def test_share_delete(self): + share_id = "fake_share_id" + share = { + 'id': share_id, + 'instances': [ + {'id': 'instance_id1', 'replica_state': 'active'}, + {'id': 'instance_id2', 'replica_state': 'error'}, + {'id': 'instance_id3', 'replica_state': 'active'}, + ] + } + self.mock_object(context, 'get_admin_context', + mock.Mock(return_value='admin_ctxt')) + self.mock_object(db, 'share_get', + mock.Mock(return_value=share)) + self.mock_object(db, 'share_instance_delete', + mock.Mock(return_value=None)) + + self.share_cmds.delete(share_id) + + db.share_instance_delete.assert_has_calls([ + mock.call('admin_ctxt', 'instance_id2'), + mock.call('admin_ctxt', 'instance_id1'), + mock.call('admin_ctxt', 'instance_id3'), + ]) + + self.assertEqual(3, db.share_instance_delete.call_count) + def test_share_server_update_capability(self): self.mock_object(context, 'get_admin_context', mock.Mock(return_value='admin_ctxt')) diff --git a/releasenotes/notes/bug-1867030-delete-share-55663c74a93e77fd.yaml b/releasenotes/notes/bug-1867030-delete-share-55663c74a93e77fd.yaml new file mode 100644 index 0000000000..21fa659da1 --- /dev/null +++ b/releasenotes/notes/bug-1867030-delete-share-55663c74a93e77fd.yaml @@ -0,0 +1,5 @@ +--- +fixes: + -| + Launchpad `bug 1867030 `_ + has been fixed for delete share. \ No newline at end of file