Пример #1
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        try:
            extra['usages'] = quotas.tenant_quota_usages(
                self.request,
                targets=('instances', 'cores', 'ram', 'volumes', 'gigabytes'))
            extra['usages_json'] = json.dumps(extra['usages'])
            extra['cinder_enabled'] = \
                base.is_service_enabled(self.request, 'volume')
            flavors = json.dumps([f._info for f in
                                  instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, self.initial['project_id'], self._images_cache)
            if images is not None:
                attrs = [{'id': i.id,
                          'min_disk': getattr(i, 'min_disk', 0),
                          'min_ram': getattr(i, 'min_ram', 0),
                          'size': functions.bytes_to_gigabytes(i.size)}
                         for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(SetInstanceDetailsAction, self).get_help_text(extra)
Пример #2
0
 def __init__(self, *args, **kwargs):
     super(LaunchMarketImage, self).__init__(*args, **kwargs)
     self.avail_zone = 'nova'
     name = self.request.user.username.split('@')[0]
     self.instance_name = random_name(prefix=name)
     self.nics = []
     self.private_ip = ''
     self.floating_ip = None
     self.port = None
     self.vpn_username = None
     self.vpn_password = None
     self.success_message = _('Created %(count)s named "%(name)s". '
                              'Please check account and password for this virtual machine in %(email)s.') % {
         "count": _("instance"), "name": self.instance_name, "email": self.request.user.username
     }
     if get_language() == 'en':
         self.vpn_email_template = 'project/instances/vpn_email_en.html'
         self.instance_email_template = 'project/instances/email_instance_info_en.html'
     elif get_language() == 'zh-cn':
         self.vpn_email_template = 'project/instances/vpn_email.html'
         self.instance_email_template = 'project/instances/email_instance_info.html'
     image_id = kwargs.get('initial', {}).get('image_id', "")
     hypervisor_type = 'docker'
     try:
         image = api.glance.image_get(self.request, image_id)
         hypervisor_type = image.properties.get('hypervisor_type', '')
     except Exception:
         pass
     flavors = instance_utils.flavor_list(self.request)
     if flavors:
         self.fields['flavor'].choices = \
             instance_utils.sort_match_flavor_list(self.request, flavors, hypervisor_type)
     self.fields['image_name'].widget.attrs['readonly'] = True
Пример #3
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        try:
            extra['usages'] = quotas.tenant_quota_usages(
                self.request,
                targets=('instances', 'cores', 'ram', 'volumes', 'gigabytes'))
            extra['usages_json'] = json.dumps(extra['usages'])
            extra['cinder_enabled'] = \
                base.is_service_enabled(self.request, 'volume')
            flavors = json.dumps(
                [f._info for f in instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, self.initial['project_id'], self._images_cache)
            if images is not None:
                attrs = [{
                    'id': i.id,
                    'min_disk': getattr(i, 'min_disk', 0),
                    'min_ram': getattr(i, 'min_ram', 0),
                    'size': functions.bytes_to_gigabytes(i.size)
                } for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super().get_help_text(extra)
Пример #4
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        try:
            data = api.order.order_hypervisor(self.request,
                                              self.context['start_time'],
                                              self.context['stop_time'])
            total_restouce = data.get('total_resource', None)
            free_resource = data.get('free_resource', None)
            extra['usages'] = {
                'disk': {
                    'available':
                    free_resource.get('disk', None),
                    'used':
                    total_restouce.get('disk', None) -
                    free_resource.get('disk', None),
                    'quota':
                    total_restouce.get('disk', None),
                },
                'cores': {
                    'available':
                    free_resource.get('vcpus', None),
                    'used':
                    total_restouce.get('vcpus', None) -
                    free_resource.get('vcpus', None),
                    'quota':
                    total_restouce.get('vcpus', None),
                },
                'ram': {
                    'available':
                    free_resource.get('ram', None),
                    'used':
                    total_restouce.get('ram', None) -
                    free_resource.get('ram', None),
                    'quota':
                    total_restouce.get('ram', None),
                }
            }
            extra['usages_json'] = json.dumps(extra['usages'])
            flavors = json.dumps(
                [f._info for f in instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, self.initial['project_id'], self._images_cache)
            if images is not None:
                attrs = [{
                    'id': i.id,
                    'min_disk': getattr(i, 'min_disk', 0),
                    'min_ram': getattr(i, 'min_ram', 0),
                    'size': functions.bytes_to_gigabytes(i.size)
                } for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(SetInstanceDetailsAction, self).get_help_text(extra)
Пример #5
0
 def _get_flavor(self, flavor_id):
     try:
         # We want to retrieve details for a given flavor,
         # however flavor_list uses a memoized decorator
         # so it is used instead of flavor_get to reduce the number
         # of API calls.
         flavors = instance_utils.flavor_list(self.request)
         flavor = [x for x in flavors if x.id == flavor_id][0]
     except IndexError:
         flavor = None
     return flavor
 def _get_flavor(self, flavor_id):
     try:
         # We want to retrieve details for a given flavor,
         # however flavor_list uses a memoized decorator
         # so it is used instead of flavor_get to reduce the number
         # of API calls.
         flavors = instance_utils.flavor_list(self.request)
         flavor = [x for x in flavors if x.id == flavor_id][0]
     except IndexError:
         flavor = None
     return flavor
Пример #7
0
 def get_help_text(self):
     extra = {}
     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
                               instance_utils.flavor_list(self.request)])
         extra['flavors'] = flavors
     except Exception:
         exceptions.handle(self.request,
                           _("Unable to retrieve quota information."))
     return super(SetFlavorChoiceAction, self).get_help_text(extra)
Пример #8
0
 def get_help_text(self):
     extra = {}
     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 instance_utils.flavor_list(self.request)])
         extra['flavors'] = flavors
     except Exception:
         exceptions.handle(self.request,
                           _("Unable to retrieve quota information."))
     return super(SetFlavorChoiceAction, self).get_help_text(extra)
Пример #9
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        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
                                  instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(SetAddSimulationDetailsAction, self).get_help_text(extra)
Пример #10
0
    def _get_flavors(self, request, source_type=None):
        sorted_flavors_list = []

        if source_type:
            flavors = instance_utils.flavor_list(request)
            if flavors:
                new_flavors = []
                for flavor in flavors:
                    flavor_name = str(flavor.name)
                    if flavor_name.startswith(source_type):
                        new_flavors.append(flavor)
                sorted_flavors_list = instance_utils.sort_flavor_list(request, new_flavors)

        return sorted_flavors_list
Пример #11
0
    def _get_flavors(self, request, source_type=None):
        sorted_flavors_list = []

        if source_type:
            flavors = instance_utils.flavor_list(request)
            if flavors:
                new_flavors = []
                for flavor in flavors:
                    flavor_name = str(flavor.name)
                    if flavor_name.startswith(source_type):
                        new_flavors.append(flavor)
                sorted_flavors_list = instance_utils.sort_flavor_list(
                    request, new_flavors)

        return sorted_flavors_list
Пример #12
0
    def __init__(self, *args, **kwargs):
        try:
            request = args[0]
            template_string = ""

            if "template_upload" in kwargs:
                template_upload = kwargs.pop('template_upload')
                super(ImportNodegroupTemplateDetailsForm, self).__init__(
                    *args, **kwargs)

                template_string = template_upload.read()
                self.fields["template"].initial = template_string

            else:
                super(ImportNodegroupTemplateDetailsForm, self).__init__(
                    *args, **kwargs)
                template_string = self.data["template"]

            template_json = json.loads(template_string)
            template_json = template_json["node_group_template"]

            security_group_list = neutron.security_group_list(request)
            security_group_choices = \
                [(sg.id, sg.name) for sg in security_group_list]
            self.fields["security_groups"].choices = security_group_choices

            pools = neutron.floating_ip_pools_list(request)
            pool_choices = [(pool.id, pool.name) for pool in pools]
            pool_choices.insert(0, (None, "Do not assign floating IPs"))
            self.fields["floating_ip_pool"].choices = pool_choices

            flavors = nova_utils.flavor_list(request)
            if flavors:
                self.fields["flavor"].choices = nova_utils.sort_flavor_list(
                    request, flavors)
            else:
                self.fields["flavor"].choices = []

            version = (template_json.get("hadoop_version", None) or
                       template_json["plugin_version"])
            self.fields["image_id"].choices = \
                self._populate_image_choices(request,
                                             template_json["plugin_name"],
                                             version)
        except (ValueError, KeyError):
            raise exceptions.BadRequest(_("Could not parse template"))
        except Exception:
            exceptions.handle(request)
Пример #13
0
    def __init__(self, *args, **kwargs):
        try:
            request = args[0]
            template_string = ""

            if "template_upload" in kwargs:
                template_upload = kwargs.pop('template_upload')
                super(ImportNodegroupTemplateDetailsForm,
                      self).__init__(*args, **kwargs)

                template_string = template_upload.read()
                self.fields["template"].initial = template_string

            else:
                super(ImportNodegroupTemplateDetailsForm,
                      self).__init__(*args, **kwargs)
                template_string = self.data["template"]

            template_json = json.loads(template_string)
            template_json = template_json["node_group_template"]

            security_group_list = neutron.security_group_list(request)
            security_group_choices = \
                [(sg.id, sg.name) for sg in security_group_list]
            self.fields["security_groups"].choices = security_group_choices

            pools = neutron.floating_ip_pools_list(request)
            pool_choices = [(pool.id, pool.name) for pool in pools]
            pool_choices.insert(0, (None, "Do not assign floating IPs"))
            self.fields["floating_ip_pool"].choices = pool_choices

            flavors = nova_utils.flavor_list(request)
            if flavors:
                self.fields["flavor"].choices = nova_utils.sort_flavor_list(
                    request, flavors)
            else:
                self.fields["flavor"].choices = []

            version = (template_json.get("hadoop_version", None)
                       or template_json["plugin_version"])
            self.fields["image_id"].choices = \
                self._populate_image_choices(request,
                                             template_json["plugin_name"],
                                             version)
        except (ValueError, KeyError):
            raise exceptions.BadRequest(_("Could not parse template"))
        except Exception:
            exceptions.handle(request)
Пример #14
0
    def get_help_text(self, extra_context=None):
        extra = extra_context or {}
        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 instance_utils.flavor_list(self.request)])
            extra["flavors"] = flavors
            images = image_utils.get_available_images(self.request, self.initial["project_id"], self._images_cache)
            if images is not None:
                attrs = [
                    {"id": i.id, "min_disk": getattr(i, "min_disk", 0), "min_ram": getattr(i, "min_ram", 0)}
                    for i in images
                ]
                extra["images"] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request, _("Unable to retrieve quota information."))
        return super(SetInstanceDetailsAction, self).get_help_text(extra)
Пример #15
0
def get_dcs(request):
    dcs = []
    for zone in get_zones(request, False):
        try:
            limit = api.proxy.project_absolute_limits(request, zone.id)
            if limit.maxTotalInstances - limit.totalInstancesUsed <= 0:
                disabled = True
            else:
                disabled = zone.disabled
        except:
            disabled = True

        _flavors = instance_utils.flavor_list(request, zone.id)
        flavors = instance_utils.sort_flavor_list(request, _flavors)

        dcs.append({"id": zone.id, "name": zone.name,
                    "disabled": disabled, "flavors": flavors})
    random.shuffle(dcs)

    return HttpResponse(json.dumps({"dcs": dcs}), content_type='application/json')
Пример #16
0
    def get_help_text(self, extra_context=None):
        extra = extra_context or {}
        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
                                  instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, self.initial['project_id'], self._images_cache)
            if images is not None:
                attrs = [{'id': i.id,
                          'min_disk': getattr(i, 'min_disk', 0),
                          'min_ram': getattr(i, 'min_ram', 0)}
                         for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(SetInstanceDetailsAction, self).get_help_text(extra)
Пример #17
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        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
                                  instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, images_cache=self._images_cache)
            if images is not None:
                attrs = [{'id': i.id,
                          'min_disk': getattr(i, 'min_disk', 0),
                          'min_ram': getattr(i, 'min_ram', 0),
                          'size': functions.bytes_to_gigabytes(i.size)}
                         for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(CreateVPNDetailAction, self).get_help_text(extra)
Пример #18
0
    def get_help_text(self):
        extra = {}
        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
                                  instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(self.request,
                                                self.initial['project_id'],
                                                self._images_cache)
            if images is not None:
                attrs = [{'id': i.id,
                          'min_disk': getattr(i, 'min_disk', 0),
                          'min_ram': getattr(i, 'min_ram', 0)}
                          for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(SetInstanceDetailsAction, self).get_help_text(extra)
Пример #19
0
    def get_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        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 instance_utils.flavor_list(self.request)])
            extra['flavors'] = flavors
            images = image_utils.get_available_images(
                self.request, images_cache=self._images_cache)
            if images is not None:
                attrs = [{
                    'id': i.id,
                    'min_disk': getattr(i, 'min_disk', 0),
                    'min_ram': getattr(i, 'min_ram', 0),
                    'size': functions.bytes_to_gigabytes(i.size)
                } for i in images]
                extra['images'] = json.dumps(attrs)

        except Exception:
            exceptions.handle(self.request,
                              _("Unable to retrieve quota information."))
        return super(CreateVPNDetailAction, self).get_help_text(extra)
