Skip to content

Commit d93f4f5

Browse files
committed
Throw exception if pulled image platform doesn't match the requested platform
Closes gh-44059
1 parent 282571a commit d93f4f5

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -236,14 +236,14 @@ Image fetchImage(ImageType type, ImageReference reference) throws IOException {
236236
() -> String.format("%s '%s' must be pulled from the '%s' authenticated registry",
237237
StringUtils.capitalize(type.getDescription()), reference, this.domain));
238238
if (this.pullPolicy == PullPolicy.ALWAYS) {
239-
return pullImage(reference, type);
239+
return checkPlatformMismatch(pullImage(reference, type), reference);
240240
}
241241
try {
242-
return Builder.this.docker.image().inspect(reference);
242+
return checkPlatformMismatch(Builder.this.docker.image().inspect(reference), reference);
243243
}
244244
catch (DockerEngineException ex) {
245245
if (this.pullPolicy == PullPolicy.IF_NOT_PRESENT && ex.getStatusCode() == 404) {
246-
return pullImage(reference, type);
246+
return checkPlatformMismatch(pullImage(reference, type), reference);
247247
}
248248
throw ex;
249249
}
@@ -260,6 +260,26 @@ private Image pullImage(ImageReference reference, ImageType imageType) throws IO
260260
return image;
261261
}
262262

263+
private Image checkPlatformMismatch(Image image, ImageReference imageReference) {
264+
if (this.defaultPlatform != null) {
265+
ImagePlatform imagePlatform = ImagePlatform.from(image);
266+
if (!imagePlatform.equals(this.defaultPlatform)) {
267+
throw new PlatformMismatchException(imageReference, this.defaultPlatform, imagePlatform);
268+
}
269+
}
270+
return image;
271+
}
272+
273+
}
274+
275+
private static final class PlatformMismatchException extends RuntimeException {
276+
277+
private PlatformMismatchException(ImageReference imageReference, ImagePlatform requestedPlatform,
278+
ImagePlatform actualPlatform) {
279+
super("Image platform mismatch detected. The configured platform '%s' is not supported by the image '%s'. Requested platform '%s' but got '%s'"
280+
.formatted(requestedPlatform, imageReference, requestedPlatform, actualPlatform));
281+
}
282+
263283
}
264284

265285
/**

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/dockerTest/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -513,6 +513,14 @@ void failsWhenCachesAreConfiguredTwice() throws IOException {
513513
assertThat(result.getOutput()).containsPattern("Each image building cache can be configured only once");
514514
}
515515

516+
@TestTemplate
517+
void failsWithIncompatiblePlatform() throws IOException {
518+
writeMainClass();
519+
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage");
520+
assertThat(result.getOutput()).contains(
521+
"Image platform mismatch detected. The configured platform 'invalid/platform' is not supported by the image 'ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1'. Requested platform 'invalid/platform' but got 'linux/amd64'");
522+
}
523+
516524
private void writeMainClass() throws IOException {
517525
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/example");
518526
examplePackage.mkdirs();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plugins {
2+
id 'java'
3+
id 'org.springframework.boot' version '{version}'
4+
}
5+
6+
bootBuildImage {
7+
builder = "ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1"
8+
runImage = "paketobuildpacks/run-jammy-tiny"
9+
buildpacks = ["ghcr.io/spring-io/spring-boot-test-info:0.0.1"]
10+
imagePlatform = "invalid/platform"
11+
}

0 commit comments

Comments
 (0)