def test_list_image_error_public_image_list(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndRaise(self.exceptions.glance) exceptions.handle(IsA(http.HttpRequest), "Unable to retrieve public images.") api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) self.mox.ReplayAll() images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in private_images if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertNotIn('public_images', images_cache) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in self.images.list() if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id]))
def test_list_image_using_cache(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': 'other-tenant', 'status': 'active'}) \ .AndReturn([private_images, False]) self.mox.ReplayAll() expected_images = [ image for image in self.images.list() if (image.status == 'active' and image.container_format not in ( 'ari', 'aki')) ] images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) # image list for other-tenant ret = utils.get_available_images(self.request, 'other-tenant', images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(2, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project']['other-tenant']))
def test_list_image_using_cache(self): public_images = [image for image in self.images.list() if image.status == 'active' and image.is_public] private_images = [image for image in self.images.list() if (image.status == 'active' and not image.is_public)] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': 'other-tenant', 'status': 'active'}) \ .AndReturn([private_images, False]) self.mox.ReplayAll() expected_images = [image for image in self.images.list() if (image.status == 'active' and image.container_format not in ('ari', 'aki'))] images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual( len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) # image list for other-tenant ret = utils.get_available_images(self.request, 'other-tenant', images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual( len(public_images), len(images_cache['public_images'])) self.assertEqual(2, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project']['other-tenant']))
def test_list_image_error_public_image_list(self): public_images = [image for image in self.images.list() if image.status == 'active' and image.is_public] private_images = [image for image in self.images.list() if (image.status == 'active' and not image.is_public)] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndRaise(self.exceptions.glance) exceptions.handle(IsA(http.HttpRequest), "Unable to retrieve public images.") api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) self.mox.ReplayAll() images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [image for image in private_images if image.container_format not in ('ami', 'aki')] self.assertEqual(len(expected_images), len(ret)) self.assertNotIn('public_images', images_cache) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [image for image in self.images.list() if image.container_format not in ('ami', 'aki')] self.assertEqual(len(expected_images), len(ret)) self.assertEqual( len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id]))
def test_list_image(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) self.mox.ReplayAll() ret = utils.get_available_images(self.request, self.tenant.id) expected_images = [ image for image in self.images.list() if (image.status == 'active' and image.container_format not in ( 'ami', 'aki')) ] self.assertEqual(len(expected_images), len(ret))
def populate_instance_snapshot_id_choices(self, request, context): images = utils.get_available_images(request, context.get("project_id"), self._images_cache) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", "") == "snapshot"] if choices: choices.insert(0, ("", _("Select Instance Snapshot"))) else: choices.insert(0, ("", _("No snapshots available."))) return choices
def populate_instance_snapshot_id_choices(self, request, context): images = utils.get_available_images(request, context.get('project_id'), self._images_cache) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", '') == "snapshot"] if choices: choices.insert(0, ("", _("Select Instance Snapshot"))) else: choices.insert(0, ("", _("No snapshots available."))) return choices
def populate_image_id_choices(self, request, context): choices = [] images = utils.get_available_images(request, context.get("project_id"), self._images_cache) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices
def __init__(self, request, *args, **kwargs): super(RebuildInstanceForm, self).__init__(request, *args, **kwargs) instance_id = kwargs.get('initial', {}).get('instance_id') self.fields['instance_id'].initial = instance_id images = utils.get_available_images(request, request.user.tenant_id) choices = [(image.id, image.name) for image in images] if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available."))) self.fields['image'].choices = choices
def populate_image_id_choices(self, request, context): self._init_images_cache() images = get_available_images(request, context.get('project_id'), self._images_cache) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", '') != "snapshot"] if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available."))) return choices
def populate_image_id_choices(self, request, context): choices = [] images = utils.get_available_images(request, context.get('project_id'), self._images_cache) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices
def __init__(self, request, context, *args, **kwargs): super(SetInstanceDetailsAction, self).__init__(request, context, *args, **kwargs) choices = [("", _("Select Image"))] try: images = utils.get_available_images(request, context.get('project_id')) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_id'].choices = choices except Exception: exceptions.handle(self.request, _('Unable to retrieve list of images .'))
def __init__(self, request, *args, **kwargs): super(RebuildInstanceForm, self).__init__(request, *args, **kwargs) instance_id = kwargs.get('initial', {}).get('instance_id') self.fields['instance_id'].initial = instance_id images = utils.get_available_images(request, request.user.tenant_id) choices = [(image.id, image) for image in images] if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) self.fields['image'].choices = choices if not api.nova.can_set_server_password(): del self.fields['password'] del self.fields['confirm_password']
def populate_image_id_choices(self, request, context): choices = [] try: images = utils.get_available_images(request, context.get('project_id')) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) except Exception: exceptions.handle(self.request, _('Unable to retrieve list of images .')) if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices
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 api.nova.flavor_list(self.request)]) extra["flavors"] = flavors images = 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 = {} 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)]) extra['flavors'] = flavors images = 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 = {} 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 api.nova.flavor_list(self.request)]) extra['flavors'] = flavors images = 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 test_list_image(self): public_images = [image for image in self.images.list() if image.status == 'active' and image.is_public] private_images = [image for image in self.images.list() if (image.status == 'active' and not image.is_public)] api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False]) self.mox.ReplayAll() ret = utils.get_available_images(self.request, self.tenant.id) expected_images = [image for image in self.images.list() if (image.status == 'active' and image.container_format not in ('ami', 'aki'))] self.assertEqual(len(expected_images), len(ret))
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields["type"].choices = [("", "")] + [(type.name, type.name) for type in volume_types] self.fields["availability_zone"].choices = self.availability_zones(request) if "snapshot_id" in request.GET: try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields["name"].initial = snapshot.display_name self.fields["size"].initial = snapshot.size self.fields["snapshot_source"].choices = ((snapshot.id, snapshot),) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields["type"].initial = orig_volume.volume_type except Exception: pass self.fields["size"].help_text = _( "Volume size must be equal " "to or greater than the snapshot size (%sGB)" % snapshot.size ) del self.fields["image_source"] del self.fields["volume_source_type"] except Exception: exceptions.handle(request, _("Unable to load the specified snapshot.")) elif "image_id" in request.GET: try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields["name"].initial = image.name self.fields["size"].initial = functions.bytes_to_gigabytes(image.size) self.fields["image_source"].choices = ((image.id, image),) self.fields["size"].help_text = _( "Volume size must be equal " "to or greater than the image size (%s)" % filesizeformat(image.size) ) del self.fields["snapshot_source"] del self.fields["volume_source_type"] except Exception: msg = _("Unable to load the specified image. %s") exceptions.handle(request, msg % request.GET["image_id"]) else: source_type_choices = [] try: snapshot_list = cinder.volume_snapshot_list(request) snapshots = [s for s in snapshot_list if s.status == "available"] if snapshots: source_type_choices.append(("snapshot_source", _("Snapshot"))) choices = [("", _("Choose a snapshot"))] + [(s.id, s) for s in snapshots] self.fields["snapshot_source"].choices = choices else: del self.fields["snapshot_source"] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = utils.get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [("", _("Choose an image"))] for image in images: image.bytes = image.size image.size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields["image_source"].choices = choices else: del self.fields["image_source"] if source_type_choices: choices = [("no_source_type", _("No source, empty volume."))] + source_type_choices self.fields["volume_source_type"].choices = choices else: del self.fields["volume_source_type"]
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) del self.fields['image_source'] del self.fields['volume_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif ('image_id' in request.GET): try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name self.fields['size'].initial = functions.bytes_to_gigabytes( image.size) self.fields['image_source'].choices = ((image.id, image), ) self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the image size (%s)' % filesizeformat(image.size)) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) else: source_type_choices = [] try: snapshots = cinder.volume_snapshot_list(request) if snapshots: source_type_choices.append( ("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = utils.get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] if source_type_choices: choices = ( [('no_source_type', _("No source, empty volume."))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type']
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] self.fields['availability_zone'].choices = \ self.availability_zones(request) if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot),) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _('Volume size must be equal ' 'to or greater than the snapshot size (%sGB)') \ % snapshot.size del self.fields['image_source'] del self.fields['volume_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif ('image_id' in request.GET): try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name min_vol_size = functions.bytes_to_gigabytes( image.size) size_help_text = _('Volume size must be equal to or greater ' 'than the image size (%s)') \ % filesizeformat(image.size) min_disk_size = getattr(image, 'min_disk', 0) if (min_disk_size > min_vol_size): min_vol_size = min_disk_size size_help_text = _('Volume size must be equal to or ' 'greater than the image minimum ' 'disk size (%sGB)') \ % min_disk_size self.fields['size'].initial = min_vol_size self.fields['size'].help_text = size_help_text self.fields['image_source'].choices = ((image.id, image),) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) else: source_type_choices = [] try: snapshot_list = cinder.volume_snapshot_list(request) snapshots = [s for s in snapshot_list if s.status == 'available'] if snapshots: source_type_choices.append(("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = utils.get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] if source_type_choices: choices = ([('no_source_type', _("No source, empty volume."))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type']
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] # Hide the volume encryption field if the hypervisor doesn't support it # NOTE: as of Grizzly this is not yet supported in Nova so enabling # this setting will not do anything useful hypervisor_features = getattr(settings, "OPENSTACK_HYPERVISOR_FEATURES", {}) can_encrypt_volumes = hypervisor_features.get("can_encrypt_volumes", False) if can_encrypt_volumes: # TODO(laura-glendenning) get from api call in future encryption_options = {"LUKS": "dmcrypt LUKS"} self.fields['encryption'].choices = [("", "")] + \ [(enc, display) for enc, display in encryption_options.items()] else: self.fields['encryption'].widget = forms.widgets.HiddenInput() self.fields['encryption'].required = False if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot),) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _('Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) del self.fields['image_source'] del self.fields['volume_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif ('image_id' in request.GET): try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name self.fields['size'].initial = bytes_to_gigabytes(image.size) self.fields['image_source'].choices = ((image.id, image),) self.fields['size'].help_text = _('Volume size must be equal ' 'to or greater than the image size (%s)' % filesizeformat(image.size)) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) else: source_type_choices = [] try: snapshots = cinder.volume_snapshot_list(request) if snapshots: source_type_choices.append(("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] if source_type_choices: choices = ([('no_source_type', _("No source, empty volume."))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type']
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] # Hide the volume encryption field if the hypervisor doesn't support it # NOTE: as of Grizzly this is not yet supported in Nova so enabling # this setting will not do anything useful hypervisor_features = getattr(settings, "OPENSTACK_HYPERVISOR_FEATURES", {}) can_encrypt_volumes = hypervisor_features.get("can_encrypt_volumes", False) if can_encrypt_volumes: # TODO(laura-glendenning) get from api call in future encryption_options = {"LUKS": "dmcrypt LUKS"} self.fields['encryption'].choices = [("", "")] + \ [(enc, display) for enc, display in encryption_options.items()] else: self.fields['encryption'].widget = forms.widgets.HiddenInput() self.fields['encryption'].required = False if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) del self.fields['image_source'] del self.fields['volume_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif ('image_id' in request.GET): try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name self.fields['size'].initial = bytes_to_gigabytes(image.size) self.fields['image_source'].choices = ((image.id, image), ) self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the image size (%s)' % filesizeformat(image.size)) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) else: source_type_choices = [] try: snapshots = cinder.volume_snapshot_list(request) if snapshots: source_type_choices.append( ("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] if source_type_choices: choices = ( [('no_source_type', _("No source, empty volume."))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type']
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 == 'image_id': 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 = 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 = _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. 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_image_id': if not cleaned_data['image_id']: msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) 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]) 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