Esempio n. 1
0
    def validate_manifest_url(self, attrs, source):
        try:
            url = attrs[source]
        except KeyError:
            return attrs

        img = self.img

        try:
            req = HttpClient(url)
            res = req.get(timeout=5, max_size=8192)
        except RequestException as e:
            raise s.ValidationError(
                _('Image manifest URL is unreachable (%s).') % e)

        try:
            self.manifest = manifest = res.json()
        except ValueError:
            raise s.ValidationError(_('Could not parse image manifest.'))

        try:
            self.img_file = manifest['files'][0]
            img.uuid = manifest['uuid']
            img.version = manifest['version']
            img.ostype = Image.os_to_ostype(manifest)
            img.size = int(manifest.get('image_size', Image.DEFAULT_SIZE))
            img.desc = manifest.get('description', '')[:128]
            tags = manifest.pop('tags', {})
            img.tags = tags.get(Image.TAGS_KEY, [])
            img.deploy = tags.get('deploy', False)
            img.resize = tags.get('resize', img.ostype in img.ZONE)
        except Exception:
            raise s.ValidationError(_('Invalid image manifest.'))

        if len(manifest['files']) > 1:
            raise s.ValidationError(
                'Multiple files inside manifest are not supported.')

        if img.uuid:
            try:
                x = Image.objects.only('name').get(uuid=img.uuid)
            except Image.DoesNotExist:
                pass
            else:
                raise s.ValidationError(
                    _('Image UUID is already registered by image "%(name)s".')
                    % {'name': x.name})

        return attrs
Esempio n. 2
0
    def _update(cls, task_id, repo):
        err = res = images = None
        repo_url = repo.get_images_url()
        logger.info('Downloading images from image repository %s (%s)',
                    repo.name, repo_url)

        try:
            curl = HttpClient(repo_url)
            res = curl.get(timeout=cls.HTTP_TIMEOUT,
                           max_size=cls.HTTP_MAX_SIZE,
                           allow_redirects=True)
            images = res.json()
        except RequestException as exc:
            err = '%s' % exc
        except ValueError as exc:
            err = 'Image server response could not be decoded (%s)' % exc
        else:
            if not isinstance(images, list):
                err = 'Unexpected output from image server (%s)' % type(images)

        if err:
            status = FAILURE
            msg = err
            logger.error(err)
            repo.error = err
            repo.save()
        else:
            status = SUCCESS
            img_count = len(images)
            msg = u'Downloaded metadata for %d images from image repository %s in %d μs' % (
                img_count, repo.name, res.elapsed.microseconds)
            logger.info(msg)
            repo.image_count = img_count
            repo.last_update = timezone.now()
            repo.error = None
            repo.save(images=images)
            del images  # The list can be big => remove from memory, we don't need it now

        task_log(task_id,
                 LOG_IMAGE_STORE_UPDATE,
                 obj=repo,
                 task_status=status,
                 detail=msg,
                 update_user_tasks=False)

        return repo
Esempio n. 3
0
    def validate(self, attrs):
        self.img_manifest_url = attrs['manifest_url']
        file_url = attrs.get('file_url', None)

        if not file_url:
            file_url = self.img_manifest_url.strip('/') + '/file'

        self.img_file_url = file_url

        try:
            req_file = HttpClient(file_url)
            req_file.get(timeout=5, max_size=32)
        except TooLarge:
            pass
        except RequestException as e:
            self._errors['file_url'] = s.ErrorList([_('Image file URL is unreachable (%s).') % e])

        return attrs