Skip to content

Commit

Permalink
Return more detailed errors when fixup fails (#113)
Browse files Browse the repository at this point in the history
* Return more detailed errors when fixup fails

It's not possible from the current error to tell what went wrong since
the real error is only sent to the debug logger, and isn't included in
the returned error message.

I have updated the errors returned from each fixup function so that you
can tell where the fixup failed from the error message.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>

* Don't fail immediatley if a fixup fails

When applying fixups to an image, accumulate any errors and only return an error if
the image ultimately was unable to be pushed.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs authored Jul 6, 2022
1 parent 3db3383 commit c911a15
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions remotes/fixup.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/remotes"
"github.com/docker/distribution/reference"
"github.com/hashicorp/go-multierror"
ocischemav1 "github.com/opencontainers/image-spec/specs-go/v1"
)

Expand Down Expand Up @@ -216,63 +217,75 @@ func fixupBaseImage(ctx context.Context, name string, baseImage *bundle.BaseImag
pushLocalImage,
}

var bigErr *multierror.Error
for _, f := range fixups {
info, pushed, ok, err := f(ctx, targetRepoOnly, baseImage, cfg)
if err != nil {
log.G(ctx).Debug(err)
// do not stop trying fixups after the first error. Only report the errors if all fixups were unable to push the image.
bigErr = multierror.Append(bigErr, fmt.Errorf("failed to fixup the image %s for service %q: %v", baseImage.Image, name, err))
}
if ok {
return info, pushed, nil
}
}

return imageFixupInfo{}, false, fmt.Errorf("failed to resolve or push image for service %q", name)
return imageFixupInfo{}, false, bigErr.ErrorOrNil()
}

func pushByDigest(ctx context.Context, target reference.Named, baseImage *bundle.BaseImage, cfg fixupConfig) (imageFixupInfo, bool, bool, error) {
if baseImage.Image != "" || !cfg.pushImages {
return imageFixupInfo{}, false, false, nil
}
descriptor, err := pushImageToTarget(ctx, baseImage.Digest, cfg)
if err != nil {
return imageFixupInfo{}, false, false, fmt.Errorf("failed to push digested image %s@%s to target %s: %v", baseImage.Image, baseImage.Digest, target, err)
}
return imageFixupInfo{
targetRepo: target,
sourceRef: nil,
resolvedDescriptor: descriptor,
}, true, err == nil, err
}, true, true, nil
}

func resolveImage(ctx context.Context, target reference.Named, baseImage *bundle.BaseImage, cfg fixupConfig) (imageFixupInfo, bool, bool, error) {
sourceImageRef, err := ref(baseImage.Image)
if err != nil {
return imageFixupInfo{}, false, false, err
return imageFixupInfo{}, false, false, fmt.Errorf("failed to resolve image: invalid source ref %s: %v", baseImage.Image, err)
}
_, descriptor, err := cfg.resolver.Resolve(ctx, sourceImageRef.String())
if err != nil {
return imageFixupInfo{}, false, false, fmt.Errorf("failed to resolve image %s: %v", sourceImageRef.String(), err)
}
return imageFixupInfo{
targetRepo: target,
sourceRef: sourceImageRef,
resolvedDescriptor: descriptor,
}, false, err == nil, err
}, false, true, nil
}

func resolveImageInRelocationMap(ctx context.Context, target reference.Named, baseImage *bundle.BaseImage, cfg fixupConfig) (imageFixupInfo, bool, bool, error) {
sourceImageRef, err := ref(baseImage.Image)
if err != nil {
return imageFixupInfo{}, false, false, err
return imageFixupInfo{}, false, false, fmt.Errorf("failed to resolve image in relocation map: invalid source ref %s: %v", baseImage.Image, err)
}
relocatedRef, ok := cfg.relocationMap[baseImage.Image]
if !ok {
return imageFixupInfo{}, false, false, nil
}
relocatedImageRef, err := ref(relocatedRef)
if err != nil {
return imageFixupInfo{}, false, false, err
return imageFixupInfo{}, false, false, fmt.Errorf("failed to resolve image in relocation map: invalid target ref %s: %v", relocatedRef, err)
}
_, descriptor, err := cfg.resolver.Resolve(ctx, relocatedImageRef.String())
if err != nil {
return imageFixupInfo{}, false, false, err
}
return imageFixupInfo{
targetRepo: target,
sourceRef: sourceImageRef,
resolvedDescriptor: descriptor,
}, false, err == nil, err
}, false, true, nil
}

func pushLocalImage(ctx context.Context, target reference.Named, baseImage *bundle.BaseImage, cfg fixupConfig) (imageFixupInfo, bool, bool, error) {
Expand All @@ -281,14 +294,17 @@ func pushLocalImage(ctx context.Context, target reference.Named, baseImage *bund
}
sourceImageRef, err := ref(baseImage.Image)
if err != nil {
return imageFixupInfo{}, false, false, err
return imageFixupInfo{}, false, false, fmt.Errorf("failed to push local image: invalid source ref %s: %v", baseImage.Image, err)
}
descriptor, err := pushImageToTarget(ctx, baseImage.Image, cfg)
if err != nil {
return imageFixupInfo{}, false, false, fmt.Errorf("failed to push local image %s: %v", baseImage.Image, err)
}
return imageFixupInfo{
targetRepo: target,
sourceRef: sourceImageRef,
resolvedDescriptor: descriptor,
}, true, err == nil, err
}, true, true, nil
}

func ref(str string) (reference.Named, error) {
Expand Down

0 comments on commit c911a15

Please sign in to comment.