Example #1
0
    def test_list_image_error_private_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"}
        ).AndReturn([public_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"}
        ).AndRaise(self.exceptions.glance)
        exceptions.handle(IsA(http.HttpRequest), "Unable to retrieve images for the current project.")
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"}
        ).AndReturn([private_images, False, False])

        self.mox.ReplayAll()

        images_cache = {}
        ret = utils.get_available_images(self.request, self.tenant.id, images_cache)

        expected_images = [image for image in public_images 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.assertFalse(len(images_cache["images_by_project"]))

        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]))
Example #2
0
    def test_list_image_communication_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(
            glance_exec.CommunicationError
        )
        # Make sure the exception is handled with the correct
        # error message. If the exception cannot be handled,
        # the error message will be different.
        messages.error(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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"is_public": True, "status": "active"}
        ).AndReturn([public_images, False, 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]))
Example #3
0
    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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': self.tenant.id,
                     'status': 'active'}) \
            .AndReturn([private_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': 'other-tenant',
                     'status': 'active'}) \
            .AndReturn([private_images, False, 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']))
Example #4
0
    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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'is_public': True, 'status': 'active'}) \
            .AndReturn([public_images, False, 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]))
Example #5
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)
Example #6
0
    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)]
        shared_images = [image for image in self.imagesV2.list()
                         if (image.status == 'active' and
                             image.visibility == 'shared')]
        self.mock_image_list.side_effect = [
            [public_images, False, False],
            [private_images, False, False],
            [shared_images, False, False]
        ]

        image_calls = [
            mock.call(test.IsHttpRequest(),
                      filters={'is_public': True, 'status': 'active'}),
            mock.call(test.IsHttpRequest(),
                      filters={'property-owner_id': self.tenant.id,
                               'status': 'active'}),
            mock.call(test.IsHttpRequest(),
                      filters={'visibility': 'shared', 'status': 'active'})
        ]

        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.mock_image_list.assert_has_calls(image_calls)
        self.assertEqual(len(expected_images), len(ret))
Example #7
0
    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']

        try:
            if not api.nova.extension_supported("DiskConfig", request):
                del self.fields['disk_config']
            else:
                # Set our disk_config choices
                config_choices = [("AUTO", _("Automatic")),
                                  ("MANUAL", _("Manual"))]
                self.fields['disk_config'].choices = config_choices
        except Exception:
            exceptions.handle(request, _('Unable to retrieve extensions '
                                         'information.'))
Example #8
0
    def get_data(self):
        token = self.request.user.token.id
        headers = {}
        headers['Accept'] = 'application/json'
        headers['X-Auth-Token'] = token

        graffiti_url = getattr(settings, 'GRAFFITI_URL', '')

        req = urllib2.Request(graffiti_url + "resource?query_string={%22resource_types%22%20:%20[%22OS::Glance::Image%22,%22OS::Glance::Snapshot%22]}", headers=headers)
        f = urllib2.urlopen(req)
        resources = json.loads(f.read())
        f.close()

        boot_images = image_utils.get_available_images(self.request,
                                            self.request.user.project_id)
        boot_images_ids = []
        for image in boot_images:
            boot_images_ids.append(image.id)

        boot_resources = []
        for resource in resources:
            if resource['id'] in boot_images_ids:
                boot_resources.append(resource)

	req = urllib2.Request(graffiti_url + "resource?query_string={%22resource_types%22%20:%20[%22OS::Cinder::Volume%22,%22OS::Cinder::VolumeSnapshot%22]}", headers=headers)
        f = urllib2.urlopen(req)
        resources = json.loads(f.read())
        f.close()

        for resource in resources:
            volume = api.cinder.volume_get(self.request, resource['id'])
            if volume._apiresource.bootable:
                boot_resources.append(resource)

        return boot_resources
    def populate_image_id_choices(self, request, context):
        choices = []
        image_dict = {}
        #images = image_utils.get_available_images(request,
        #                                    context.get('zone_id'),
        #                                    images_cache=self._images_cache)
        try:
            zones = api.proxy.availability_zone_list(request)
        except:
            zones = []
            exceptions.handle(request, _('Unable to retrieve zones.'), ignore=True)

        for zone in zones:
            images = image_utils.get_available_images(
                    request, zone.id, images_cache=self._images_cache)
            for image in images:
                image_dict[image.name] = image

        for image in image_dict.values():
            image.bytes = image.size
            image.volume_size = max(
                image.min_disk, functions.bytes_to_gigabytes(image.bytes))
            choices.append((image.imageid, image))
        if choices:
            choices.sort(key=lambda c: c[1].name)
            choices.insert(0, ("", _("Select Image")))
        else:
            choices.insert(0, ("", _("No images available")))
        return choices
