Merge branch '2.5.x'

Closes gh-27994
pull/28028/head
Scott Frederick 3 years ago
commit a6d03279ca

@ -105,8 +105,8 @@ public class Builder {
assertStackIdsMatch(runImage, builderImage); assertStackIdsMatch(runImage, builderImage);
BuildOwner buildOwner = BuildOwner.fromEnv(builderImage.getConfig().getEnv()); BuildOwner buildOwner = BuildOwner.fromEnv(builderImage.getConfig().getEnv());
Buildpacks buildpacks = getBuildpacks(request, imageFetcher, builderMetadata); Buildpacks buildpacks = getBuildpacks(request, imageFetcher, builderMetadata);
EphemeralBuilder ephemeralBuilder = new EphemeralBuilder(buildOwner, builderImage, builderMetadata, EphemeralBuilder ephemeralBuilder = new EphemeralBuilder(buildOwner, builderImage, request.getName(),
request.getCreator(), request.getEnv(), buildpacks); builderMetadata, request.getCreator(), request.getEnv(), buildpacks);
this.docker.image().load(ephemeralBuilder.getArchive(), UpdateListener.none()); this.docker.image().load(ephemeralBuilder.getArchive(), UpdateListener.none());
try { try {
executeLifecycle(request, ephemeralBuilder); executeLifecycle(request, ephemeralBuilder);

@ -34,6 +34,8 @@ import org.springframework.boot.buildpack.platform.io.Owner;
*/ */
class EphemeralBuilder { class EphemeralBuilder {
static final String BUILDER_FOR_LABEL_NAME = "org.springframework.boot.builderFor";
private final BuildOwner buildOwner; private final BuildOwner buildOwner;
private final BuilderMetadata builderMetadata; private final BuilderMetadata builderMetadata;
@ -45,21 +47,24 @@ class EphemeralBuilder {
/** /**
* Create a new {@link EphemeralBuilder} instance. * Create a new {@link EphemeralBuilder} instance.
* @param buildOwner the build owner * @param buildOwner the build owner
* @param builderImage the image * @param builderImage the base builder image
* @param targetImage the image being built
* @param builderMetadata the builder metadata * @param builderMetadata the builder metadata
* @param creator the builder creator * @param creator the builder creator
* @param env the builder env * @param env the builder env
* @param buildpacks an optional set of buildpacks to apply * @param buildpacks an optional set of buildpacks to apply
* @throws IOException on IO error * @throws IOException on IO error
*/ */
EphemeralBuilder(BuildOwner buildOwner, Image builderImage, BuilderMetadata builderMetadata, Creator creator, EphemeralBuilder(BuildOwner buildOwner, Image builderImage, ImageReference targetImage,
Map<String, String> env, Buildpacks buildpacks) throws IOException { BuilderMetadata builderMetadata, Creator creator, Map<String, String> env, Buildpacks buildpacks)
throws IOException {
ImageReference name = ImageReference.random("pack.local/builder/").inTaggedForm(); ImageReference name = ImageReference.random("pack.local/builder/").inTaggedForm();
this.buildOwner = buildOwner; this.buildOwner = buildOwner;
this.creator = creator; this.creator = creator;
this.builderMetadata = builderMetadata.copy(this::updateMetadata); this.builderMetadata = builderMetadata.copy(this::updateMetadata);
this.archive = ImageArchive.from(builderImage, (update) -> { this.archive = ImageArchive.from(builderImage, (update) -> {
update.withUpdatedConfig(this.builderMetadata::attachTo); update.withUpdatedConfig(this.builderMetadata::attachTo);
update.withUpdatedConfig((config) -> config.withLabel(BUILDER_FOR_LABEL_NAME, targetImage.toString()));
update.withTag(name); update.withTag(name);
if (env != null && !env.isEmpty()) { if (env != null && !env.isEmpty()) {
update.withNewLayer(getEnvLayer(env)); update.withNewLayer(getEnvLayer(env));

@ -48,6 +48,7 @@ import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
/** /**
* Tests for {@link EphemeralBuilder}. * Tests for {@link EphemeralBuilder}.
@ -64,6 +65,8 @@ class EphemeralBuilderTests extends AbstractJsonTests {
private Image image; private Image image;
private ImageReference targetImage;
private BuilderMetadata metadata; private BuilderMetadata metadata;
private Map<String, String> env; private Map<String, String> env;
@ -75,6 +78,7 @@ class EphemeralBuilderTests extends AbstractJsonTests {
@BeforeEach @BeforeEach
void setup() throws Exception { void setup() throws Exception {
this.image = Image.of(getContent("image.json")); this.image = Image.of(getContent("image.json"));
this.targetImage = ImageReference.of("my-image:latest");
this.metadata = BuilderMetadata.fromImage(this.image); this.metadata = BuilderMetadata.fromImage(this.image);
this.env = new HashMap<>(); this.env = new HashMap<>();
this.env.put("spring", "boot"); this.env.put("spring", "boot");
@ -83,18 +87,18 @@ class EphemeralBuilderTests extends AbstractJsonTests {
@Test @Test
void getNameHasRandomName() throws Exception { void getNameHasRandomName() throws Exception {
EphemeralBuilder b1 = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder b1 = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
EphemeralBuilder b2 = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder b2 = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
assertThat(b1.getName().toString()).startsWith("pack.local/builder/").endsWith(":latest"); assertThat(b1.getName().toString()).startsWith("pack.local/builder/").endsWith(":latest");
assertThat(b1.getName().toString()).isNotEqualTo(b2.getName().toString()); assertThat(b1.getName().toString()).isNotEqualTo(b2.getName().toString());
} }
@Test @Test
void getArchiveHasCreatedByConfig() throws Exception { void getArchiveHasCreatedByConfig() throws Exception {
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
ImageConfig config = builder.getArchive().getImageConfig(); ImageConfig config = builder.getArchive().getImageConfig();
BuilderMetadata ephemeralMetadata = BuilderMetadata.fromImageConfig(config); BuilderMetadata ephemeralMetadata = BuilderMetadata.fromImageConfig(config);
assertThat(ephemeralMetadata.getCreatedBy().getName()).isEqualTo("Spring Boot"); assertThat(ephemeralMetadata.getCreatedBy().getName()).isEqualTo("Spring Boot");
@ -103,16 +107,16 @@ class EphemeralBuilderTests extends AbstractJsonTests {
@Test @Test
void getArchiveHasTag() throws Exception { void getArchiveHasTag() throws Exception {
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
ImageReference tag = builder.getArchive().getTag(); ImageReference tag = builder.getArchive().getTag();
assertThat(tag.toString()).startsWith("pack.local/builder/").endsWith(":latest"); assertThat(tag.toString()).startsWith("pack.local/builder/").endsWith(":latest");
} }
@Test @Test
void getArchiveHasFixedCreateDate() throws Exception { void getArchiveHasFixedCreateDate() throws Exception {
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
Instant createInstant = builder.getArchive().getCreateDate(); Instant createInstant = builder.getArchive().getCreateDate();
OffsetDateTime createDateTime = OffsetDateTime.ofInstant(createInstant, ZoneId.of("UTC")); OffsetDateTime createDateTime = OffsetDateTime.ofInstant(createInstant, ZoneId.of("UTC"));
assertThat(createDateTime.getYear()).isEqualTo(1980); assertThat(createDateTime.getYear()).isEqualTo(1980);
@ -125,13 +129,22 @@ class EphemeralBuilderTests extends AbstractJsonTests {
@Test @Test
void getArchiveContainsEnvLayer() throws Exception { void getArchiveContainsEnvLayer() throws Exception {
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env, EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, this.env, this.buildpacks);
File directory = unpack(getLayer(builder.getArchive(), 0), "env"); File directory = unpack(getLayer(builder.getArchive(), 0), "env");
assertThat(new File(directory, "platform/env/spring")).usingCharset(StandardCharsets.UTF_8).hasContent("boot"); assertThat(new File(directory, "platform/env/spring")).usingCharset(StandardCharsets.UTF_8).hasContent("boot");
assertThat(new File(directory, "platform/env/empty")).usingCharset(StandardCharsets.UTF_8).hasContent(""); assertThat(new File(directory, "platform/env/empty")).usingCharset(StandardCharsets.UTF_8).hasContent("");
} }
@Test
void getArchiveHasBuilderForLabel() throws Exception {
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.creator, this.env, this.buildpacks);
ImageConfig config = builder.getArchive().getImageConfig();
assertThat(config.getLabels())
.contains(entry(EphemeralBuilder.BUILDER_FOR_LABEL_NAME, this.targetImage.toString()));
}
@Test @Test
void getArchiveContainsBuildpackLayers() throws Exception { void getArchiveContainsBuildpackLayers() throws Exception {
List<Buildpack> buildpackList = new ArrayList<>(); List<Buildpack> buildpackList = new ArrayList<>();
@ -139,8 +152,8 @@ class EphemeralBuilderTests extends AbstractJsonTests {
buildpackList.add(new TestBuildpack("example/buildpack2", "0.0.2")); buildpackList.add(new TestBuildpack("example/buildpack2", "0.0.2"));
buildpackList.add(new TestBuildpack("example/buildpack3", "0.0.3")); buildpackList.add(new TestBuildpack("example/buildpack3", "0.0.3"));
this.buildpacks = Buildpacks.of(buildpackList); this.buildpacks = Buildpacks.of(buildpackList);
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, null, EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
this.buildpacks); this.creator, null, this.buildpacks);
assertBuildpackLayerContent(builder, 0, "/cnb/buildpacks/example_buildpack1/0.0.1/buildpack.toml"); assertBuildpackLayerContent(builder, 0, "/cnb/buildpacks/example_buildpack1/0.0.1/buildpack.toml");
assertBuildpackLayerContent(builder, 1, "/cnb/buildpacks/example_buildpack2/0.0.2/buildpack.toml"); assertBuildpackLayerContent(builder, 1, "/cnb/buildpacks/example_buildpack2/0.0.2/buildpack.toml");
assertBuildpackLayerContent(builder, 2, "/cnb/buildpacks/example_buildpack3/0.0.3/buildpack.toml"); assertBuildpackLayerContent(builder, 2, "/cnb/buildpacks/example_buildpack3/0.0.3/buildpack.toml");

Loading…
Cancel
Save