def get_image_metadata_v1( staging_dirs, manifest_data, dockerfile_contents="", dockerfile_mode="", ): """ Extract image metadata from the manifest and content/dockerfile :param staging_dirs: :param manifest_data: :param dockerfile_contents: :param dockerfile_mode: :return: """ unpackdir = staging_dirs["unpackdir"] parser = DockerV1ManifestMetadata(manifest_data) docker_history = parser.history layers = parser.layer_ids architecture = parser.architecture 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)) return docker_history, layers, dockerfile_contents, dockerfile_mode, architecture
def test_dockerv1manifestmetadata(manifest, expected_history, expected_layer_ids): t = DockerV1ManifestMetadata(manifest) assert t.history == expected_history assert t.layer_ids == expected_layer_ids
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]