@@ -138,6 +138,13 @@ private JsonStream jsonStream() {
138138 return this .jsonStream ;
139139 }
140140
141+ URI buildPlatformJsonUrl (Feature feature , ImagePlatform platform , String path ) {
142+ if (platform != null && getApiVersion ().supports (feature .minimumVersion ())) {
143+ return buildUrl (feature , path , "platform" , platform .toJson ());
144+ }
145+ return buildUrl (path );
146+ }
147+
141148 private URI buildUrl (String path , Collection <?> params ) {
142149 return buildUrl (Feature .BASELINE , path , (params != null ) ? params .toArray () : null );
143150 }
@@ -243,9 +250,8 @@ public Image pull(ImageReference reference, ImagePlatform platform,
243250 UpdateListener <PullImageUpdateEvent > listener , String registryAuth ) throws IOException {
244251 Assert .notNull (reference , "'reference' must not be null" );
245252 Assert .notNull (listener , "'listener' must not be null" );
246- URI createUri = (platform != null )
247- ? buildUrl (Feature .PLATFORM , "/images/create" , "fromImage" , reference , "platform" , platform )
248- : buildUrl ("/images/create" , "fromImage" , reference );
253+ URI createUri = (platform != null ) ? buildUrl (Feature .PLATFORM_IMAGE_PULL , "/images/create" , "fromImage" ,
254+ reference , "platform" , platform ) : buildUrl ("/images/create" , "fromImage" , reference );
249255 DigestCaptureUpdateListener digestCapture = new DigestCaptureUpdateListener ();
250256 listener .onStart ();
251257 try {
@@ -324,9 +330,24 @@ public void load(ImageArchive archive, UpdateListener<LoadImageUpdateEvent> list
324330 */
325331 public void exportLayers (ImageReference reference , IOBiConsumer <String , TarArchive > exports )
326332 throws IOException {
333+ exportLayers (reference , null , exports );
334+ }
335+
336+ /**
337+ * Export the layers of an image as {@link TarArchive TarArchives}.
338+ * @param reference the reference to export
339+ * @param platform the platform (os/architecture/variant) of the image to export.
340+ * Ignored on older versions of Docker.
341+ * @param exports a consumer to receive the layers (contents can only be accessed
342+ * during the callback)
343+ * @throws IOException on IO error
344+ * @since 3.4.12
345+ */
346+ public void exportLayers (ImageReference reference , ImagePlatform platform ,
347+ IOBiConsumer <String , TarArchive > exports ) throws IOException {
327348 Assert .notNull (reference , "'reference' must not be null" );
328349 Assert .notNull (exports , "'exports' must not be null" );
329- URI uri = buildUrl ( "/images/" + reference + "/get" );
350+ URI uri = buildPlatformJsonUrl ( Feature . PLATFORM_IMAGE_EXPORT , platform , "/images/" + reference + "/get" );
330351 try (Response response = http ().get (uri )) {
331352 try (ExportedImageTar exportedImageTar = new ExportedImageTar (reference , response .getContent ())) {
332353 exportedImageTar .exportLayers (exports );
@@ -370,20 +391,13 @@ public Image inspect(ImageReference reference, ImagePlatform platform) throws IO
370391 // The Docker documentation is incomplete but platform parameters
371392 // are supported since 1.49 (see https://github.com/moby/moby/pull/49586)
372393 Assert .notNull (reference , "'reference' must not be null" );
373- URI inspectUrl = inspectUrl (reference , platform );
394+ URI inspectUrl = buildPlatformJsonUrl (Feature .PLATFORM_IMAGE_INSPECT , platform ,
395+ "/images/" + reference + "/json" );
374396 try (Response response = http ().get (inspectUrl )) {
375397 return Image .of (response .getContent ());
376398 }
377399 }
378400
379- private URI inspectUrl (ImageReference reference , ImagePlatform platform ) {
380- String path = "/images/" + reference + "/json" ;
381- if (platform != null && getApiVersion ().supports (Feature .PLATFORM_INSPECT .minimumVersion ())) {
382- return buildUrl (Feature .PLATFORM_INSPECT , path , "platform" , platform .toJson ());
383- }
384- return buildUrl (path );
385- }
386-
387401 public void tag (ImageReference sourceReference , ImageReference targetReference ) throws IOException {
388402 Assert .notNull (sourceReference , "'sourceReference' must not be null" );
389403 Assert .notNull (targetReference , "'targetReference' must not be null" );
@@ -425,7 +439,8 @@ public ContainerReference create(ContainerConfig config, ImagePlatform platform,
425439 }
426440
427441 private ContainerReference createContainer (ContainerConfig config , ImagePlatform platform ) throws IOException {
428- URI createUri = (platform != null ) ? buildUrl (Feature .PLATFORM , "/containers/create" , "platform" , platform )
442+ URI createUri = (platform != null )
443+ ? buildUrl (Feature .PLATFORM_CONTAINER_CREATE , "/containers/create" , "platform" , platform )
429444 : buildUrl ("/containers/create" );
430445 try (Response response = http ().post (createUri , "application/json" , config ::writeTo )) {
431446 return ContainerReference
@@ -631,9 +646,13 @@ enum Feature {
631646
632647 BASELINE (ApiVersion .of (1 , 24 )),
633648
634- PLATFORM (ApiVersion .of (1 , 41 )),
649+ PLATFORM_IMAGE_PULL (ApiVersion .of (1 , 41 )),
650+
651+ PLATFORM_CONTAINER_CREATE (ApiVersion .of (1 , 41 )),
652+
653+ PLATFORM_IMAGE_INSPECT (ApiVersion .of (1 , 49 )),
635654
636- PLATFORM_INSPECT (ApiVersion .of (1 , 49 ));
655+ PLATFORM_IMAGE_EXPORT (ApiVersion .of (1 , 48 ));
637656
638657 private final ApiVersion minimumVersion ;
639658
0 commit comments