UNPKG

snyk-docker-plugin

Version:
99 lines (86 loc) 3.11 kB
import * as Debug from "debug"; import { DockerFileAnalysis } from "../../dockerfile/types"; import { ExtractedLayers } from "../../extractor/types"; import { getOsReleaseStatic as getOsRelease } from "../../inputs/os-release"; import { OsReleaseFilePath } from "../../types"; import { OSRelease } from "../types"; import { tryAlpineRelease, tryCentosRelease, tryDebianVersion, tryLsbRelease, tryOracleRelease, tryOSRelease, tryRedHatRelease, } from "./release-analyzer"; const debug = Debug("snyk"); type OsReleaseHandler = (text: string) => Promise<OSRelease | null>; const releaseDetectors: Record<OsReleaseFilePath, OsReleaseHandler> = { [OsReleaseFilePath.Linux]: tryOSRelease, // Fallback for the case where the same file exists in different location or is a symlink to the other location [OsReleaseFilePath.LinuxFallback]: tryOSRelease, // Generic fallback [OsReleaseFilePath.Lsb]: tryLsbRelease, // Fallbacks for specific older distributions [OsReleaseFilePath.Debian]: tryDebianVersion, [OsReleaseFilePath.Alpine]: tryAlpineRelease, [OsReleaseFilePath.Oracle]: tryOracleRelease, [OsReleaseFilePath.RedHat]: tryRedHatRelease, [OsReleaseFilePath.Centos]: tryCentosRelease, }; export async function detect( extractedLayers: ExtractedLayers, dockerfileAnalysis: DockerFileAnalysis | undefined, ): Promise<OSRelease> { /** * We want to detect whether the OS release file existed, but it just could not be parsed successfully. * This is so that we can distinguish between images with multiple "os-release" files - some of them * may fail to parse while others will succeed. This will depend purely on the order of our handlers. * We want to run all handlers and only then decide if detection succeeded or not. */ let hadOsReleaseFile = false; let osRelease: OSRelease | null = null; for (const [type, handler] of Object.entries(releaseDetectors)) { const osReleaseFile = getOsRelease( extractedLayers, type as OsReleaseFilePath, ); if (!osReleaseFile) { continue; } hadOsReleaseFile = true; try { osRelease = await handler(osReleaseFile); } catch (err) { debug("Malformed OS release file", JSON.stringify(err)); } if (osRelease) { break; } } if (!osRelease && hadOsReleaseFile) { throw new Error("Failed to parse OS release file"); } if (!osRelease) { if (dockerfileAnalysis && dockerfileAnalysis.baseImage === "scratch") { // If the docker file was build from a scratch image // then we don't have a known OS osRelease = { name: "scratch", version: "0.0", prettyName: "" }; } else { osRelease = { name: "unknown", version: "0.0", prettyName: "" }; } } // Oracle Linux identifies itself as "ol" if (osRelease.name.trim() === "ol") { osRelease.name = "oracle"; } // Support round version. ie change SLES 15 to SLES 15.0 if ( osRelease.name.trim() === "sles" && osRelease.version && !osRelease.version.includes(".") ) { osRelease.version += ".0"; } return osRelease; }