@@ -191,29 +191,31 @@ func (s *Strategy) findImage(ctx context.Context, namespace, imageName string) (
191191// - tag name (with default): <registry>/<repo> or <repo> -> Will be matched against the default tag (:latest)
192192// - Note: if we get some string here, that matches the SHAPermissivePrefixPattern, it could be both a digest or a name without a tag
193193// so we will try to match it against the default tag (:latest) first and if that fails, we treat it as a digest(-prefix)
194- func findImageMatch (images apiv1.ImageList , imageName string ) (* apiv1.Image , string , error ) {
194+ func findImageMatch (images apiv1.ImageList , search string ) (* apiv1.Image , string , error ) {
195195 var (
196196 repoDigest name.Digest
197197 digest string
198198 digestPrefix string
199199 tagName string
200200 tagNameDefault string
201+ canBeMultiple bool // if true, we will not return on first match
201202 )
202- if strings .HasPrefix (imageName , "sha256:" ) {
203- digest = imageName
204- } else if tags2 .SHAPattern .MatchString (imageName ) {
205- digest = "sha256:" + imageName
206- tagNameDefault = imageName
207- } else if tags2 .SHAPermissivePrefixPattern .MatchString (imageName ) {
208- digestPrefix = "sha256:" + imageName
209- tagNameDefault = imageName
203+ if strings .HasPrefix (search , "sha256:" ) {
204+ digest = search
205+ } else if tags2 .SHAPattern .MatchString (search ) {
206+ digest = "sha256:" + search
207+ tagNameDefault = search // this could as well be some name without registry/repo path and tag
208+ } else if tags2 .SHAPermissivePrefixPattern .MatchString (search ) {
209+ digestPrefix = "sha256:" + search
210+ tagNameDefault = search // this could as well be some name without registry/repo path and tag
210211 } else {
211- ref , err := name .ParseReference (imageName , name .WithDefaultRegistry ("" ), name .WithDefaultTag ("" ))
212+ ref , err := name .ParseReference (search , name .WithDefaultRegistry ("" ), name .WithDefaultTag ("" ))
212213 if err != nil {
213214 return nil , "" , err
214215 }
215216 if ref .Identifier () == "" {
216- tagNameDefault = ref .Name ()
217+ tagNameDefault = ref .Name () // some name without a tag, so we will try to match it against the default tag (:latest)
218+ canBeMultiple = true
217219 } else if dig , ok := ref .(name.Digest ); ok {
218220 repoDigest = dig
219221 } else {
@@ -231,28 +233,31 @@ func findImageMatch(images apiv1.ImageList, imageName string) (*apiv1.Image, str
231233 }
232234
233235 var matchedImage apiv1.Image
236+ var matchedTag string
234237 for _ , image := range images .Items {
238+ // >>> match by tag name with default tag (:latest)
235239 if tagNameDefault != "" {
236240 for _ , tag := range image .Tags {
237241 if tag == tagNameDefault {
238- return & image , "" , nil
242+ return & image , tag , nil
239243 }
240244 }
241245 }
242246
247+ // >>> match by digest or digest prefix
243248 if image .Digest == digest {
244249 return & image , "" , nil
245250 } else if digestPrefix != "" && strings .HasPrefix (image .Digest , digestPrefix ) {
246251 if matchedImage .Digest != "" && matchedImage .Digest != image .Digest {
247- reason := fmt .Sprintf ("Image identifier %v is not unique" , imageName )
248- return nil , "" , apierrors .NewBadRequest (reason )
252+ return nil , "" , apierrors .NewBadRequest (fmt .Sprintf ("Image identifier %v is not unique" , search ))
249253 }
250254 matchedImage = image
251255 }
252256
257+ // >>> match by repo digest
258+ // this returns an image which matches the digest and has at least one tag
259+ // which matches the repo part of the repo digest.
253260 if repoDigest .Name () != "" && image .Digest == repoDigest .DigestStr () {
254- // Matching by repo digest returns an image which matches the digest and has at least one tag
255- // which matches the repo part of the repo digest.
256261 for _ , tag := range image .Tags {
257262 imageParsedTag , err := name .NewTag (tag , name .WithDefaultRegistry ("" ))
258263 if err != nil {
@@ -264,27 +269,42 @@ func findImageMatch(images apiv1.ImageList, imageName string) (*apiv1.Image, str
264269 }
265270 }
266271
267- for i , tag := range image .Tags {
268- if tag == imageName {
269- return & image , image .Tags [i ], nil
272+ // >>> match by tag name
273+ for _ , tag := range image .Tags {
274+ if tag == search {
275+ if ! canBeMultiple {
276+ return & image , tag , nil
277+ }
278+ if matchedImage .Digest != "" && matchedImage .Digest != image .Digest {
279+ return nil , "" , apierrors .NewBadRequest (fmt .Sprintf ("Image identifier %v is not unique" , search ))
280+ }
281+ matchedImage = image
282+ matchedTag = tag
270283 } else if tag != "" {
271- imageParsedTag , err := name .NewTag (tag , name .WithDefaultRegistry ("" ))
284+ imageParsedTag , err := name .NewTag (tag , name .WithDefaultRegistry ("" ), name . WithDefaultTag ( "" )) // no default here, as we also have repo-only tag items
272285 if err != nil {
273286 continue
274287 }
275288 if imageParsedTag .Name () == tagName {
276- return & image , tag , nil
289+ if ! canBeMultiple {
290+ return & image , tag , nil
291+ }
292+ if matchedImage .Digest != "" && matchedImage .Digest != image .Digest {
293+ return nil , "" , apierrors .NewBadRequest (fmt .Sprintf ("Image identifier %v is not unique" , search ))
294+ }
295+ matchedImage = image
296+ matchedTag = tag
277297 }
278298 }
279299 }
280300 }
281301
282302 if matchedImage .Digest != "" {
283- return & matchedImage , "" , nil
303+ return & matchedImage , matchedTag , nil
284304 }
285305
286306 return nil , "" , apierrors .NewNotFound (schema.GroupResource {
287307 Group : api .Group ,
288308 Resource : "images" ,
289- }, imageName )
309+ }, search )
290310}
0 commit comments