Esempio n. 1
0
def get_image_metadata_v2(
    staging_dirs,
    imageId,
    manifest_data,
    dockerfile_contents="",
):
    """
    Load the image metadata such as building docker history, best effort dockerfile, and layers from the metadata and on-disk image data

    :param staging_dirs:
    :param imageDigest:
    :param imageId:
    :param manifest_data:
    :param dockerfile_contents:
    :param dockerfile_mode:
    :return:
    """
    unpackdir = staging_dirs["unpackdir"]
    copydir = staging_dirs["copydir"]
    cachedir = staging_dirs["cachedir"]

    image_config = get_image_config(copydir, cachedir, imageId)
    parser = DockerV2ManifestMetadata(manifest_data, image_config)
    docker_history = parser.history
    layers = parser.layer_ids

    if dockerfile_contents:
        dockerfile_mode = "Actual"
    else:
        dockerfile_contents = parser.inferred_dockerfile
        dockerfile_mode = "Guessed"

    with open(os.path.join(unpackdir, "docker_history.json"), "w") as OFH:
        OFH.write(json.dumps(docker_history))

    architecture = parser.architecture

    return docker_history, layers, dockerfile_contents, dockerfile_mode, architecture
Esempio n. 2
0
def test_dockerv2manifestmetadata(manifest, image_config, expected_history,
                                  expected_layer_ids):
    t = DockerV2ManifestMetadata(manifest, image_config)
    assert t.history == expected_history
    assert t.layer_ids == expected_layer_ids
Esempio n. 3
0
def process_import(
    image_record: dict,
    sbom: dict,
    import_manifest: InternalImportManifest,
):
    """

    :param image_record:
    :param sbom: map of content type to manifest (e.g. {'packages': {....}, 'dockerfile': '....'}
    :param import_manifest:
    :return:
    """

    # need all this
    analyzer_manifest = {}
    image_id = import_manifest.local_image_id or import_manifest.digest
    syft_packages = sbom.get("packages")
    dockerfile = sbom.get("dockerfile")
    manifest = sbom.get("manifest")
    image_config = sbom.get("image_config")

    if manifest.get("schemaVersion", 1) == 2:
        parser = DockerV2ManifestMetadata(manifest, image_config)
    else:
        parser = DockerV1ManifestMetadata(manifest)

    layers = parser.layer_ids
    image_arch = parser.architecture
    docker_history = parser.history
    image_size = get_image_size(manifest)
    familytree = []

    pullstring = None
    fulltag = None
    if dockerfile:
        dockerfile_mode = "Actual"
    else:
        dockerfile_mode = "Guessed"
        dockerfile = parser.inferred_dockerfile

    try:
        image_digest = image_record["imageDigest"]
        if image_digest != import_manifest.digest:
            raise Exception(
                "Image digest in import manifest does not match catalog record"
            )

        image_detail = image_record["image_detail"][0]
        pullstring = (image_detail["registry"] + "/" + image_detail["repo"] +
                      "@" + image_detail["imageDigest"])
        fulltag = (image_detail["registry"] + "/" + image_detail["repo"] +
                   ":" + image_detail["tag"])

        timer = time.time()

        distro = syft_packages.get("distro", {}).get("name")
        # Map 'redhat' distro to 'rhel' distro for consistency between internal metadata fetch from squashtar and the syft implementation used for import
        if distro == "redhat":
            distro = "rhel"

        # Move data from the syft sbom into the analyzer output
        analyzer_report = {
            "analyzer_meta": {
                "analyzer_meta": {
                    "base": {
                        "DISTRO":
                        distro,
                        "DISTROVERS":
                        syft_packages.get("distro", {}).get("version"),
                        "LIKEDISTRO":
                        syft_packages.get("distro", {}).get("idLike"),
                    }
                }
            }
        }

        try:
            syft_results = convert_syft_to_engine(syft_packages)
            merge_nested_dict(analyzer_report, syft_results)
        except Exception as err:
            raise anchore_engine.clients.localanchore_standalone.AnalysisError(
                cause=err, pull_string=pullstring, tag=fulltag)
        logger.debug("timing: total analyzer time: {} - {}".format(
            pullstring,
            time.time() - timer))

        try:
            image_report = (anchore_engine.clients.localanchore_standalone.
                            generate_image_export(
                                image_id,
                                analyzer_report,
                                image_size,
                                fulltag,
                                docker_history,
                                dockerfile_mode,
                                dockerfile,
                                layers,
                                familytree,
                                image_arch,
                                pullstring,
                                analyzer_manifest,
                            ))
        except Exception as err:
            raise anchore_engine.clients.localanchore_standalone.AnalysisReportGenerationError(
                cause=err, pull_string=pullstring, tag=fulltag)

    except AnchoreException:
        raise
    except Exception as err:
        raise anchore_engine.clients.localanchore_standalone.AnalysisError(
            cause=err,
            pull_string=pullstring,
            tag=fulltag,
            msg=
            "failed to download, unpack, analyze, and generate image export",
        )

    # if not imageDigest or not imageId or not manifest or not image_report:
    if not image_report:
        raise Exception("failed to analyze")

    return [image_report, manifest]