diff --git a/artifactory/utils/container/buildinfo.go b/artifactory/utils/container/buildinfo.go index 9afc98063..38080befd 100644 --- a/artifactory/utils/container/buildinfo.go +++ b/artifactory/utils/container/buildinfo.go @@ -20,11 +20,14 @@ import ( ) const ( - Pull CommandType = "pull" - Push CommandType = "push" - foreignLayerMediaType string = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip" - imageNotFoundErrorMessage string = "Could not find docker image in Artifactory, expecting image tag: %s" - markerLayerSuffix string = ".marker" + Pull CommandType = "pull" + Push CommandType = "push" + foreignLayerMediaType string = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip" + imageNotFoundErrorMessage string = "Could not find docker image in Artifactory, expecting image tag: %s" + markerLayerSuffix string = ".marker" + attestationManifestRefType string = "attestation-manifest" + unknownPlatformPlaceholder string = "unknown" + attestationsModuleIdPrefix string = "attestations" ) // Docker image build info builder. @@ -337,22 +340,22 @@ func (builder *buildInfoBuilder) createBuildInfo(commandType CommandType, manife } // Create the image's build info from list.manifest.json. -func (builder *buildInfoBuilder) createMultiPlatformBuildInfo(fatManifest *FatManifest, searchResultFatManifest *utils.ResultItem, candidateImages map[string][]*utils.ResultItem, module string) (*buildinfo.BuildInfo, error) { +func (builder *buildInfoBuilder) createMultiPlatformBuildInfo(fatManifest *FatManifest, searchResultFatManifest *utils.ResultItem, candidateImages map[string][]*utils.ResultItem, baseModuleId string) (*buildinfo.BuildInfo, error) { imageProperties := map[string]string{ "docker.image.tag": builder.image.Name(), } - if module == "" { + if baseModuleId == "" { imageName, err := builder.image.GetImageShortNameWithTag() if err != nil { return nil, err } - module = imageName + baseModuleId = imageName } // Add layers. builder.imageLayers = append(builder.imageLayers, *searchResultFatManifest) // Create fat-manifest module buildInfo := &buildinfo.BuildInfo{Modules: []buildinfo.Module{{ - Id: module, + Id: baseModuleId, Type: buildinfo.Docker, Properties: imageProperties, Artifacts: []buildinfo.Artifact{getFatManifestArtifact(searchResultFatManifest)}, @@ -370,7 +373,7 @@ func (builder *buildInfoBuilder) createMultiPlatformBuildInfo(fatManifest *FatMa } } buildInfo.Modules = append(buildInfo.Modules, buildinfo.Module{ - Id: manifest.Platform.Os + "/" + manifest.Platform.Architecture + "/" + module, + Id: getModuleIdByManifest(manifest, baseModuleId), Type: buildinfo.Docker, Artifacts: artifacts, }) @@ -378,6 +381,17 @@ func (builder *buildInfoBuilder) createMultiPlatformBuildInfo(fatManifest *FatMa return buildInfo, setBuildProperties(builder.buildName, builder.buildNumber, builder.project, builder.imageLayers, builder.serviceManager) } +// Construct the manifest's module ID by its type (attestation) or its platform. +func getModuleIdByManifest(manifest ManifestDetails, baseModuleId string) string { + if manifest.Annotations.ReferenceType == attestationManifestRefType { + return path.Join(attestationsModuleIdPrefix, baseModuleId) + } + if manifest.Platform.Os != unknownPlatformPlaceholder && manifest.Platform.Architecture != unknownPlatformPlaceholder { + return path.Join(manifest.Platform.Os, manifest.Platform.Architecture, baseModuleId) + } + return baseModuleId +} + func (builder *buildInfoBuilder) createPushBuildProperties(imageManifest *manifest, candidateLayers map[string]*utils.ResultItem) (artifacts []buildinfo.Artifact, dependencies []buildinfo.Dependency, imageLayers []utils.ResultItem, err error) { // Add artifacts. artifacts = append(artifacts, getManifestArtifact(candidateLayers["manifest.json"])) diff --git a/artifactory/utils/container/manifest.go b/artifactory/utils/container/manifest.go index fc45ca2e0..210d5916d 100644 --- a/artifactory/utils/container/manifest.go +++ b/artifactory/utils/container/manifest.go @@ -39,8 +39,9 @@ type FatManifest struct { } type ManifestDetails struct { - Digest string `json:"digest"` - Platform Platform `json:"platform"` + Digest string `json:"digest"` + Platform Platform `json:"platform"` + Annotations Annotations `json:"annotations"` } type Platform struct { @@ -48,6 +49,12 @@ type Platform struct { Os string `json:"os"` } +// Annotations for attestation manifests. +type Annotations struct { + ReferenceDigest string `json:"vnd.docker.reference.digest"` + ReferenceType string `json:"vnd.docker.reference.type"` +} + // Return all the search patterns in which manifest can be found. func getManifestPaths(imagePath, repo string, commandType CommandType) []string { // pattern 1: reverse proxy e.g. ecosysjfrog-docker-local.jfrog.io.