Removing non-bootable volumes from boot source

Volumes which bootable flag is set to False should
not be included in the boot source combo box when
the user select the Boot from volume option

Change-Id: I7bfe0aa1c4954ef2d50fa27db147bf15d4daccc1
Closes-Bug: #1319900
This commit is contained in:
Santiago Baldassin 2014-05-15 17:15:34 -03:00
parent cacd93ea49
commit 023caca4ba
5 changed files with 109 additions and 3 deletions

View File

@ -1281,6 +1281,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',

View File

@ -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,

View File

@ -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))

View File

@ -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,

View File

@ -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