From 0c380d37d6ba3d9c952fb00abd3b7e7707810bad Mon Sep 17 00:00:00 2001 From: Jeff Nelson Date: Mon, 9 Mar 2026 21:34:54 -0400 Subject: [PATCH 1/3] Add support for extra jvm options --- concourse-server/conf/concourse.yaml | 7 ++ concourse-server/scripts/concourse | 8 ++- .../startup-script/tests/test_jvm_options.sh | 71 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 one-off-tests/startup-script/tests/test_jvm_options.sh diff --git a/concourse-server/conf/concourse.yaml b/concourse-server/conf/concourse.yaml index 467bc466a..c17de1e37 100644 --- a/concourse-server/conf/concourse.yaml +++ b/concourse-server/conf/concourse.yaml @@ -150,6 +150,13 @@ java_home: # DEFAULT: 9010 jmx_port: +# Extra JVM options to pass to the Concourse Server process. Use this to +# specify Java agents, system properties, garbage collection tuning flags, or +# any other JVM arguments. +# +# DEFAULT: (none) +jvm_options: + # The amount of runtime information logged by the system. The options below # are listed from least to most verbose. In addition to the indicated types # of information, each level also logs the information for each less verbose diff --git a/concourse-server/scripts/concourse b/concourse-server/scripts/concourse index 10b254974..9a1d0348e 100755 --- a/concourse-server/scripts/concourse +++ b/concourse-server/scripts/concourse @@ -211,7 +211,7 @@ CLASSPATH="$APP_HOME/lib/*" configure(){ echo "Loading Concourse Server configuration..." CONFIG_SCRIPT=$BIN_DIR"/config" - CONFIG=$(exec $CONFIG_SCRIPT view -k jmx_port -k remote_debugger_port -k heap_size -k log_level -k force_g1gc -k java_home 2>&1) || { + CONFIG=$(exec $CONFIG_SCRIPT view -k jmx_port -k remote_debugger_port -k heap_size -k log_level -k force_g1gc -k java_home -k jvm_options 2>&1) || { echo "$CONFIG" >&2 exit 1 } @@ -316,6 +316,12 @@ configure(){ " fi + #jvm_options + JVM_OPTIONS_PREF=`echo "$CONFIG" | grep -e '^jvm_options\s*=' | head -n1 | sed 's/^jvm_options\s*=\s*//'` + if [ ! -z "$JVM_OPTIONS_PREF" ]; then + JVMOPTS=$JVMOPTS" "$JVM_OPTIONS_PREF + fi + # Set the $JAVA, etc paths based on the configured or detected java_home JAVA_HOME_PREF=`echo "$CONFIG" | grep -e '^java_home\s*=' | head -n1 | cut -d'=' -f2 | xargs` try_set_java "$JAVA_HOME_PREF" diff --git a/one-off-tests/startup-script/tests/test_jvm_options.sh b/one-off-tests/startup-script/tests/test_jvm_options.sh new file mode 100644 index 000000000..596ad3589 --- /dev/null +++ b/one-off-tests/startup-script/tests/test_jvm_options.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Copyright (c) 2013-2026 Cinchapi Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source /test/lib/assertions.sh + +test_jvm_options_from_config() { + # Set jvm_options in the config file + echo "jvm_options: -Dconcourse.test.jvmopt=fromconfig" >> /opt/concourse-server/conf/concourse.yaml + + # Start server + run_test "cd /opt/concourse-server && ./bin/concourse start" + assertOutputContains "running PID:" + sleep 3 + + # Check that the JVM option is present in the process + run_test "ps aux | grep java | grep -v grep" + assertOutputContains "-Dconcourse.test.jvmopt=fromconfig" + + # Stop server + run_test "cd /opt/concourse-server && ./bin/concourse stop" + assertOutputContains "Stopped Concourse Server" +} + +test_jvm_options_from_env_var() { + # Set jvm_options via environment variable + export CONCOURSE_JVM_OPTIONS="-Dconcourse.test.envopt=fromenv" + + # Start server + run_test "cd /opt/concourse-server && ./bin/concourse start" + assertOutputContains "running PID:" + sleep 3 + + # Check that the JVM option is present in the process + run_test "ps aux | grep java | grep -v grep" + assertOutputContains "-Dconcourse.test.envopt=fromenv" + + # Stop server + run_test "cd /opt/concourse-server && ./bin/concourse stop" + assertOutputContains "Stopped Concourse Server" + + unset CONCOURSE_JVM_OPTIONS +} + +test_server_starts_without_jvm_options() { + # Start server with no jvm_options configured (default) + run_test "cd /opt/concourse-server && ./bin/concourse start" + assertOutputContains "running PID:" + sleep 3 + + # Check that server is running + run_test "cd /opt/concourse-server && ./bin/concourse status" + assertExitStatus 0 + assertOutputContains "is running" + + # Stop server + run_test "cd /opt/concourse-server && ./bin/concourse stop" + assertOutputContains "Stopped Concourse Server" +} From a89278fdb9df687e52acb9edefb0123700172945 Mon Sep 17 00:00:00 2001 From: Jeff Nelson Date: Tue, 10 Mar 2026 08:47:56 -0400 Subject: [PATCH 2/3] extra jvm options chanelong entry and hardening --- CHANGELOG.md | 1 + concourse-server/scripts/concourse | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62eb313c0..4067af303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * **`monitor` CLI tool**: run `concourse monitor` with subcommands (`overview`, `storage`, `operations`, `transactions`, `locks`, `heap`, `gc`, `threads`, `transport`, `compaction`) to view formatted metric dashboards. Use `--json` for machine-readable output, `--watch` for continuous refresh with per-interval delta tracking, `--interval` to control the refresh rate, and `-e` to target a specific environment. * **JMX access**: metrics are exposed as standard MXBeans under `com.cinchapi.concourse:type=Server` (server-wide) and `com.cinchapi.concourse:type=Engine,environment=` (per-environment), allowing integration with any JMX-compatible monitoring tool such as JConsole, VisualVM, or Prometheus via a JMX exporter. * Fixed a bug that caused the `CONTAINS` and `NOT_CONTAINS` search operators to fail when used with navigation keys (e.g., `mother.children contains 'foo'`). +* **Added the `jvm_options` configuration preference** to pass custom JVM arguments (e.g., Java agents, system properties, garbage collection tuning flags) to the Concourse Server process. #### Version 0.12.0 (February 14, 2026) diff --git a/concourse-server/scripts/concourse b/concourse-server/scripts/concourse index 9a1d0348e..0bab10506 100755 --- a/concourse-server/scripts/concourse +++ b/concourse-server/scripts/concourse @@ -99,7 +99,7 @@ BIN_DIR="$APP_HOME/bin" # Allow the JVM to attempt to hook into native thread prioritization if the application # user is root. if [ $(id -u) -eq 0 ]; then - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -XX:ThreadPriorityPolicy=1 " fi @@ -144,7 +144,7 @@ recommended_heap_size(){ echo "$heap_size" } -JVMOPTS=$JVMOPTS" +JVMOPTS="$JVMOPTS -D$APP_HOME_PROPERTY " @@ -152,7 +152,7 @@ if [ "$darwin" = "true" ]; then # Disable MaxFDLimit on macOS to prevent file descriptor limitations. # By default, HotSpot on macOS enforces a built-in OPEN_MAX of 10,240 file descriptors # even when the OS ulimit or kern.maxfilesperproc is set higher. - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -XX:-MaxFDLimit " fi @@ -227,7 +227,7 @@ configure(){ #remote_debugger_port RDP_PREF=`echo "$CONFIG" | grep -e '^remote_debugger_port\s*=\s*[0-9]\{1,\}$' | head -n1 | cut -d'=' -f2 | tr -d ' '` if [ ! -z "$RDP_PREF" ] && [ "$RDP_PREF" -ne "0" ]; then - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$RDP_PREF " @@ -282,7 +282,7 @@ configure(){ CONC_GC_THREADS=$(( PARALLEL_GC_THREADS / 4 )) [ "$CONC_GC_THREADS" -lt 1 ] && CONC_GC_THREADS=1 - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=200 @@ -303,7 +303,7 @@ configure(){ DEBUG=`echo "$CONFIG" | grep -e '^log_level\s*=\s*[Dd][Ee][Bb][Uu][Gg]'` if [ -n "$DEBUG" ] then - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$APP_HOME/log -Xloggc:$APP_HOME/log/gc.log @@ -317,9 +317,11 @@ configure(){ fi #jvm_options + # NOTE: sed is used instead of cut because option values may + # contain '=' characters (e.g., -Dfoo=bar) JVM_OPTIONS_PREF=`echo "$CONFIG" | grep -e '^jvm_options\s*=' | head -n1 | sed 's/^jvm_options\s*=\s*//'` if [ ! -z "$JVM_OPTIONS_PREF" ]; then - JVMOPTS=$JVMOPTS" "$JVM_OPTIONS_PREF + JVMOPTS="$JVMOPTS $JVM_OPTIONS_PREF" fi # Set the $JAVA, etc paths based on the configured or detected java_home @@ -476,7 +478,7 @@ console(){ pid=`getpid` if [ "X$pid" = "X" ] then - JVMOPTS=$JVMOPTS" + JVMOPTS="$JVMOPTS -Dcom.cinchapi.concourse.server.logging.console=true " echo "Running Concourse Server..." From 3dc7984ac2918bf96c672d2d760b5907193bdca1 Mon Sep 17 00:00:00 2001 From: Jeff Nelson Date: Tue, 10 Mar 2026 09:06:41 -0400 Subject: [PATCH 3/3] formatting of comments --- concourse-server/scripts/concourse | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/concourse-server/scripts/concourse b/concourse-server/scripts/concourse index 0bab10506..7ce84f5d2 100755 --- a/concourse-server/scripts/concourse +++ b/concourse-server/scripts/concourse @@ -316,9 +316,8 @@ configure(){ " fi - #jvm_options - # NOTE: sed is used instead of cut because option values may - # contain '=' characters (e.g., -Dfoo=bar) + #jvm_options: sed is used to parse here (instead of cut) because option values + # may contain '=' characters (e.g., -Dfoo=bar) JVM_OPTIONS_PREF=`echo "$CONFIG" | grep -e '^jvm_options\s*=' | head -n1 | sed 's/^jvm_options\s*=\s*//'` if [ ! -z "$JVM_OPTIONS_PREF" ]; then JVMOPTS="$JVMOPTS $JVM_OPTIONS_PREF"