Example #10
0
 def __init__(self, request, *args, **kwargs):
     super(RescueInstanceForm, self).__init__(request, *args, **kwargs)
     images = image_utils.get_available_images(request,
                                               request.user.tenant_id)
     choices = [(image.id, image) for image in images]
     if not choices:
         choices.insert(0, ("", _("No images available")))
     self.fields['image'].choices = choices
Example #11
0
 def populate_instance_snapshot_id_choices(self, request, context):
     images = image_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.sort(key=operator.itemgetter(1))
         choices.insert(0, ("", _("Select Instance Snapshot")))
     else:
         choices.insert(0, ("", _("No snapshots available")))
     return choices
Example #12
0
 def __init__(self, request, *args, **kwargs):
     super(RebuildForm, self).__init__(request, *args, **kwargs)
     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
Example #13
0
 def update(self, request, **kwargs):
     try:
         images = image_utils.get_available_images(request, request.user.tenant_id, None)
     except Exception:
         images = []
         exceptions.handle(request, _("Unable to retrieve volume types."))
     choices = [(image.id, image.name) for image in images]
     if not choices:
         choices.insert(0, ("", _("No images available")))
     self.choices = choices
Example #14
0
 def _get_image(self, image_id):
     try:
         # 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
     return image
Example #15
0
    def get_data(self):
        zones = []
        image_dict = {}
        instances = []
        try:
            instances = api.proxy.server_list(self.request)
        except:
            servers = []
            exceptions.handle(self.request,
                              _('Unable to retrieve instances.'),
                              ignore=True)

        try:
            for zone in api.proxy.availability_zone_list(self.request, True):
                zones.append(zone)
                try:
                    images = SortedDict([(image.imageid, image) for image in
                         image_utils.get_available_images(self.request, zone.id)])
                except:
                    images = {}
                image_dict.update(images)
        except:
            zones = []
            exceptions.handle(self.request, _('Unable to retrieve zones.'), ignore=True)

#        zone_dict = SortedDict([(zone.id, zone.name) for zone in zones])
#
#        gateway_dict = SortedDict([(g.hostname, g.ext_ip)
#                                  for g in api.proxy.gateway_list(self.request)])
        for instance in instances:
#            if zone_dict.has_key(instance.availability_zone):
#                instance.availability_zone = zone_dict[instance.availability_zone]

            image = image_dict.get(instance.image_id)
            if image:
                instance.image_name = image.name
                if image.container_format == 'docker':
                    instance.instance_type = 'Docker'
                    instance.image_name += '(Container)'
                else:
                    instance.instance_type = 'VM'
                    instance.image_name += '(VM)'
            else:
                instance.image_name = instance.image_id

#            firewall = [(gateway_dict.get(f.hostname), f.gateway_port) for f in
#                        api.proxy.firewall_get(self.request, instance.id)]
#            if firewall:
#                instance.gateway = '%s:%s' % firewall[0]
#            else:
#                instance.gateway= ''

        return instances
 def __init__(self, request, *args, **kwargs):
     super(LaunchInstance, self).__init__(request, *args, **kwargs)
     images = imageutils.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")))
     zones = self._availability_zone_choices(request)
     self.fields['image'].choices = choices
     self.fields['availability_zone'].choices = zones
     self.fields['flavor'].choices = self._flavor_choices(request)
Example #17
0
def get_images(request):
    _images = []
    _type = {"docker": "container", "container": "container"}
    for zone in get_zones(request):
        images = image_utils.get_available_images(request, zone.id)
        for image in images:
            _images.append({'id': image.imageid, 'name': image.name,
                           'type': image.display_format,
                           'category': _type.get(image.container_format, 'vm'),
                           'class': image.display_format,
                           'dc_id': zone.id,
                           'dc_name': zone.name})
    return _images
