Enforce builder and run images in the same registry
Previously, when an authenticated Docker builder registry was configured in the Maven or Gradle plugin and the builder and run images specified different registries, the authentication credentials would be sent to both registries. This could cause confusion if both registries don't recognize the same credentials. This commit enforces that both images are in the same registry when authentication is configured. Fixes gh-24552
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -116,6 +116,7 @@ public class Builder {
|
||||
ImageReference runImage = getRunImageReferenceForStack(builderStack);
|
||||
request = request.withRunImage(runImage);
|
||||
}
|
||||
assertImageRegistriesMatch(request);
|
||||
Image runImage = getImage(request, ImageType.RUNNER);
|
||||
assertStackIdsMatch(runImage, builderImage);
|
||||
return request;
|
||||
@@ -172,6 +173,14 @@ public class Builder {
|
||||
? this.dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader() : null;
|
||||
}
|
||||
|
||||
private void assertImageRegistriesMatch(BuildRequest request) {
|
||||
if (getBuilderAuthHeader() != null) {
|
||||
Assert.state(request.getRunImage().getDomain().equals(request.getBuilder().getDomain()),
|
||||
"Builder image '" + request.getBuilder() + "' and run image '" + request.getRunImage()
|
||||
+ "' must be pulled from the same authenticated registry");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertStackIdsMatch(Image runImage, Image builderImage) {
|
||||
StackId runImageStackId = StackId.fromImage(runImage);
|
||||
StackId builderImageStackId = StackId.fromImage(builderImage);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -308,6 +308,42 @@ class BuilderTests {
|
||||
.withMessage("Builder lifecycle 'creator' failed with status code 9");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenDetectedRunImageInDifferentAuthenticatedRegistryThrowsException() throws Exception {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image-with-run-image-different-registry.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token");
|
||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest();
|
||||
assertThatIllegalStateException().isThrownBy(() -> builder.build(request))
|
||||
.withMessageContaining(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)
|
||||
.withMessageContaining("example.com/custom/run:latest")
|
||||
.withMessageContaining("must be pulled from the same authenticated registry");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenRequestedRunImageInDifferentAuthenticatedRegistryThrowsException() throws Exception {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token");
|
||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest().withRunImage(ImageReference.of("example.com/custom/run:latest"));
|
||||
assertThatIllegalStateException().isThrownBy(() -> builder.build(request))
|
||||
.withMessageContaining(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)
|
||||
.withMessageContaining("example.com/custom/run:latest")
|
||||
.withMessageContaining("must be pulled from the same authenticated registry");
|
||||
}
|
||||
|
||||
private DockerApi mockDockerApi() throws IOException {
|
||||
ContainerApi containerApi = mock(ContainerApi.class);
|
||||
ContainerReference reference = ContainerReference.of("container-ref");
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user