From e60ec35af4d46a58536ce735aaf61b034f9a007e Mon Sep 17 00:00:00 2001 From: Jose Date: Wed, 8 Mar 2023 15:27:33 +0100 Subject: [PATCH] Support of startup probes in Kubernetes/OpenShift/Knative manifests Fix https://github.com/quarkusio/quarkus/issues/29482 --- .../kind/deployment/KindProcessor.java | 3 + .../deployment/MinikubeProcessor.java | 3 + .../deployment/DevClusterHelper.java | 8 ++- .../kubernetes/deployment/KnativeConfig.java | 10 +++ .../deployment/KnativeProcessor.java | 4 +- .../deployment/KubernetesCommonHelper.java | 24 ++++++- .../deployment/KubernetesConfig.java | 10 +++ .../deployment/OpenshiftConfig.java | 10 +++ .../deployment/OpenshiftProcessor.java | 8 ++- .../deployment/PlatformConfiguration.java | 2 + .../VanillaKubernetesProcessor.java | 11 ++- .../it/kubernetes/KnativeWithHealthTest.java | 7 ++ .../kubernetes/KubernetesWithHealthTest.java | 7 ++ .../KubernetesWithStartupProbePortTest.java | 67 +++++++++++++++++++ .../kubernetes/OpenshiftWithHealthTest.java | 7 ++ 15 files changed, 173 insertions(+), 8 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithStartupProbePortTest.java diff --git a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java index 1ccf464bc2d36..d3ff1e49e8b4f 100644 --- a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java +++ b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java @@ -37,6 +37,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -108,6 +109,7 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional portName, Optional livenessPath, Optional readinessPath, + Optional startupPath, List roles, List roleBindings, Optional customProjectRoot) { @@ -117,6 +119,7 @@ public List createDecorators(ApplicationInfoBuildItem applic portName, livenessPath, readinessPath, + startupPath, roles, roleBindings, customProjectRoot); } diff --git a/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java b/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java index d1d34577a3c66..299079fa9a47e 100644 --- a/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java +++ b/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java @@ -34,6 +34,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -104,6 +105,7 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional portName, Optional livenessPath, Optional readinessPath, + Optional startupPath, List roles, List roleBindings, Optional customProjectRoot) { @@ -113,6 +115,7 @@ public List createDecorators(ApplicationInfoBuildItem applic portName, livenessPath, readinessPath, + startupPath, roles, roleBindings, customProjectRoot); } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java index a7c7c44c2d0dd..e6d17260dc07b 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java @@ -37,6 +37,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -67,6 +68,7 @@ public static List createDecorators(String clusterKind, Optional portName, Optional livenessPath, Optional readinessPath, + Optional startupPath, List roles, List roleBindings, Optional customProjectRoot) { @@ -80,7 +82,7 @@ public static List createDecorators(String clusterKind, result.addAll(KubernetesCommonHelper.createDecorators(project, clusterKind, name, config, metricsConfiguration, annotations, labels, command, - port, livenessPath, readinessPath, roles, roleBindings)); + port, livenessPath, readinessPath, startupPath, roles, roleBindings)); image.ifPresent(i -> { result.add(new DecoratorBuildItem(clusterKind, new ApplyContainerImageDecorator(name, i.getImage()))); @@ -127,6 +129,10 @@ public static List createDecorators(String clusterKind, KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "readinessProbe", config.readinessProbe, portName, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "startupProbe", config.startupProbe, + portName, + ports)); // Handle init Containers result.addAll(KubernetesCommonHelper.createInitContainerDecorators(clusterKind, name, initContainers, result)); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java index 67920150ee0ac..639bf7d53c8a4 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java @@ -126,6 +126,12 @@ public class KnativeConfig implements PlatformConfiguration { @ConfigItem ProbeConfig readinessProbe; + /** + * The startup probe + */ + @ConfigItem + ProbeConfig startupProbe; + /** * Prometheus configuration */ @@ -324,6 +330,10 @@ public ProbeConfig getReadinessProbe() { return readinessProbe; } + public ProbeConfig getStartupProbe() { + return startupProbe; + } + public PrometheusConfig getPrometheusConfig() { return prometheus; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java index d4d3029bf28c4..1e224bf41a5d6 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java @@ -57,6 +57,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; @@ -141,6 +142,7 @@ public List createDecorators(ApplicationInfoBuildItem applic List ports, Optional livenessPath, Optional readinessPath, + Optional startupProbePath, List roles, List roleBindings, Optional customProjectRoot, @@ -157,7 +159,7 @@ public List createDecorators(ApplicationInfoBuildItem applic packageConfig); Optional port = KubernetesCommonHelper.getPort(ports, config, "http"); result.addAll(KubernetesCommonHelper.createDecorators(project, KNATIVE, name, config, metricsConfiguration, annotations, - labels, command, port, livenessPath, readinessPath, roles, roleBindings)); + labels, command, port, livenessPath, readinessPath, startupProbePath, roles, roleBindings)); image.ifPresent(i -> { result.add(new DecoratorBuildItem(KNATIVE, new ApplyContainerImageDecorator(name, i.getImage()))); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 26e87d10a89f1..566530e02001d 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -47,6 +47,7 @@ import io.dekorate.kubernetes.decorator.AddRoleBindingResourceDecorator; import io.dekorate.kubernetes.decorator.AddSecretVolumeDecorator; import io.dekorate.kubernetes.decorator.AddServiceAccountResourceDecorator; +import io.dekorate.kubernetes.decorator.AddStartupProbeDecorator; import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator; import io.dekorate.kubernetes.decorator.ApplyArgsDecorator; import io.dekorate.kubernetes.decorator.ApplyCommandDecorator; @@ -80,6 +81,7 @@ import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -184,6 +186,7 @@ public static List createDecorators(Optional projec Optional port, Optional livenessProbePath, Optional readinessProbePath, + Optional startupPath, List roles, List roleBindings) { List result = new ArrayList<>(); @@ -201,7 +204,7 @@ public static List createDecorators(Optional projec //Handle Probes if (!port.isEmpty()) { result.addAll(createProbeDecorators(name, target, config.getLivenessProbe(), config.getReadinessProbe(), - livenessProbePath, readinessProbePath)); + config.getStartupProbe(), livenessProbePath, readinessProbePath, startupPath)); } //Handle RBAC @@ -706,7 +709,7 @@ private static List createAnnotationDecorators(Optional createProbeDecorators(String name, String target, ProbeConfig livenessProbe, ProbeConfig readinessProbe, + ProbeConfig startupProbe, Optional livenessPath, - Optional readinessPath) { + Optional readinessPath, + Optional startupPath) { List result = new ArrayList<>(); createLivenessProbe(name, target, livenessProbe, livenessPath).ifPresent(d -> result.add(d)); createReadinessProbe(name, target, readinessProbe, readinessPath).ifPresent(d -> result.add(d)); + createStartupProbe(name, target, startupProbe, startupPath).ifPresent(d -> result.add(d)); return result; } @@ -770,6 +776,18 @@ private static Optional createReadinessProbe(String name, St return Optional.empty(); } + private static Optional createStartupProbe(String name, String target, ProbeConfig startupProbe, + Optional startupPath) { + if (startupProbe.hasUserSuppliedAction()) { + return Optional.of(new DecoratorBuildItem(target, + new AddStartupProbeDecorator(name, ProbeConverter.convert(startupProbe)))); + } else if (startupPath.isPresent()) { + return Optional.of(new DecoratorBuildItem(target, new AddStartupProbeDecorator(name, + ProbeConverter.builder(startupProbe).withHttpActionPath(startupPath.get().getPath()).build()))); + } + return Optional.empty(); + } + private static Map verifyPorts(List kubernetesPortBuildItems) { final Map result = new HashMap<>(); final Set usedPorts = new HashSet<>(); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java index 5759c635b48c7..c07a97d49864b 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java @@ -163,6 +163,12 @@ public enum DeploymentResourceKind { @ConfigItem ProbeConfig readinessProbe; + /** + * The startup probe + */ + @ConfigItem + ProbeConfig startupProbe; + /** * Prometheus configuration */ @@ -480,6 +486,10 @@ public ProbeConfig getReadinessProbe() { return readinessProbe; } + public ProbeConfig getStartupProbe() { + return startupProbe; + } + public PrometheusConfig getPrometheusConfig() { return prometheus; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java index 46a81b67f3bab..cae5959a3ceae 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java @@ -194,6 +194,12 @@ public static enum DeploymentResourceKind { @ConfigItem ProbeConfig readinessProbe; + /** + * The startup probe + */ + @ConfigItem + ProbeConfig startupProbe; + /** * Prometheus configuration */ @@ -417,6 +423,10 @@ public ProbeConfig getReadinessProbe() { return readinessProbe; } + public ProbeConfig getStartupProbe() { + return startupProbe; + } + public PrometheusConfig getPrometheusConfig() { return prometheus; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index ffe3064fd6672..c8effd4e10a99 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -56,6 +56,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -183,6 +184,7 @@ public List createDecorators(ApplicationInfoBuildItem applic List ports, Optional livenessPath, Optional readinessPath, + Optional startupPath, List roles, List roleBindings, Optional customProjectRoot, @@ -202,7 +204,7 @@ public List createDecorators(ApplicationInfoBuildItem applic result.addAll(KubernetesCommonHelper.createDecorators(project, OPENSHIFT, name, config, metricsConfiguration, annotations, labels, command, - port, livenessPath, readinessPath, roles, roleBindings)); + port, livenessPath, readinessPath, startupPath, roles, roleBindings)); if (config.flavor == v3) { //Openshift 3.x doesn't recognize 'app.kubernetes.io/name', it uses 'app' instead. @@ -309,6 +311,10 @@ public List createDecorators(ApplicationInfoBuildItem applic KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "readinessProbe", config.readinessProbe, portName, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "startupProbe", config.startupProbe, + portName, + ports)); // Handle non-openshift builds if (deploymentKind == DeploymentResourceKind.DeploymentConfig diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java index 239b7b4694474..84318ae6d93c9 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/PlatformConfiguration.java @@ -50,6 +50,8 @@ public interface PlatformConfiguration extends EnvVarHolder { ProbeConfig getReadinessProbe(); + ProbeConfig getStartupProbe(); + PrometheusConfig getPrometheusConfig(); Map getMounts(); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java index 6119ea9c0ff44..3fb365bb73888 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java @@ -47,6 +47,7 @@ import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; +import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem; import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; @@ -134,7 +135,9 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional image, Optional command, Optional portName, List ports, Optional livenessPath, - Optional readinessPath, List roles, + Optional readinessPath, + Optional startupPath, + List roles, List roleBindings, Optional customProjectRoot, List targets) { @@ -149,7 +152,7 @@ public List createDecorators(ApplicationInfoBuildItem applic packageConfig); Optional port = KubernetesCommonHelper.getPort(ports, config); result.addAll(KubernetesCommonHelper.createDecorators(project, KUBERNETES, name, config, metricsConfiguration, - annotations, labels, command, port, livenessPath, readinessPath, roles, roleBindings)); + annotations, labels, command, port, livenessPath, readinessPath, startupPath, roles, roleBindings)); KubernetesConfig.DeploymentResourceKind deploymentKind = config.getDeploymentResourceKind(capabilities); if (deploymentKind != KubernetesConfig.DeploymentResourceKind.Deployment) { @@ -250,6 +253,10 @@ public List createDecorators(ApplicationInfoBuildItem applic KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "readinessProbe", config.readinessProbe, portName, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "startupProbe", config.startupProbe, + portName, + ports)); // Handle remote debug configuration if (config.remoteDebug.enabled) { diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithHealthTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithHealthTest.java index 7c864082ded53..fad52a2db7019 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithHealthTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithHealthTest.java @@ -68,6 +68,13 @@ public void assertGeneratedResources() throws IOException { assertThat(p.getInitialDelaySeconds()).isEqualTo(20); assertProbePath(p, "/q/health/live"); + assertNotNull(p.getHttpGet()); + assertNull(p.getHttpGet().getPort()); + }); + assertThat(c.getStartupProbe()).isNotNull().satisfies(p -> { + assertThat(p.getInitialDelaySeconds()).isEqualTo(5); + assertProbePath(p, "/q/health/started"); + assertNotNull(p.getHttpGet()); assertNull(p.getHttpGet().getPort()); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithHealthTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithHealthTest.java index ed3457813cb4c..8c87b32684082 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithHealthTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithHealthTest.java @@ -82,6 +82,13 @@ public void assertGeneratedResources() throws IOException { assertThat(p.getInitialDelaySeconds()).isEqualTo(20); assertProbePath(p, "/liveness"); + assertNotNull(p.getHttpGet()); + assertEquals(p.getHttpGet().getPort().getIntVal(), 9090); + }); + assertThat(container.getStartupProbe()).isNotNull().satisfies(p -> { + assertThat(p.getInitialDelaySeconds()).isEqualTo(5); + assertProbePath(p, "/q/health/started"); + assertNotNull(p.getHttpGet()); assertEquals(p.getHttpGet().getPort().getIntVal(), 9090); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithStartupProbePortTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithStartupProbePortTest.java new file mode 100644 index 0000000000000..bc0fdccdf3cc3 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithStartupProbePortTest.java @@ -0,0 +1,67 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +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.builder.Version; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithStartupProbePortTest { + + private static final String APP_NAME = "kubernetes-with-startup-probe-port"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) + .setApplicationName(APP_NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .overrideConfigKey("quarkus.kubernetes.startup-probe.http-action-port", "9191") + .setLogFileName("k8s.log") + .setForcedDependencies(List.of( + Dependency.of("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + Dependency.of("io.quarkus", "quarkus-smallrye-health", Version.getVersion()))); + + @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")); + 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(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement() + .satisfies(container -> { + assertThat(container.getStartupProbe()).isNotNull().satisfies(p -> { + assertEquals(p.getHttpGet().getPort().getIntVal(), 9191); + }); + }); + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithHealthTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithHealthTest.java index c79168a99e6a3..081128984d4c5 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithHealthTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithHealthTest.java @@ -3,6 +3,8 @@ import static io.restassured.RestAssured.given; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.IOException; import java.nio.file.Path; @@ -79,6 +81,11 @@ public void assertGeneratedResources() throws IOException { assertThat(e.getCommand()).containsOnly("kill"); }); }); + assertThat(container.getStartupProbe()).isNotNull().satisfies(p -> { + assertThat(p.getInitialDelaySeconds()).isEqualTo(5); + assertNotNull(p.getHttpGet()); + assertEquals(p.getHttpGet().getPath(), "/q/health/started"); + }); }); }); });