Example #18
0
 def _get_image(self, image_id):
     try:
         # 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
     return image
Example #19
0
 def populate_instance_snapshot_id_choices(self, request, context):
     images = image_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.sort(key=operator.itemgetter(1))
         choices.insert(0, ("", _("Select Instance Snapshot")))
     else:
         choices.insert(0, ("", _("No snapshots available")))
     return choices
Example #20
0
    def prepare_source_fields_default(self, request):
        source_type_choices = []
        self.fields['availability_zone'].choices = \
            self.availability_zones(request)

        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']

        volumes = self.get_volumes(request)
        if volumes:
            source_type_choices.append(("volume_source", _("Volume")))
            choices = [('', _("Choose a volume"))]
            for volume in volumes:
                choices.append((volume.id, volume))
            self.fields['volume_source'].choices = choices
        else:
            del self.fields['volume_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']
Example #21
0
    def prepare_source_fields_default(self, request):
        source_type_choices = []
        self.fields['availability_zone'].choices = \
            availability_zones(request)

        try:
            available = api.cinder.VOLUME_STATE_AVAILABLE
            snapshots = cinder.volume_snapshot_list(
                request, search_opts=dict(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']

        volumes = self.get_volumes(request)
        if volumes:
            source_type_choices.append(("volume_source", _("Volume")))
            choices = [('', _("Choose a volume"))]
            for volume in volumes:
                choices.append((volume.id, volume))
            self.fields['volume_source'].choices = choices
        else:
            del self.fields['volume_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']
Example #22
0
    def test_list_image_error_public_image_list(self, mock_exception_handle):
        private_images = [image for image in self.images.list()
                          if (image.status == 'active' and
                              not image.is_public)]
        community_images = [image for image in self.imagesV2.list()
                            if (image.status == 'active' and
                                image.visibility == 'community')]
        shared_images = [image for image in self.imagesV2.list()
                         if (image.status == 'active' and
                             image.visibility == 'shared')]

        self.mock_image_list.side_effect = [
            self.exceptions.glance,
            [private_images, False, False],
            [community_images, False, False],
            [shared_images, False, False]
        ]

        images_cache = {}
        ret = utils.get_available_images(self.request, self.tenant.id,
                                         images_cache)
        image_calls = [
            mock.call(test.IsHttpRequest(),
                      filters={'is_public': True, 'status': 'active'}),
            mock.call(test.IsHttpRequest(),
                      filters={'status': 'active', 'property-owner_id': '1'}),
            mock.call(test.IsHttpRequest(),
                      filters={'visibility': 'community', 'status': 'active'}),
            mock.call(test.IsHttpRequest(),
                      filters={'visibility': 'shared', 'status': 'active'})
        ]
        self.mock_image_list.assert_has_calls(image_calls)
        mock_exception_handle.assert_called_once_with(
            test.IsHttpRequest(),
            "Unable to retrieve public images.")

        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]))
        self.assertEqual(
            len(community_images),
            len(images_cache['community_images']))
        self.assertEqual(
            len(shared_images),
            len(images_cache['shared_images']))
Example #23
0
    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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"}
        ).AndReturn([private_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"property-owner_id": "other-tenant", "status": "active"}
        ).AndReturn([private_images, False, 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"]))
Example #24
0
 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.sort(key=lambda c: c[1].name)
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #25
0
 def populate_image_id_choices(self, request, context):
     choices = []
     images = image_utils.get_available_images(request, context.get("project_id"), self._images_cache)
     for image in images:
         image.bytes = getattr(image, "virtual_size", None) or image.size
         image.volume_size = max(image.min_disk, functions.bytes_to_gigabytes(image.bytes))
         choices.append((image.id, image))
         if context.get("image_id") == image.id and "volume_size" not in context:
             context["volume_size"] = image.volume_size
     if choices:
         choices.sort(key=lambda c: c[1].name or "")
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #26
0
    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']
Example #27
0
 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)
         img_attr = image.properties.get(IMG_ATTR, None)
         if img_attr is not None:
             choices.append((image.id, image))
     if choices:
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #28
0
    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']
Example #29
0
    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)
        ]
        shared_images = [
            image for image in self.imagesV2.list()
            if (image.status == 'active' and image.visibility == 'shared')
        ]
        self.mock_image_list.side_effect = [[public_images, False, False],
                                            [private_images, False, False],
                                            [shared_images, False, False]]

        image_calls = [
            mock.call(test.IsHttpRequest(),
                      filters={
                          'is_public': True,
                          'status': 'active'
                      }),
            mock.call(test.IsHttpRequest(),
                      filters={
                          'property-owner_id': self.tenant.id,
                          'status': 'active'
                      }),
            mock.call(test.IsHttpRequest(),
                      filters={
                          'visibility': 'shared',
                          'status': 'active'
                      })
        ]

        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.mock_image_list.assert_has_calls(image_calls)
        self.assertEqual(len(expected_images), len(ret))
Example #30
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)
Example #31
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)

            for quota in cinder.tenant_quota_get(self.request,
                                                 self.request.user.tenant_id):
                if quota.name == 'gigabytes_Tier1':
                    extra['usages']['maxTotalTier1Size'] = quota.limit

            totalTier1Used = 0

            volumes = []  # needed later for getting snapshot type
            for volume in cinder.volume_list(self.request):
                if volume.volume_type == 'Tier1':
                    volumes.append(volume.id)
                    totalTier1Used += volume.size

            for snapshot in cinder.volume_snapshot_list(self.request):
                if snapshot.volume_id in volumes:
                    totalTier1Used += snapshot.size

            extra['usages']['totalTier1Used'] = totalTier1Used

            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 populate_image_id_choices(self, request, context):
     choices = []
     images = image_utils.get_available_images(request,
                                               context.get('project_id'),
                                               self._images_cache)
     for image in images:
         image.bytes = getattr(image, 'virtual_size', None) or image.size
         image.volume_size = max(image.min_disk,
                                 functions.bytes_to_gigabytes(image.bytes))
         choices.append((image.id, image))
         if context.get('image_id') == image.id and \
                 'volume_size' not in context:
             context['volume_size'] = image.volume_size
     if choices:
         choices.sort(key=lambda c: c[1].name or '')
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #33
0
    def test_list_image_error_public_image_list(self, mock_exception_handle):
        private_images = [image for image in self.images.list()
                          if (image.status == 'active' and
                              not image.is_public)]
        shared_images = [image for image in self.imagesV2.list()
                         if (image.status == 'active' and
                             image.visibility == 'shared')]

        self.mock_image_list.side_effect = [
            self.exceptions.glance,
            [private_images, False, False],
            [shared_images, False, False],
            ]

        images_cache = {}
        ret = utils.get_available_images(self.request, self.tenant.id,
                                         images_cache)
        image_calls = [
            mock.call(test.IsHttpRequest(),
                      filters={'is_public': True, 'status': 'active'}),
            mock.call(test.IsHttpRequest(),
                      filters={'status': 'active', 'property-owner_id': '1'}),
            mock.call(test.IsHttpRequest(),
                      filters={'visibility': 'shared', 'status': 'active'})
        ]
        self.mock_image_list.assert_has_calls(image_calls)
        handle_calls = [
            mock.call(test.IsHttpRequest(),
                      "Unable to retrieve public images."),
        ]
        mock_exception_handle.assert_has_calls(handle_calls)

        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]))
        self.assertEqual(
            len(shared_images),
            len(images_cache['shared_images']))
Example #34
0
    def prepare_source_fields_default(self, request):
        source_type_choices = []
        self.fields["availability_zone"].choices = self.availability_zones(request)

        try:
            available = api.cinder.VOLUME_STATE_AVAILABLE
            snapshots = cinder.volume_snapshot_list(request, search_opts=dict(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"]

        volumes = self.get_volumes(request)
        if volumes:
            source_type_choices.append(("volume_source", _("Volume")))
            choices = [("", _("Choose a volume"))]
            for volume in volumes:
                choices.append((volume.id, volume))
            self.fields["volume_source"].choices = choices
        else:
            del self.fields["volume_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"]
Example #35
0
    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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"}
        ).AndReturn([private_images, False, 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))
Example #36
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 _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)
Example #37
0
 def populate_image_id_choices(self, request, context):
     choices = []
     images = image_utils.get_available_images(request,
                                               context.get('project_id'),
                                               self._images_cache)
     for image in images:
         if image.properties.get("image_type", '') != "snapshot":
             image.bytes = getattr(
                 image, 'virtual_size', None) or image.size
             image.volume_size = max(
                 image.min_disk, functions.bytes_to_gigabytes(image.bytes))
             choices.append((image.id, image))
             if context.get('image_id') == image.id and \
                     'volume_size' not in context:
                 context['volume_size'] = image.volume_size
     if choices:
         choices.sort(key=lambda c: c[1].name or '')
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #38
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)
Example #39
0
 def populate_image_id_choices(self, request, context):
     choices = []
     images = image_utils.get_available_images(request,
                                         context.get('project_id'),
                                         self._images_cache)
     for image in images:
         image.bytes = image.size
         image.volume_size = max(
             image.min_disk, functions.bytes_to_gigabytes(image.bytes))
         # Commit @ https://github.com/JioCloud/horizon/commit/9e3766a608da0ba2ca78bd9091308817311cd320
         # Do not show instance snapshots in image list.
         if image.properties.get('image_type', '') != 'snapshot':
             choices.append((image.id, image))
         if context.get('image_id') == image.id and \
                 'volume_size' not in context:
             context['volume_size'] = image.volume_size
     if choices:
         choices.sort(key=lambda c: c[1].name)
         choices.insert(0, ("", _("Select Image")))
     else:
         choices.insert(0, ("", _("No images available")))
     return choices
Example #40
0
    def populate_image_id_choices(self, request, context):
        choices = []
        images = image_utils.get_available_images(request,
                                                  context.get('project_id'),
                                                  self._images_cache)

        # prepare account plan marks
        plans = dict([(plan['id'], plan) for plan in get_plans(request)])
        marks = []
        for plan_map in get_project_plan_mappings(request,
                                                  context.get('project_id')):
            plan = plans.get(plan_map['plan_id'])
            if plan:
                mark = plan.get('metadata_mark')
                if mark:
                    marks.append(mark.upper())

        for image in images:
            # filter out image by `astute_plan_mark`
            if marks:
                plan_mark = image.properties.get('astute_plan_mark')
                if plan_mark and not plan_mark.upper() in marks:
                    continue
            image.bytes = getattr(image, 'virtual_size', None) or image.size
            image.volume_size = max(image.min_disk,
                                    functions.bytes_to_gigabytes(image.bytes))
            choices.append((image.id, image))
            if context.get('image_id') == image.id and \
                    'volume_size' not in context:
                context['volume_size'] = image.volume_size
        if choices:
            #choices.sort(key=lambda c: c[1].name)
            #Converting to lowercase for sorting in alphabetical order
            choices.sort(key=lambda c: c[1].name.lower())

            choices.insert(0, ("", _("Select Image")))
        else:
            choices.insert(0, ("", _("No images available")))
        return choices
Example #41
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)
Example #42
0
    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))
Example #43
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'])
            # delete by zhihao.ding 2015/7/16 for kill_flavor start
            #flavors = json.dumps([f._info for f in instance_utils.flavor_list(self.request)])
            #extra['flavors'] = flavors
            # delete by zhihao.ding 2015/7/16 for kill_flavor start
            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_help_text(self, extra_context=None):
        extra = {} if extra_context is None else dict(extra_context)
        try:
            extra['usages'] = quotas.tenant_limit_usages(self.request)
            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)
Example #45
0
    def test_list_image_error_private_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)
        ]
        shared_images = [
            image for image in self.imagesV2.list()
            if (image.status == 'active' and image.visibility == 'shared')
        ]
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'is_public': True, 'status': 'active'}) \
            .AndReturn([public_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': self.tenant.id,
                     'status': 'active'}) \
            .AndRaise(self.exceptions.glance)
        exceptions.handle(
            IsA(http.HttpRequest),
            "Unable to retrieve images for the current project.")
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'visibility': 'shared', 'status': 'active'}) \
            .AndReturn([shared_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': self.tenant.id,
                     'status': 'active'}) \
            .AndReturn([private_images, False, False])

        self.mox.ReplayAll()

        images_cache = {}
        ret = utils.get_available_images(self.request, self.tenant.id,
                                         images_cache)

        expected_images = [
            image for image in public_images
            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.assertFalse(len(images_cache['images_by_project']))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))

        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]))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))
