diff --git a/openstack_dashboard/dashboards/project/instances/utils.py b/openstack_dashboard/dashboards/project/instances/utils.py new file mode 100644 index 00000000000..97405aa3533 --- /dev/null +++ b/openstack_dashboard/dashboards/project/instances/utils.py @@ -0,0 +1,63 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from django.conf import settings +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions + +from openstack_dashboard import api + +LOG = logging.getLogger(__name__) + + +def flavor_list(request): + """Utility method to retrieve a list of flavors.""" + try: + return api.nova.flavor_list(request) + except Exception: + exceptions.handle(request, + _('Unable to retrieve instance flavors.')) + return [] + + +def sort_flavor_list(request, flavors): + """Utility method to sort a list of flavors. + By default, returns the available flavors, sorted by RAM + usage (ascending). Override these behaviours with a + CREATE_INSTANCE_FLAVOR_SORT dict + in local_settings.py. + """ + def get_key(flavor, sort_key): + try: + return getattr(flavor, sort_key) + except AttributeError: + LOG.warning('Could not find sort key "%s". Using the default ' + '"ram" instead.', sort_key) + return getattr(flavor, 'ram') + try: + flavor_sort = getattr(settings, 'CREATE_INSTANCE_FLAVOR_SORT', {}) + sort_key = flavor_sort.get('key', 'ram') + rev = flavor_sort.get('reverse', False) + if not callable(sort_key): + key = lambda flavor: get_key(flavor, sort_key) + else: + key = sort_key + flavor_list = [(flavor.id, '%s' % flavor.name) + for flavor in sorted(flavors, key=key, reverse=rev)] + return flavor_list + except Exception: + exceptions.handle(request, + _('Unable to sort instance flavors.')) + return [] diff --git a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py index aa84ae270e0..2f7f9306a20 100644 --- a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py +++ b/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py @@ -21,7 +21,6 @@ import json import logging -from django.conf import settings from django.template.defaultfilters import filesizeformat # noqa from django.utils.text import normalize_newlines # noqa from django.utils.translation import ugettext_lazy as _ @@ -40,22 +39,15 @@ from openstack_dashboard.api import cinder from openstack_dashboard.usage import quotas -from openstack_dashboard.dashboards.project.images import utils +from openstack_dashboard.dashboards.project.images \ + import utils as image_utils +from openstack_dashboard.dashboards.project.instances \ + import utils as instance_utils LOG = logging.getLogger(__name__) -def _flavor_list(request): - """Utility method to retrieve a list of flavor.""" - try: - return api.nova.flavor_list(request) - except Exception: - exceptions.handle(request, - _('Unable to retrieve instance flavors.')) - return [] - - class SelectProjectUserAction(workflows.Action): project_id = forms.ChoiceField(label=_("Project")) user_id = forms.ChoiceField(label=_("User")) @@ -203,7 +195,7 @@ def clean(self): # however get_available_images uses a cache of image list, # so it is used instead of image_get to reduce the number # of API calls. - images = utils.get_available_images( + images = image_utils.get_available_images( self.request, self.context.get('project_id'), self._images_cache) @@ -217,7 +209,7 @@ def clean(self): # however flavor_list uses a memoized decorator # so it is used instead of flavor_get to reduce the number # of API calls. - flavors = _flavor_list(self.request) + flavors = instance_utils.flavor_list(self.request) flavor = [x for x in flavors if x.id == flavor_id][0] except IndexError: flavor = None @@ -277,30 +269,9 @@ def clean(self): return cleaned_data def populate_flavor_choices(self, request, context): - """By default, returns the available flavors, sorted by RAM - usage (ascending). - Override these behaviours with a CREATE_INSTANCE_FLAVOR_SORT dict - in local_settings.py. - """ - def get_key(flavor, sort_key): - try: - return getattr(flavor, sort_key) - except AttributeError: - LOG.warning('Could not find sort key "%s". Using the default ' - '"ram" instead.', sort_key) - return getattr(flavor, 'ram') - - flavors = _flavor_list(request) + flavors = instance_utils.flavor_list(request) if flavors: - flavor_sort = getattr(settings, 'CREATE_INSTANCE_FLAVOR_SORT', {}) - rev = flavor_sort.get('reverse', False) - sort_key = flavor_sort.get('key', 'ram') - if not callable(sort_key): - key = lambda flavor: get_key(flavor, sort_key) - else: - key = sort_key - return [(flavor.id, "%s" % flavor.name) - for flavor in sorted(flavors, key=key, reverse=rev)] + return instance_utils.sort_flavor_list(request, flavors) return [] def populate_availability_zone_choices(self, request, context): @@ -325,9 +296,10 @@ def get_help_text(self): try: extra['usages'] = api.nova.tenant_absolute_limits(self.request) extra['usages_json'] = json.dumps(extra['usages']) - flavors = json.dumps([f._info for f in _flavor_list(self.request)]) + flavors = json.dumps([f._info for f in + instance_utils.flavor_list(self.request)]) extra['flavors'] = flavors - images = utils.get_available_images(self.request, + images = image_utils.get_available_images(self.request, self.initial['project_id'], self._images_cache) if images is not None: @@ -361,7 +333,7 @@ def _get_volume_display_name(self, volume): def populate_image_id_choices(self, request, context): choices = [] - images = utils.get_available_images(request, + images = image_utils.get_available_images(request, context.get('project_id'), self._images_cache) for image in images: @@ -376,7 +348,7 @@ def populate_image_id_choices(self, request, context): return choices def populate_instance_snapshot_id_choices(self, request, context): - images = utils.get_available_images(request, + images = image_utils.get_available_images(request, context.get('project_id'), self._images_cache) choices = [(image.id, image.name) diff --git a/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py index 72d58495514..afeba8e8065 100644 --- a/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py +++ b/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py @@ -26,6 +26,9 @@ from openstack_dashboard import api +from openstack_dashboard.dashboards.project.instances \ + import utils as instance_utils + class SetFlavorChoiceAction(workflows.Action): old_flavor_id = forms.CharField(required=False, widget=forms.HiddenInput()) @@ -54,14 +57,14 @@ def clean(self): return cleaned_data def populate_flavor_choices(self, request, context): - flavors = context.get('flavors') - flavor_list = [(flavor.id, '%s' % flavor.name) - for flavor in flavors.values()] - if flavor_list: - flavor_list.insert(0, ("", _("Select an New Flavor"))) + flavors = context.get('flavors').values() + if len(flavors) > 1: + flavors = instance_utils.sort_flavor_list(request, flavors) + if flavors: + flavors.insert(0, ("", _("Select a New Flavor"))) else: - flavor_list.insert(0, ("", _("No flavors available"))) - return sorted(flavor_list) + flavors.insert(0, ("", _("No flavors available"))) + return flavors def get_help_text(self): extra = {} @@ -69,7 +72,7 @@ def get_help_text(self): extra['usages'] = api.nova.tenant_absolute_limits(self.request) extra['usages_json'] = json.dumps(extra['usages']) flavors = json.dumps([f._info for f in - api.nova.flavor_list(self.request)]) + instance_utils.flavor_list(self.request)]) extra['flavors'] = flavors except Exception: exceptions.handle(self.request,