UNPKG

snyk-docker-plugin

Version:
122 lines 5.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getManifestLayers = exports.createGetImageIdFromManifest = exports.createExtractArchive = exports.kanikoArchiveConfig = exports.dockerArchiveConfig = exports.InvalidArchiveError = void 0; const Debug = require("debug"); const fs_1 = require("fs"); const gunzip = require("gunzip-maybe"); const path_1 = require("path"); const tar_stream_1 = require("tar-stream"); const error_utils_1 = require("../error-utils"); const stream_utils_1 = require("../stream-utils"); class InvalidArchiveError extends Error { constructor(message) { super(); this.name = "InvalidArchiveError"; this.message = message; } } exports.InvalidArchiveError = InvalidArchiveError; const types_1 = require("../types"); const layer_1 = require("./layer"); const debug = Debug("snyk"); exports.dockerArchiveConfig = { isLayerFile: (name) => (0, path_1.basename)(name).endsWith(".tar"), isImageConfigFile: (name) => new RegExp("[A-Fa-f0-9]{64}\\.json").test(name), formatLabel: "Docker", layerErrorType: "tar", extractImageId: (configValue) => configValue.split(".")[0], }; exports.kanikoArchiveConfig = { isLayerFile: (name) => (0, path_1.basename)(name).endsWith(".tar.gz"), isImageConfigFile: (name) => new RegExp("sha256:[A-Fa-f0-9]{64}").test(name), formatLabel: "Kaniko", layerErrorType: "tar.gz", extractImageId: (configValue) => configValue, }; function createExtractArchive(config) { return (archiveFilesystemPath, extractActions, _options) => new Promise((resolve, reject) => { const tarExtractor = (0, tar_stream_1.extract)(); const layers = {}; let manifest; let imageConfig; tarExtractor.on("entry", async (header, stream, next) => { if (header.type === "file") { const normalizedName = (0, path_1.normalize)(header.name); if (config.isLayerFile(normalizedName)) { try { layers[normalizedName] = await (0, layer_1.extractImageLayer)(stream, extractActions); } catch (error) { debug(`Error extracting layer content from: '${(0, error_utils_1.getErrorMessage)(error)}'`); reject(new Error(`Error reading ${config.layerErrorType} archive`)); } } else if (isManifestFile(normalizedName)) { const manifestArray = await getManifestFile(stream); manifest = manifestArray[0]; } else if (config.isImageConfigFile(normalizedName)) { imageConfig = await getManifestFile(stream); } } stream.resume(); next(); }); tarExtractor.on("finish", () => { try { resolve(assembleLayersAndManifest(manifest, imageConfig, layers)); } catch (error) { debug(`Error getting layers and manifest content from ${config.formatLabel} archive: ${(0, error_utils_1.getErrorMessage)(error)}`); reject(new InvalidArchiveError(`Invalid ${config.formatLabel} archive`)); } }); tarExtractor.on("error", (error) => reject(error)); (0, fs_1.createReadStream)(archiveFilesystemPath) .on("error", (error) => reject(error)) .pipe(gunzip()) .pipe(tarExtractor); }); } exports.createExtractArchive = createExtractArchive; function assembleLayersAndManifest(manifest, imageConfig, layers) { const layersWithNormalizedNames = manifest.Layers.map((layerName) => (0, path_1.normalize)(layerName)); const filteredLayers = layersWithNormalizedNames .filter((layerName) => layers[layerName]) .map((layerName) => layers[layerName]) .reverse(); if (filteredLayers.length === 0) { throw new Error("We found no layers in the provided image"); } return { layers: filteredLayers, manifest, imageConfig, }; } async function getManifestFile(stream) { return (0, stream_utils_1.streamToJson)(stream); } function isManifestFile(name) { return name === "manifest.json"; } function createGetImageIdFromManifest(config) { return (manifest) => { try { const imageId = config.extractImageId(manifest.Config); if (imageId.includes(":")) { return imageId; } return `${types_1.HashAlgorithm.Sha256}:${imageId}`; } catch (err) { throw new Error("Failed to extract image ID from archive manifest"); } }; } exports.createGetImageIdFromManifest = createGetImageIdFromManifest; function getManifestLayers(manifest) { return manifest.Layers.map((layer) => (0, path_1.normalize)(layer)); } exports.getManifestLayers = getManifestLayers; //# sourceMappingURL=generic-archive-extractor.js.map