Allow delete servers in error state

In instance list, when we have one/multiple servers in error state,
Horizon does not display "Terminate instances" button in top-right
side (close to "Launch instance" button). So, Horizon does not allow
terminate instances in error state.

When you click on "DELETE INSTANCE" button in Horizon, and something
went wrong (for example, the message to delete did not arrive to
Nova or Nova was stuck during the deletion process), you can see the
instance in "deleting" status forever. Right now, in this status,
the "delete instance" button disapears, so the user can not "retry"
the deletion.

Change-Id: I6486d6989d4bd89d5c9346125aa01ec1359352d4
Closes-bug: #1557353
This commit is contained in:
Marcos Fermin Lobo
2016-03-15 09:05:37 +01:00
parent 018df171fb
commit 41533820a0
2 changed files with 32 additions and 2 deletions

View File

@@ -102,8 +102,13 @@ class DeleteInstance(policy.PolicyTargetMixin, tables.DeleteAction):
)
def allowed(self, request, instance=None):
"""Allow delete action if instance not currently being deleted."""
return not is_deleting(instance)
"""Allow delete action if instance is in error state or not currently
being deleted.
"""
error_state = False
if instance:
error_state = (instance.status == 'ERROR')
return error_state or not is_deleting(instance)
def action(self, request, obj_id):
api.nova.server_delete(request, obj_id)

View File

@@ -260,6 +260,31 @@ class InstanceTests(helpers.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_list',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_delete_instance_error_state(self):
servers = self.servers.list()
server = servers[0]
server.status = 'ERROR'
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False, False))
api.nova.server_delete(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
formData = {'action': 'instances__delete__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_list',
'flavor_list',
'server_delete',),