From 29a134f49c339f1453ff248e21ad2b408a5911e8 Mon Sep 17 00:00:00 2001
From: Jose <josecarvajalhilario@gmail.com>
Date: Thu, 4 May 2023 06:07:39 +0200
Subject: [PATCH] Don't generate the init task for db migration if migrate at
 start is off

The `quarkus.[flyway or liquibase or liquibase-mongodb].enabled` and `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start` properties are runtime properties, so I have to create the following build time properties to read these values and allow users configurating it:

- `quarkus.[flyway or liquibase or liquibase-mongodb].generate-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].enabled`
- `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-with-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start`

Plus, I've extended the coverage of these extensions with the K8s tests.

Fix https://github.com/quarkusio/quarkus/issues/33097
---
 .../io/quarkus/flyway/FlywayProcessor.java    |  16 +--
 .../flyway/runtime/FlywayBuildTimeConfig.java |   9 ++
 .../FlywayDataSourceBuildTimeConfig.java      |   9 ++
 .../deployment/LiquibaseMongodbProcessor.java |  18 +--
 .../LiquibaseMongodbBuildTimeConfig.java      |  18 +++
 .../deployment/LiquibaseProcessor.java        |  16 +--
 .../runtime/LiquibaseBuildTimeConfig.java     |   9 ++
 .../LiquibaseDataSourceBuildTimeConfig.java   |   9 ++
 ...esWithFlywayInitMigrationDisabledTest.java |  89 ++++++++++++++
 .../KubernetesWithFlywayInitTest.java         |  11 +-
 ...ithLiquibaseInitMigrationDisabledTest.java |  89 ++++++++++++++
 .../KubernetesWithLiquibaseInitTest.java      | 109 +++++++++++++++++
 ...ibaseMongoDbInitMigrationDisabledTest.java |  90 ++++++++++++++
 ...ubernetesWithLiquibaseMongoDbInitTest.java | 111 ++++++++++++++++++
 14 files changed, 577 insertions(+), 26 deletions(-)
 create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java
 create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java
 create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java
 create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java
 create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java

diff --git a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java
index ce3fa9db00e21..01cd379b1e9e5 100644
--- a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java
+++ b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java
@@ -221,13 +221,15 @@ public ServiceStartBuildItem startActions(FlywayRecorder recorder,
     }
 
     @BuildStep
