summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2019-04-03 16:48:38 +0000
committerGerrit Code Review <review@openstack.org>2019-04-03 16:48:38 +0000
commitabe9fdb1c6960d6c0bf3de8646b1400f74a749af (patch)
treeed31ccbb8f0e514bd577e8da4d97b8393254d7d3
parent785d485004fea2f64eda06f87c19e3284ad263ed (diff)
parent1d01721919eb16f1e4b577c41c8d27fd7dd098b8 (diff)
downloadhorizon-abe9fdb1c6960d6c0bf3de8646b1400f74a749af.tar.gz
Merge "Display first volume image_metadata as an instance image" into stable/stein
-rw-r--r--openstack_dashboard/dashboards/project/instances/tests.py84
-rw-r--r--openstack_dashboard/dashboards/project/instances/views.py35
2 files changed, 92 insertions, 27 deletions
diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py
index f587188d9..2edc2ee99 100644
--- a/openstack_dashboard/dashboards/project/instances/tests.py
+++ b/openstack_dashboard/dashboards/project/instances/tests.py
@@ -185,6 +185,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
api.network: (
'servers_update_addresses',
),
+ api.cinder: ('volume_list',),
})
def _get_index(self, use_servers_update_address=True):
servers = self.servers.list()
@@ -268,6 +269,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'tenant_absolute_limits',
'flavor_list'),
api.glance: ('image_list_detailed',),
+ api.cinder: ('volume_list',),
})
def test_index_server_list_exception(self):
search_opts = {'marker': None, 'paginate': True}
@@ -306,6 +308,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
@@ -364,6 +367,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_index_with_instance_booted_from_volume(self):
volume_server = self.servers.first()
@@ -447,7 +451,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_delete_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -480,7 +485,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_delete_instance_error_state(self):
servers = self.servers.list()
server = servers[0]
@@ -515,7 +521,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_delete_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -551,7 +558,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_pause_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -590,7 +598,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_pause_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -629,7 +638,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unpause_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -668,7 +678,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unpause_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -706,7 +717,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_reboot_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -740,7 +752,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_reboot_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -774,7 +787,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_soft_reboot_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -810,7 +824,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_suspend_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -853,7 +868,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_suspend_instance_if_placed_on_2nd_page(self):
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 2)
servers = self.servers.list()[:3]
@@ -897,7 +913,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_suspend_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -936,7 +953,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_resume_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -976,7 +994,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available'),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_resume_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -1016,7 +1035,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_shelve_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -1054,7 +1074,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_shelve_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -1093,7 +1114,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unshelve_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -1133,7 +1155,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unshelve_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -1173,7 +1196,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_lock_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -1214,7 +1238,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_lock_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -1257,7 +1282,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available'),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unlock_instance(self):
servers = self.servers.list()
server = servers[0]
@@ -1298,7 +1324,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'extension_supported',
'is_feature_available'),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unlock_instance_exception(self):
servers = self.servers.list()
server = servers[0]
@@ -1812,6 +1839,7 @@ class InstanceTests(InstanceTestBase):
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def _test_instances_index_retrieve_password_action(self):
servers = self.servers.list()
@@ -4107,6 +4135,7 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_launch_button_attributes(self):
servers = self.servers.list()
@@ -4171,6 +4200,7 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_launch_button_disabled_when_quota_exceeded(self):
servers = self.servers.list()
@@ -4360,6 +4390,7 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_index_options_after_migrate(self):
servers = self.servers.list()
@@ -4936,6 +4967,7 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',),
})
def test_index_form_action_with_pagination(self):
# The form action on the next page should have marker
@@ -5022,7 +5054,8 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_delete_instance_with_pagination(self):
# Instance should be deleted from the next page.
@@ -5145,7 +5178,8 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
'flavor_list',
'server_unrescue',),
api.glance: ('image_list_detailed',),
- api.network: ('servers_update_addresses',)})
+ api.network: ('servers_update_addresses',),
+ api.cinder: ('volume_list',)})
def test_unrescue_instance(self):
servers = self.servers.list()
server = servers[0]
diff --git a/openstack_dashboard/dashboards/project/instances/views.py b/openstack_dashboard/dashboards/project/instances/views.py
index 07a105ff0..410a272ac 100644
--- a/openstack_dashboard/dashboards/project/instances/views.py
+++ b/openstack_dashboard/dashboards/project/instances/views.py
@@ -125,12 +125,23 @@ class IndexView(tables.PagedTableMixin, tables.DataTableView):
return instances
+ def _get_volumes(self):
+ # Gather our volumes to get their image metadata for instance
+ try:
+ volumes = api.cinder.volume_list(self.request)
+ return dict((str(volume.id), volume) for volume in volumes)
+ except Exception:
+ exceptions.handle(self.request, ignore=True)
+ return {}
+
def get_data(self):
marker, sort_dir = self._get_marker()
search_opts = self.get_filters({'marker': marker, 'paginate': True})
- image_dict, flavor_dict = futurist_utils.call_functions_parallel(
- self._get_images, self._get_flavors)
+ image_dict, flavor_dict, volume_dict = \
+ futurist_utils.call_functions_parallel(
+ self._get_images, self._get_flavors, self._get_volumes
+ )
non_api_filter_info = (
('image_name', 'image', image_dict.values()),
@@ -155,6 +166,26 @@ class IndexView(tables.PagedTableMixin, tables.DataTableView):
# until the call is deprecated in api itself
else:
instance.image['name'] = _("-")
+ # Otherwise trying to get image from volume metadata
+ else:
+ instance_volumes = [
+ attachment
+ for volume in volume_dict.values()
+ for attachment in volume.attachments
+ if attachment['server_id'] == instance.id
+ ]
+ # Sorting attached volumes by device name (eg '/dev/sda')
+ instance_volumes.sort(key=lambda attach: attach['device'])
+ # While instance from volume is being created,
+ # it does not have volumes
+ if instance_volumes:
+ # Getting volume object, which is as attached
+ # as the first device
+ boot_volume = volume_dict[instance_volumes[0]['id']]
+ if hasattr(boot_volume, "volume_image_metadata"):
+ instance.image = image_dict[
+ boot_volume.volume_image_metadata['image_id']
+ ]
flavor_id = instance.flavor["id"]
if flavor_id in flavor_dict: