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)
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
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)
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)
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_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)
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)
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)
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
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
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)
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)
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)
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')
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)
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)
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)
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)
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
def flavor_list(request): return instance_utils.flavor_list(request)
def populate_flavor_choices(self, request, context): flavors = nova_utils.flavor_list(request) if flavors: return nova_utils.sort_flavor_list(request, flavors) return []
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
def _flavor_choices(self, request): flavors = utils.flavor_list(request) if flavors: return utils.sort_flavor_list(request, flavors) return []
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
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
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
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
def populate_flavor_choices(self, request, context): flavors = instance_utils.flavor_list(request) if flavors: return instance_utils.sort_flavor_list(request, flavors) return []