Пример #20
0
 def __init__(self, *args, **kwargs):
     super(LaunchMarketImage, self).__init__(*args, **kwargs)
     self.avail_zone = 'nova'
     name = self.request.user.username.split('@')[0]
     self.instance_name = random_name(prefix=name)
     self.nics = []
     self.private_ip = ''
     self.floating_ip = None
     self.port = None
     self.vpn_username = None
     self.vpn_password = None
     self.success_message = _(
         'Created %(count)s named "%(name)s". '
         'Please check account and password for this virtual machine in %(email)s.'
     ) % {
         "count": _("instance"),
         "name": self.instance_name,
         "email": self.request.user.username
     }
     if get_language() == 'en':
         self.vpn_email_template = 'project/instances/vpn_email_en.html'
         self.instance_email_template = 'project/instances/email_instance_info_en.html'
     elif get_language() == 'zh-cn':
         self.vpn_email_template = 'project/instances/vpn_email.html'
         self.instance_email_template = 'project/instances/email_instance_info.html'
     image_id = kwargs.get('initial', {}).get('image_id', "")
     hypervisor_type = 'docker'
     try:
         image = api.glance.image_get(self.request, image_id)
         hypervisor_type = image.properties.get('hypervisor_type', '')
     except Exception:
         pass
     flavors = instance_utils.flavor_list(self.request)
     if flavors:
         self.fields['flavor'].choices = \
             instance_utils.sort_match_flavor_list(self.request, flavors, hypervisor_type)
     self.fields['image_name'].widget.attrs['readonly'] = True
Пример #21
0
def flavor_list(request):
    return instance_utils.flavor_list(request)
Пример #22
0
 def populate_flavor_choices(self, request, context):
     flavors = nova_utils.flavor_list(request)
     if flavors:
         return nova_utils.sort_flavor_list(request, flavors)
     return []
Пример #23
0
    def clean(self):
        cleaned_data = super(SetInstanceDetailsAction, self).clean()

        count = cleaned_data.get("count", 1)
        # Prevent launching more instances than the quota allows
        usages = quotas.tenant_quota_usages(self.request)
        available_count = usages["instances"]["available"]
        if available_count < count:
            error_message = ungettext_lazy(
                "The requested instance "
                "cannot be launched as you only "
                "have %(avail)i of your quota "
                "available. ",
                "The requested %(req)i instances "
                "cannot be launched as you only "
                "have %(avail)i of your quota "
                "available.",
                count,
            )
            params = {"req": count, "avail": available_count}
            raise forms.ValidationError(error_message % params)

        # Validate our instance source.
        source_type = self.data.get("source_type", None)

        if source_type in ("image_id", "volume_image_id"):
            if source_type == "volume_image_id":
                if not self.data.get("volume_size", None):
                    msg = _("You must set volume size")
                    self._errors["volume_size"] = self.error_class([msg])
                if not cleaned_data.get("device_name"):
                    msg = _("You must set device name")
                    self._errors["device_name"] = self.error_class([msg])
            if not cleaned_data.get("image_id"):
                msg = _("You must select an image.")
                self._errors["image_id"] = self.error_class([msg])
            else:
                # Prevents trying to launch an image needing more resources.
                try:
                    image_id = cleaned_data.get("image_id")
                    # We want to retrieve details for a given image,
                    # 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 = image_utils.get_available_images(
                        self.request, self.context.get("project_id"), self._images_cache
                    )
                    image = [x for x in images if x.id == image_id][0]
                except IndexError:
                    image = None

                try:
                    flavor_id = cleaned_data.get("flavor")
                    # We want to retrieve details for a given flavor,
                    # however flavor_list uses a memoized decorator
                    # so it is used instead of flavor_get to reduce the number
                    # of API calls.
                    flavors = instance_utils.flavor_list(self.request)
                    flavor = [x for x in flavors if x.id == flavor_id][0]
                except IndexError:
                    flavor = None

                if image and flavor:
                    props_mapping = (("min_ram", "ram"), ("min_disk", "disk"))
                    for iprop, fprop in props_mapping:
                        if getattr(image, iprop) > 0 and getattr(image, iprop) > getattr(flavor, fprop):
                            msg = _(
                                "The flavor '%(flavor)s' is too small "
                                "for requested image.\n"
                                "Minimum requirements: "
                                "%(min_ram)s MB of RAM and "
                                "%(min_disk)s GB of Root Disk."
                            ) % {"flavor": flavor.name, "min_ram": image.min_ram, "min_disk": image.min_disk}
                            self._errors["image_id"] = self.error_class([msg])
                            break  # Not necessary to continue the tests.

                    volume_size = cleaned_data.get("volume_size")
                    if volume_size and source_type == "volume_image_id":
                        volume_size = int(volume_size)
                        img_gigs = functions.bytes_to_gigabytes(image.size)
                        smallest_size = max(img_gigs, image.min_disk)
                        if volume_size < smallest_size:
                            msg = _(
                                "The Volume size is too small for the"
                                " '%(image_name)s' image and has to be"
                                " greater than or equal to "
                                "'%(smallest_size)d' GB."
                            ) % {"image_name": image.name, "smallest_size": smallest_size}
                            self._errors["volume_size"] = self.error_class([msg])

        elif source_type == "instance_snapshot_id":
            if not cleaned_data["instance_snapshot_id"]:
                msg = _("You must select a snapshot.")
                self._errors["instance_snapshot_id"] = self.error_class([msg])

        elif source_type == "volume_id":
            if not cleaned_data.get("volume_id"):
                msg = _("You must select a volume.")
                self._errors["volume_id"] = self.error_class([msg])
            # Prevent launching multiple instances with the same volume.
            # TODO(gabriel): is it safe to launch multiple instances with
            # a snapshot since it should be cloned to new volumes?
            if count > 1:
                msg = _("Launching multiple instances is only supported for " "images and instance snapshots.")
                raise forms.ValidationError(msg)

        elif source_type == "volume_snapshot_id":
            if not cleaned_data.get("volume_snapshot_id"):
                msg = _("You must select a snapshot.")
                self._errors["volume_snapshot_id"] = self.error_class([msg])
            if not cleaned_data.get("device_name"):
                msg = _("You must set device name")
                self._errors["device_name"] = self.error_class([msg])

        return cleaned_data
Пример #24
0
 def _flavor_choices(self, request):
     flavors = utils.flavor_list(request)
     if flavors:
         return utils.sort_flavor_list(request, flavors)
     return []
Пример #25
0
def flavor_get(request, flavor_id):
    flavors = instance_utils.flavor_list(request)
    flavor = [x for x in flavors if x.id == flavor_id][0]
    return flavor
Пример #26
0
    def clean(self):
        cleaned_data = super(SetInstanceDetailsAction, self).clean()

        count = cleaned_data.get('count', 1)
        # Prevent launching more instances than the quota allows
        usages = quotas.tenant_quota_usages(self.request)
        available_count = usages['instances']['available']
        if available_count < count:
            error_message = ungettext_lazy(
                'The requested instance '
                'cannot be launched as you only '
                'have %(avail)i of your quota '
                'available. ', 'The requested %(req)i instances '
                'cannot be launched as you only '
                'have %(avail)i of your quota '
                'available.', count)
            params = {'req': count, 'avail': available_count}
            raise forms.ValidationError(error_message % params)
        try:
            flavor_id = cleaned_data.get('flavor')
            # We want to retrieve details for a given flavor,
            # however flavor_list uses a memoized decorator
            # so it is used instead of flavor_get to reduce the number
            # of API calls.
            flavors = instance_utils.flavor_list(self.request)
            flavor = [x for x in flavors if x.id == flavor_id][0]
        except IndexError:
            flavor = None

        count_error = []
        # Validate cores and ram.
        available_cores = usages['cores']['available']
        if flavor and available_cores < count * flavor.vcpus:
            count_error.append(
                _("Cores(Available: %(avail)s, "
                  "Requested: %(req)s)") % {
                      'avail': available_cores,
                      'req': count * flavor.vcpus
                  })

        available_ram = usages['ram']['available']
        if flavor and available_ram < count * flavor.ram:
            count_error.append(
                _("RAM(Available: %(avail)s, "
                  "Requested: %(req)s)") % {
                      'avail': available_ram,
                      'req': count * flavor.ram
                  })

        if count_error:
            value_str = ", ".join(count_error)
            msg = (_('The requested instance cannot be launched. '
                     'The following requested resource(s) exceed '
                     'quota(s): %s.') % value_str)
            if count == 1:
                self._errors['flavor'] = self.error_class([msg])
            else:
                self._errors['count'] = self.error_class([msg])

        # Validate our instance source.
        source_type = self.data.get('source_type', None)

        if source_type in ('image_id', 'volume_image_id'):
            if source_type == 'volume_image_id':
                volume_size = self.data.get('volume_size', None)
                if not volume_size:
                    msg = _("You must set volume size")
                    self._errors['volume_size'] = self.error_class([msg])
                if float(volume_size) <= 0:
                    msg = _("Volume size must be greater than 0")
                    self._errors['volume_size'] = self.error_class([msg])
                if not cleaned_data.get('device_name'):
                    msg = _("You must set device name")
                    self._errors['device_name'] = self.error_class([msg])
            if not cleaned_data.get('image_id'):
                msg = _("You must select an image.")
                self._errors['image_id'] = self.error_class([msg])
            else:
                # Prevents trying to launch an image needing more resources.
                try:
                    image_id = cleaned_data.get('image_id')
                    # We want to retrieve details for a given image,
                    # 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 = image_utils.get_available_images(
                        self.request, self.context.get('project_id'),
                        self._images_cache)
                    image = [x for x in images if x.id == image_id][0]
                except IndexError:
                    image = None

                if image and flavor:
                    props_mapping = (("min_ram", "ram"), ("min_disk", "disk"))
                    for iprop, fprop in props_mapping:
                        if getattr(image, iprop) > 0 and \
                                getattr(image, iprop) > getattr(flavor, fprop):
                            msg = (_("The flavor '%(flavor)s' is too small "
                                     "for requested image.\n"
                                     "Minimum requirements: "
                                     "%(min_ram)s MB of RAM and "
                                     "%(min_disk)s GB of Root Disk.") % {
                                         'flavor': flavor.name,
                                         'min_ram': image.min_ram,
                                         'min_disk': image.min_disk
                                     })
                            self._errors['image_id'] = self.error_class([msg])
                            break  # Not necessary to continue the tests.

                    volume_size = cleaned_data.get('volume_size')
                    if volume_size and source_type == 'volume_image_id':
                        volume_size = int(volume_size)
                        img_gigs = functions.bytes_to_gigabytes(image.size)
                        smallest_size = max(img_gigs, image.min_disk)
                        if volume_size < smallest_size:
                            msg = (_("The Volume size is too small for the"
                                     " '%(image_name)s' image and has to be"
                                     " greater than or equal to "
                                     "'%(smallest_size)d' GB.") % {
                                         'image_name': image.name,
                                         'smallest_size': smallest_size
                                     })
                            self._errors['volume_size'] = self.error_class(
                                [msg])

        elif source_type == 'instance_snapshot_id':
            if not cleaned_data['instance_snapshot_id']:
                msg = _("You must select a snapshot.")
                self._errors['instance_snapshot_id'] = self.error_class([msg])

        elif source_type == 'volume_id':
            if not cleaned_data.get('volume_id'):
                msg = _("You must select a volume.")
                self._errors['volume_id'] = self.error_class([msg])
            # Prevent launching multiple instances with the same volume.
            # TODO(gabriel): is it safe to launch multiple instances with
            # a snapshot since it should be cloned to new volumes?
            if count > 1:
                msg = _('Launching multiple instances is only supported for '
                        'images and instance snapshots.')
                raise forms.ValidationError(msg)

        elif source_type == 'volume_snapshot_id':
            if not cleaned_data.get('volume_snapshot_id'):
                msg = _("You must select a snapshot.")
                self._errors['volume_snapshot_id'] = self.error_class([msg])
            if not cleaned_data.get('device_name'):
                msg = _("You must set device name")
                self._errors['device_name'] = self.error_class([msg])

        return cleaned_data
Пример #27
0
 def get_context_data(self, **kwargs):
     context = super(LaunchMarketImageView, self).get_context_data(**kwargs)
     context['image'] = self.get_object()
     context['flavors'] = json.dumps([f._info for f in
                                      instance_utils.flavor_list(self.request)])
     return context
Пример #28
0
    def clean(self):
        cleaned_data = super(SetInstanceDetailsAction, self).clean()

        count = cleaned_data.get('count', 1)
        # Prevent launching more instances than the quota allows
        usages = quotas.tenant_quota_usages(self.request)
        available_count = usages['instances']['available']
        if available_count < count:
            error_message = ungettext_lazy('The requested instance '
                                           'cannot be launched as you only '
                                           'have %(avail)i of your quota '
                                           'available. ',
                                           'The requested %(req)i instances '
                                           'cannot be launched as you only '
                                           'have %(avail)i of your quota '
                                           'available.',
                                           count)
            params = {'req': count,
                      'avail': available_count}
            raise forms.ValidationError(error_message % params)
        try:
            flavor_id = cleaned_data.get('flavor')
            # We want to retrieve details for a given flavor,
            # however flavor_list uses a memoized decorator
            # so it is used instead of flavor_get to reduce the number
            # of API calls.
            flavors = instance_utils.flavor_list(self.request)
            flavor = [x for x in flavors if x.id == flavor_id][0]
        except IndexError:
            flavor = None

        count_error = []
        # Validate cores and ram.
        available_cores = usages['cores']['available']
        if flavor and available_cores < count * flavor.vcpus:
            count_error.append(_("Cores(Available: %(avail)s, "
                                 "Requested: %(req)s)")
                    % {'avail': available_cores,
                       'req': count * flavor.vcpus})

        available_ram = usages['ram']['available']
        if flavor and available_ram < count * flavor.ram:
            count_error.append(_("RAM(Available: %(avail)s, "
                                 "Requested: %(req)s)")
                    % {'avail': available_ram,
                       'req': count * flavor.ram})

        if count_error:
            value_str = ", ".join(count_error)
            msg = (_('The requested instance cannot be launched. '
                     'The following requested resource(s) exceed '
                     'quota(s): %s.') % value_str)
            if count == 1:
                self._errors['flavor'] = self.error_class([msg])
            else:
                self._errors['count'] = self.error_class([msg])

        # Validate our instance source.
        source_type = self.data.get('source_type', None)

        if source_type in ('image_id', 'volume_image_id'):
            if source_type == 'volume_image_id':
                if not self.data.get('volume_size', None):
                    msg = _("You must set volume size")
                    self._errors['volume_size'] = self.error_class([msg])
                if not cleaned_data.get('device_name'):
                    msg = _("You must set device name")
                    self._errors['device_name'] = self.error_class([msg])
            if not cleaned_data.get('image_id'):
                msg = _("You must select an image.")
                self._errors['image_id'] = self.error_class([msg])
            else:
                # Prevents trying to launch an image needing more resources.
                try:
                    image_id = cleaned_data.get('image_id')
                    # We want to retrieve details for a given image,
                    # 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 = image_utils.get_available_images(
                        self.request,
                        self.context.get('project_id'),
                        self._images_cache)
                    image = [x for x in images if x.id == image_id][0]
                except IndexError:
                    image = None

                if image and flavor:
                    props_mapping = (("min_ram", "ram"), ("min_disk", "disk"))
                    for iprop, fprop in props_mapping:
                        if getattr(image, iprop) > 0 and \
                                getattr(image, iprop) > getattr(flavor, fprop):
                            msg = (_("The flavor '%(flavor)s' is too small "
                                     "for requested image.\n"
                                     "Minimum requirements: "
                                     "%(min_ram)s MB of RAM and "
                                     "%(min_disk)s GB of Root Disk.") %
                                   {'flavor': flavor.name,
                                    'min_ram': image.min_ram,
                                    'min_disk': image.min_disk})
                            self._errors['image_id'] = self.error_class([msg])
                            break  # Not necessary to continue the tests.

                    volume_size = cleaned_data.get('volume_size')
                    if volume_size and source_type == 'volume_image_id':
                        volume_size = int(volume_size)
                        img_gigs = functions.bytes_to_gigabytes(image.size)
                        smallest_size = max(img_gigs, image.min_disk)
                        if volume_size < smallest_size:
                            msg = (_("The Volume size is too small for the"
                                     " '%(image_name)s' image and has to be"
                                     " greater than or equal to "
                                     "'%(smallest_size)d' GB.") %
                                   {'image_name': image.name,
                                    'smallest_size': smallest_size})
                            self._errors['volume_size'] = self.error_class(
                                [msg])

        elif source_type == 'instance_snapshot_id':
            if not cleaned_data['instance_snapshot_id']:
                msg = _("You must select a snapshot.")
                self._errors['instance_snapshot_id'] = self.error_class([msg])

        elif source_type == 'volume_id':
            if not cleaned_data.get('volume_id'):
                msg = _("You must select a volume.")
                self._errors['volume_id'] = self.error_class([msg])
            # Prevent launching multiple instances with the same volume.
            # TODO(gabriel): is it safe to launch multiple instances with
            # a snapshot since it should be cloned to new volumes?
            if count > 1:
                msg = _('Launching multiple instances is only supported for '
                        'images and instance snapshots.')
                raise forms.ValidationError(msg)

        elif source_type == 'volume_snapshot_id':
            if not cleaned_data.get('volume_snapshot_id'):
                msg = _("You must select a snapshot.")
                self._errors['volume_snapshot_id'] = self.error_class([msg])
            if not cleaned_data.get('device_name'):
                msg = _("You must set device name")
                self._errors['device_name'] = self.error_class([msg])

        return cleaned_data
Пример #29
0
 def populate_flavor_choices(self, request, context):
     flavors = instance_utils.flavor_list(request)
     if flavors:
         return instance_utils.sort_flavor_list(request, flavors)
     return []
Пример #30
0
 def _flavor_choices(self, request):
     flavors = utils.flavor_list(request)
     if flavors:
         return utils.sort_flavor_list(request, flavors)
     return []