Skip to content

Commit 74be969

Browse files
committed
fixes ImagePruner error wrapping
This removes ErrImage wrapping / detection from the acceptable error path in favor of directly inspecting the errors returned. However, we keep ErrImage wrapping in place so that we can ensure that the image name is associated with the error.
1 parent 759466d commit 74be969

File tree

2 files changed

+30
-54
lines changed

2 files changed

+30
-54
lines changed

pkg/controller/build/imagepruner/errors.go

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ func IsImageNotFoundErr(err error) bool {
4545
return false
4646
}
4747

48-
if !isErrImage(err) {
49-
return false
50-
}
51-
5248
if isMaskedHTTP404(err) {
5349
return true
5450
}
@@ -68,10 +64,6 @@ func IsAccessDeniedErr(err error) bool {
6864
return false
6965
}
7066

71-
if !isErrImage(err) {
72-
return false
73-
}
74-
7567
if isAccessDeniedErrorCode(err) {
7668
return true
7769
}
@@ -225,61 +217,35 @@ func isTolerableUnexpectedHTTPStatusError(err error) bool {
225217

226218
// ErrImage holds and wraps an error related to a specific image.
227219
type ErrImage struct {
228-
msg string
229-
img string
230-
err error
231-
}
232-
233-
// newErrImageWithMessage constructs a new ErrImage instance with a custom message,
234-
// image pullspec, and wrapped error.
235-
func newErrImageWithMessage(msg, img string, err error) error {
236-
return &ErrImage{msg: msg, img: img, err: err}
220+
image string
221+
err error
237222
}
238223

239224
// newErrImage constructs a new ErrImage instance with an image pullspec and
240-
// wrapped error, without a custom message.
225+
// wrapped error.
241226
func newErrImage(img string, err error) error {
242-
return &ErrImage{img: img, err: err}
227+
return &ErrImage{image: img, err: err}
243228
}
244229

245-
// Image returns the image pullspec that caused the error.
230+
// Returns the image embedded within the ErrImage struct.
246231
func (e *ErrImage) Image() string {
247-
return e.img
232+
return e.image
248233
}
249234

250235
// Error implements the error interface, providing a formatted error string
251-
// including the message (if present), image (if present), and the wrapped error's string.
236+
// including the image (if present), and the wrapped error's string.
252237
func (e *ErrImage) Error() string {
253-
if e.msg != "" && e.img != "" {
254-
// If both the message and image are not empty, include both.
255-
return fmt.Sprintf("%s: image %q: %s", e.msg, e.img, e.err.Error())
238+
// If the image is defined and not contained within the underlying error, inject it here.
239+
if e.image != "" && !strings.Contains(e.err.Error(), e.image) {
240+
return fmt.Sprintf("error occurred with image %q: %s", e.image, e.err.Error())
256241
}
257242

258-
if e.msg == "" && e.img != "" {
259-
// If the message is empty and the image is not, only include the image.
260-
return fmt.Sprintf("image %q: %s", e.img, e.err.Error())
261-
}
262-
263-
// If neither the message nor the image is populated, just return the error
264-
// string as-is.
243+
// If the image is undefined or is already present in the error, return the
244+
// error as-is.
265245
return e.err.Error()
266246
}
267247

268248
// Unwrap implements the Unwrap interface, allowing the nested error to be surfaced.
269249
func (e *ErrImage) Unwrap() error {
270250
return e.err
271251
}
272-
273-
// isErrImage determines whether the given error is an instance of the ErrImage
274-
// type defined above.
275-
func isErrImage(err error) bool {
276-
if err == nil {
277-
return false
278-
}
279-
280-
// Any errors related to the actual image registry query are wrapped in an
281-
// ErrImage instance. This allows us to easily identify intolerable errors
282-
// such as not being able to write the authfile or certs, etc.
283-
var errImage *ErrImage
284-
return errors.As(err, &errImage)
285-
}

pkg/controller/build/imagepruner/imageinspect.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,21 @@ func NewImageInspectorDeleter() ImageInspectorDeleter {
4949

5050
// ImageInspect uses the provided system context to inspect the provided image pullspec.
5151
func (i *imageInspectorImpl) ImageInspect(ctx context.Context, sysCtx *types.SystemContext, image string) (*types.ImageInspectInfo, *digest.Digest, error) {
52-
return imageInspect(ctx, sysCtx, image)
52+
info, digest, err := imageInspect(ctx, sysCtx, image)
53+
if err == nil {
54+
return info, digest, nil
55+
}
56+
57+
return nil, nil, newErrImage(image, err)
5358
}
5459

5560
// DeleteImage uses the provided system context to delete the provided image pullspec.
5661
func (i *imageInspectorImpl) DeleteImage(ctx context.Context, sysCtx *types.SystemContext, image string) error {
57-
return deleteImage(ctx, sysCtx, image)
62+
if err := deleteImage(ctx, sysCtx, image); err != nil {
63+
return newErrImage(image, err)
64+
}
65+
66+
return nil
5867
}
5968

6069
// deleteImage attempts to delete the specified image with retries,
@@ -74,8 +83,9 @@ func deleteImage(ctx context.Context, sysCtx *types.SystemContext, imageName str
7483
if err := retry.IfNecessary(ctx, func() error {
7584
return ref.DeleteImage(ctx, sysCtx)
7685
}, &retryOpts); err != nil {
77-
return newErrImage(imageName, err)
86+
return err
7887
}
88+
7989
return nil
8090
}
8191

@@ -88,15 +98,15 @@ func deleteImage(ctx context.Context, sysCtx *types.SystemContext, imageName str
8898
func imageInspect(ctx context.Context, sysCtx *types.SystemContext, imageName string) (*types.ImageInspectInfo, *digest.Digest, error) {
8999
ref, err := imageutils.ParseImageName(imageName)
90100
if err != nil {
91-
return nil, nil, fmt.Errorf("error parsing image name %q: %w", imageName, err)
101+
return nil, nil, fmt.Errorf("error parsing image name: %w", err)
92102
}
93103

94104
retryOpts := retry.RetryOptions{
95105
MaxRetry: cmdRetriesCount,
96106
}
97107
src, err := imageutils.GetImageSourceFromReference(ctx, sysCtx, ref, &retryOpts)
98108
if err != nil {
99-
return nil, nil, fmt.Errorf("error getting image source for %s: %w", imageName, err)
109+
return nil, nil, fmt.Errorf("error getting image source: %w", err)
100110
}
101111
defer src.Close()
102112

@@ -112,20 +122,20 @@ func imageInspect(ctx context.Context, sysCtx *types.SystemContext, imageName st
112122
// get the digest here because it's not part of the image inspection
113123
digest, err := manifest.Digest(rawManifest)
114124
if err != nil {
115-
return nil, nil, fmt.Errorf("error retrieving image digest: %q: %w", imageName, err)
125+
return nil, nil, fmt.Errorf("error retrieving image digest: %w", err)
116126
}
117127

118128
img, err := image.FromUnparsedImage(ctx, sysCtx, unparsedInstance)
119129
if err != nil {
120-
return nil, nil, newErrImage(imageName, fmt.Errorf("error parsing manifest for image: %w", err))
130+
return nil, nil, fmt.Errorf("error parsing manifest for image: %w", err)
121131
}
122132

123133
var imgInspect *types.ImageInspectInfo
124134
if err := retry.IfNecessary(ctx, func() error {
125135
imgInspect, err = img.Inspect(ctx)
126136
return err
127137
}, &retryOpts); err != nil {
128-
return nil, nil, newErrImage(imageName, err)
138+
return nil, nil, err
129139
}
130140

131141
return imgInspect, &digest, nil

0 commit comments

Comments
 (0)