Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "unknown/unknown" module id for docker attestations #1223

Merged
merged 2 commits into from
Aug 6, 2024
Merged
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
34 changes: 24 additions & 10 deletions artifactory/utils/container/buildinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)},
Expand All @@ -370,14 +373,25 @@ 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,
})
}
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 {
RobiNino marked this conversation as resolved.
Show resolved Hide resolved
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"]))
Expand Down
11 changes: 9 additions & 2 deletions artifactory/utils/container/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,22 @@ 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 {
Architecture string `json:"architecture"`
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.
Expand Down
Loading