-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23212 from geoand/dockerfile-java17-warning
Fail the building docker image when a Java version mismatch exists
- Loading branch information
Showing
12 changed files
with
367 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
.../java/io/quarkus/container/image/docker/deployment/DockerFileBaseInformationProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import java.nio.file.Path; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
interface DockerFileBaseInformationProvider { | ||
|
||
Optional<DockerFileBaseInformation> determine(Path dockerFile); | ||
|
||
static DockerFileBaseInformationProvider impl() { | ||
return new DockerFileBaseInformationProvider() { | ||
|
||
private final List<DockerFileBaseInformationProvider> delegates = List.of(new UbiMinimalBaseProvider(), | ||
new RedHatOpenJDKRuntimeBaseProvider()); | ||
|
||
@Override | ||
public Optional<DockerFileBaseInformation> determine(Path dockerFile) { | ||
for (DockerFileBaseInformationProvider delegate : delegates) { | ||
Optional<DockerFileBaseInformation> result = delegate.determine(dockerFile); | ||
if (result.isPresent()) { | ||
return result; | ||
} | ||
} | ||
return Optional.empty(); | ||
} | ||
}; | ||
} | ||
|
||
class DockerFileBaseInformation { | ||
private final int javaVersion; | ||
private final String baseImage; | ||
|
||
public DockerFileBaseInformation(String baseImage, int javaVersion) { | ||
this.javaVersion = javaVersion; | ||
this.baseImage = baseImage; | ||
} | ||
|
||
public int getJavaVersion() { | ||
return javaVersion; | ||
} | ||
|
||
public String getBaseImage() { | ||
return baseImage; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
...n/java/io/quarkus/container/image/docker/deployment/RedHatOpenJDKRuntimeBaseProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Optional; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* Can extract information from Dockerfile that uses {@code registry.access.redhat.com/ubi8/openjdk-$d-runtime:$d.$d} as the | ||
* base image | ||
*/ | ||
class RedHatOpenJDKRuntimeBaseProvider | ||
implements DockerFileBaseInformationProvider { | ||
|
||
@Override | ||
public Optional<DockerFileBaseInformation> determine(Path dockerFile) { | ||
try (Stream<String> lines = Files.lines(dockerFile)) { | ||
Optional<String> fromOpt = lines.filter(l -> l.startsWith("FROM")).findFirst(); | ||
if (fromOpt.isPresent()) { | ||
String fromLine = fromOpt.get(); | ||
String baseImage = fromLine.substring(4).trim(); | ||
Pattern pattern = Pattern.compile(".*ubi8/openjdk-(\\w+)-runtime.*"); | ||
Matcher matcher = pattern.matcher(baseImage); | ||
if (matcher.find()) { | ||
String match = matcher.group(1); | ||
try { | ||
return Optional.of(new DockerFileBaseInformationProvider.DockerFileBaseInformation(baseImage, | ||
Integer.parseInt(match))); | ||
} catch (NumberFormatException ignored) { | ||
|
||
} | ||
} | ||
} | ||
} catch (IOException ignored) { | ||
|
||
} | ||
return Optional.empty(); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...nt/src/main/java/io/quarkus/container/image/docker/deployment/UbiMinimalBaseProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Optional; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* Can extract information from Dockerfile that uses {@code registry.access.redhat.com/ubi8/ubi-minimal:$d.$d} as the | ||
* base image | ||
*/ | ||
class UbiMinimalBaseProvider | ||
implements DockerFileBaseInformationProvider { | ||
|
||
public static final String UBI_MINIMAL_PREFIX = "registry.access.redhat.com/ubi8/ubi-minimal"; | ||
|
||
@Override | ||
public Optional<DockerFileBaseInformation> determine(Path dockerFile) { | ||
AtomicInteger state = new AtomicInteger(0); //0: 'FROM' not yet encountered, 1: matching 'FROM' found, 2: ARG JAVA_PACKAGE found, 3: non matching 'FROM' found, 4: exception occurred | ||
AtomicReference<String> baseImage = new AtomicReference<>(null); | ||
AtomicInteger javaVersion = new AtomicInteger(0); | ||
try (Stream<String> lines = Files.lines(dockerFile)) { | ||
lines.takeWhile(s -> state.get() < 2).forEach(s -> { | ||
if (s.startsWith("FROM")) { | ||
String image = s.substring(4).trim(); | ||
if (image.startsWith(UBI_MINIMAL_PREFIX)) { | ||
baseImage.set(image); | ||
state.set(1); | ||
} else { | ||
state.set(3); | ||
} | ||
} else if (s.startsWith("ARG JAVA_PACKAGE")) { | ||
Pattern pattern = Pattern.compile("ARG JAVA_PACKAGE=java-(\\w+)-openjdk-headless"); | ||
Matcher matcher = pattern.matcher(s); | ||
if (matcher.find()) { | ||
String match = matcher.group(1); | ||
try { | ||
javaVersion.set(Integer.parseInt(match)); | ||
state.set(2); | ||
} catch (NumberFormatException ignored) { | ||
state.set(4); | ||
} | ||
} | ||
} | ||
}); | ||
} catch (IOException ignored) { | ||
state.set(4); | ||
} | ||
if (state.get() == 2) { | ||
return Optional.of(new DockerFileBaseInformation(baseImage.get(), javaVersion.get())); | ||
} | ||
return Optional.empty(); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...va/io/quarkus/container/image/docker/deployment/RedHatOpenJDKRuntimeBaseProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import static io.quarkus.container.image.docker.deployment.TestUtil.getPath; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.nio.file.Path; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
class RedHatOpenJDKRuntimeBaseProviderTest { | ||
|
||
private final DockerFileBaseInformationProvider sut = new RedHatOpenJDKRuntimeBaseProvider(); | ||
|
||
@Test | ||
void testImageWithJava11() { | ||
Path path = getPath("openjdk-11-runtime"); | ||
var result = sut.determine(path); | ||
assertThat(result).hasValueSatisfying(v -> { | ||
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/openjdk-11-runtime:1.10"); | ||
assertThat(v.getJavaVersion()).isEqualTo(11); | ||
}); | ||
} | ||
|
||
@Test | ||
void testImageWithJava17() { | ||
Path path = getPath("openjdk-17-runtime"); | ||
var result = sut.determine(path); | ||
assertThat(result).hasValueSatisfying(v -> { | ||
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/openjdk-17-runtime"); | ||
assertThat(v.getJavaVersion()).isEqualTo(17); | ||
}); | ||
} | ||
|
||
@Test | ||
void testUnhandled() { | ||
Path path = getPath("ubi-java11"); | ||
var result = sut.determine(path); | ||
assertThat(result).isEmpty(); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
...ocker/deployment/src/test/java/io/quarkus/container/image/docker/deployment/TestUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import java.net.URISyntaxException; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
final class TestUtil { | ||
|
||
private TestUtil() { | ||
} | ||
|
||
static Path getPath(String filename) { | ||
try { | ||
return Paths.get(Thread.currentThread().getContextClassLoader().getResource(filename).toURI()); | ||
} catch (URISyntaxException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...rc/test/java/io/quarkus/container/image/docker/deployment/UbiMinimalBaseProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package io.quarkus.container.image.docker.deployment; | ||
|
||
import static io.quarkus.container.image.docker.deployment.TestUtil.getPath; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.nio.file.Path; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
class UbiMinimalBaseProviderTest { | ||
|
||
private final DockerFileBaseInformationProvider sut = new UbiMinimalBaseProvider(); | ||
|
||
@Test | ||
void testImageWithJava11() { | ||
Path path = getPath("ubi-java11"); | ||
var result = sut.determine(path); | ||
assertThat(result).hasValueSatisfying(v -> { | ||
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/ubi-minimal:8.3"); | ||
assertThat(v.getJavaVersion()).isEqualTo(11); | ||
}); | ||
} | ||
|
||
@Test | ||
void testImageWithJava17() { | ||
Path path = getPath("ubi-java17"); | ||
var result = sut.determine(path); | ||
assertThat(result).hasValueSatisfying(v -> { | ||
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/ubi-minimal"); | ||
assertThat(v.getJavaVersion()).isEqualTo(17); | ||
}); | ||
} | ||
|
||
@Test | ||
void testUnhandled() { | ||
Path path = getPath("openjdk-11-runtime"); | ||
var result = sut.determine(path); | ||
assertThat(result).isEmpty(); | ||
} | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
...s/container-image/container-image-docker/deployment/src/test/resources/openjdk-11-runtime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
FROM registry.access.redhat.com/ubi8/openjdk-11-runtime:1.10 | ||
|
||
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' | ||
|
||
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. | ||
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" | ||
|
||
# We make four distinct layers so if there are application changes the library layers can be re-used | ||
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ | ||
COPY --chown=185 target/quarkus-app/*.jar /deployments/ | ||
COPY --chown=185 target/quarkus-app/app/ /deployments/app/ | ||
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ | ||
|
||
EXPOSE 8080 | ||
USER 185 | ||
|
||
ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ] |
18 changes: 18 additions & 0 deletions
18
...s/container-image/container-image-docker/deployment/src/test/resources/openjdk-17-runtime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Use Java 17 base image | ||
FROM registry.access.redhat.com/ubi8/openjdk-17-runtime | ||
|
||
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' | ||
|
||
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. | ||
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" | ||
|
||
# We make four distinct layers so if there are application changes the library layers can be re-used | ||
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ | ||
COPY --chown=185 target/quarkus-app/*.jar /deployments/ | ||
COPY --chown=185 target/quarkus-app/app/ /deployments/app/ | ||
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ | ||
|
||
EXPOSE 8080 | ||
USER 185 | ||
|
||
ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ] |
31 changes: 31 additions & 0 deletions
31
extensions/container-image/container-image-docker/deployment/src/test/resources/ubi-java11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 | ||
|
||
ARG JAVA_PACKAGE=java-11-openjdk-headless | ||
ARG RUN_JAVA_VERSION=1.3.8 | ||
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' | ||
# Install java and the run-java script | ||
# Also set up permissions for user `1001` | ||
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ | ||
&& microdnf update \ | ||
&& microdnf clean all \ | ||
&& mkdir /deployments \ | ||
&& chown 1001 /deployments \ | ||
&& chmod "g+rwX" /deployments \ | ||
&& chown 1001:root /deployments \ | ||
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ | ||
&& chown 1001 /deployments/run-java.sh \ | ||
&& chmod 540 /deployments/run-java.sh \ | ||
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security | ||
|
||
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. | ||
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" | ||
# We make four distinct layers so if there are application changes the library layers can be re-used | ||
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/ | ||
COPY --chown=1001 target/quarkus-app/*.jar /deployments/ | ||
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/ | ||
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/ | ||
|
||
EXPOSE 8080 | ||
USER 1001 | ||
|
||
ENTRYPOINT [ "/deployments/run-java.sh" ] |
Oops, something went wrong.