Exemple #1
0
    def _get_manifest_local_blobs(self,
                                  manifest,
                                  repo_id,
                                  include_placements=False,
                                  by_manifest=False):
        parsed = manifest.get_parsed_manifest()
        if parsed is None:
            return None

        local_blob_digests = list(set(parsed.local_blob_digests))
        if not len(local_blob_digests):
            return []

        blob_query = self._lookup_repo_storages_by_content_checksum(
            repo_id, local_blob_digests, by_manifest=by_manifest)
        blobs = []
        for image_storage in blob_query:
            placements = None
            if include_placements:
                placements = list(
                    model.storage.get_storage_locations(image_storage.uuid))

            blob = Blob.for_image_storage(
                image_storage,
                storage_path=model.storage.get_layer_path(image_storage),
                placements=placements,
            )
            blobs.append(blob)

        return blobs
Exemple #2
0
    def get_repo_blob_by_digest(self,
                                repository_ref,
                                blob_digest,
                                include_placements=False):
        """
    Returns the blob in the repository with the given digest, if any or None if none. Note that
    there may be multiple records in the same repository for the same blob digest, so the return
    value of this function may change.
    """
        image_storage = self._get_shared_storage(blob_digest)
        if image_storage is None:
            try:
                image_storage = model.blob.get_repository_blob_by_digest(
                    repository_ref._db_id, blob_digest)
            except model.BlobDoesNotExist:
                return None

        assert image_storage.cas_path is not None

        placements = None
        if include_placements:
            placements = list(
                model.storage.get_storage_locations(image_storage.uuid))

        return Blob.for_image_storage(
            image_storage,
            storage_path=model.storage.get_layer_path(image_storage),
            placements=placements)
Exemple #3
0
    def commit_blob_upload(self, blob_upload, blob_digest_str,
                           blob_expiration_seconds):
        """
        Commits the blob upload into a blob and sets an expiration before that blob will be GCed.
        """
        upload_record = model.blob.get_blob_upload_by_uuid(
            blob_upload.upload_id)
        if upload_record is None:
            return None

        repository_id = upload_record.repository_id

        # Create the blob and temporarily tag it.
        location_obj = model.storage.get_image_location_for_name(
            blob_upload.location_name)
        blob_record = model.blob.store_blob_record_and_temp_link_in_repo(
            repository_id,
            blob_digest_str,
            location_obj.id,
            blob_upload.byte_count,
            blob_expiration_seconds,
            blob_upload.uncompressed_byte_count,
        )

        # Delete the blob upload.
        upload_record.delete_instance()
        return Blob.for_image_storage(
            blob_record,
            storage_path=model.storage.get_layer_path(blob_record))
Exemple #4
0
    def get_legacy_image(self,
                         repository_ref,
                         docker_image_id,
                         include_parents=False,
                         include_blob=False):
        """
    Returns the matching LegacyImages under the matching repository, if any. If none,
    returns None.
    """
        repo = model.repository.lookup_repository(repository_ref._db_id)
        if repo is None:
            return None

        image = model.image.get_image(repository_ref._db_id, docker_image_id)
        if image is None:
            return None

        parent_images_map = None
        if include_parents:
            parent_images = model.image.get_parent_images(
                repo.namespace_user.username, repo.name, image)
            parent_images_map = {image.id: image for image in parent_images}

        blob = None
        if include_blob:
            placements = list(
                model.storage.get_storage_locations(image.storage.uuid))
            blob = Blob.for_image_storage(
                image.storage,
                storage_path=model.storage.get_layer_path(image.storage),
                placements=placements)

        return LegacyImage.for_image(image,
                                     images_map=parent_images_map,
                                     blob=blob)
Exemple #5
0
    def get_cached_repo_blob(self, model_cache, namespace_name, repo_name,
                             blob_digest):
        """
    Returns the blob in the repository with the given digest if any or None if none.
    Caches the result in the caching system.
    """
        def load_blob():
            repository_ref = self.lookup_repository(namespace_name, repo_name)
            if repository_ref is None:
                return None

            blob_found = self.get_repo_blob_by_digest(repository_ref,
                                                      blob_digest,
                                                      include_placements=True)
            if blob_found is None:
                return None

            return blob_found.asdict()

        blob_cache_key = cache_key.for_repository_blob(namespace_name,
                                                       repo_name, blob_digest,
                                                       2)
        blob_dict = model_cache.retrieve(blob_cache_key, load_blob)

        try:
            return Blob.from_dict(blob_dict) if blob_dict is not None else None
        except FromDictionaryException:
            # The data was stale in some way. Simply reload.
            repository_ref = self.lookup_repository(namespace_name, repo_name)
            if repository_ref is None:
                return None

            return self.get_repo_blob_by_digest(repository_ref,
                                                blob_digest,
                                                include_placements=True)
Exemple #6
0
    def _list_manifest_layers(self,
                              repo_id,
                              parsed,
                              storage,
                              include_placements=False,
                              by_manifest=False):
        """ Returns an *ordered list* of the layers found in the manifest, starting at the base and
        working towards the leaf, including the associated Blob and its placements (if specified).
        Returns None if the manifest could not be parsed and validated.
    """
        assert not parsed.is_manifest_list

        retriever = RepositoryContentRetriever(repo_id, storage)
        requires_empty_blob = parsed.get_requires_empty_layer_blob(retriever)

        storage_map = {}
        blob_digests = list(parsed.local_blob_digests)
        if requires_empty_blob:
            blob_digests.append(EMPTY_LAYER_BLOB_DIGEST)

        if blob_digests:
            blob_query = self._lookup_repo_storages_by_content_checksum(
                repo_id, blob_digests, by_manifest=by_manifest)
            storage_map = {blob.content_checksum: blob for blob in blob_query}

        layers = parsed.get_layers(retriever)
        if layers is None:
            logger.error("Could not load layers for manifest `%s`",
                         parsed.digest)
            return None

        manifest_layers = []
        for layer in layers:
            if layer.is_remote:
                manifest_layers.append(ManifestLayer(layer, None))
                continue

            digest_str = str(layer.blob_digest)
            if digest_str not in storage_map:
                logger.error("Missing digest `%s` for manifest `%s`",
                             layer.blob_digest, parsed.digest)
                return None

            image_storage = storage_map[digest_str]
            assert image_storage.cas_path is not None
            assert image_storage.image_size is not None

            placements = None
            if include_placements:
                placements = list(
                    model.storage.get_storage_locations(image_storage.uuid))

            blob = Blob.for_image_storage(
                image_storage,
                storage_path=model.storage.get_layer_path(image_storage),
                placements=placements,
            )
            manifest_layers.append(ManifestLayer(layer, blob))

        return manifest_layers
Exemple #7
0
    def _build_derived(self, derived, verb, varying_metadata, include_placements):
        if derived is None:
            return None

        derived_storage = derived.derivative
        placements = None
        if include_placements:
            placements = list(model.storage.get_storage_locations(derived_storage.uuid))

        blob = Blob.for_image_storage(
            derived_storage,
            storage_path=model.storage.get_layer_path(derived_storage),
            placements=placements,
        )

        return DerivedImage.for_derived_storage(derived, verb, varying_metadata, blob)