From 56c604b7c1c951803c8d776f4b8247e5e9cc8587 Mon Sep 17 00:00:00 2001 From: Jose Date: Wed, 25 Jan 2023 07:58:58 +0100 Subject: [PATCH] Resolve correct container tag when application version is unset Fix https://github.com/quarkusio/quarkus/issues/30559 --- .../deployment/ContainerImageProcessor.java | 8 ++- .../quarkus/container/spi/ImageReference.java | 2 +- .../deployment/KubernetesConfigUtil.java | 6 +- ...etesWithDefaultApplicationVersionTest.java | 64 +++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithDefaultApplicationVersionTest.java diff --git a/extensions/container-image/deployment/src/main/java/io/quarkus/container/image/deployment/ContainerImageProcessor.java b/extensions/container-image/deployment/src/main/java/io/quarkus/container/image/deployment/ContainerImageProcessor.java index 4b3593d647e5f..23df621db72e1 100644 --- a/extensions/container-image/deployment/src/main/java/io/quarkus/container/image/deployment/ContainerImageProcessor.java +++ b/extensions/container-image/deployment/src/main/java/io/quarkus/container/image/deployment/ContainerImageProcessor.java @@ -1,6 +1,8 @@ package io.quarkus.container.image.deployment; import static io.quarkus.container.image.deployment.util.EnablementUtil.*; +import static io.quarkus.container.spi.ImageReference.DEFAULT_TAG; +import static io.quarkus.deployment.builditem.ApplicationInfoBuildItem.UNSET_VALUE; import java.util.Collections; import java.util.Optional; @@ -91,7 +93,11 @@ public void publishImageInfo(ApplicationInfoBuildItem app, + effectiveGroup + "' and name '" + effectiveName + "' is invalid"); } - final String effectiveTag = containerImageConfig.tag.orElse(app.getVersion()); + String effectiveTag = containerImageConfig.tag.orElse(app.getVersion()); + if (effectiveTag.equals(UNSET_VALUE)) { + effectiveTag = DEFAULT_TAG; + } + if (!ImageReference.isValidTag(effectiveTag)) { throw new IllegalArgumentException("The supplied container-image tag '" + effectiveTag + "' is invalid"); } diff --git a/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ImageReference.java b/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ImageReference.java index c95d076b95931..33eea11727021 100644 --- a/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ImageReference.java +++ b/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ImageReference.java @@ -26,8 +26,8 @@ */ public class ImageReference { + public static final String DEFAULT_TAG = "latest"; private static final String DOCKER_HUB_REGISTRY = "registry-1.docker.io"; - private static final String DEFAULT_TAG = "latest"; private static final String LIBRARY_REPOSITORY_PREFIX = "library/"; /** diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java index 0208f3f9f69cb..085ac6b982be3 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java @@ -1,5 +1,7 @@ package io.quarkus.kubernetes.deployment; +import static io.quarkus.container.spi.ImageReference.DEFAULT_TAG; +import static io.quarkus.deployment.builditem.ApplicationInfoBuildItem.UNSET_VALUE; import static io.quarkus.kubernetes.deployment.Constants.DEPLOY; import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_TARGET; import static io.quarkus.kubernetes.deployment.Constants.DOCKER; @@ -142,7 +144,9 @@ public static Map toMap(PlatformConfiguration... platformConfigu Arrays.stream(platformConfigurations).forEach(p -> { p.getPartOf().ifPresent(g -> quarkusPrefixed.put(DEKORATE_PREFIX + p.getConfigName() + ".part-of", g)); p.getName().ifPresent(n -> quarkusPrefixed.put(DEKORATE_PREFIX + p.getConfigName() + ".name", n)); - p.getVersion().ifPresent(v -> quarkusPrefixed.put(DEKORATE_PREFIX + p.getConfigName() + ".version", v)); + p.getVersion() + .map(v -> v.equals(UNSET_VALUE) ? DEFAULT_TAG : v) + .ifPresent(v -> quarkusPrefixed.put(DEKORATE_PREFIX + p.getConfigName() + ".version", v)); }); Map unPrefixed = StreamSupport.stream(config.getPropertyNames().spliterator(), false) diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithDefaultApplicationVersionTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithDefaultApplicationVersionTest.java new file mode 100644 index 0000000000000..2e547bb0d6415 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithDefaultApplicationVersionTest.java @@ -0,0 +1,64 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.deployment.builditem.ApplicationInfoBuildItem; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithDefaultApplicationVersionTest { + + private static final String APP_NAME = "kubernetes-with-default-application-version"; + private static final String EXPECTED_VERSION = "latest"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) + .setApplicationName(APP_NAME) + // Simulates when there is no application version + .setApplicationVersion(ApplicationInfoBuildItem.UNSET_VALUE); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")) + .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2)); + List kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(APP_NAME); + assertThat(m.getLabels()).contains(entry("app.kubernetes.io/name", APP_NAME), + entry("app.kubernetes.io/version", EXPECTED_VERSION)); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + // then, we should use `latest` and not `<< unset >>` which gives an exception. + assertThat(container.getImage()).endsWith(APP_NAME + ":" + EXPECTED_VERSION); + }); + }); + }); + }); + }); + } +}