-    public InitTaskBuildItem configureInitTask() {
-        return InitTaskBuildItem.create()
-                .withName("flyway-init")
-                .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_FLYWAY_ENABLED", "true"))
-                .withAppEnvVars(Map.of("QUARKUS_FLYWAY_ENABLED", "false"))
-                .withSharedEnvironment(true)
-                .withSharedFilesystem(true);
+    public void configureInitTask(FlywayBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) {
+        if (config.generateInitTask && config.defaultDataSource.migrateWithInitTask) {
+            initTasks.produce(InitTaskBuildItem.create()
+                    .withName("flyway-init")
+                    .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_FLYWAY_ENABLED", "true"))
+                    .withAppEnvVars(Map.of("QUARKUS_FLYWAY_ENABLED", "false"))
+                    .withSharedEnvironment(true)
+                    .withSharedFilesystem(true));
+        }
     }
 
     private Set<String> getDataSourceNames(List<JdbcDataSourceBuildItem> jdbcDataSourceBuildItems) {
diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java
index 47e7a4878c7f4..fb89b198ef227 100644
--- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java
+++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java
@@ -21,6 +21,15 @@ public FlywayDataSourceBuildTimeConfig getConfigForDataSourceName(String dataSou
         return namedDataSources.getOrDefault(dataSourceName, FlywayDataSourceBuildTimeConfig.defaultConfig());
     }
 
+    /**
+     * Flag to enable / disable the generation of the init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.flyway.enabled`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.flyway.enabled:true}")
+    public boolean generateInitTask;
+
     /**
      * Flyway configuration for the default datasource.
      */
diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java
index 7668f4ca191ea..c58c527656d99 100644
--- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java
+++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java
@@ -36,6 +36,15 @@ public final class FlywayDataSourceBuildTimeConfig {
     @ConfigItem
     public Optional<List<String>> callbacks = Optional.empty();
 
+    /**
+     * Flag to enable / disable the migration using the generated init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.flyway.migrate-at-start`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.flyway.migrate-at-start:false}")
+    public boolean migrateWithInitTask;
+
     /**
      * Creates a {@link FlywayDataSourceBuildTimeConfig} with default settings.
      *
diff --git a/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java b/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java
index 462e0d5f6d61d..dfbaeb81c64aa 100644
--- a/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java
+++ b/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java
@@ -254,14 +254,16 @@ ServiceStartBuildItem startLiquibase(LiquibaseMongodbRecorder recorder,
     }
 
     @BuildStep
-    public InitTaskBuildItem configureInitTask() {
-        return InitTaskBuildItem.create()
-                .withName("liquibase-mongodb-init")
-                .withTaskEnvVars(
-                        Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_MONGODB_ENABLED", "true"))
-                .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_MONGODB_ENABLED", "false"))
-                .withSharedEnvironment(true)
-                .withSharedFilesystem(true);
+    public void configureInitTask(LiquibaseMongodbBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) {
+        if (config.generateInitTask && config.migrateWithInitTask) {
+            initTasks.produce(InitTaskBuildItem.create()
+                    .withName("liquibase-mongodb-init")
+                    .withTaskEnvVars(
+                            Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_MONGODB_ENABLED", "true"))
+                    .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_MONGODB_ENABLED", "false"))
+                    .withSharedEnvironment(true)
+                    .withSharedFilesystem(true));
+        }
     }
 
     /**
diff --git a/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java b/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java
index 08bdc6b5363bb..141b5cbb256f4 100644
--- a/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java
+++ b/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java
@@ -15,4 +15,22 @@ public class LiquibaseMongodbBuildTimeConfig {
      */
     @ConfigItem(defaultValue = "db/changeLog.xml")
     public String changeLog;
+
+    /**
+     * Flag to enable / disable the generation of the init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.liquibase-mongodb.enabled`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.liquibase-mongodb.enabled:true}")
+    public boolean generateInitTask;
+
+    /**
+     * Flag to enable / disable the migration using the generated init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.liquibase-mongodb.migrate-at-start`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.liquibase-mongodb.migrate-at-start:false}")
+    public boolean migrateWithInitTask;
 }
diff --git a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
index cd935d27f0e65..56a4cd875b3e7 100644
--- a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
+++ b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
@@ -314,13 +314,15 @@ ServiceStartBuildItem startLiquibase(LiquibaseRecorder recorder,
     }
 
     @BuildStep
-    public InitTaskBuildItem configureInitTask() {
-        return InitTaskBuildItem.create()
-                .withName("liquibase-init")
-                .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_ENABLED", "true"))
-                .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_ENABLED", "false"))
-                .withSharedEnvironment(true)
-                .withSharedFilesystem(true);
+    public void configureInitTask(LiquibaseBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) {
+        if (config.generateInitTask && config.defaultDataSource.migrateWithInitTask) {
+            initTasks.produce(InitTaskBuildItem.create()
+                    .withName("liquibase-init")
+                    .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_ENABLED", "true"))
+                    .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_ENABLED", "false"))
+                    .withSharedEnvironment(true)
+                    .withSharedFilesystem(true));
+        }
     }
 
     private Set<String> getDataSourceNames(List<JdbcDataSourceBuildItem> jdbcDataSourceBuildItems) {
diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java
index 1055e3bbc7b57..8e498ecad3cac 100644
--- a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java
+++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java
@@ -31,6 +31,15 @@ public LiquibaseDataSourceBuildTimeConfig getConfigForDataSourceName(String data
         return namedDataSources.getOrDefault(dataSourceName, LiquibaseDataSourceBuildTimeConfig.defaultConfig());
     }
 
+    /**
+     * Flag to enable / disable the generation of the init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.liquibase.enabled`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.liquibase.enabled:true}")
+    public boolean generateInitTask;
+
     /**
      * Liquibase configuration for the default datasource.
      */
diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java
index 02be6092e80cc..1d3d5dd4134a6 100644
--- a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java
+++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java
@@ -28,4 +28,13 @@ public static final LiquibaseDataSourceBuildTimeConfig defaultConfig() {
     @ConfigItem(defaultValue = DEFAULT_CHANGE_LOG)
     public String changeLog;
 
+    /**
+     * Flag to enable / disable the migration using the generated init task Kubernetes resources.
+     * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present.
+     *
+     * The default value is `quarkus.liquibase.migrate-at-start`.
+     */
+    @ConfigItem(defaultValue = "${quarkus.liquibase.migrate-at-start:false}")
+    public boolean migrateWithInitTask;
+
 }
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java
new file mode 100644
index 0000000000000..835ce44239537
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java
@@ -0,0 +1,89 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+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.fabric8.kubernetes.api.model.batch.v1.Job;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.quarkus.bootstrap.model.AppArtifact;
+import io.quarkus.builder.Version;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KubernetesWithFlywayInitMigrationDisabledTest {
+
+    private static final String NAME = "kubernetes-with-flyway-init-migration-disabled";
+
+    @RegisterExtension
+    static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+            .setApplicationName(NAME)
+            .setApplicationVersion("0.1-SNAPSHOT")
+            .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.flyway.migrate-at-start", "false")
+            .setForcedDependencies(Arrays.asList(
+                    new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
+                    new AppArtifact("io.quarkus", "quarkus-flyway", 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<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
+
+        Optional<Deployment> deployment = kubernetesList.stream()
+                .filter(d -> "Deployment".equals(d.getKind())
+                        && NAME.equals(d.getMetadata().getName()))
+                .map(d -> (Deployment) d).findAny();
+
+        assertTrue(deployment.isPresent());
+        assertThat(deployment).satisfies(j -> j.isPresent());
+        assertThat(deployment.get()).satisfies(d -> {
+            assertThat(d.getMetadata()).satisfies(m -> {
+                assertThat(m.getName()).isEqualTo(NAME);
+            });
+
+            assertThat(d.getSpec()).satisfies(deploymentSpec -> {
+                assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getInitContainers()).noneSatisfy(container -> {
+                            assertThat(container.getName()).isEqualTo("init");
+                        });
+
+                    });
+                });
+            });
+        });
+
+        Optional<Job> job = kubernetesList.stream()
+                .filter(j -> "Job".equals(j.getKind()) && "flyway-init".equals(j.getMetadata().getName())).map(j -> (Job) j)
+                .findAny();
+        assertFalse(job.isPresent());
+
+        Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
+                .map(r -> (RoleBinding) r).findFirst();
+        assertFalse(roleBinding.isPresent());
+    }
+}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java
index 827c7b3c0c7f6..c6bc3daac8e25 100644
--- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java
@@ -26,12 +26,15 @@
 
 public class KubernetesWithFlywayInitTest {
 
+    private static final String NAME = "kubernetes-with-flyway-init";
+
     @RegisterExtension
     static final QuarkusProdModeTest config = new QuarkusProdModeTest()
             .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
-            .setApplicationName("kubernetes-with-flyway-init")
+            .setApplicationName(NAME)
             .setApplicationVersion("0.1-SNAPSHOT")
             .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.flyway.migrate-at-start", "true")
             .setForcedDependencies(Arrays.asList(
                     new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
                     new AppArtifact("io.quarkus", "quarkus-flyway", Version.getVersion())));
@@ -50,14 +53,14 @@ public void assertGeneratedResources() throws IOException {
 
         Optional<Deployment> deployment = kubernetesList.stream()
                 .filter(d -> "Deployment".equals(d.getKind())
-                        && "kubernetes-with-flyway-init".equals(d.getMetadata().getName()))
+                        && NAME.equals(d.getMetadata().getName()))
                 .map(d -> (Deployment) d).findAny();
 
         assertTrue(deployment.isPresent());
         assertThat(deployment).satisfies(j -> j.isPresent());
         assertThat(deployment.get()).satisfies(d -> {
             assertThat(d.getMetadata()).satisfies(m -> {
-                assertThat(m.getName()).isEqualTo("kubernetes-with-flyway-init");
+                assertThat(m.getName()).isEqualTo(NAME);
             });
 
             assertThat(d.getSpec()).satisfies(deploymentSpec -> {
@@ -99,7 +102,7 @@ public void assertGeneratedResources() throws IOException {
         });
 
         Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
-                r -> r instanceof RoleBinding && "kubernetes-with-flyway-init-view-jobs".equals(r.getMetadata().getName()))
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
                 .map(r -> (RoleBinding) r).findFirst();
         assertTrue(roleBinding.isPresent());
     }
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java
new file mode 100644
index 0000000000000..9bdd79963271a
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java
@@ -0,0 +1,89 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+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.fabric8.kubernetes.api.model.batch.v1.Job;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.quarkus.bootstrap.model.AppArtifact;
+import io.quarkus.builder.Version;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KubernetesWithLiquibaseInitMigrationDisabledTest {
+
+    private static final String NAME = "kubernetes-with-liquibase-init-migration-disabled";
+
+    @RegisterExtension
+    static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+            .setApplicationName(NAME)
+            .setApplicationVersion("0.1-SNAPSHOT")
+            .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.liquibase.migrate-at-start", "false")
+            .setForcedDependencies(Arrays.asList(
+                    new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
+                    new AppArtifact("io.quarkus", "quarkus-liquibase", 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<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
+
+        Optional<Deployment> deployment = kubernetesList.stream()
+                .filter(d -> "Deployment".equals(d.getKind())
+                        && NAME.equals(d.getMetadata().getName()))
+                .map(d -> (Deployment) d).findAny();
+
+        assertTrue(deployment.isPresent());
+        assertThat(deployment).satisfies(j -> j.isPresent());
+        assertThat(deployment.get()).satisfies(d -> {
+            assertThat(d.getMetadata()).satisfies(m -> {
+                assertThat(m.getName()).isEqualTo(NAME);
+            });
+
+            assertThat(d.getSpec()).satisfies(deploymentSpec -> {
+                assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getInitContainers()).noneSatisfy(container -> {
+                            assertThat(container.getName()).isEqualTo("init");
+                        });
+
+                    });
+                });
+            });
+        });
+
+        Optional<Job> job = kubernetesList.stream()
+                .filter(j -> "Job".equals(j.getKind()) && "liquibase-init".equals(j.getMetadata().getName())).map(j -> (Job) j)
+                .findAny();
+        assertFalse(job.isPresent());
+
+        Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
+                .map(r -> (RoleBinding) r).findFirst();
+        assertFalse(roleBinding.isPresent());
+    }
+}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java
new file mode 100644
index 0000000000000..578b8c25e1531
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java
@@ -0,0 +1,109 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+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.fabric8.kubernetes.api.model.batch.v1.Job;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.quarkus.bootstrap.model.AppArtifact;
+import io.quarkus.builder.Version;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KubernetesWithLiquibaseInitTest {
+
+    private static final String NAME = "kubernetes-with-liquibase-init";
+
+    @RegisterExtension
+    static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+            .setApplicationName(NAME)
+            .setApplicationVersion("0.1-SNAPSHOT")
+            .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.liquibase.migrate-at-start", "true")
+            .setForcedDependencies(Arrays.asList(
+                    new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
+                    new AppArtifact("io.quarkus", "quarkus-liquibase", 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<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
+
+        Optional<Deployment> deployment = kubernetesList.stream()
+                .filter(d -> "Deployment".equals(d.getKind())
+                        && NAME.equals(d.getMetadata().getName()))
+                .map(d -> (Deployment) d).findAny();
+
+        assertTrue(deployment.isPresent());
+        assertThat(deployment).satisfies(j -> j.isPresent());
+        assertThat(deployment.get()).satisfies(d -> {
+            assertThat(d.getMetadata()).satisfies(m -> {
+                assertThat(m.getName()).isEqualTo(NAME);
+            });
+
+            assertThat(d.getSpec()).satisfies(deploymentSpec -> {
+                assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getInitContainers()).singleElement().satisfies(container -> {
+                            assertThat(container.getName()).isEqualTo("init");
+                        });
+
+                    });
+                });
+            });
+        });
+
+        Optional<Job> job = kubernetesList.stream()
+                .filter(j -> "Job".equals(j.getKind()) && "liquibase-init".equals(j.getMetadata().getName())).map(j -> (Job) j)
+                .findAny();
+        assertTrue(job.isPresent());
+
+        assertThat(job.get()).satisfies(j -> {
+            assertThat(j.getSpec()).satisfies(jobSpec -> {
+                assertThat(jobSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getContainers()).singleElement().satisfies(container -> {
+                            assertThat(container.getName()).isEqualTo("liquibase-init");
+                            assertThat(container.getEnv()).filteredOn(env -> "QUARKUS_LIQUIBASE_ENABLED".equals(env.getName()))
+                                    .singleElement().satisfies(env -> {
+                                        assertThat(env.getValue()).isEqualTo("true");
+                                    });
+                            assertThat(container.getEnv())
+                                    .filteredOn(env -> "QUARKUS_INIT_AND_EXIT".equals(env.getName())).singleElement()
+                                    .satisfies(env -> {
+                                        assertThat(env.getValue()).isEqualTo("true");
+                                    });
+                        });
+                    });
+                });
+            });
+        });
+
+        Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
+                .map(r -> (RoleBinding) r).findFirst();
+        assertTrue(roleBinding.isPresent());
+    }
+}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java
new file mode 100644
index 0000000000000..f54702922f00b
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java
@@ -0,0 +1,90 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+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.fabric8.kubernetes.api.model.batch.v1.Job;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.quarkus.bootstrap.model.AppArtifact;
+import io.quarkus.builder.Version;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest {
+
+    private static final String NAME = "kubernetes-with-liquibase-mongodb-init-migration-disabled";
+
+    @RegisterExtension
+    static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+            .setApplicationName(NAME)
+            .setApplicationVersion("0.1-SNAPSHOT")
+            .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.liquibase-mongodb.migrate-at-start", "false")
+            .setForcedDependencies(Arrays.asList(
+                    new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
+                    new AppArtifact("io.quarkus", "quarkus-liquibase-mongodb", 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<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
+
+        Optional<Deployment> deployment = kubernetesList.stream()
+                .filter(d -> "Deployment".equals(d.getKind())
+                        && NAME.equals(d.getMetadata().getName()))
+                .map(d -> (Deployment) d).findAny();
+
+        assertTrue(deployment.isPresent());
+        assertThat(deployment).satisfies(j -> j.isPresent());
+        assertThat(deployment.get()).satisfies(d -> {
+            assertThat(d.getMetadata()).satisfies(m -> {
+                assertThat(m.getName()).isEqualTo(NAME);
+            });
+
+            assertThat(d.getSpec()).satisfies(deploymentSpec -> {
+                assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getInitContainers()).noneSatisfy(container -> {
+                            assertThat(container.getName()).isEqualTo("init");
+                        });
+
+                    });
+                });
+            });
+        });
+
+        Optional<Job> job = kubernetesList.stream()
+                .filter(j -> "Job".equals(j.getKind()) && "liquibase-mongodb-init".equals(j.getMetadata().getName()))
+                .map(j -> (Job) j)
+                .findAny();
+        assertFalse(job.isPresent());
+
+        Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
+                .map(r -> (RoleBinding) r).findFirst();
+        assertFalse(roleBinding.isPresent());
+    }
+}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java
new file mode 100644
index 0000000000000..f91925218cf33
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java
@@ -0,0 +1,111 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+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.fabric8.kubernetes.api.model.batch.v1.Job;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.quarkus.bootstrap.model.AppArtifact;
+import io.quarkus.builder.Version;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KubernetesWithLiquibaseMongoDbInitTest {
+
+    private static final String NAME = "kubernetes-with-liquibase-mongodb-init";
+
+    @RegisterExtension
+    static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+            .setApplicationName(NAME)
+            .setApplicationVersion("0.1-SNAPSHOT")
+            .setLogFileName("k8s.log")
+            .overrideConfigKey("quarkus.liquibase-mongodb.migrate-at-start", "true")
+            .setForcedDependencies(Arrays.asList(
+                    new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()),
+                    new AppArtifact("io.quarkus", "quarkus-liquibase-mongodb", 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<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
+
+        Optional<Deployment> deployment = kubernetesList.stream()
+                .filter(d -> "Deployment".equals(d.getKind())
+                        && NAME.equals(d.getMetadata().getName()))
+                .map(d -> (Deployment) d).findAny();
+
+        assertTrue(deployment.isPresent());
+        assertThat(deployment).satisfies(j -> j.isPresent());
+        assertThat(deployment.get()).satisfies(d -> {
+            assertThat(d.getMetadata()).satisfies(m -> {
+                assertThat(m.getName()).isEqualTo(NAME);
+            });
+
+            assertThat(d.getSpec()).satisfies(deploymentSpec -> {
+                assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getInitContainers()).singleElement().satisfies(container -> {
+                            assertThat(container.getName()).isEqualTo("init");
+                        });
+
+                    });
+                });
+            });
+        });
+
+        Optional<Job> job = kubernetesList.stream()
+                .filter(j -> "Job".equals(j.getKind()) && "liquibase-mongodb-init".equals(j.getMetadata().getName()))
+                .map(j -> (Job) j)
+                .findAny();
+        assertTrue(job.isPresent());
+
+        assertThat(job.get()).satisfies(j -> {
+            assertThat(j.getSpec()).satisfies(jobSpec -> {
+                assertThat(jobSpec.getTemplate()).satisfies(t -> {
+                    assertThat(t.getSpec()).satisfies(podSpec -> {
+                        assertThat(podSpec.getContainers()).singleElement().satisfies(container -> {
+                            assertThat(container.getName()).isEqualTo("liquibase-mongodb-init");
+                            assertThat(container.getEnv())
+                                    .filteredOn(env -> "QUARKUS_LIQUIBASE_MONGODB_ENABLED".equals(env.getName()))
+                                    .singleElement().satisfies(env -> {
+                                        assertThat(env.getValue()).isEqualTo("true");
+                                    });
+                            assertThat(container.getEnv())
+                                    .filteredOn(env -> "QUARKUS_INIT_AND_EXIT".equals(env.getName())).singleElement()
+                                    .satisfies(env -> {
+                                        assertThat(env.getValue()).isEqualTo("true");
+                                    });
+                        });
+                    });
+                });
+            });
+        });
+
+        Optional<RoleBinding> roleBinding = kubernetesList.stream().filter(
+                r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName()))
+                .map(r -> (RoleBinding) r).findFirst();
+        assertTrue(roleBinding.isPresent());
+    }
+}