-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: experimental support for Distroless images
- requires the experimental flag to be turned on - assumption #1: the image is present in the local Docker daemon - assumption #2: the "docker" binary is available to use - saves the image as an archive, statically scans it using new capabilities that check each individual file meeting the APT standards, collecting it to the result and cleaning the archive - tested with distroless base debian 9 and 10
- Loading branch information
Showing
10 changed files
with
229 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,54 @@ | ||
import { PluginResponse } from "./types"; | ||
import * as fs from "fs"; | ||
import * as os from "os"; | ||
import * as path from "path"; | ||
|
||
import { Docker } from "./docker"; | ||
import * as staticModule from "./static"; | ||
import { ImageType, PluginResponse } from "./types"; | ||
|
||
export async function experimentalAnalysis( | ||
options: any, | ||
targetImage: string, | ||
): Promise<PluginResponse> { | ||
// assume Distroless scanning | ||
return distroless(options); | ||
return distroless(targetImage); | ||
} | ||
|
||
// experimental flow expected to be merged with the static analysis when ready | ||
export async function distroless(options: any): Promise<PluginResponse> { | ||
// assumption #1: the image is present in the local Docker daemon | ||
export async function distroless(targetImage: string): Promise<PluginResponse> { | ||
const archiveDir = path.join(os.tmpdir(), "snyk-image-archives"); | ||
createTempDirIfMissing(archiveDir); | ||
// TODO terrible way to convert slashes to anything else | ||
// so we don't think it's a directory | ||
const archiveFileName = `${targetImage.replace(/\//g, "__")}.tar`; | ||
const archiveFullPath = path.join(archiveDir, archiveFileName); | ||
|
||
// assumption #2: the `docker` binary is available locally | ||
throw new Error("not implemented"); | ||
const docker = new Docker(targetImage); | ||
// assumption #1: the image is present in the local Docker daemon | ||
await docker.save(targetImage, archiveFullPath); | ||
try { | ||
const scanningOptions = { | ||
staticAnalysisOptions: { | ||
imagePath: archiveFullPath, | ||
imageType: ImageType.DockerArchive, | ||
// TODO only for RPM, may be removed once we get rid of bdb dep | ||
tmpDirPath: "", | ||
distroless: true, | ||
}, | ||
}; | ||
|
||
return staticModule.analyzeStatically(targetImage, scanningOptions); | ||
} finally { | ||
fs.unlinkSync(archiveFullPath); | ||
} | ||
} | ||
|
||
function createTempDirIfMissing(archiveDir: string): void { | ||
try { | ||
fs.mkdirSync(archiveDir); | ||
} catch (err) { | ||
if (err.code !== "EEXIST") { | ||
throw err; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ExtractAction, ExtractedLayers } from "../../extractor/types"; | ||
import { streamToString } from "../../stream-utils"; | ||
|
||
export const getDpkgPackageFileContentAction: ExtractAction = { | ||
actionName: "dpkg", | ||
fileNamePattern: "/var/lib/dpkg/status.d/*", | ||
callback: streamToString, // TODO replace with a parser for apt data extractor | ||
}; | ||
|
||
export function getAptFiles(extractedLayers: ExtractedLayers): string[] { | ||
const files: string[] = []; | ||
|
||
for (const fileName of Object.keys(extractedLayers)) { | ||
if (!("dpkg" in extractedLayers[fileName])) { | ||
continue; | ||
} | ||
files.push(extractedLayers[fileName].dpkg.toString("utf8")); | ||
} | ||
|
||
return files; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters