From 0d331a6134ee1d5e07e314e63fd58332f5fa5916 Mon Sep 17 00:00:00 2001 From: Julie Pichon Date: Tue, 19 Feb 2013 12:55:04 +0000 Subject: [PATCH] Add support for both soft and hard reboot options Fixes bug #1088859. Thanks to Yufang Zhang for the initial patch. Change-Id: Ic91feb6859586c2df1b6758f72f3981039914095 --- openstack_dashboard/api/nova.py | 2 +- .../dashboards/admin/instances/tables.py | 10 +++---- .../dashboards/project/instances/tables.py | 19 ++++++++++---- .../dashboards/project/instances/tests.py | 26 +++++++++++++++++-- .../test/api_tests/nova_tests.py | 13 ++++++++++ 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py index 64c86d72613..326fff58895 100644 --- a/openstack_dashboard/api/nova.py +++ b/openstack_dashboard/api/nova.py @@ -30,7 +30,7 @@ from novaclient.v1_1 import client as nova_client from novaclient.v1_1 import security_group_rules as nova_rules from novaclient.v1_1.security_groups import SecurityGroup as NovaSecurityGroup -from novaclient.v1_1.servers import REBOOT_HARD +from novaclient.v1_1.servers import REBOOT_HARD, REBOOT_SOFT from horizon.conf import HORIZON_CONFIG from horizon.utils.memoized import memoized diff --git a/openstack_dashboard/dashboards/admin/instances/tables.py b/openstack_dashboard/dashboards/admin/instances/tables.py index 4d578bb0aab..4c3afbaa4f8 100644 --- a/openstack_dashboard/dashboards/admin/instances/tables.py +++ b/openstack_dashboard/dashboards/admin/instances/tables.py @@ -26,9 +26,9 @@ from openstack_dashboard import api from openstack_dashboard.dashboards.project.instances.tables import ( TerminateInstance, EditInstance, ConsoleLink, LogLink, CreateSnapshot, - TogglePause, ToggleSuspend, RebootInstance, ConfirmResize, - RevertResize, get_size, UpdateRow, get_ips, get_power_state, - is_deleting, ACTIVE_STATES, STATUS_DISPLAY_CHOICES, + TogglePause, ToggleSuspend, RebootInstance, SoftRebootInstance, + ConfirmResize, RevertResize, get_size, UpdateRow, get_ips, + get_power_state, is_deleting, ACTIVE_STATES, STATUS_DISPLAY_CHOICES, TASK_DISPLAY_CHOICES) LOG = logging.getLogger(__name__) @@ -118,5 +118,5 @@ class Meta: row_class = AdminUpdateRow row_actions = (ConfirmResize, RevertResize, AdminEditInstance, ConsoleLink, LogLink, CreateSnapshot, TogglePause, - ToggleSuspend, MigrateInstance, RebootInstance, - TerminateInstance) + ToggleSuspend, MigrateInstance, SoftRebootInstance, + RebootInstance, TerminateInstance) diff --git a/openstack_dashboard/dashboards/project/instances/tables.py b/openstack_dashboard/dashboards/project/instances/tables.py index 24b90bba567..0db38116701 100644 --- a/openstack_dashboard/dashboards/project/instances/tables.py +++ b/openstack_dashboard/dashboards/project/instances/tables.py @@ -88,8 +88,8 @@ def action(self, request, obj_id): class RebootInstance(tables.BatchAction): name = "reboot" - action_present = _("Reboot") - action_past = _("Rebooted") + action_present = _("Hard Reboot") + action_past = _("Hard Rebooted") data_type_singular = _("Instance") data_type_plural = _("Instances") classes = ('btn-danger', 'btn-reboot') @@ -100,7 +100,16 @@ def allowed(self, request, instance=None): and not is_deleting(instance)) def action(self, request, obj_id): - api.nova.server_reboot(request, obj_id) + api.nova.server_reboot(request, obj_id, api.nova.REBOOT_HARD) + + +class SoftRebootInstance(RebootInstance): + name = "soft_reboot" + action_present = _("Soft Reboot") + action_past = _("Soft Rebooted") + + def action(self, request, obj_id): + api.nova.server_reboot(request, obj_id, api.nova.REBOOT_SOFT) class TogglePause(tables.BatchAction): @@ -471,5 +480,5 @@ class Meta: SimpleAssociateIP, AssociateIP, SimpleDisassociateIP, EditInstance, EditInstanceSecurityGroups, ConsoleLink, LogLink, - TogglePause, ToggleSuspend, RebootInstance, - TerminateInstance) + TogglePause, ToggleSuspend, SoftRebootInstance, + RebootInstance, TerminateInstance) diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py index 58e47e47512..07c4621b778 100644 --- a/openstack_dashboard/dashboards/project/instances/tests.py +++ b/openstack_dashboard/dashboards/project/instances/tests.py @@ -262,7 +262,8 @@ def test_reboot_instance(self): .AndReturn(self.flavors.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn(self.servers.list()) - api.nova.server_reboot(IsA(http.HttpRequest), server.id) + api.nova.server_reboot(IsA(http.HttpRequest), server.id, + api.nova.REBOOT_HARD) self.mox.ReplayAll() @@ -281,7 +282,8 @@ def test_reboot_instance_exception(self): .AndReturn(self.flavors.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn(self.servers.list()) - api.nova.server_reboot(IsA(http.HttpRequest), server.id) \ + api.nova.server_reboot(IsA(http.HttpRequest), server.id, + api.nova.REBOOT_HARD) \ .AndRaise(self.exceptions.nova) self.mox.ReplayAll() @@ -291,6 +293,26 @@ def test_reboot_instance_exception(self): self.assertRedirectsNoFollow(res, INDEX_URL) + @test.create_stubs({api.nova: ('server_reboot', + 'server_list', + 'flavor_list',)}) + def test_soft_reboot_instance(self): + server = self.servers.first() + + api.nova.flavor_list(IsA(http.HttpRequest)) \ + .AndReturn(self.flavors.list()) + api.nova.server_list(IsA(http.HttpRequest)) \ + .AndReturn(self.servers.list()) + api.nova.server_reboot(IsA(http.HttpRequest), server.id, + api.nova.REBOOT_SOFT) + + self.mox.ReplayAll() + + formData = {'action': 'instances__soft_reboot__%s' % server.id} + res = self.client.post(INDEX_URL, formData) + + self.assertRedirectsNoFollow(res, INDEX_URL) + @test.create_stubs({api.nova: ('server_suspend', 'server_list', 'flavor_list',)}) diff --git a/openstack_dashboard/test/api_tests/nova_tests.py b/openstack_dashboard/test/api_tests/nova_tests.py index 6e9d97cd329..f66aeb5bdad 100644 --- a/openstack_dashboard/test/api_tests/nova_tests.py +++ b/openstack_dashboard/test/api_tests/nova_tests.py @@ -59,6 +59,19 @@ def test_server_reboot(self): ret_val = api.nova.server_reboot(self.request, server.id) self.assertIsNone(ret_val) + def test_server_soft_reboot(self): + server = self.servers.first() + HARDNESS = servers.REBOOT_SOFT + + novaclient = self.stub_novaclient() + novaclient.servers = self.mox.CreateMockAnything() + novaclient.servers.get(server.id).AndReturn(server) + novaclient.servers.reboot(server.id, HARDNESS) + self.mox.ReplayAll() + + ret_val = api.nova.server_reboot(self.request, server.id, HARDNESS) + self.assertIsNone(ret_val) + def test_server_vnc_console(self): server = self.servers.first() console = self.servers.vnc_console_data