Skip to content

Commit

Permalink
Don't generate the init task for db migration if migrate at start is off
Browse files Browse the repository at this point in the history
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 quarkusio#33097
  • Loading branch information
Sgitario committed May 4, 2023
1 parent 998ff4c commit 29a134f
Show file tree
Hide file tree
Showing 14 changed files with 577 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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())));
Expand All @@ -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 -> {
Expand Down Expand Up @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}
}
Loading

0 comments on commit 29a134f

Please sign in to comment.