diff --git a/common-npm-packages/docker-common/containerimageutils.ts b/common-npm-packages/docker-common/containerimageutils.ts index bdad3fef..ca4d126a 100644 --- a/common-npm-packages/docker-common/containerimageutils.ts +++ b/common-npm-packages/docker-common/containerimageutils.ts @@ -253,3 +253,51 @@ export function getImageIdFromBuildOutput(output: string): string { return ""; } +export function getBaseImageDigestDockerFile(dockerFileContentPath: string): string { + // This method checks if there is FROM image@sha256:digest present in Dockerfile + // if matched it returns digest + // if not, it returns null + + try { + var dockerFileContent=fs.readFileSync(dockerFileContentPath).toString(); + if (!dockerFileContent || dockerFileContent == "") { + return null; + } + var lines=dockerFileContent.split(/[\r?\n]/); + var aliasToImageNameMapping: Map = new Map(); + var baseImage = ""; + + for (var i = 0; i < lines.length; i++) { + const currentLine = lines[i].trim(); + + // Added regex pattern to check line starts with FROM IMAGE + const matchPatternForDockerImage = new RegExp(/^FROM\s+IMAGE/); + if (!currentLine.toUpperCase().match(matchPatternForDockerImage)) { + continue; + } + var nameComponents = currentLine.substring(4).toLowerCase().split(" as "); + var prospectImageName = nameComponents[0].trim(); + + if (nameComponents.length > 1) { + var alias = nameComponents[1].trim(); + + if (aliasToImageNameMapping.has(prospectImageName)) { + aliasToImageNameMapping.set(alias, aliasToImageNameMapping.get(prospectImageName)); + } else { + aliasToImageNameMapping.set(alias, prospectImageName); + } + + baseImage = aliasToImageNameMapping.get(alias); + } else { + baseImage = aliasToImageNameMapping.has(prospectImageName) + ? aliasToImageNameMapping.get(prospectImageName) + : prospectImageName; + } + } + + return baseImage.split('@')[1].split(':')[1]; + } catch (error) { + tl.debug(`An error ocurred getting the base image digest. ${error.message}`); + return null; + } +} \ No newline at end of file diff --git a/common-npm-packages/docker-common/pipelineutils.ts b/common-npm-packages/docker-common/pipelineutils.ts index c9e8132b..b40e1738 100644 --- a/common-npm-packages/docker-common/pipelineutils.ts +++ b/common-npm-packages/docker-common/pipelineutils.ts @@ -65,11 +65,19 @@ function addBaseImageLabels(connection: ContainerConnection, labels: string[], d tl.debug("Image digest couldn't be extracted because no connection was found."); return; } + let digestImageFromFileEnabled = tl.getPipelineFeature('UseDigestImageFromFile'); + if (digestImageFromFileEnabled) { + var baseImageDigest = containerUtils.getBaseImageDigestDockerFile(dockerFilePath); + } + //first check if there is digest passed in Dockerfile + if (!baseImageDigest) { + baseImageDigest = containerUtils.getImageDigest(connection, baseImageName); + } - const baseImageDigest = containerUtils.getImageDigest(connection, baseImageName); + //if not there is no digest in Dockerfile, get digest using ImageName:tag if (baseImageDigest) { addLabelWithValue("image.base.digest", baseImageDigest, labels); - } + } } function getReverseDNSName(): string {