diff --git a/common-npm-packages/docker-common/containerimageutils.ts b/common-npm-packages/docker-common/containerimageutils.ts index fa0f07af..5c8a681e 100644 --- a/common-npm-packages/docker-common/containerimageutils.ts +++ b/common-npm-packages/docker-common/containerimageutils.ts @@ -253,41 +253,39 @@ export function getImageIdFromBuildOutput(output: string): string { return ""; } -export function getBaseImageDigestDockerFile(dockerFileContentPath: string): string { +export function getBaseImageDetialsFromDockerFIle(dockerFileContentPath: string, connection?: ContainerConnection):baseImageDetails { // 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(); + var dockerFileContent = fs.readFileSync(dockerFileContentPath).toString(); if (!dockerFileContent || dockerFileContent == "") { return null; - } + } var lines = dockerFileContent.split(/[\r?\n]/); var aliasToImageNameMapping: Map = new Map(); var baseImage = ""; - - // Added regex pattern to check line starts with FROM IMAGE - const matchPatternForDockerImage = new RegExp(/^FROM\s+IMAGE/); + const baseImageDetails = { name: "", digest: "" }; for (var i = 0; i < lines.length; i++) { const currentLine = lines[i].trim(); - - if (!currentLine.toUpperCase().match(matchPatternForDockerImage)) { + + if (!currentLine.toUpperCase().startsWith("FROM")) { 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) @@ -295,18 +293,30 @@ export function getBaseImageDigestDockerFile(dockerFileContentPath: string): str : prospectImageName; } } - - let baseImageData = baseImage.split('@'); - if (baseImageData.length > 1) { - let digest = baseImageData[1].split(':'); - if (digest.length > 1){ - return digest[1]; + baseImageDetails.name = baseImage.includes("$") ? null : sanityzeBaseImage(baseImage);// In this case the base image has an argument and we don't know what its real value is + + if (!connection) { + tl.debug("Image digest couldn't be extracted because no connection was found."); + return baseImageDetails; + } + else { + let baseImageData = baseImage.split('@'); + if (baseImageData.length > 1) { + let digest = baseImageData[1].split(':'); + if (digest.length > 1) { + baseImageDetails.digest = digest[1]; + } + } else { + baseImageDetails.digest = null; } } - - return null; + return baseImageDetails; } catch (error) { - tl.debug(`An error ocurred getting the base image digest. ${error.message}`); + tl.debug(`An error ocurred getting the base image details. ${error.message}`); return null; } +} +export class baseImageDetails{ + name: string; + digest: string ; } \ No newline at end of file diff --git a/common-npm-packages/docker-common/package-lock.json b/common-npm-packages/docker-common/package-lock.json index ab8dccf1..37b4eb92 100644 --- a/common-npm-packages/docker-common/package-lock.json +++ b/common-npm-packages/docker-common/package-lock.json @@ -1,12 +1,12 @@ { "name": "azure-pipelines-tasks-docker-common", - "version": "2.256.0", + "version": "2.256.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "azure-pipelines-tasks-docker-common", - "version": "2.256.0", + "version": "2.256.1", "license": "MIT", "dependencies": { "@types/mocha": "^5.2.7", diff --git a/common-npm-packages/docker-common/package.json b/common-npm-packages/docker-common/package.json index 28c76eaf..0758c4f9 100644 --- a/common-npm-packages/docker-common/package.json +++ b/common-npm-packages/docker-common/package.json @@ -1,6 +1,6 @@ { "name": "azure-pipelines-tasks-docker-common", - "version": "2.256.0", + "version": "2.256.1", "description": "Common Library for Azure Rest Calls", "repository": { "type": "git", diff --git a/common-npm-packages/docker-common/pipelineutils.ts b/common-npm-packages/docker-common/pipelineutils.ts index 5319babd..e4ac844b 100644 --- a/common-npm-packages/docker-common/pipelineutils.ts +++ b/common-npm-packages/docker-common/pipelineutils.ts @@ -54,31 +54,47 @@ function addReleaseLabels(hostName: string, labels: string[], addPipelineData?: } function addBaseImageLabels(connection: ContainerConnection, labels: string[], dockerFilePath: string): void { - const baseImageName = containerUtils.getBaseImageNameFromDockerFile(dockerFilePath); - if (!baseImageName) { - return; - } - - addLabelWithValue("image.base.ref.name", baseImageName, labels); - if (!connection) { - tl.debug("Image digest couldn't be extracted because no connection was found."); - return; - } + //Added Dynamic feature flag to fix getting digest image from docker file let digestImageFromFileEnabled = tl.getPipelineFeature('UseDigestImageFromFile'); - var baseImageDigest = ""; + if (digestImageFromFileEnabled) { - baseImageDigest = containerUtils.getBaseImageDigestDockerFile(dockerFilePath); - } - //first check if there is digest passed in Dockerfile - if (!baseImageDigest) { - baseImageDigest = containerUtils.getImageDigest(connection, baseImageName); + + // using getBaseImageDetialsFromDockerFIle method to fetch both image and imagedigest + const baseImage = containerUtils.getBaseImageDetialsFromDockerFIle(dockerFilePath, connection); + if (!baseImage.name) { + return; + } + addLabelWithValue("image.base.ref.name", baseImage.name, labels); + //first check if there is digest passed in ]Dockerfile + if (!baseImage.digest) { + baseImage.digest = containerUtils.getImageDigest(connection, baseImage.name); + } + //if there is no digest in Dockerfile, get digest using ImageName:tag + if (baseImage.digest) { + addLabelWithValue("image.base.digest", baseImage.digest, labels); + } + } + else { + const baseImageName = containerUtils.getBaseImageNameFromDockerFile(dockerFilePath); + if (!baseImageName) { + return; + } + addLabelWithValue("image.base.ref.name", baseImageName, labels); + + if (!connection) { + tl.debug("Image digest couldn't be extracted because no connection was found."); + return; + } + + const baseImageDigest = containerUtils.getImageDigest(connection, baseImageName); - //if there is no digest in Dockerfile, get digest using ImageName:tag - if (baseImageDigest) { - addLabelWithValue("image.base.digest", baseImageDigest, labels); - } + //if there is no digest in Dockerfile, get digest using ImageName:tag + if (baseImageDigest) { + addLabelWithValue("image.base.digest", baseImageDigest, labels); + } + } } function getReverseDNSName(): string {