Merge "Hiding device name field when unhandled"

This commit is contained in:
Jenkins 2014-10-16 05:57:09 +00:00 committed by Gerrit Code Review
commit ca4b126117
4 changed files with 130 additions and 6 deletions

View File

@ -853,3 +853,10 @@ def can_set_server_password():
def instance_action_list(request, instance_id):
return nova_instance_action.InstanceActionManager(
novaclient(request)).list(instance_id)
def can_set_mount_point():
"""Return the Hypervisor's capability of setting mount points."""
hypervisor_features = getattr(
settings, "OPENSTACK_HYPERVISOR_FEATURES", {})
return hypervisor_features.get("can_set_mount_point", False)

View File

@ -22,6 +22,7 @@ import uuid
from django.conf import settings
from django.core.urlresolvers import reverse
from django.forms import widgets
from django import http
import django.test
from django.utils.datastructures import SortedDict
@ -2554,6 +2555,120 @@ class InstanceTests(helpers.TestCase):
self.test_launch_form_instance_requirement_error_ram(
test_with_profile=True)
@helpers.create_stubs({api.glance: ('image_list_detailed',),
api.neutron: ('network_list',
'profile_list',),
api.nova: ('extension_supported',
'flavor_list',
'keypair_list',
'tenant_absolute_limits',
'availability_zone_list',),
api.network: ('security_group_list',),
cinder: ('volume_list',
'volume_snapshot_list',),
quotas: ('tenant_quota_usages',)})
def _test_launch_form_instance_show_device_name(self, device_name,
widget_class,
widget_attrs):
flavor = self.flavors.first()
image = self.images.first()
keypair = self.keypairs.first()
server = self.servers.first()
volume = self.volumes.first()
sec_group = self.security_groups.first()
avail_zone = self.availability_zones.first()
customization_script = 'user data'
volume_choice = "%s:vol" % volume.id
quota_usages = self.quota_usages.first()
api.nova.extension_supported('BlockDeviceMappingV2Boot',
IsA(http.HttpRequest)).AndReturn(True)
api.nova.flavor_list(
IsA(http.HttpRequest)).AndReturn(self.flavors.list())
api.nova.keypair_list(
IsA(http.HttpRequest)).AndReturn(self.keypairs.list())
api.network.security_group_list(
IsA(http.HttpRequest)).AndReturn(self.security_groups.list())
api.nova.availability_zone_list(
IsA(http.HttpRequest)).AndReturn(self.availability_zones.list())
api.glance.image_list_detailed(
IsA(http.HttpRequest),
filters={'is_public': True,
'status': 'active'}).AndReturn(
[self.images.list(), False, False])
api.glance.image_list_detailed(
IsA(http.HttpRequest),
filters={'property-owner_id': self.tenant.id,
'status': 'active'}).AndReturn([[], False, False])
api.neutron.network_list(
IsA(http.HttpRequest),
tenant_id=self.tenant.id,
shared=False).AndReturn(self.networks.list()[:1])
api.neutron.network_list(
IsA(http.HttpRequest),
shared=True).AndReturn(self.networks.list()[1:])
api.nova.extension_supported(
'DiskConfig', IsA(http.HttpRequest)).AndReturn(True)
api.nova.extension_supported(
'ConfigDrive', IsA(http.HttpRequest)).AndReturn(True)
cinder.volume_list(
IsA(http.HttpRequest)).AndReturn(self.volumes.list())
cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
api.nova.flavor_list(
IsA(http.HttpRequest)).AndReturn(self.flavors.list())
api.nova.tenant_absolute_limits(
IsA(http.HttpRequest)).AndReturn(self.limits['absolute'])
quotas.tenant_quota_usages(
IsA(http.HttpRequest)).AndReturn(quota_usages)
api.nova.flavor_list(
IsA(http.HttpRequest)).AndReturn(self.flavors.list())
self.mox.ReplayAll()
form_data = {'flavor': flavor.id,
'source_type': 'volume_image_id',
'image_id': image.id,
'availability_zone': avail_zone.zoneName,
'keypair': keypair.name,
'name': server.name,
'customization_script': customization_script,
'project_id': self.tenants.first().id,
'user_id': self.user.id,
'groups': sec_group.name,
'volume_type': 'volume_id',
'volume_id': volume_choice,
'volume_size': max(
image.min_disk, image.size / 1024 ** 3),
'device_name': device_name,
'count': 1}
url = reverse('horizon:project:instances:launch')
res = self.client.post(url, form_data)
self.assertNoFormErrors(res)
widget_content = widget_class().render(**widget_attrs)
# In django 1.4, the widget's html attributes are not always rendered
# in the same order and checking the fully rendered widget fails.
for widget_part in widget_content.split():
self.assertContains(res, widget_part)
@django.test.utils.override_settings(
OPENSTACK_HYPERVISOR_FEATURES={'can_set_mount_point': True})
def test_launch_form_instance_device_name_showed(self):
self._test_launch_form_instance_show_device_name(
u'vda', widgets.TextInput, {
'name': 'device_name', 'value': 'vda',
'attrs': {'id': 'id_device_name'}}
)
@django.test.utils.override_settings(
OPENSTACK_HYPERVISOR_FEATURES={'can_set_mount_point': False})
def test_launch_form_instance_device_name_hidden(self):
self._test_launch_form_instance_show_device_name(
u'', widgets.HiddenInput, {
'name': 'device_name', 'value': '',
'attrs': {'id': 'id_device_name'}}
)
@helpers.create_stubs({api.glance: ('image_list_detailed',),
api.neutron: ('network_list',
'profile_list',),

View File

@ -35,6 +35,7 @@ from horizon import workflows
from openstack_dashboard import api
from openstack_dashboard.api import base
from openstack_dashboard.api import cinder
from openstack_dashboard.api import nova
from openstack_dashboard.usage import quotas
from openstack_dashboard.dashboards.project.images \
@ -141,6 +142,11 @@ class SetInstanceDetailsAction(workflows.Action):
self.context = context
super(SetInstanceDetailsAction, self).__init__(
request, context, *args, **kwargs)
# Hide the device field if the hypervisor doesn't support it.
if not nova.can_set_mount_point():
self.fields['device_name'].widget = forms.widgets.HiddenInput()
source_type_choices = [
('', _("Select source")),
("image_id", _("Boot from image")),

View File

@ -33,6 +33,7 @@ from horizon.utils.memoized import memoized # noqa
from openstack_dashboard import api
from openstack_dashboard.api import cinder
from openstack_dashboard.api import glance
from openstack_dashboard.api import nova
from openstack_dashboard.dashboards.project.images import utils
from openstack_dashboard.dashboards.project.instances import tables
from openstack_dashboard.usage import quotas
@ -410,12 +411,7 @@ class AttachForm(forms.SelfHandlingForm):
super(AttachForm, self).__init__(*args, **kwargs)
# Hide the device field if the hypervisor doesn't support it.
hypervisor_features = getattr(settings,
"OPENSTACK_HYPERVISOR_FEATURES",
{})
can_set_mount_point = hypervisor_features.get("can_set_mount_point",
False)
if not can_set_mount_point:
if not nova.can_set_mount_point():
self.fields['device'].widget = forms.widgets.HiddenInput()
# populate volume_id