Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ schemas:
enum:
- autoDetectedUserInstructions
- binaries
- baseRuntimes
- depGraph
- dockerfileAnalysis
- dockerLayers
Expand Down
11 changes: 11 additions & 0 deletions lib/analyzer/base-runtimes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ExtractedLayers } from "../../extractor/types";
import { BaseRuntime } from "../../facts";
import { getJavaRuntimeReleaseContent } from "../../inputs/base-runtimes/static";
import { parseJavaRuntimeRelease } from "./parser";

export function detectJavaRuntime(
extractedLayers: ExtractedLayers,
): BaseRuntime | null {
const releaseContent = getJavaRuntimeReleaseContent(extractedLayers);
return releaseContent ? parseJavaRuntimeRelease(releaseContent) : null;
}
34 changes: 34 additions & 0 deletions lib/analyzer/base-runtimes/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BaseRuntime } from "../../facts";

const VALID_VERSION_PATTERN =
/^(?!.*\.\.)[0-9]+(?:[._+a-zA-Z0-9-]*[a-zA-Z0-9])?$/;

const regex = /^\s*JAVA_VERSION\s*=\s*(?:(["'])(.*?)\1|([^#\r\n]+))/gm;

function isValidJavaVersion(version: string): boolean {
if (!version || version.length === 0) {
return false;
}
return VALID_VERSION_PATTERN.test(version);
}

export function parseJavaRuntimeRelease(content: string): BaseRuntime | null {
if (!content || content.trim().length === 0) {
return null;
}
try {
const matches = [...content.matchAll(regex)];

if (matches.length !== 1) {
return null;
}
const version = (matches[0][2] || matches[0][3] || "").trim();

if (!isValidJavaVersion(version)) {
return null;
}
return { type: "java", version };
} catch (error) {
return null;
}
}
6 changes: 6 additions & 0 deletions lib/analyzer/static-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
getDpkgFileContentAction,
getExtFileContentAction,
} from "../inputs/apt/static";
import { getJavaRuntimeReleaseAction } from "../inputs/base-runtimes/static";
import {
getBinariesHashes,
getNodeBinariesFileContentAction,
Expand Down Expand Up @@ -67,6 +68,7 @@ import { jarFilesToScannedResults } from "./applications/java";
import { pipFilesToScannedProjects } from "./applications/python";
import { getApplicationFiles } from "./applications/runtime-common";
import { AppDepsScanResultWithoutTarget } from "./applications/types";
import { detectJavaRuntime } from "./base-runtimes";
import * as osReleaseDetector from "./os-release";
import { analyze as apkAnalyze } from "./package-managers/apk";
import {
Expand Down Expand Up @@ -105,6 +107,7 @@ export async function analyze(
...getOsReleaseActions,
getNodeBinariesFileContentAction,
getOpenJDKBinariesFileContentAction,
getJavaRuntimeReleaseAction,
getDpkgPackageFileContentAction,
getRedHatRepositoriesContentAction,
];
Expand Down Expand Up @@ -233,6 +236,8 @@ export async function analyze(
}

const binaries = getBinariesHashes(extractedLayers);
const javaRuntime = detectJavaRuntime(extractedLayers);
const baseRuntimes = javaRuntime ? [javaRuntime] : undefined;

const applicationDependenciesScanResults: AppDepsScanResultWithoutTarget[] =
[];
Expand Down Expand Up @@ -309,6 +314,7 @@ export async function analyze(
platform,
results,
binaries,
baseRuntimes,
imageLayers: manifestLayers,
rootFsLayers,
applicationDependenciesScanResults,
Expand Down
2 changes: 2 additions & 0 deletions lib/analyzer/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ImageName } from "../extractor/image";
import { BaseRuntime } from "../facts";
import { AutoDetectedUserInstructions, ManifestFile } from "../types";
import {
AppDepsScanResultWithoutTarget,
Expand Down Expand Up @@ -75,6 +76,7 @@ export interface StaticAnalysis {
osRelease: OSRelease;
results: ImageAnalysis[];
binaries: string[];
baseRuntimes?: BaseRuntime[];
imageLayers: string[];
rootFsLayers?: string[];
autoDetectedUserInstructions?: AutoDetectedUserInstructions;
Expand Down
10 changes: 10 additions & 0 deletions lib/facts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,13 @@ export interface PluginWarningsFact {
parameterChecks?: string[];
};
}

export interface BaseRuntime {
type: string;
version: string;
}

export interface BaseRuntimesFact {
type: "baseRuntimes";
data: BaseRuntime[];
}
21 changes: 21 additions & 0 deletions lib/inputs/base-runtimes/static.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { normalize as normalizePath } from "path";
import { getContentAsString } from "../../extractor";
import { ExtractAction, ExtractedLayers } from "../../extractor/types";
import { streamToString } from "../../stream-utils";

export const getJavaRuntimeReleaseAction: ExtractAction = {
actionName: "java-runtime-release",
filePathMatches: (filePath) =>
filePath === normalizePath("/opt/java/openjdk/release"),
callback: streamToString,
};

export function getJavaRuntimeReleaseContent(
extractedLayers: ExtractedLayers,
): string {
const content = getContentAsString(
extractedLayers,
getJavaRuntimeReleaseAction,
);
return content || "";
}
7 changes: 7 additions & 0 deletions lib/response-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ async function buildResponse(
};
additionalFacts.push(keyBinariesHashesFact);
}
if (depsAnalysis.baseRuntimes && depsAnalysis.baseRuntimes.length > 0) {
const baseRuntimesFact: facts.BaseRuntimesFact = {
type: "baseRuntimes",
data: depsAnalysis.baseRuntimes,
};
additionalFacts.push(baseRuntimesFact);
}

if (dockerfileAnalysis !== undefined) {
const dockerfileAnalysisFact: facts.DockerfileAnalysisFact = {
Expand Down
2 changes: 2 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export type FactType =
| "jarFingerprints"
// Hashes of executables not installed by a package manager (e.g. if they were copied straight onto the image).
| "keyBinariesHashes"
// Base runtime metadata (e.g., Java ) extracted from release files
| "baseRuntimes"
| "loadedPackages"
| "ociDistributionMetadata"
| "containerConfig"
Expand Down
Loading
Loading