Skip to content
Draft
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
8 changes: 8 additions & 0 deletions changelog/unreleased/SOLR-14361-SIP-6-Solr-start-jar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
title: New Bootstrap module. Solr now owns the bootstrap and starts Jetty embedded (SIP-6)
type: added
authors:
- name: Jan Høydahl
url: https://home.apache.org/phonebook.html?uid=janhoy
links:
- name: SOLR-14361
url: https://issues.apache.org/jira/browse/SOLR-14361
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ include "solr:solrj-zookeeper"
include "solr:solrj-streaming"
include "solr:core"
include "solr:cross-dc-manager"
include "solr:bootstrap"
include "solr:server"
include "solr:modules:analysis-extras"
include "solr:modules:clustering"
Expand Down
92 changes: 29 additions & 63 deletions solr/bin/solr
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ fi

# Select HTTP OR HTTPS related configurations
SOLR_URL_SCHEME=http
SOLR_JETTY_CONFIG=()
SOLR_SSL_OPTS=""

if [ -z "${SOLR_SSL_ENABLED:-}" ]; then
Expand All @@ -210,45 +209,36 @@ if [ -z "${SOLR_SSL_ENABLED:-}" ]; then
fi
fi
if [ "$SOLR_SSL_ENABLED" == "true" ]; then
SOLR_JETTY_CONFIG+=("--module=https" "--lib=$DEFAULT_SERVER_DIR/solr-webapp/webapp/WEB-INF/lib/*")
# SIP-6: Server-side SSL is configured in Java (SslCertificateGenerator, ServerConfiguration)
# No longer using: --module=https, --module=ssl-reload, -Dsolr.jetty.keystore, etc.
if [ "${SOLR_SSL_RELOAD_ENABLED:-true}" == "true" ]; then
SOLR_JETTY_CONFIG+=("--module=ssl-reload")
SOLR_SSL_OPTS+=" -Dsolr.keystore.reload.enabled=true"
# Also set for server process (for HttpShardHandlerFactory client SSL reload)
SOLR_OPTS_INTERNAL="${SOLR_OPTS_INTERNAL:-} -Dsolr.keystore.reload.enabled=true"
fi
SOLR_URL_SCHEME=https
if [ -n "$SOLR_SSL_KEY_STORE" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
if [ "${SOLR_SSL_RELOAD_ENABLED:-true}" == "true" ] && [ "${SOLR_SECURITY_MANAGER_ENABLED:-true}" == "true" ]; then
# In this case we need to allow reads from the parent directory of the keystore
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystoreParentPath=$SOLR_SSL_KEY_STORE/.."
fi
fi
# Note: SOLR_SSL_KEY_STORE and SOLR_SSL_TRUST_STORE are now read as env vars by Java,
# not passed as -Dsolr.jetty.* system properties
if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
export SOLR_SSL_KEY_STORE_PASSWORD=$SOLR_SSL_KEY_STORE_PASSWORD
fi
if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.type=$SOLR_SSL_KEY_STORE_TYPE"
fi

if [ -n "$SOLR_SSL_TRUST_STORE" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore=$SOLR_SSL_TRUST_STORE"
fi
if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
export SOLR_SSL_TRUST_STORE_PASSWORD=$SOLR_SSL_TRUST_STORE_PASSWORD
fi
if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.type=$SOLR_SSL_TRUST_STORE_TYPE"
fi

if [ "${SOLR_SSL_CLIENT_HOSTNAME_VERIFICATION:true}" == "true" ] ; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.ssl.verifyClientHostName=HTTPS"
SOLR_OPTS_INTERNAL="${SOLR_OPTS_INTERNAL:-} -Dsolr.jetty.ssl.verifyClientHostName=HTTPS"
fi

if [ -n "$SOLR_SSL_NEED_CLIENT_AUTH" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.ssl.need.client.auth.enabled=$SOLR_SSL_NEED_CLIENT_AUTH"
SOLR_OPTS_INTERNAL="${SOLR_OPTS_INTERNAL:-} -Dsolr.jetty.ssl.need.client.auth.enabled=$SOLR_SSL_NEED_CLIENT_AUTH"
fi
if [ -n "$SOLR_SSL_WANT_CLIENT_AUTH" ]; then
SOLR_SSL_OPTS+=" -Dsolr.jetty.ssl.want.client.auth.enabled=$SOLR_SSL_WANT_CLIENT_AUTH"
SOLR_OPTS_INTERNAL="${SOLR_OPTS_INTERNAL:-} -Dsolr.jetty.ssl.want.client.auth.enabled=$SOLR_SSL_WANT_CLIENT_AUTH"
fi

if [ -n "$SOLR_SSL_CLIENT_KEY_STORE" ]; then
Expand All @@ -275,6 +265,7 @@ if [ "$SOLR_SSL_ENABLED" == "true" ]; then

if [ -n "$SOLR_SSL_CHECK_PEER_NAME" ]; then
SOLR_SSL_OPTS+=" -Dsolr.ssl.check.peer.name.enabled=$SOLR_SSL_CHECK_PEER_NAME -Dsolr.jetty.ssl.sni.host.check.enabled=$SOLR_SSL_CHECK_PEER_NAME"
SOLR_OPTS_INTERNAL="${SOLR_OPTS_INTERNAL:-} -Dsolr.ssl.check.peer.name.enabled=$SOLR_SSL_CHECK_PEER_NAME -Dsolr.jetty.ssl.sni.host.check.enabled=$SOLR_SSL_CHECK_PEER_NAME"
fi

if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE" ]; then
Expand All @@ -295,36 +286,9 @@ if [ "$SOLR_SSL_ENABLED" == "true" ]; then
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_TRUST_STORE_TYPE"
fi
fi
else
SOLR_JETTY_CONFIG+=("--module=http")
fi
export SOLR_URL_SCHEME

# Gracefully wait for existing requests on shutdown
if [ "${SOLR_JETTY_GRACEFUL:-false}" == "true" ]; then
SOLR_JETTY_CONFIG+=("--module=graceful")
fi

# Requestlog options
if [ "${SOLR_LOGS_REQUESTLOG_ENABLED:-true}" == "true" ]; then
SOLR_JETTY_CONFIG+=("--module=requestlog")
fi

# Jetty gzip module enabled by default
if [ "${SOLR_GZIP_ENABLED:-true}" == "true" ]; then
SOLR_JETTY_CONFIG+=("--module=gzip")
fi

# Jetty configuration for new Admin UI
if [ "${SOLR_UI_ENABLED:-true}" == "false" ] ||
[ "${SOLR_UI_EXPERIMENTAL_ENABLED:-true}" == "false" ]; then
# Do not enable new Solr UI
echo -e "New Solr UI not enabled"
else
# Enable new Admin UI
SOLR_JETTY_CONFIG+=("--module=new-ui")
fi

# Authentication options
if [ -z "${SOLR_AUTH_TYPE:-}" ] && [ -n "${SOLR_AUTHENTICATION_OPTS:-}" ]; then
echo "WARNING: SOLR_AUTHENTICATION_OPTS environment variable configured without associated SOLR_AUTH_TYPE variable"
Expand Down Expand Up @@ -478,7 +442,7 @@ function solr_pid_by_port() {
# extract the value of the -Dsolr.port.listen parameter from a running Solr process
function solr_port_listen() {
SOLR_PID="$1"
SOLR_PROC=$(ps -fww -p "$SOLR_PID" | grep start\.jar | grep solr\.port\.listen)
SOLR_PROC=$(ps -fww -p "$SOLR_PID" | grep solr-start.jar | grep solr\.port\.listen)
IFS=' ' read -a proc_args <<< "$SOLR_PROC"
for arg in "${proc_args[@]}"
do
Expand Down Expand Up @@ -984,7 +948,7 @@ if [[ "$SCRIPT_CMD" == "start" ]]; then

if [ -z "${SOLR_PID:-}" ]; then
# not found using the pid file ... but use ps to ensure not found
SOLR_PID=$(ps auxww | grep start\.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
SOLR_PID=$(ps auxww | grep solr-start.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
fi

if [ -n "${SOLR_PID:-}" ]; then
Expand All @@ -997,7 +961,7 @@ else
SOLR_PID=$(solr_pid_by_port "$SOLR_PORT_LISTEN")
if [ -z "$SOLR_PID" ]; then
# not found using the pid file ... but use ps to ensure not found
SOLR_PID=$(ps auxww | grep start\.jar | awk "/\-Djetty\.port=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
SOLR_PID=$(ps auxww | grep solr-start.jar | awk "/\-Djetty\.port=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
fi
if [ "$SOLR_PID" != "" ]; then
stop_solr "$SOLR_SERVER_DIR" "$SOLR_PORT_LISTEN" "$STOP_KEY" "$SOLR_PID"
Expand All @@ -1024,9 +988,12 @@ fi
# so that we can write logs for examples to $SOLR_HOME/../logs
: "${SOLR_LOGS_DIR:="$SOLR_SERVER_DIR/logs"}"
EXAMPLE_DIR="$SOLR_TIP/example"

# Set default log4j configuration
LOG4J_PROPS="$DEFAULT_SERVER_DIR/resources/log4j2.xml"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is still one of those "chicken/egg" things that you can't configure in the bootstrap?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, guess it needs to be set fairly early, but who knows, could probably be set programatically in main method as well...


# if SOLR_HOME is inside of EXAMPLE_DIR
if [ "${SOLR_HOME:0:${#EXAMPLE_DIR}}" = "$EXAMPLE_DIR" ]; then
LOG4J_PROPS="$DEFAULT_SERVER_DIR/resources/log4j2.xml"
SOLR_LOGS_DIR="$SOLR_HOME/../logs"
fi

Expand Down Expand Up @@ -1210,12 +1177,8 @@ function start_solr() {
fi


# If SSL-related system props are set, add them to SCRIPT_SOLR_OPTS
if [ "$SOLR_SSL_ENABLED" == "true" ]; then
# If using SSL and solr.jetty.https.port not set explicitly, use the solr.port.listen
SSL_PORT_PROP="-Dsolr.jetty.https.port=$SOLR_PORT_LISTEN"
SCRIPT_SOLR_OPTS+=($SOLR_SSL_OPTS "$SSL_PORT_PROP")
fi
# SIP-6: SSL configuration is now handled by ServerConfiguration and ConnectorFactory in Java
# No need to pass SSL properties explicitly - they're read from environment variables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose eventually we can remove these comments, but nice to see now in draft mode!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, this is just POC filler.

If we go this direction, it will open up for porting most of the start script to Java, except the JVM level props like heap, gc etc.


# If authentication system props are set, add them to SCRIPT_SOLR_OPTS
if [ -n "$AUTHC_OPTS" ]; then
Expand Down Expand Up @@ -1283,8 +1246,8 @@ function start_solr() {
# need to launch solr from the server dir
cd "$SOLR_SERVER_DIR" || (echo -e "\nCd to SOLR_SERVER_DIR failed" && exit 1)

if [ ! -e "$SOLR_SERVER_DIR/start.jar" ]; then
echo -e "\nERROR: start.jar file not found in $SOLR_SERVER_DIR!\nPlease check your --server-dir parameter to set the correct Solr server directory.\n"
if [ ! -e "$SOLR_SERVER_DIR/solr-start.jar" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solr.jar ??? versus solr-start.jar??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the original SIP text proposes solr.jar here. But I got the idea that if we use solr-start.jar, it will still match a grep for start.jar when listing processes :) Really, since the module name is bootstrap it will probably be called solr-bootstrap-11.0.0.jar in maven. It's just a name, noone will call it manually except those who write their own daemon wrappers or something.

echo -e "\nERROR: solr-start.jar file not found in $SOLR_SERVER_DIR!\nPlease check your --server-dir parameter to set the correct Solr server directory.\n"
exit 1
fi

Expand All @@ -1304,7 +1267,7 @@ function start_solr() {
# '+CrashOnOutOfMemoryError' ensures that Solr crashes whenever
# OOME is thrown. Program operation after OOME is unpredictable.
"-XX:+CrashOnOutOfMemoryError" "-XX:ErrorFile=${SOLR_LOGS_DIR}/jvm_crash_%p.log" \
"-Djetty.home=$SOLR_SERVER_DIR" "-Dsolr.solr.home=$SOLR_HOME" "-Dsolr.install.dir=$SOLR_TIP" "-Dsolr.install.symDir=$SOLR_TIP_SYM" \
"-Dsolr.jetty.home=$SOLR_SERVER_DIR" "-Dsolr.solr.home=$SOLR_HOME" "-Dsolr.install.dir=$SOLR_TIP" "-Dsolr.install.symDir=$SOLR_TIP_SYM" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance that this is an opportunity to rethink all these various flavours of path? Could we just have a single value, and derive everything esle? Do we really need control over these? Also, if we kept them as env variables, couldn't you just read them IN as part of the java code? I find all these various settings quite confusing to keep straight. Last thought in my long run-opn thought... I would love to have the production.properties or production.yml type file define all these, and just pass that into solr-start.jar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, probably lots of cleanup to be done there. But in this POC my goal is to prove that it is not a huge change to do this thing, and the startup command line is almost the same. I just normalized some sys props here.

"${LOG4J_CONFIG[@]}" "${SCRIPT_SOLR_OPTS[@]}" "${SECURITY_MANAGER_OPTS[@]}" "${SOLR_OPTS[@]}")

mk_writable_dir "$SOLR_LOGS_DIR" "Logs"
Expand All @@ -1320,12 +1283,15 @@ function start_solr() {

if [ "$run_in_foreground" == "true" ]; then
# shellcheck disable=SC2086
exec "$JAVA" "${SOLR_START_OPTS[@]}" $SOLR_ADDL_ARGS -jar start.jar "${SOLR_JETTY_CONFIG[@]}" $SOLR_JETTY_ADDL_CONFIG
exec "$JAVA" "${SOLR_START_OPTS[@]}" $SOLR_ADDL_ARGS \
-cp "solr-start.jar:lib/*:lib/ext/*:solr-webapp/webapp/WEB-INF/lib/*" \
org.apache.solr.bootstrap.SolrStart
else
# run Solr in the background
# shellcheck disable=SC2086
nohup "$JAVA" "${SOLR_START_OPTS[@]}" $SOLR_ADDL_ARGS -Dsolr.log.muteconsole \
-jar start.jar "${SOLR_JETTY_CONFIG[@]}" $SOLR_JETTY_ADDL_CONFIG \
-cp "solr-start.jar:lib/*:lib/ext/*:solr-webapp/webapp/WEB-INF/lib/*" \
org.apache.solr.bootstrap.SolrStart \
1>"$SOLR_LOGS_DIR/solr-$SOLR_PORT_LISTEN-console.log" 2>&1 & echo $! > "$SOLR_PID_DIR/solr-$SOLR_PORT_LISTEN.pid"

# Check and warn about low entropy on Linux systems
Expand Down Expand Up @@ -1370,7 +1336,7 @@ function start_solr() {
exit # subshell!
fi
else
SOLR_PID=$(ps auxww | grep start\.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
SOLR_PID=$(ps auxww | grep solr-start.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
echo -e "\nStarted Solr server on port $SOLR_PORT_LISTEN (pid=$SOLR_PID). Happy searching!\n"
exit # subshell!
fi
Expand All @@ -1379,7 +1345,7 @@ function start_solr() {
else
echo -e "NOTE: Please install lsof as this script needs it to determine if Solr is listening on port $SOLR_PORT_LISTEN."
sleep 10
SOLR_PID=$(ps auxww | grep start\.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
SOLR_PID=$(ps auxww | grep solr-start.jar | awk "/\-Dsolr\.port\.listen=$SOLR_PORT_LISTEN/"' {print $2}' | sort -r)
echo -e "\nStarted Solr server on port $SOLR_PORT_LISTEN (pid=$SOLR_PID). Happy searching!\n"
return;
fi
Expand Down
Loading
Loading