Browse code

c8d: Wrap matchRequestedOrDefault result with a platform

Allowing it to obtain a specific `ocispec.Platform` used to create this
platform matcher.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>

Paweł Gronowski authored on 2024/08/01 20:14:35
Showing 3 changed files
... ...
@@ -33,7 +33,7 @@ func (e *errPlatformNotFound) NotFound() {}
33 33
 func (e *errPlatformNotFound) Error() string {
34 34
 	msg := "image with reference " + e.imageRef + " was found but does not match the specified platform"
35 35
 	if e.wanted.OS != "" {
36
-		msg += ": wanted " + platforms.Format(e.wanted)
36
+		msg += ": wanted " + platforms.FormatAll(e.wanted)
37 37
 	}
38 38
 	return msg
39 39
 }
... ...
@@ -49,14 +49,6 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options bac
49 49
 
50 50
 	imgV1, err := i.getImageV1(ctx, img, pm)
51 51
 	if err != nil {
52
-		var e *errPlatformNotFound
53
-		if errors.As(err, &e) {
54
-			if options.Platform != nil {
55
-				e.wanted = *options.Platform
56
-			} else {
57
-				e.wanted = platforms.DefaultSpec()
58
-			}
59
-		}
60 52
 		return nil, err
61 53
 	}
62 54
 
... ...
@@ -97,15 +89,6 @@ func (i *ImageService) GetImageManifest(ctx context.Context, refOrID string, opt
97 97
 
98 98
 	im, err := i.getBestPresentImageManifest(ctx, img, pm)
99 99
 	if err != nil {
100
-		var e *errPlatformNotFound
101
-		if errors.As(err, &e) {
102
-			if options.Platform != nil {
103
-				e.wanted = *options.Platform
104
-			} else {
105
-				e.wanted = platforms.DefaultSpec()
106
-			}
107
-			return nil, e
108
-		}
109 100
 		return nil, err
110 101
 	}
111 102
 
... ...
@@ -139,7 +122,11 @@ func (i *ImageService) getBestPresentImageManifest(ctx context.Context, img cont
139 139
 	}
140 140
 
141 141
 	if best == nil {
142
-		return nil, &errPlatformNotFound{imageRef: imageFamiliarName(img)}
142
+		err := &errPlatformNotFound{imageRef: imageFamiliarName(img)}
143
+		if p, ok := pm.(platformMatcherWithRequestedPlatform); ok && p.Requested != nil {
144
+			err.wanted = *p.Requested
145
+		}
146
+		return nil, err
143 147
 	}
144 148
 
145 149
 	return best, nil
... ...
@@ -30,10 +30,6 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
30 30
 
31 31
 	im, err := i.getBestPresentImageManifest(ctx, img, pm)
32 32
 	if err != nil {
33
-		var e *errPlatformNotFound
34
-		if errors.As(err, &e) {
35
-			e.wanted = platforms.DefaultSpec()
36
-		}
37 33
 		return nil, err
38 34
 	}
39 35
 
... ...
@@ -25,16 +25,32 @@ func (c allPlatformsWithPreferenceMatcher) Less(p1, p2 ocispec.Platform) bool {
25 25
 	return c.preferred.Less(p1, p2)
26 26
 }
27 27
 
28
+// platformMatcherWithRequestedPlatform is a platform matcher that also
29
+// contains the platform that was requested by the user in the context
30
+// in which the matcher was created.
31
+type platformMatcherWithRequestedPlatform struct {
32
+	Requested *ocispec.Platform
33
+
34
+	platforms.MatchComparer
35
+}
36
+
28 37
 type matchComparerProvider func(ocispec.Platform) platforms.MatchComparer
29 38
 
30 39
 func (i *ImageService) matchRequestedOrDefault(
31 40
 	fpm matchComparerProvider, // function to create a platform matcher if platform is not nil
32 41
 	platform *ocispec.Platform, // input platform, nil if not specified
33
-) platforms.MatchComparer {
42
+) platformMatcherWithRequestedPlatform {
43
+	var inner platforms.MatchComparer
34 44
 	if platform == nil {
35
-		return matchAllWithPreference(i.hostPlatformMatcher())
45
+		inner = matchAllWithPreference(i.hostPlatformMatcher())
46
+	} else {
47
+		inner = fpm(*platform)
48
+	}
49
+
50
+	return platformMatcherWithRequestedPlatform{
51
+		Requested:     platform,
52
+		MatchComparer: inner,
36 53
 	}
37
-	return fpm(*platform)
38 54
 }
39 55
 
40 56
 func (i *ImageService) hostPlatformMatcher() platforms.MatchComparer {