diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py index 493af170a9..372c3560b3 100644 --- a/openstack_dashboard/dashboards/project/instances/tests.py +++ b/openstack_dashboard/dashboards/project/instances/tests.py @@ -1299,6 +1299,89 @@ class InstanceTests(test.TestCase): def test_launch_instance_get_with_only_one_network(self): self.test_launch_instance_get(only_one_network=True) + @test.create_stubs({api.nova: ('extension_supported', + 'flavor_list', + 'keypair_list', + 'tenant_absolute_limits', + 'availability_zone_list',), + api.network: ('security_group_list',), + cinder: ('volume_snapshot_list', + 'volume_list',), + api.neutron: ('network_list', + 'profile_list',), + api.glance: ('image_list_detailed',)}) + def test_launch_instance_get_bootable_volumes(self, + block_device_mapping_v2=True, + only_one_network=False, + disk_config=True): + api.nova.extension_supported('BlockDeviceMappingV2Boot', + IsA(http.HttpRequest)) \ + .AndReturn(block_device_mapping_v2) + cinder.volume_list(IsA(http.HttpRequest)) \ + .AndReturn(self.volumes.list()) + cinder.volume_snapshot_list(IsA(http.HttpRequest)) \ + .AndReturn(self.volumes.list()) + api.glance.image_list_detailed(IsA(http.HttpRequest), + filters={'is_public': True, + 'status': 'active'}) \ + .AndReturn([self.images.list(), False]) + api.glance.image_list_detailed(IsA(http.HttpRequest), + filters={'property-owner_id': self.tenant.id, + 'status': 'active'}) \ + .AndReturn([[], False]) + api.neutron.network_list(IsA(http.HttpRequest), + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + if only_one_network: + api.neutron.network_list(IsA(http.HttpRequest), + shared=True).AndReturn([]) + else: + api.neutron.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) + + if api.neutron.is_port_profiles_supported(): + policy_profiles = self.policy_profiles.list() + api.neutron.profile_list(IsA(http.HttpRequest), + 'policy').AndReturn(policy_profiles) + api.nova.extension_supported('DiskConfig', + IsA(http.HttpRequest)) \ + .AndReturn(disk_config) + api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\ + .AndReturn(self.limits['absolute']) + api.nova.flavor_list(IsA(http.HttpRequest)) \ + .AndReturn(self.flavors.list()) + 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()) + + self.mox.ReplayAll() + + url = reverse('horizon:project:instances:launch') + res = self.client.get(url) + + bootable_volumes = [v.id for v in self.volumes.list() + if v.bootable == 'true' and v.status == 'available'] + + volume_sources = res.context_data['workflow'].steps[0].\ + action.fields['volume_id'].choices + + volume_sources_ids = [] + for volume in volume_sources: + self.assertTrue(volume[0].split(":vol")[0] in bootable_volumes or + volume[0] == '') + if volume[0] != '': + volume_sources_ids.append(volume[0].split(":vol")[0]) + + for volume in bootable_volumes: + self.assertTrue(volume in volume_sources_ids) + @test.create_stubs({api.glance: ('image_list_detailed',), api.neutron: ('network_list', 'profile_list', diff --git a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py index 67ff397f16..14aa1ffcff 100644 --- a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py +++ b/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py @@ -377,7 +377,8 @@ class SetInstanceDetailsAction(workflows.Action): try: volumes = [self._get_volume_display_name(v) for v in cinder.volume_list(self.request) - if v.status == api.cinder.VOLUME_STATE_AVAILABLE] + if v.status == api.cinder.VOLUME_STATE_AVAILABLE + and v.bootable == 'true'] except Exception: volumes = [] exceptions.handle(self.request, diff --git a/openstack_dashboard/test/test_data/cinder_data.py b/openstack_dashboard/test/test_data/cinder_data.py index 9deb2e0d17..df519e9419 100644 --- a/openstack_dashboard/test/test_data/cinder_data.py +++ b/openstack_dashboard/test/test_data/cinder_data.py @@ -62,6 +62,11 @@ def data(TEST): 'volume_type': None, 'attachments': [{"id": "1", "server_id": '1', "device": "/dev/hda"}]}) + + volume.bootable = 'true' + nameless_volume.bootable = 'true' + other_volume.bootable = 'true' + TEST.cinder_volumes.add(api.cinder.Volume(volume)) TEST.cinder_volumes.add(api.cinder.Volume(nameless_volume)) TEST.cinder_volumes.add(api.cinder.Volume(other_volume)) @@ -75,6 +80,7 @@ def data(TEST): 'size': 20, 'created_at': '2014-01-27 10:30:00', 'volume_type': None, + 'bootable': 'true', 'attachments': []}) TEST.cinder_volumes.add(api.cinder.Volume(volume_v2)) diff --git a/openstack_dashboard/test/test_data/nova_data.py b/openstack_dashboard/test/test_data/nova_data.py index 56cd6987be..ff1f6ba19a 100644 --- a/openstack_dashboard/test/test_data/nova_data.py +++ b/openstack_dashboard/test/test_data/nova_data.py @@ -212,9 +212,25 @@ def data(TEST): volume_type='vol_type_2', attachments=[{"id": "2", "server_id": '1', "device": "/dev/hdk"}])) + non_bootable_volume = volumes.Volume(volumes.VolumeManager(None), + dict(id="41023e92-8008-4c8b-8059-7f2293ff3771", + name='non_bootable_volume', + status='available', + size=40, + display_name='Non Bootable Volume', + created_at='2012-04-01 10:30:00', + volume_type=None, + attachments=[])) + + volume.bootable = 'true' + nameless_volume.bootable = 'true' + attached_volume.bootable = 'true' + non_bootable_volume.bootable = 'false' + TEST.volumes.add(volume) TEST.volumes.add(nameless_volume) TEST.volumes.add(attached_volume) + TEST.volumes.add(non_bootable_volume) vol_type1 = volume_types.VolumeType(volume_types.VolumeTypeManager(None), {'id': 1, diff --git a/openstack_dashboard/test/tests/quotas.py b/openstack_dashboard/test/tests/quotas.py index ccb3c2d79d..fcb23fe009 100644 --- a/openstack_dashboard/test/tests/quotas.py +++ b/openstack_dashboard/test/tests/quotas.py @@ -42,10 +42,10 @@ class QuotaTests(test.APITestCase): 'instances': {'available': 8, 'used': 2, 'quota': 10}, 'cores': {'available': 8, 'used': 2, 'quota': 10}} if with_volume: - usages.update({'volumes': {'available': 0, 'used': 3, 'quota': 1}, + usages.update({'volumes': {'available': 0, 'used': 4, 'quota': 1}, 'snapshots': {'available': 0, 'used': 3, 'quota': 1}, - 'gigabytes': {'available': 920, 'used': 80, + 'gigabytes': {'available': 880, 'used': 120, 'quota': 1000}}) return usages