From a49a7175619d319cb530ff6684af209d01052746 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Tue, 14 May 2024 16:56:05 -0500 Subject: [PATCH] Retain Architecture config in ephemeral builder images --- .../buildpack/platform/docker/type/Image.java | 23 +++++++++++++++++++ .../platform/docker/type/ImageArchive.java | 23 +++++++++++-------- .../docker/type/ImageArchiveTests.java | 2 +- .../platform/docker/type/ImageTests.java | 12 ++++++++++ .../docker/type/image-archive-config.json | 11 +++++---- .../docker/type/image-archive-manifest.json | 2 +- 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Image.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Image.java index 24a488bd4a14..2972bb1d1b5b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Image.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Image.java @@ -32,6 +32,7 @@ * Image details as returned from {@code Docker inspect}. * * @author Phillip Webb + * @author Scott Frederick * @since 2.3.0 */ public class Image extends MappedObject { @@ -40,8 +41,12 @@ public class Image extends MappedObject { private final ImageConfig config; + private final String rootFsType; + private final List layers; + private final String architecture; + private final String os; private final String created; @@ -50,7 +55,9 @@ public class Image extends MappedObject { super(node, MethodHandles.lookup()); this.digests = getDigests(getNode().at("/RepoDigests")); this.config = new ImageConfig(getNode().at("/Config")); + this.rootFsType = valueAt("/RootFS/Type", String.class); this.layers = extractLayers(valueAt("/RootFS/Layers", String[].class)); + this.architecture = valueAt("/Architecture", String.class); this.os = valueAt("/Os", String.class); this.created = valueAt("/Created", String.class); } @@ -87,6 +94,14 @@ public ImageConfig getConfig() { return this.config; } + /** + * Return the type of the root FS. + * @return the root FS type + */ + public String getRootFsType() { + return this.rootFsType; + } + /** * Return the layer IDs contained in the image. * @return the layer IDs. @@ -95,6 +110,14 @@ public List getLayers() { return this.layers; } + /** + * Return the architecture of the image. + * @return the image architecture + */ + public String getArchitecture() { + return this.architecture; + } + /** * Return the OS of the image. * @return the image OS diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchive.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchive.java index ee1ab5cae7d7..76702ed2a7a2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchive.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchive.java @@ -74,18 +74,21 @@ public class ImageArchive implements TarArchive { private final ImageReference tag; + private final String architecture; + private final String os; private final List existingLayers; private final List newLayers; - ImageArchive(ObjectMapper objectMapper, ImageConfig imageConfig, Instant createDate, ImageReference tag, String os, - List existingLayers, List newLayers) { + ImageArchive(ObjectMapper objectMapper, ImageConfig imageConfig, Instant createDate, ImageReference tag, + String architecture, String os, List existingLayers, List newLayers) { this.objectMapper = objectMapper; this.imageConfig = imageConfig; this.createDate = createDate; this.tag = tag; + this.architecture = architecture; this.os = os; this.existingLayers = existingLayers; this.newLayers = newLayers; @@ -164,11 +167,12 @@ private String writeConfig(Layout writer, List writtenLayers) throws IO private ObjectNode createConfig(List writtenLayers) { ObjectNode config = this.objectMapper.createObjectNode(); - config.set("config", this.imageConfig.getNodeCopy()); - config.set("created", config.textNode(getCreatedDate())); - config.set("history", createHistory(writtenLayers)); - config.set("os", config.textNode(this.os)); - config.set("rootfs", createRootFs(writtenLayers)); + config.set("Config", this.imageConfig.getNodeCopy()); + config.set("Created", config.textNode(getCreatedDate())); + config.set("History", createHistory(writtenLayers)); + config.set("Architecture", config.textNode(this.architecture)); + config.set("Os", config.textNode(this.os)); + config.set("RootFS", createRootFs(writtenLayers)); return config; } @@ -263,8 +267,9 @@ private Update(Image image) { private ImageArchive applyTo(IOConsumer update) throws IOException { update.accept(this); Instant createDate = (this.createDate != null) ? this.createDate : WINDOWS_EPOCH_PLUS_SECOND; - return new ImageArchive(SharedObjectMapper.get(), this.config, createDate, this.tag, this.image.getOs(), - this.image.getLayers(), Collections.unmodifiableList(this.newLayers)); + return new ImageArchive(SharedObjectMapper.get(), this.config, createDate, this.tag, + this.image.getArchitecture(), this.image.getOs(), this.image.getLayers(), + Collections.unmodifiableList(this.newLayers)); } /** diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchiveTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchiveTests.java index 20717b8a5d7c..9af2ba19a60c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchiveTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageArchiveTests.java @@ -78,7 +78,7 @@ private void assertExpectedLayer(TarArchiveEntry entry, byte[] content) throws E } private void assertExpectedConfig(TarArchiveEntry entry, byte[] content) throws Exception { - assertThat(entry.getName()).isEqualTo("682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json"); + assertThat(entry.getName()).isEqualTo("974b1da0e6ca36b645fd11a5e35b20924f0a6348ecef5884d14531f14dcb732b.json"); String actualJson = new String(content, StandardCharsets.UTF_8); String expectedJson = StreamUtils.copyToString(getContent("image-archive-config.json"), StandardCharsets.UTF_8); JSONAssert.assertEquals(expectedJson, actualJson, false); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageTests.java index 851a9c781a7a..5375e03c2e2f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageTests.java @@ -50,6 +50,12 @@ void getConfigLabelsReturnsLabels() throws Exception { assertThat(labels).contains(entry("io.buildpacks.stack.id", "org.cloudfoundry.stacks.cflinuxfs3")); } + @Test + void getRootFsTypeReturnsRootFsType() throws Exception { + Image image = getImage(); + assertThat(image.getRootFsType()).isEqualTo("layers"); + } + @Test void getLayersReturnsImageLayers() throws Exception { Image image = getImage(); @@ -61,6 +67,12 @@ void getLayersReturnsImageLayers() throws Exception { .hasToString("sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"); } + @Test + void getArchitectureReturnsArchitecture() throws Exception { + Image image = getImage(); + assertThat(image.getArchitecture()).isEqualTo("amd64"); + } + @Test void getOsReturnsOs() throws Exception { Image image = getImage(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-config.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-config.json index 395bbcda70b1..efd144fec7b5 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-config.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-config.json @@ -1,5 +1,5 @@ { - "config": { + "Config": { "Hostname": "", "Domainname": "", "User": "vcap", @@ -25,8 +25,8 @@ "io.buildpacks.stack.id": "org.cloudfoundry.stacks.cflinuxfs3" } }, - "created": "1980-01-01T00:00:01Z", - "history": [ + "Created": "1980-01-01T00:00:01Z", + "History": [ { }, @@ -169,8 +169,9 @@ } ], - "os": "linux", - "rootfs": { + "Architecture": "amd64", + "Os": "linux", + "RootFS": { "diff_ids": [ "sha256:733a8e5ce32984099ef675fce04730f6e2a6dcfdf5bd292fea01a8f936265342", "sha256:7755b972f0b4f49de73ef5114fb3ba9c69d80f217e80da99f56f0d0a5dcb3d70", diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-manifest.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-manifest.json index 4830d4e8e1c3..d2aa9be177d3 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-manifest.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/type/image-archive-manifest.json @@ -1,6 +1,6 @@ [ { - "Config": "682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json", + "Config": "974b1da0e6ca36b645fd11a5e35b20924f0a6348ecef5884d14531f14dcb732b.json", "Layers": [ "blank_0", "blank_1",