@@ -18,6 +18,8 @@ import (
18
18
kclient "sigs.k8s.io/controller-runtime/pkg/client"
19
19
)
20
20
21
+ const defaultNoReg = "xxx-no-reg"
22
+
21
23
var (
22
24
syncQueue = make (chan struct {}, 1 )
23
25
ticker * time.Ticker
@@ -198,18 +200,28 @@ func (d *daemon) sync(ctx context.Context) error {
198
200
// If it determines a newer version of an image is available for an app, it will update the app with that information
199
201
// which will trigger the appInstance handlers to pick up the change and deploy the new version of the app
200
202
for imageKey , appsForImage := range refresh {
201
- current , tags , err := pull .ListTags (ctx , d .client , imageKey .namespace , imageKey .image )
202
- if err != nil {
203
- logrus .Errorf ("Problem listing tags for image %v: %v" , imageKey .image , err )
204
- }
205
- r , err := imagename .ParseReference (imageKey .image )
203
+ current , err := imagename .ParseReference (imageKey .image , imagename .WithDefaultRegistry (defaultNoReg ))
206
204
if err != nil {
207
205
logrus .Errorf ("Problem parsing image referece %v: %v" , imageKey .image , err )
206
+ continue
207
+ }
208
+ // if the registry after being parsed is our default fake one, then this is a local image with no registry
209
+ hasValidRegistry := current .Context ().RegistryStr () != defaultNoReg
210
+ var tags []string
211
+ var pullErr error
212
+ if hasValidRegistry {
213
+ _ , tags , pullErr = pull .ListTags (ctx , d .client , imageKey .namespace , imageKey .image )
208
214
}
209
- localTags , err := tags2 .GetTagsMatchingRepository (r , ctx , d .client , "acorn" )
215
+ localTags , err := tags2 .GetTagsMatchingRepository (current , ctx , d .client , "acorn" , defaultNoReg )
210
216
if err != nil {
217
+ // We aren't doing a continue here because this just means there was a parsing error with the local images
218
+ // configMap. We should still see if the image can be updated via digest or if there are non-local images
211
219
logrus .Errorf ("Problem finding local tags matching %v: %v" , imageKey .image , err )
212
220
}
221
+ if len (localTags ) == 0 && pullErr != nil {
222
+ // We aren't doing a continue here because it is still possible we can find a new version via digest
223
+ logrus .Errorf ("Couldn't find any remote tags for image %v. Error: %v" , imageKey .image , pullErr )
224
+ }
213
225
tags = append (tags , localTags ... )
214
226
215
227
for _ , appKey := range appsForImage {
@@ -234,11 +246,8 @@ func (d *daemon) sync(ctx context.Context) error {
234
246
updated = true
235
247
mode , _ := Mode (app .Spec )
236
248
t := current .Context ().Tag (newTag ).Name ()
237
- // go-containerregistry adds this prefix by default. We need to strip it if it wasn't present in the original so that
238
- // local images work
239
- if strings .HasPrefix (t , "index.docker.io/library/" ) && ! strings .HasPrefix (imageKey .image , "index.docker.io/library/" ) {
240
- t = strings .TrimPrefix (t , "index.docker.io/library/" )
241
- }
249
+ // If the registry is our fake default, remove it from the constructed reference
250
+ t = strings .TrimPrefix (t , defaultNoReg + "/" )
242
251
switch mode {
243
252
case "enabled" :
244
253
if app .Status .AvailableAppImage == t {
@@ -273,12 +282,19 @@ func (d *daemon) sync(ctx context.Context) error {
273
282
// In either case, we also want to check to see if new content was pushed to the current tag
274
283
// This satisfies the usecase of autoUpgrade with an app's tag is something static, like "latest"
275
284
if ! updated {
276
- digest , err := pull .ImageDigest (ctx , d .client , app .Namespace , imageKey .image )
277
- if err != nil {
278
- logrus .Errorf ("Problem getting digest app %v: %v" , appKey , err )
279
- continue
285
+ var digest string
286
+ var pullErr error
287
+ if hasValidRegistry {
288
+ digest , pullErr = pull .ImageDigest (ctx , d .client , app .Namespace , imageKey .image )
289
+ }
290
+ // Whether or not we got a digest from a remote registry, check to see if there is a version of this tag locally
291
+ if localDigest , ok , _ := tags2 .ResolveLocal (ctx , d .client , app .Namespace , imageKey .image ); ok && localDigest != "" {
292
+ digest = localDigest
293
+ }
294
+ if digest == "" && pullErr != nil {
295
+ logrus .Errorf ("Problem getting updated digest for image %v from remote. Error: %v" , imageKey .image , pullErr )
280
296
}
281
- if app .Status .AppImage .Digest != digest {
297
+ if strings . TrimPrefix ( app .Status .AppImage .Digest , "sha256:" ) != strings . TrimPrefix ( digest , "sha256:" ) {
282
298
mode , _ := Mode (app .Spec )
283
299
switch mode {
284
300
case "enabled" :
@@ -297,8 +313,8 @@ func (d *daemon) sync(ctx context.Context) error {
297
313
logrus .Warnf ("Unrecognized auto-upgrade mode %v for %v" , mode , app .Name )
298
314
continue
299
315
}
300
- logrus .Infof ("Triggering an auto-upprade of app %v because a new digest was detected for image %v" ,
301
- appKey , imageKey .image )
316
+ logrus .Infof ("Triggering an auto-upprade of app %v because a new digest [%v] was detected for image %v" ,
317
+ appKey , digest , imageKey .image )
302
318
if err := d .client .Status ().Update (ctx , & app ); err != nil {
303
319
logrus .Errorf ("Problem updating %v: %v" , appKey , err )
304
320
continue
@@ -355,6 +371,7 @@ func removeTagPattern(image string) string {
355
371
return strings .TrimSuffix (image , ":" + p )
356
372
}
357
373
374
+ // AutoUpgradePattern returns the tag and a boolean indicating whether it is actually a pattern (versus a concrete tag)
358
375
func AutoUpgradePattern (image string ) (string , bool ) {
359
376
// This first bit is adapted from https://github.com/google/go-containerregistry/blob/main/pkg/name/tag.go
360
377
// Split on ":"
0 commit comments