@@ -122,6 +122,13 @@ private JsonStream jsonStream() {
122122 return this .jsonStream ;
123123 }
124124
125+ URI buildPlatformJsonUrl (Feature feature , ImagePlatform platform , String path ) {
126+ if (platform != null && getApiVersion ().supports (feature .minimumVersion ())) {
127+ return buildUrl (feature , path , "platform" , platform .toJson ());
128+ }
129+ return buildUrl (path );
130+ }
131+
125132 private URI buildUrl (String path , Collection <?> params ) {
126133 return buildUrl (Feature .BASELINE , path , (params != null ) ? params .toArray () : null );
127134 }
@@ -227,9 +234,8 @@ public Image pull(ImageReference reference, ImagePlatform platform,
227234 UpdateListener <PullImageUpdateEvent > listener , String registryAuth ) throws IOException {
228235 Assert .notNull (reference , "Reference must not be null" );
229236 Assert .notNull (listener , "Listener must not be null" );
230- URI createUri = (platform != null )
231- ? buildUrl (Feature .PLATFORM , "/images/create" , "fromImage" , reference , "platform" , platform )
232- : buildUrl ("/images/create" , "fromImage" , reference );
237+ URI createUri = (platform != null ) ? buildUrl (Feature .PLATFORM_IMAGE_PULL , "/images/create" , "fromImage" ,
238+ reference , "platform" , platform ) : buildUrl ("/images/create" , "fromImage" , reference );
233239 DigestCaptureUpdateListener digestCapture = new DigestCaptureUpdateListener ();
234240 listener .onStart ();
235241 try {
@@ -336,9 +342,24 @@ public void exportLayerFiles(ImageReference reference, IOBiConsumer<String, Path
336342 */
337343 public void exportLayers (ImageReference reference , IOBiConsumer <String , TarArchive > exports )
338344 throws IOException {
345+ exportLayers (reference , null , exports );
346+ }
347+
348+ /**
349+ * Export the layers of an image as {@link TarArchive TarArchives}.
350+ * @param reference the reference to export
351+ * @param platform the platform (os/architecture/variant) of the image to export.
352+ * Ignored on older versions of Docker.
353+ * @param exports a consumer to receive the layers (contents can only be accessed
354+ * during the callback)
355+ * @throws IOException on IO error
356+ * @since 3.4.12
357+ */
358+ public void exportLayers (ImageReference reference , ImagePlatform platform ,
359+ IOBiConsumer <String , TarArchive > exports ) throws IOException {
339360 Assert .notNull (reference , "Reference must not be null" );
340361 Assert .notNull (exports , "Exports must not be null" );
341- URI uri = buildUrl ( "/images/" + reference + "/get" );
362+ URI uri = buildPlatformJsonUrl ( Feature . PLATFORM_IMAGE_EXPORT , platform , "/images/" + reference + "/get" );
342363 try (Response response = http ().get (uri )) {
343364 try (ExportedImageTar exportedImageTar = new ExportedImageTar (reference , response .getContent ())) {
344365 exportedImageTar .exportLayers (exports );
@@ -382,20 +403,13 @@ public Image inspect(ImageReference reference, ImagePlatform platform) throws IO
382403 // The Docker documentation is incomplete but platform parameters
383404 // are supported since 1.49 (see https://github.com/moby/moby/pull/49586)
384405 Assert .notNull (reference , "Reference must not be null" );
385- URI inspectUrl = inspectUrl (reference , platform );
406+ URI inspectUrl = buildPlatformJsonUrl (Feature .PLATFORM_IMAGE_INSPECT , platform ,
407+ "/images/" + reference + "/json" );
386408 try (Response response = http ().get (inspectUrl )) {
387409 return Image .of (response .getContent ());
388410 }
389411 }
390412
391- private URI inspectUrl (ImageReference reference , ImagePlatform platform ) {
392- String path = "/images/" + reference + "/json" ;
393- if (platform != null && getApiVersion ().supports (Feature .PLATFORM_INSPECT .minimumVersion ())) {
394- return buildUrl (Feature .PLATFORM_INSPECT , path , "platform" , platform .toJson ());
395- }
396- return buildUrl (path );
397- }
398-
399413 public void tag (ImageReference sourceReference , ImageReference targetReference ) throws IOException {
400414 Assert .notNull (sourceReference , "SourceReference must not be null" );
401415 Assert .notNull (targetReference , "TargetReference must not be null" );
@@ -437,7 +451,8 @@ public ContainerReference create(ContainerConfig config, ImagePlatform platform,
437451 }
438452
439453 private ContainerReference createContainer (ContainerConfig config , ImagePlatform platform ) throws IOException {
440- URI createUri = (platform != null ) ? buildUrl (Feature .PLATFORM , "/containers/create" , "platform" , platform )
454+ URI createUri = (platform != null )
455+ ? buildUrl (Feature .PLATFORM_CONTAINER_CREATE , "/containers/create" , "platform" , platform )
441456 : buildUrl ("/containers/create" );
442457 try (Response response = http ().post (createUri , "application/json" , config ::writeTo )) {
443458 return ContainerReference
@@ -639,9 +654,13 @@ enum Feature {
639654
640655 BASELINE (ApiVersion .of (1 , 24 )),
641656
642- PLATFORM (ApiVersion .of (1 , 41 )),
657+ PLATFORM_IMAGE_PULL (ApiVersion .of (1 , 41 )),
658+
659+ PLATFORM_CONTAINER_CREATE (ApiVersion .of (1 , 41 )),
660+
661+ PLATFORM_IMAGE_INSPECT (ApiVersion .of (1 , 49 )),
643662
644- PLATFORM_INSPECT (ApiVersion .of (1 , 49 ));
663+ PLATFORM_IMAGE_EXPORT (ApiVersion .of (1 , 48 ));
645664
646665 private final ApiVersion minimumVersion ;
647666
0 commit comments