@@ -2,6 +2,7 @@ package container
22
33import (
44 "encoding/json"
5+ "fmt"
56 "os"
67 "path"
78 "strings"
@@ -91,7 +92,7 @@ func (builder *buildInfoBuilder) getSearchableRepo() string {
9192}
9293
9394// Set build properties on image layers in Artifactory.
94- func setBuildProperties (buildName , buildNumber , project string , imageLayers []utils.ResultItem , serviceManager artifactory.ArtifactoryServicesManager ) (err error ) {
95+ func setBuildProperties (buildName , buildNumber , project string , imageLayers []utils.ResultItem , serviceManager artifactory.ArtifactoryServicesManager , originalRepo string ) (err error ) {
9596 // Skip if no build info is provided
9697 if buildName == "" || buildNumber == "" {
9798 log .Debug ("Skipping setting properties - build name and build number are required" )
@@ -109,7 +110,14 @@ func setBuildProperties(buildName, buildNumber, project string, imageLayers []ut
109110 return nil
110111 }
111112
112- pathToFile , err := writeLayersToFile (imageLayers )
113+ // Filter image layers for virtual repositories to only include layers from default deployment repository
114+ filteredLayers , err := filterLayersForVirtualRepository (imageLayers , serviceManager , originalRepo )
115+ if err != nil {
116+ log .Debug ("Failed to filter layers for virtual repository, proceeding with all layers:" , err .Error ())
117+ filteredLayers = imageLayers
118+ }
119+
120+ pathToFile , err := writeLayersToFile (filteredLayers )
113121 if err != nil {
114122 return
115123 }
@@ -119,6 +127,87 @@ func setBuildProperties(buildName, buildNumber, project string, imageLayers []ut
119127 return
120128}
121129
130+ // filterLayersForVirtualRepository filters image layers to only include those from the default deployment repository
131+ // when dealing with virtual repositories. For non-virtual repositories, it returns all layers unchanged.
132+ func filterLayersForVirtualRepository (imageLayers []utils.ResultItem , serviceManager artifactory.ArtifactoryServicesManager , originalRepo string ) ([]utils.ResultItem , error ) {
133+ if len (imageLayers ) == 0 {
134+ return imageLayers , nil
135+ }
136+
137+ // Check if the original repository is a virtual repository by getting its configuration
138+ repoConfig , err := getRepositoryConfiguration (originalRepo , serviceManager )
139+ if err != nil {
140+ log .Debug ("Failed to get repository configuration for" , originalRepo , ":" , err .Error ())
141+ return imageLayers , err
142+ }
143+
144+ // If it's not a virtual repository, return all layers unchanged
145+ if repoConfig == nil || repoConfig .Rclass != "virtual" {
146+ log .Debug ("Repository" , originalRepo , "is not virtual, proceeding with all layers" )
147+ return imageLayers , nil
148+ }
149+
150+ // If it's a virtual repository but has no default deployment repo, return all layers
151+ if repoConfig .DefaultDeploymentRepo == "" {
152+ log .Debug ("Virtual repository" , originalRepo , "has no default deployment repository, proceeding with all layers" )
153+ return imageLayers , nil
154+ }
155+
156+ // Filter layers to only include those from the default deployment repository
157+ var filteredLayers []utils.ResultItem
158+ for _ , layer := range imageLayers {
159+ if layer .Repo == repoConfig .DefaultDeploymentRepo {
160+ filteredLayers = append (filteredLayers , layer )
161+ }
162+ }
163+
164+ if len (filteredLayers ) > 0 {
165+ log .Debug ("Filtered" , len (imageLayers ), "layers to" , len (filteredLayers ), "layers from default deployment repository:" , repoConfig .DefaultDeploymentRepo )
166+ } else {
167+ log .Debug ("No layers found in default deployment repository" , repoConfig .DefaultDeploymentRepo , ", proceeding with all layers" )
168+ return imageLayers , nil
169+ }
170+
171+ return filteredLayers , nil
172+ }
173+
174+ // repositoryConfig represents the virtual repository configuration
175+ type repositoryConfig struct {
176+ Key string `json:"key"`
177+ Rclass string `json:"rclass"`
178+ DefaultDeploymentRepo string `json:"defaultDeploymentRepo"`
179+ }
180+
181+ // getRepositoryConfiguration fetches the repository configuration from Artifactory
182+ func getRepositoryConfiguration (repoKey string , serviceManager artifactory.ArtifactoryServicesManager ) (* repositoryConfig , error ) {
183+ // Create HTTP client details for the request
184+ httpClientDetails := serviceManager .GetConfig ().GetServiceDetails ().CreateHttpClientDetails ()
185+
186+ // Construct the API endpoint URL
187+ baseUrl := serviceManager .GetConfig ().GetServiceDetails ().GetUrl ()
188+ endpoint := "api/repositories/" + repoKey
189+ url := baseUrl + endpoint
190+
191+ // Make the HTTP GET request
192+ resp , body , _ , err := serviceManager .Client ().SendGet (url , true , & httpClientDetails )
193+ if err != nil {
194+ return nil , err
195+ }
196+
197+ // Check for successful response
198+ if resp .StatusCode != 200 {
199+ return nil , fmt .Errorf ("failed to get repository configuration: HTTP %d" , resp .StatusCode )
200+ }
201+
202+ // Parse the JSON response
203+ var config repositoryConfig
204+ if err := json .Unmarshal (body , & config ); err != nil {
205+ return nil , fmt .Errorf ("failed to parse repository configuration: %v" , err )
206+ }
207+
208+ return & config , nil
209+ }
210+
122211// Download the content of layer search result.
123212func downloadLayer (searchResult utils.ResultItem , result interface {}, serviceManager artifactory.ArtifactoryServicesManager , repo string ) error {
124213 // Search results may include artifacts from the remote-cache repository.
@@ -340,7 +429,7 @@ func (builder *buildInfoBuilder) createBuildInfo(commandType CommandType, manife
340429 return nil , err
341430 }
342431 if ! builder .skipTaggingLayers {
343- if err := setBuildProperties (builder .buildName , builder .buildNumber , builder .project , builder .imageLayers , builder .serviceManager ); err != nil {
432+ if err := setBuildProperties (builder .buildName , builder .buildNumber , builder .project , builder .imageLayers , builder .serviceManager , builder . repositoryDetails . key ); err != nil {
344433 return nil , err
345434 }
346435 }
@@ -399,7 +488,7 @@ func (builder *buildInfoBuilder) createMultiPlatformBuildInfo(fatManifest *FatMa
399488 Parent : imageLongNameWithoutRepo ,
400489 })
401490 }
402- return buildInfo , setBuildProperties (builder .buildName , builder .buildNumber , builder .project , builder .imageLayers , builder .serviceManager )
491+ return buildInfo , setBuildProperties (builder .buildName , builder .buildNumber , builder .project , builder .imageLayers , builder .serviceManager , builder . repositoryDetails . key )
403492}
404493
405494// Construct the manifest's module ID by its type (attestation) or its platform.
0 commit comments