diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1c8ea3811..28b8752d7a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ Usage:
* Fix #1929: Docker Image Name parsing fix
* Fix #1985: Update outdated methods in Spring Boot CRD Maven Quickstart
* Fix #2116: Remove user field from ImageName class
+* Fix #2138: Support for Spring Boot Native Image
* Fix #2219: Kind/Filename mappings include optional apiVersion configuration
* Fix #2224: Quarkus native base image read from properties (configurable)
* Fix #2228: Quarkus native base image uses UBI 8.7
diff --git a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/SpringBootUtil.java b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/SpringBootUtil.java
index 14bc942065..f9fe454c3d 100644
--- a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/SpringBootUtil.java
+++ b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/SpringBootUtil.java
@@ -13,6 +13,7 @@
*/
package org.eclipse.jkube.kit.common.util;
+import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
@@ -111,5 +112,27 @@ public static boolean isSpringBootRepackage(JavaProject project) {
.map(e -> e.contains("repackage"))
.orElse(false);
}
+
+ public static Plugin getNativePlugin(JavaProject project) {
+ Plugin plugin = JKubeProjectUtil.getPlugin(project, "org.graalvm.buildtools", "native-maven-plugin");
+ if (plugin != null) {
+ return plugin;
+ }
+ return JKubeProjectUtil.getPlugin(project, "org.graalvm.buildtools.native", "org.graalvm.buildtools.native.gradle.plugin");
+ }
+
+ public static File getNativeArtifactFile(JavaProject project) {
+ Plugin plugin = getNativePlugin(project);
+ String nativeArtifactName = (String) Optional.ofNullable(plugin.getConfiguration())
+ .map(c -> c.get("imageName"))
+ .orElse(project.getArtifactId());
+ for (String location : new String[] {"", "native/nativeCompile/"}) {
+ File nativeArtifact = new File(project.getBuildDirectory(), location + nativeArtifactName);
+ if (nativeArtifact.exists()) {
+ return nativeArtifact;
+ }
+ }
+ return null;
+ }
}
diff --git a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/SpringBootUtilTest.java b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/SpringBootUtilTest.java
index b5db038b12..521f3ec1be 100644
--- a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/SpringBootUtilTest.java
+++ b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/SpringBootUtilTest.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
@@ -264,4 +265,124 @@ void isSpringBootRepackage_whenNoExecution_thenReturnFalse() {
// Then
assertThat(result).isFalse();
}
+
+ @Test
+ void getNativePlugin_whenNoNativePluginPresent_thenReturnNull() {
+ assertThat(SpringBootUtil.getNativePlugin(JavaProject.builder().build())).isNull();
+ }
+
+ @Test
+ void getNativePlugin_whenMavenNativePluginPresent_thenReturnPlugin() {
+ // Given
+ JavaProject javaProject = JavaProject.builder()
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools")
+ .artifactId("native-maven-plugin")
+ .build())
+ .build();
+
+ // When
+ Plugin plugin = SpringBootUtil.getNativePlugin(javaProject);
+
+ // Then
+ assertThat(plugin).isNotNull();
+ }
+
+ @Test
+ void getNativePlugin_whenGradleNativePluginPresent_thenReturnPlugin() {
+ // Given
+ JavaProject javaProject = JavaProject.builder()
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools.native")
+ .artifactId("org.graalvm.buildtools.native.gradle.plugin")
+ .build())
+ .build();
+
+ // When
+ Plugin plugin = SpringBootUtil.getNativePlugin(javaProject);
+
+ // Then
+ assertThat(plugin).isNotNull();
+ }
+
+ @Test
+ void getNativeArtifactFile_whenNativeExecutableNotFound_thenReturnNull(@TempDir File temporaryFolder) throws IOException {
+ // Given
+ JavaProject javaProject = JavaProject.builder()
+ .artifactId("sample")
+ .buildDirectory(temporaryFolder)
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools")
+ .artifactId("native-maven-plugin")
+ .build())
+ .build();
+
+ // When
+ File nativeArtifactFound = SpringBootUtil.getNativeArtifactFile(javaProject);
+
+ // Then
+ assertThat(nativeArtifactFound).isNull();
+ }
+
+ @Test
+ void getNativeArtifactFile_whenNativeExecutableInStandardMavenBuildDirectory_thenReturnNativeArtifact(@TempDir File temporaryFolder) throws IOException {
+ // Given
+ Files.createFile(temporaryFolder.toPath().resolve("sample"));
+ JavaProject javaProject = JavaProject.builder()
+ .artifactId("sample")
+ .buildDirectory(temporaryFolder)
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools")
+ .artifactId("native-maven-plugin")
+ .build())
+ .build();
+
+ // When
+ File nativeArtifactFound = SpringBootUtil.getNativeArtifactFile(javaProject);
+
+ // Then
+ assertThat(nativeArtifactFound).hasName("sample");
+ }
+
+ @Test
+ void getNativeArtifactFile_whenNativeExecutableInStandardMavenBuildDirectoryAndImageNameOverridden_thenReturnNativeArtifact(@TempDir File temporaryFolder) throws IOException {
+ // Given
+ Files.createFile(temporaryFolder.toPath().resolve("custom-native-name"));
+ JavaProject javaProject = JavaProject.builder()
+ .artifactId("sample")
+ .buildDirectory(temporaryFolder)
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools")
+ .artifactId("native-maven-plugin")
+ .configuration(Collections.singletonMap("imageName", "custom-native-name"))
+ .build())
+ .build();
+
+ // When
+ File nativeArtifactFound = SpringBootUtil.getNativeArtifactFile(javaProject);
+
+ // Then
+ assertThat(nativeArtifactFound).hasName("custom-native-name");
+ }
+
+ @Test
+ void getNativeArtifactFile_whenNativeExecutableInStandardGradleNativeDirectory_thenReturnNativeArtifact(@TempDir File temporaryFolder) throws IOException {
+ // Given
+ Files.createDirectories(temporaryFolder.toPath().resolve("native").resolve("nativeCompile"));
+ Files.createFile(temporaryFolder.toPath().resolve("native").resolve("nativeCompile").resolve("sample"));
+ JavaProject javaProject = JavaProject.builder()
+ .artifactId("sample")
+ .buildDirectory(temporaryFolder)
+ .plugin(Plugin.builder()
+ .groupId("org.graalvm.buildtools.native")
+ .artifactId("org.graalvm.buildtools.native.gradle.plugin")
+ .build())
+ .build();
+
+ // When
+ File nativeArtifactFound = SpringBootUtil.getNativeArtifactFile(javaProject);
+
+ // Then
+ assertThat(nativeArtifactFound).hasName("sample");
+ }
}
diff --git a/jkube-kit/jkube-kit-spring-boot/pom.xml b/jkube-kit/jkube-kit-spring-boot/pom.xml
index 507c7e7267..c4aa13f456 100644
--- a/jkube-kit/jkube-kit-spring-boot/pom.xml
+++ b/jkube-kit/jkube-kit-spring-boot/pom.xml
@@ -81,4 +81,18 @@
+
+
+
+
+ src/main/resources-filtered
+ true
+
+
+ src/main/resources
+ false
+
+
+
+
diff --git a/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/NativeGenerator.java b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/NativeGenerator.java
new file mode 100644
index 0000000000..f9bfe6b5fd
--- /dev/null
+++ b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/NativeGenerator.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at:
+ *
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.jkube.springboot.generator;
+
+import org.eclipse.jkube.generator.api.FromSelector;
+import org.eclipse.jkube.generator.api.GeneratorConfig;
+import org.eclipse.jkube.generator.api.GeneratorContext;
+import org.eclipse.jkube.kit.common.Arguments;
+import org.eclipse.jkube.kit.common.Assembly;
+import org.eclipse.jkube.kit.common.AssemblyConfiguration;
+import org.eclipse.jkube.kit.common.AssemblyFileSet;
+import org.eclipse.jkube.kit.common.JavaProject;
+
+import java.io.File;
+import java.util.List;
+
+import static org.eclipse.jkube.kit.common.util.FileUtil.getRelativePath;
+
+public class NativeGenerator extends AbstractSpringBootNestedGenerator {
+ private final File nativeBinary;
+ private final FromSelector fromSelector;
+
+ public NativeGenerator(GeneratorContext generatorContext, GeneratorConfig generatorConfig, File nativeBinary) {
+ super(generatorContext, generatorConfig);
+ this.nativeBinary = nativeBinary;
+ fromSelector = new FromSelector.Default(generatorContext, "springboot-native");
+ }
+
+
+ @Override
+ public String getFrom() {
+ return fromSelector.getFrom();
+ }
+
+ @Override
+ public String getDefaultJolokiaPort() {
+ return "0";
+ }
+
+ @Override
+ public String getDefaultPrometheusPort() {
+ return "0";
+ }
+
+ @Override
+ public Arguments getBuildEntryPoint() {
+ return Arguments.builder()
+ .execArgument("./" + nativeBinary.getName())
+ .build();
+ }
+
+ @Override
+ public String getBuildWorkdir() {
+ return "/";
+ }
+
+ @Override
+ public String getTargetDir() {
+ return "/";
+ }
+
+ @Override
+ public AssemblyConfiguration createAssemblyConfiguration(List defaultFileSets) {
+ Assembly.AssemblyBuilder assemblyBuilder = Assembly.builder();
+ final JavaProject project = getProject();
+ final AssemblyFileSet.AssemblyFileSetBuilder artifactFileSetBuilder = AssemblyFileSet.builder()
+ .outputDirectory(new File("."))
+ .directory(getRelativePath(project.getBaseDirectory(), nativeBinary.getParentFile()))
+ .fileMode("0755");
+ artifactFileSetBuilder.include(nativeBinary.getName());
+
+ assemblyBuilder.fileSets(defaultFileSets);
+ assemblyBuilder.fileSet(artifactFileSetBuilder.build());
+
+ return AssemblyConfiguration.builder()
+ .targetDir(getTargetDir())
+ .excludeFinalOutputArtifact(true)
+ .layer(assemblyBuilder.build())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootGenerator.java b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootGenerator.java
index c64e12dda0..9b64f961ae 100644
--- a/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootGenerator.java
+++ b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootGenerator.java
@@ -129,7 +129,7 @@ protected String getDefaultWebPort() {
@Override
protected AssemblyConfiguration createAssembly() {
- return Optional.ofNullable(nestedGenerator.createAssemblyConfiguration())
+ return Optional.ofNullable(nestedGenerator.createAssemblyConfiguration(addAdditionalFiles()))
.orElse(super.createAssembly());
}
diff --git a/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootNestedGenerator.java b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootNestedGenerator.java
index 68b5c5f3e1..12ba0ec3ab 100644
--- a/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootNestedGenerator.java
+++ b/jkube-kit/jkube-kit-spring-boot/src/main/java/org/eclipse/jkube/springboot/generator/SpringBootNestedGenerator.java
@@ -17,15 +17,21 @@
import org.eclipse.jkube.generator.api.GeneratorContext;
import org.eclipse.jkube.kit.common.Arguments;
import org.eclipse.jkube.kit.common.AssemblyConfiguration;
+import org.eclipse.jkube.kit.common.AssemblyFileSet;
import org.eclipse.jkube.kit.common.JavaProject;
+import java.io.File;
+import java.util.List;
+
import static org.eclipse.jkube.generator.javaexec.JavaExecGenerator.JOLOKIA_PORT_DEFAULT;
import static org.eclipse.jkube.generator.javaexec.JavaExecGenerator.PROMETHEUS_PORT_DEFAULT;
+import static org.eclipse.jkube.kit.common.util.SpringBootUtil.getNativeArtifactFile;
+import static org.eclipse.jkube.kit.common.util.SpringBootUtil.getNativePlugin;
public interface SpringBootNestedGenerator {
JavaProject getProject();
- default AssemblyConfiguration createAssemblyConfiguration() {
+ default AssemblyConfiguration createAssemblyConfiguration(List defaultFileSets) {
return null;
}
@@ -50,6 +56,12 @@ default Arguments getBuildEntryPoint() {
String getTargetDir();
static SpringBootNestedGenerator from(GeneratorContext generatorContext, GeneratorConfig generatorConfig) {
+ if (getNativePlugin(generatorContext.getProject()) != null) {
+ File nativeBinary = getNativeArtifactFile(generatorContext.getProject());
+ if (nativeBinary != null) {
+ return new NativeGenerator(generatorContext, generatorConfig, nativeBinary);
+ }
+ }
return new FatJarGenerator(generatorContext, generatorConfig);
}
}
diff --git a/jkube-kit/jkube-kit-spring-boot/src/main/resources-filtered/META-INF/jkube/default-images.properties b/jkube-kit/jkube-kit-spring-boot/src/main/resources-filtered/META-INF/jkube/default-images.properties
new file mode 100644
index 0000000000..55db026634
--- /dev/null
+++ b/jkube-kit/jkube-kit-spring-boot/src/main/resources-filtered/META-INF/jkube/default-images.properties
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2019 Red Hat, Inc.
+# This program and the accompanying materials are made
+# available under the terms of the Eclipse Public License 2.0
+# which is available at:
+#
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat, Inc. - initial API and implementation
+#
+
+# Properties for specifying the default images version to use
+# The replacement values are defined in the parent pom.xml as properties
+
+# Upstream images
+springboot-native.upstream.s2i=${image.springboot-native.upstream.s2i}
+springboot-native.upstream.docker=${image.springboot-native.upstream.docker}
+springboot-native.upstream.istag=${image.springboot-native.upstream.istag}
diff --git a/jkube-kit/jkube-kit-spring-boot/src/test/java/org/eclipse/jkube/springboot/generator/SpringBootGeneratorIntegrationTest.java b/jkube-kit/jkube-kit-spring-boot/src/test/java/org/eclipse/jkube/springboot/generator/SpringBootGeneratorIntegrationTest.java
index 60633943c3..d54fe9042e 100644
--- a/jkube-kit/jkube-kit-spring-boot/src/test/java/org/eclipse/jkube/springboot/generator/SpringBootGeneratorIntegrationTest.java
+++ b/jkube-kit/jkube-kit-spring-boot/src/test/java/org/eclipse/jkube/springboot/generator/SpringBootGeneratorIntegrationTest.java
@@ -25,10 +25,14 @@
import org.eclipse.jkube.kit.common.Plugin;
import org.eclipse.jkube.kit.config.image.ImageConfiguration;
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
+import org.eclipse.jkube.kit.config.resource.RuntimeMode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.MockedConstruction;
import java.io.File;
@@ -39,6 +43,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Properties;
+import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -48,6 +53,7 @@
class SpringBootGeneratorIntegrationTest {
private File targetDir;
private Properties properties;
+ private JavaProject javaProject;
@TempDir
Path temporaryFolder;
@@ -57,7 +63,7 @@ class SpringBootGeneratorIntegrationTest {
void setUp() throws IOException {
properties = new Properties();
targetDir = Files.createDirectory(temporaryFolder.resolve("target")).toFile();
- JavaProject javaProject = JavaProject.builder()
+ javaProject = JavaProject.builder()
.baseDirectory(temporaryFolder.toFile())
.buildDirectory(targetDir.getAbsoluteFile())
.buildPackageDirectory(targetDir.getAbsoluteFile())
@@ -74,6 +80,7 @@ void setUp() throws IOException {
.artifactId("spring-boot-maven-plugin")
.version("2.7.2")
.build())
+ .artifactId("sample")
.buildFinalName("sample")
.build();
context = GeneratorContext.builder()
@@ -209,6 +216,101 @@ void customize_inKubernetesAndJarArtifact_shouldCreateAssembly() throws IOExcept
}
}
+ @Test
+ @DisplayName("customize, in Kubernetes and native artifact, should create assembly")
+ void customize_inKubernetesAndNativeArtifact_shouldCreateNativeAssembly() throws IOException {
+ // Given
+ withCustomMainClass();
+ withNativePluginAndArtifactInProject();
+
+ // When
+ final List resultImages = new SpringBootGenerator(context).customize(new ArrayList<>(), false);
+
+ // Then
+ assertThat(resultImages)
+ .isNotNull()
+ .singleElement()
+ .extracting(ImageConfiguration::getBuild)
+ .extracting(BuildConfiguration::getAssembly)
+ .hasFieldOrPropertyWithValue("targetDir", "/")
+ .hasFieldOrPropertyWithValue("excludeFinalOutputArtifact", true)
+ .extracting(AssemblyConfiguration::getLayers)
+ .asList().hasSize(1)
+ .satisfies(layers -> assertThat(layers).element(0).asInstanceOf(InstanceOfAssertFactories.type(Assembly.class))
+ .extracting(Assembly::getFileSets)
+ .asList().element(2)
+ .hasFieldOrPropertyWithValue("outputDirectory", new File("."))
+ .hasFieldOrPropertyWithValue("fileMode", "0755")
+ .extracting("includes").asList()
+ .containsExactly("sample"));
+ }
+
+ @Test
+ @DisplayName("customize, with native packaging, disables Jolokia port")
+ void customize_withNativePackaging_disablesJolokiaPort() throws IOException {
+ // Given
+ withCustomMainClass();
+ withNativePluginAndArtifactInProject();
+
+ // When
+ final List result = new SpringBootGenerator(context).customize(new ArrayList<>(), true);
+ // Then
+ assertThat(result).singleElement()
+ .extracting("buildConfiguration.env")
+ .asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class))
+ .containsEntry("AB_JOLOKIA_OFF", "true");
+ }
+
+ @Test
+ @DisplayName("customize, with native packaging, disables Prometheus port")
+ void customize_withNativePackaging_disablesPrometheusPort() throws IOException {
+ // Given
+ withCustomMainClass();
+ withNativePluginAndArtifactInProject();
+ // When
+ final List result = new SpringBootGenerator(context).customize(new ArrayList<>(), true);
+ // Then
+ assertThat(result).singleElement()
+ .extracting("buildConfiguration.env")
+ .asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class))
+ .containsEntry("AB_PROMETHEUS_OFF", "true");
+ }
+
+ @ParameterizedTest(name = "{index}: customize, native packaging in ''{0}'' mode, should return ''{1}'' as from image")
+ @MethodSource("customize_withNativePackaging_fromData")
+ void customize_withNativePackaging_from(RuntimeMode runtimeMode, String expectedFromStartsWith) throws IOException {
+ // Given
+ withCustomMainClass();
+ withNativePluginAndArtifactInProject();
+ context = context.toBuilder().runtimeMode(runtimeMode).build();
+ // When
+ final List result = new SpringBootGenerator(context).customize(new ArrayList<>(), true);
+ // Then
+ assertThat(result).singleElement()
+ .extracting("buildConfiguration.from").asString()
+ .startsWith(expectedFromStartsWith);
+ }
+
+ static Stream customize_withNativePackaging_fromData() {
+ return Stream.of(
+ Arguments.of(RuntimeMode.KUBERNETES, "registry.access.redhat.com/ubi8/ubi-minimal:"),
+ Arguments.of(RuntimeMode.OPENSHIFT, "registry.access.redhat.com/ubi8/ubi-minimal:")
+ );
+ }
+
+ @Test
+ @DisplayName("customize, with native packaging, should set workDir to root directory")
+ void customize_withNativePackaging_workDir() throws IOException {
+ // Given
+ withNativePluginAndArtifactInProject();
+ // When
+ final List result = new SpringBootGenerator(context).customize(new ArrayList<>(), true);
+ // Then
+ assertThat(result).singleElement()
+ .extracting("buildConfiguration.workdir").asString()
+ .startsWith("/");
+ }
+
@Test
@DisplayName("customize, with standard packaging, has java environment variables")
void customize_withStandardPackaging_thenImageHasJavaMainClassAndJavaAppDirEnvVars() {
@@ -300,6 +402,16 @@ void customize_withColorConfiguration_shouldAddAnsiEnabledPropertyToJavaOptions(
.containsEntry("JAVA_OPTIONS", "-Dspring.output.ansi.enabled=always");
}
+ private void withNativePluginAndArtifactInProject() throws IOException {
+ javaProject = javaProject.toBuilder()
+ .plugin(Plugin.builder().groupId("org.graalvm.buildtools").artifactId("native-maven-plugin").build())
+ .build();
+ context = context.toBuilder()
+ .project(javaProject)
+ .build();
+ Files.createFile(targetDir.toPath().resolve("sample"));
+ }
+
private void withCustomMainClass() {
properties.put("jkube.generator.spring-boot.mainClass", "org.example.Foo");
}
diff --git a/jkube-kit/parent/pom.xml b/jkube-kit/parent/pom.xml
index f616821c40..13b09524d8 100644
--- a/jkube-kit/parent/pom.xml
+++ b/jkube-kit/parent/pom.xml
@@ -105,6 +105,11 @@
registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}
registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}
+
+ registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}
+ registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}
+ registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}
+
quay.io/quarkus/ubi-quarkus-native-binary-s2i:1.0
registry.access.redhat.com/ubi8/ubi-minimal:${version.image.ubi-minimal}