Skip to content

Commit 174fdb3

Browse files
committed
Support platform queries for image inspect and export
Signed-off-by: hojooo <ghwn5833@gmail.com>
1 parent 9319625 commit 174fdb3

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public class DockerApi {
6868

6969
static final ApiVersion PLATFORM_API_VERSION = ApiVersion.of(1, 41);
7070

71+
static final ApiVersion INSPECT_PLATFORM_API_VERSION = ApiVersion.of(1, 49);
72+
73+
static final ApiVersion EXPORT_PLATFORM_API_VERSION = ApiVersion.of(1, 51);
74+
7175
static final ApiVersion UNKNOWN_API_VERSION = ApiVersion.of(0, 0);
7276

7377
static final String API_VERSION_HEADER_NAME = "API-Version";
@@ -239,9 +243,12 @@ public Image pull(ImageReference reference, @Nullable ImagePlatform platform,
239243
listener.onUpdate(event);
240244
});
241245
}
242-
String digest = digestCapture.getDigest();
243-
ImageReference inspectReference = (digest != null) ? reference.withDigest(digest) : reference;
244-
return inspect((platform != null) ? PLATFORM_API_VERSION : API_VERSION, inspectReference);
246+
ApiVersion callVersion = API_VERSION;
247+
if (platform != null) {
248+
callVersion = (getApiVersion().supports(INSPECT_PLATFORM_API_VERSION))
249+
? INSPECT_PLATFORM_API_VERSION : PLATFORM_API_VERSION;
250+
}
251+
return inspect(callVersion, reference, platform);
245252
}
246253
finally {
247254
listener.onFinish();
@@ -328,9 +335,20 @@ public void exportLayers(ImageReference reference, @Nullable ImagePlatform platf
328335
IOBiConsumer<String, TarArchive> exports) throws IOException {
329336
Assert.notNull(reference, "'reference' must not be null");
330337
Assert.notNull(exports, "'exports' must not be null");
331-
URI uri = (platform != null)
332-
? buildUrl(PLATFORM_API_VERSION, "/images/" + reference + "/get", "platform", platform)
333-
: buildUrl("/images/" + reference + "/get");
338+
URI uri;
339+
if (platform != null) {
340+
if (getApiVersion().supports(EXPORT_PLATFORM_API_VERSION)) {
341+
uri = buildUrl(EXPORT_PLATFORM_API_VERSION, "/images/" + reference + "/get", "platform",
342+
platform.toString());
343+
}
344+
else {
345+
// Platform selection for /images/{ref}/get is supported from 1.51
346+
uri = buildUrl("/images/" + reference + "/get");
347+
}
348+
}
349+
else {
350+
uri = buildUrl("/images/" + reference + "/get");
351+
}
334352
try (Response response = http().get(uri)) {
335353
try (ExportedImageTar exportedImageTar = new ExportedImageTar(reference, response.getContent())) {
336354
exportedImageTar.exportLayers(exports);
@@ -362,8 +380,15 @@ public Image inspect(ImageReference reference) throws IOException {
362380
}
363381

364382
private Image inspect(ApiVersion apiVersion, ImageReference reference) throws IOException {
383+
return inspect(apiVersion, reference, null);
384+
}
385+
386+
private Image inspect(ApiVersion apiVersion, ImageReference reference, @Nullable ImagePlatform platform)
387+
throws IOException {
365388
Assert.notNull(reference, "'reference' must not be null");
366-
URI imageUri = buildUrl(apiVersion, "/images/" + reference + "/json");
389+
URI imageUri = (platform != null)
390+
? buildUrl(apiVersion, "/images/" + reference + "/json", "platform", platform.toQueryParameter(getApiVersion()))
391+
: buildUrl(apiVersion, "/images/" + reference + "/json");
367392
try (Response response = http().get(imageUri)) {
368393
return Image.of(response.getContent());
369394
}

buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImagePlatform.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,31 @@ public static ImagePlatform from(Image image) {
101101
return new ImagePlatform(image.getOs(), image.getArchitecture(), image.getVariant());
102102
}
103103

104+
/**
105+
* Return the value to use for the Docker API {@code platform} query parameter for the
106+
* given API version.
107+
*
108+
* For API versions that support JSON (1.49 and above), this method returns a JSON
109+
* object in the form {@code {"os":"...","architecture":"...","variant":"..."}}.
110+
* For lower API versions, the legacy string representation {@code os[/arch[/variant]]}
111+
* is returned.
112+
* @param apiVersion the Docker API version to target
113+
* @return the query parameter value to use for {@code platform}
114+
*/
115+
public String toQueryParameter(ApiVersion apiVersion) {
116+
Assert.notNull(apiVersion, "'apiVersion' must not be null");
117+
if (apiVersion.supports(ApiVersion.of(1, 49))) {
118+
StringBuilder json = new StringBuilder("{");
119+
json.append("\"os\":\"").append(this.os).append("\"");
120+
if (this.architecture != null && !this.architecture.isEmpty()) {
121+
json.append(",\"architecture\":\"").append(this.architecture).append("\"");
122+
}
123+
if (this.variant != null && !this.variant.isEmpty()) {
124+
json.append(",\"variant\":\"").append(this.variant).append("\"");
125+
}
126+
json.append("}");
127+
return json.toString();
128+
}
129+
return toString();
130+
}
104131
}

0 commit comments

Comments
 (0)