Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new property to openshift config that allows appending jvm args #24162

Merged
merged 1 commit into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/container-image.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ For example, the presence of `src/main/jib/foo/bar` would result in `/foo/bar`

There are cases where the built container image may need to have Java debugging conditionally enabled at runtime.

When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime` or `ubi8/openjdk-17-runtime` is used), then the `quarkus.jib.jvm-arguments` configuration property can be used in order to
When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime` or `ubi8/openjdk-17-runtime` is used), then the `quarkus.jib.jvm-additional-arguments` configuration property can be used in order to
make the JVM listen on the debug port at startup.

The exact configuration is:

[source,properties]
----
quarkus.jib.jvm-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
quarkus.jib.jvm-additional-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
----

Other base images might provide launch scripts that enable debugging when an environment variable is set, in which case you would set than environment variable when launching the container.
Expand Down
2 changes: 2 additions & 0 deletions docs/src/main/asciidoc/deploying-to-kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,8 @@ The OpenShift resources can be customized in a similar approach with Kubernetes.
| quarkus.openshift.working-dir | String | |
| quarkus.openshift.command | String[] | |
| quarkus.openshift.arguments | String[] | |
| quarkus.openshift.jvm-arguments | String[] | The JVM arguments to pass to the JVM when starting the application | -Dquarkus.http.host=0.0.0.0,-Djava.util.logging.manager=org.jboss.logmanager.LogManager
| quarkus.openshift.jvm-additional-arguments | String[] | Additional JVM arguments to pass to the JVM when starting the application |
| quarkus.openshift.replicas | int | | 1
| quarkus.openshift.service-account | String | |
| quarkus.openshift.ports | Map<String, Port> | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class DockerConfig {

/**
* Path to the the JVM Dockerfile.
* Path to the JVM Dockerfile.
* If not set ${project.root}/src/main/docker/Dockerfile.jvm will be used
* If set to an absolute path then the absolute path will be used, otherwise the path
* will be considered relative to the project root
Expand All @@ -21,7 +21,7 @@ public class DockerConfig {
public Optional<String> dockerfileJvmPath;

/**
* Path to the the JVM Dockerfile.
* Path to the JVM Dockerfile.
* If not set ${project.root}/src/main/docker/Dockerfile.native will be used
* If set to an absolute path then the absolute path will be used, otherwise the path
* will be considered relative to the project root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ public class JibConfig {
public String baseNativeImage;

/**
* Additional JVM arguments to pass to the JVM when starting the application
* The JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem(defaultValue = "-Djava.util.logging.manager=org.jboss.logmanager.LogManager")
public List<String> jvmArguments;

/**
* Additional JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem
public Optional<List<String>> jvmAdditionalArguments;

/**
* Additional arguments to pass when starting the native application
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ private JibContainerBuilder createContainerBuilderFromFastJar(String baseJvmImag

private List<String> determineEffectiveJvmArguments(JibConfig jibConfig, Optional<AppCDSResultBuildItem> appCDSResult) {
List<String> effectiveJvmArguments = new ArrayList<>(jibConfig.jvmArguments);
jibConfig.jvmAdditionalArguments.ifPresent(effectiveJvmArguments::addAll);
if (appCDSResult.isPresent()) {
boolean containsAppCDSOptions = false;
for (String effectiveJvmArgument : effectiveJvmArguments) {
Expand Down Expand Up @@ -567,7 +568,7 @@ private JibContainerBuilder createContainerBuilderFromLegacyJar(String baseJvmIm
// when there is no custom entry point, we just set everything up for a regular java run
if (!jibConfig.jvmEntrypoint.isPresent()) {
javaContainerBuilder
.addJvmFlags(jibConfig.jvmArguments)
.addJvmFlags(determineEffectiveJvmArguments(jibConfig, Optional.empty()))
.setMainClass(mainClassBuildItem.getClassName());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.container.image.openshift.deployment;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -67,11 +68,17 @@ public static String getDefaultJvmImage(CompiledJavaVersionBuildItem.JavaVersion
public String nativeDockerfile;

/**
* Additional JVM arguments to pass to the JVM when starting the application
* The JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem(defaultValue = "-Dquarkus.http.host=0.0.0.0,-Djava.util.logging.manager=org.jboss.logmanager.LogManager")
public List<String> jvmArguments;

/**
* Additional JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem
public Optional<List<String>> jvmAdditionalArguments;

/**
* Additional arguments to pass when starting the native application
*/
Expand Down Expand Up @@ -144,8 +151,17 @@ public boolean hasDefaultJvmDockerfile() {
*
* @returns true if nativeDockerfile is the default
*/
public boolean hasDefaultativeDockerfile() {
public boolean hasDefaultNativeDockerfile() {
return nativeDockerfile.equals(DEFAULT_NATIVE_DOCKERFILE);
}

/**
* @return the effective JVM arguments to use by getting the jvmArguments and the jvmAdditionalArguments properties.
*/
public List<String> getEffectiveJvmArguments() {
List<String> effectiveJvmArguments = new ArrayList<>(jvmArguments);
jvmAdditionalArguments.ifPresent(effectiveJvmArguments::addAll);
return effectiveJvmArguments;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ public void openshiftRequirementsJvm(OpenshiftConfig openshiftConfig,
baseImage.ifPresent(b -> {
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJarEnvVar(), pathToJar, null));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJvmOptionsEnvVar(),
String.join(" ", config.jvmArguments), null));
String.join(" ", config.getEffectiveJvmArguments()), null));
});
//In all other cases its the responsibility of the image to set those up correctly.
if (!baseImage.isPresent()) {
List<String> cmd = new ArrayList<>();
cmd.add("java");
cmd.addAll(config.jvmArguments);
cmd.addAll(config.getEffectiveJvmArguments());
cmd.addAll(Arrays.asList("-jar", pathToJar));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar("JAVA_APP_JAR", pathToJar, null));
commandProducer.produce(KubernetesCommandBuildItem.command(cmd));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void visit(SourceBuildStrategyFluent strategy) {
*
* @param openshiftConfig the Openshift config
* @param s2iConfig the s2i config
* @param an instance of {@link OpenshiftConfig} with the merged configuration.
* @return an instance of {@link OpenshiftConfig} with the merged configuration.
*/
public static OpenshiftConfig mergeConfig(OpenshiftConfig openshiftConfig, S2iConfig s2iConfig) {
OpenshiftConfig result = openshiftConfig != null ? openshiftConfig : new OpenshiftConfig();
Expand All @@ -101,6 +101,7 @@ public static OpenshiftConfig mergeConfig(OpenshiftConfig openshiftConfig, S2iCo
boolean hasS2iBaseJvmImage = properties.contains("quarkus.s2i.base-jvm-image");
boolean hasS2iBaseNativeImage = properties.contains("quarkus.s2i.base-native-image");
boolean hasS2iJvmArguments = properties.contains("quarkus.s2i.jvm-arguments");
boolean hasS2iJvmAdditionalArguments = properties.contains("quarkus.s2i.jvm-additional-arguments");
boolean hasS2iNativeArguments = properties.contains("quarkus.s2i.native-arguments");
boolean hasS2iJarDirectory = properties.contains("quarkus.s2i.jar-directory");
boolean hasS2iJarFileName = properties.contains("quarkus.s2i.jar-file-name");
Expand All @@ -111,6 +112,7 @@ public static OpenshiftConfig mergeConfig(OpenshiftConfig openshiftConfig, S2iCo
boolean hasOpenshiftBaseJvmImage = properties.contains("quarkus.openshift.base-jvm-image");
boolean hasOpenshiftBaseNativeImage = properties.contains("quarkus.openshift.base-native-image");
boolean hasOpenshiftJvmArguments = properties.contains("quarkus.openshift.jvm-arguments");
boolean hasOpenshiftJvmAdditionalArguments = properties.contains("quarkus.openshift.jvm-additional-arguments");
boolean hasOpenshiftNativeArguments = properties.contains("quarkus.openshift.native-arguments");
boolean hasOpenshiftJarDirectory = properties.contains("quarkus.openshift.jar-directory");
boolean hasOpenshiftJarFileName = properties.contains("quarkus.openshift.jar-file-name");
Expand All @@ -124,6 +126,9 @@ public static OpenshiftConfig mergeConfig(OpenshiftConfig openshiftConfig, S2iCo
: openshiftConfig.baseNativeImage;
result.jvmArguments = hasS2iJvmArguments && !hasOpenshiftJvmArguments ? s2iConfig.jvmArguments
: openshiftConfig.jvmArguments;
result.jvmAdditionalArguments = hasS2iJvmAdditionalArguments && !hasOpenshiftJvmAdditionalArguments
? s2iConfig.jvmAdditionalArguments
: openshiftConfig.jvmAdditionalArguments;
result.nativeArguments = hasS2iNativeArguments && !hasOpenshiftNativeArguments ? s2iConfig.nativeArguments
: openshiftConfig.nativeArguments;
result.jarDirectory = hasS2iJarDirectory && !hasOpenshiftJarDirectory ? Optional.of(s2iConfig.jarDirectory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,17 @@ public static String getDefaultJvmImage(CompiledJavaVersionBuildItem.JavaVersion
public String baseNativeImage;

/**
* Additional JVM arguments to pass to the JVM when starting the application
* The JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem(defaultValue = "-Dquarkus.http.host=0.0.0.0,-Djava.util.logging.manager=org.jboss.logmanager.LogManager")
public List<String> jvmArguments;

/**
* Additional JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem
public Optional<List<String>> jvmAdditionalArguments;

/**
* Additional arguments to pass when starting the native application
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.container.image.s2i.deployment;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -39,11 +40,17 @@ public static String getDefaultJvmImage(CompiledJavaVersionBuildItem.JavaVersion
public String baseNativeImage;

/**
* Additional JVM arguments to pass to the JVM when starting the application
* The JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem(defaultValue = "-Djava.util.logging.manager=org.jboss.logmanager.LogManager")
public List<String> jvmArguments;

/**
* Additional JVM arguments to pass to the JVM when starting the application
*/
@ConfigItem
public Optional<List<String>> jvmAdditionalArguments;

/**
* Additional arguments to pass when starting the native application
*/
Expand Down Expand Up @@ -102,4 +109,13 @@ public boolean hasDefaultBaseNativeImage() {
return baseNativeImage.equals(DEFAULT_BASE_NATIVE_IMAGE);
}

/**
* @return the effective JVM arguments to use by getting the jvmArguments and the jvmAdditionalArguments properties.
*/
public List<String> getEffectiveJvmArguments() {
List<String> effectiveJvmArguments = new ArrayList<>(jvmArguments);
jvmAdditionalArguments.ifPresent(effectiveJvmArguments::addAll);
return effectiveJvmArguments;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ public void s2iRequirementsJvm(S2iConfig s2iConfig,
concatUnixPaths(jarDirectory, "lib"), OPENSHIFT));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getClasspathEnvVar(), classpath, OPENSHIFT));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJvmOptionsEnvVar(),
String.join(" ", s2iConfig.jvmArguments), OPENSHIFT));
String.join(" ", s2iConfig.getEffectiveJvmArguments()), OPENSHIFT));
});