Example #46
0
    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']
                del self.fields['availability_zone']
            except Exception:
                exceptions.handle(request,
                                  _('Unable to load the specified snapshot.'))
        elif 'image_id' in request.GET:
            self.fields['availability_zone'].choices = \
                self.availability_zones(request)
            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'])
        elif 'volume_id' in request.GET:
            self.fields['availability_zone'].choices = \
                self.availability_zones(request)
            volume = None
            try:
                volume = self.get_volume(request, request.GET["volume_id"])
            except Exception:
                msg = _('Unable to load the specified volume. %s')
                exceptions.handle(request, msg % request.GET['volume_id'])

            if volume is not None:
                self.fields['name'].initial = volume.display_name
                self.fields['description'].initial = volume.display_description
                min_vol_size = volume.size
                size_help_text = _('Volume size must be equal to or greater '
                                   'than the origin volume size (%s)') \
                                 % filesizeformat(volume.size)
                self.fields['size'].initial = min_vol_size
                self.fields['size'].help_text = size_help_text
                self.fields['volume_source'].choices = ((volume.id, volume),)
                self.fields['type'].initial = volume.type
                del self.fields['snapshot_source']
                del self.fields['image_source']
                del self.fields['volume_source_type']
        else:
            source_type_choices = []
            self.fields['availability_zone'].choices = \
                self.availability_zones(request)

            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']

            volumes = self.get_volumes(request)
            if volumes:
                source_type_choices.append(("volume_source", _("Volume")))
                choices = [('', _("Choose a volume"))]
                for volume in volumes:
                    choices.append((volume.id, volume))
                self.fields['volume_source'].choices = choices
            else:
                del self.fields['volume_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']
Example #47
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 == '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
Example #48
0
    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)
        ]
        shared_images = [
            image for image in self.imagesV2.list()
            if (image.status == 'active' and image.visibility == 'shared')
        ]

        self.mock_image_list.side_effect = [[public_images, False, False],
                                            [private_images, False, False],
                                            [shared_images, False, False],
                                            [private_images, False, False]]

        image_calls = [
            mock.call(test.IsHttpRequest(),
                      filters={
                          'is_public': True,
                          'status': 'active'
                      }),
            mock.call(test.IsHttpRequest(),
                      filters={
                          'property-owner_id': self.tenant.id,
                          'status': 'active'
                      }),
            mock.call(test.IsHttpRequest(),
                      filters={
                          'visibility': 'shared',
                          'status': 'active'
                      }),
            mock.call(test.IsHttpRequest(),
                      filters={
                          'property-owner_id': 'other-tenant',
                          'status': 'active'
                      })
        ]

        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]))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))

        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']))

        self.mock_image_list.assert_has_calls(image_calls)
Example #49
0
    def test_list_image_communication_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)
        ]
        shared_images = [
            image for image in self.imagesV2.list()
            if (image.status == 'active' and image.visibility == 'shared')
        ]
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'is_public': True, 'status': 'active'}) \
            .AndRaise(glance_exec.CommunicationError)
        # Make sure the exception is handled with the correct
        # error message. If the exception cannot be handled,
        # the error message will be different.
        messages.error(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, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'visibility': 'shared', 'status': 'active'}) \
            .AndReturn([shared_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'is_public': True, 'status': 'active'}) \
            .AndReturn([public_images, False, 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]))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))

        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]))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))
Example #50
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
Example #51
0
    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)
        ]
        shared_images = [
            image for image in self.imagesV2.list()
            if (image.status == 'active' and image.visibility == 'shared')
        ]
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'is_public': True, 'status': 'active'}) \
            .AndReturn([public_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': self.tenant.id,
                     'status': 'active'}) \
            .AndReturn([private_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'visibility': 'shared', 'status': 'active'}) \
            .AndReturn([shared_images, False, False])
        api.glance.image_list_detailed(
            IsA(http.HttpRequest),
            filters={'property-owner_id': 'other-tenant',
                     'status': 'active'}) \
            .AndReturn([private_images, False, 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]))
        self.assertEqual(len(shared_images),
                         len(images_cache['shared_images']))

        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']))