if (!baseImage.isPresent()) {
List<String> cmd = new ArrayList<>();
cmd.add("java");
cmd.addAll(s2iConfig.jvmArguments);
cmd.addAll(s2iConfig.getEffectiveJvmArguments());
cmd.addAll(Arrays.asList("-jar", pathToJar, "-cp", classpath));
commandProducer.produce(KubernetesCommandBuildItem.command(cmd));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.quarkus.it.kubernetes;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
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.openshift.api.model.DeploymentConfig;
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 OpenshiftWithJvmAdditionalArgumentsTest {

@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class))
.setApplicationName("openshift-with-jvm-additional-arguments")
.setApplicationVersion("0.1-SNAPSHOT")
.withConfigurationResource("openshift-with-jvm-additional-arguments.properties")
.setForcedDependencies(Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-openshift", Version.getVersion())));;

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@Test
public void assertGeneratedResources() throws IOException {
Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
List<HasMetadata> openshiftList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("openshift.yml"));

assertThat(openshiftList.get(1)).isInstanceOfSatisfying(DeploymentConfig.class, dc -> {
assertThat(dc.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo("openshift-with-jvm-additional-arguments");
});
assertThat(dc.getSpec()).satisfies(deploymentSpec -> {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getContainers()).singleElement().satisfies(container -> {
assertThat(container.getCommand()).containsExactly("java",
"-Dquarkus.http.host=0.0.0.0",
"-Djava.util.logging.manager=org.jboss.logmanager.LogManager",
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005",
"-jar",
"/deployments/quarkus-run.jar");
});
});
});
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.quarkus.it.kubernetes;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
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.openshift.api.model.DeploymentConfig;
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 OpenshiftWithJvmArgumentsTest {

@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class))
.setApplicationName("openshift-with-jvm-arguments")
.setApplicationVersion("0.1-SNAPSHOT")
.withConfigurationResource("openshift-with-jvm-arguments.properties")
.setForcedDependencies(Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-openshift", Version.getVersion())));;

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@Test
public void assertGeneratedResources() throws IOException {
Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
List<HasMetadata> openshiftList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("openshift.yml"));

assertThat(openshiftList.get(1)).isInstanceOfSatisfying(DeploymentConfig.class, dc -> {
assertThat(dc.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo("openshift-with-jvm-arguments");
});
assertThat(dc.getSpec()).satisfies(deploymentSpec -> {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getContainers()).singleElement().satisfies(container -> {
assertThat(container.getCommand()).containsExactly("java",
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005",
"-jar",
"/deployments/quarkus-run.jar");
});
});
});
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkus.kubernetes.deployment-target=openshift
quarkus.openshift.jvm-additional-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkus.kubernetes.deployment-target=openshift
quarkus.openshift.jvm-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005