diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e374df4ab0a..7ba609e2d33 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -242,13 +242,16 @@ New Features * SOLR-6787: API to manage blobs in Solr (Noble Paul) -* SOLR-6801: Load RequestHandler from blob store (Noble Paul) +* SOLR-6801: Load RequestHandler from blob store (Noble Paul) * SOLR-1632: Support Distributed IDF (Andrzej Bialecki, Mark Miller, Yonik Seeley, Robert Muir, Markus Jelsma, Vitaliy Zhovtyuk, Anshum Gupta) * SOLR-6729: createNodeSet.shuffle=(true|false) support for /admin/collections?action=CREATE. (Christine Poerschke, Ramkumar Aiyengar via Mark Miller) + +* SOLR-6851: Scripts to support installing and running Solr as a service on Linux + (Timothy Potter, Hossman, Steve Rowe) Bug Fixes ---------------------- diff --git a/solr/bin/init.d/solr b/solr/bin/init.d/solr new file mode 100644 index 00000000000..5fb91d37384 --- /dev/null +++ b/solr/bin/init.d/solr @@ -0,0 +1,78 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +### BEGIN INIT INFO +# Provides: solr +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Description: Controls Apache Solr as a Service +### END INIT INFO + +# Example of a very simple *nix init script that delegates commands to the bin/solr script +# Typical usage is to do: +# +# cp bin/init.d/solr /etc/init.d/solr +# chmod 755 /etc/init.d/solr +# chown root:root /etc/init.d/solr +# update-rc.d solr defaults +# update-rc.d solr enable + +# Where you extracted the Solr distribution bundle +SOLR_INSTALL_DIR=/opt/solr + +if [ ! -d "$SOLR_INSTALL_DIR" ]; then + echo "$SOLR_INSTALL_DIR not found! Please check the SOLR_INSTALL_DIR setting in your $0 script." + exit 1 +fi + +# Path to an include file that defines environment specific settings to override default +# variables used by the bin/solr script. It's highly recommended to define this script so +# that you can keep the Solr binary files separated from live files (pid, logs, index data, etc) +# see bin/solr.in.sh for an example +SOLR_ENV=/var/solr/solr.in.sh + +if [ ! -f "$SOLR_ENV" ]; then + echo "$SOLR_ENV not found! Please check the SOLR_ENV setting in your $0 script." + exit 1 +fi + +# Specify the user to run Solr as; if not set, then Solr will run as root. +# Running Solr as root is not recommended for production environments +RUNAS=solr + +# verify the specified run as user exists +runas_uid=`id -u $RUNAS` +if [ $? -ne 0 ]; then + echo "User $RUNAS not found! Please create the $RUNAS user before running this script." + exit 1 +fi + +case "$1" in + start|stop|restart|status) + SOLR_CMD=$1 + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit +esac + +if [ -n "$RUNAS" ]; then + su -c "SOLR_INCLUDE=$SOLR_ENV $SOLR_INSTALL_DIR/bin/solr $SOLR_CMD" - $RUNAS +else + SOLR_INCLUDE=$SOLR_ENV $SOLR_INSTALL_DIR/bin/solr $SOLR_CMD +fi diff --git a/solr/bin/install_solr_service.sh b/solr/bin/install_solr_service.sh new file mode 100644 index 00000000000..8a6d91b9c3d --- /dev/null +++ b/solr/bin/install_solr_service.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +if [[ $EUID -ne 0 ]]; then + echo -e "\nERROR: This script must be run as root\n" 1>&2 + exit 1 +fi + +print_usage() { + ERROR_MSG="$1" + + if [ "$ERROR_MSG" != "" ]; then + echo -e "\nERROR: $ERROR_MSG\n" 1>&2 + fi + + echo "" + echo "Usage: install_solr_service.sh path_to_solr_distribution_archive OPTIONS" + echo "" + echo " The first argument to the script must be a path to a Solr distribution archive, such as solr-5.0.0.tgz" + echo " (only .tgz or .zip are supported formats for the archive)" + echo "" + echo " Supported OPTIONS include:" + echo "" + echo " -d Directory for live / writable Solr files, such as logs, pid files, and index data; defaults to /var/solr" + echo "" + echo " -i Directory to extract the Solr installation archive; defaults to /opt/" + echo " The specified path must exist prior to using this script." + echo "" + echo " -p Port Solr should bind to; default is 8983" + echo "" + echo " -s Service name; defaults to solr" + echo "" + echo " -u User to own the Solr files and run the Solr process as; defaults to solr" + echo " This script will create the specified user account if it does not exist." + echo "" + echo " NOTE: Must be run as the root user" + echo "" +} # end print_usage + +if [ -f "/proc/version" ]; then + proc_version=`cat /proc/version` +else + proc_version=`uname -a` +fi + +if [[ $proc_version == *"Debian"* ]]; then + distro=Debian +elif [[ $proc_version == *"Red Hat"* ]]; then + distro=RedHat +elif [[ $proc_version == *"Ubuntu"* ]]; then + distro=Ubuntu +elif [[ $proc_version == *"SUSE"* ]]; then + distro=SUSE +else + echo -e "\nERROR: Your Linux distribution ($proc_version) not supported by this script!\nYou'll need to setup Solr as a service manually using the documentation provided in the Solr Reference Guide.\n" 1>&2 + exit 1 +fi + +if [ -z "$1" ]; then + print_usage "Must specify the path to the Solr installation archive, such as solr-5.0.0.tgz" + exit 1 +fi + +SOLR_ARCHIVE=$1 +if [ ! -f "$SOLR_ARCHIVE" ]; then + print_usage "Specified Solr installation archive $SOLR_ARCHIVE not found!" + exit 1 +fi + +# strip off path info +SOLR_INSTALL_FILE=${SOLR_ARCHIVE##*/} +is_tar=true +if [ ${SOLR_INSTALL_FILE: -4} == ".tgz" ]; then + SOLR_DIR=${SOLR_INSTALL_FILE:0:-4} +elif [ ${SOLR_INSTALL_FILE: -4} == ".zip" ]; then + SOLR_DIR=${SOLR_INSTALL_FILE:0:-4} + is_tar=false +else + print_usage "Solr installation archive $SOLR_ARCHIVE is invalid, expected a .tgz or .zip file!" + exit 1 +fi + +if [ $# -gt 1 ]; then + shift + while true; do + case $1 in + -i) + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then + print_usage "Directory path is required when using the $1 option!" + exit 1 + fi + SOLR_EXTRACT_DIR=$2 + shift 2 + ;; + -d) + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then + print_usage "Directory path is required when using the $1 option!" + exit 1 + fi + SOLR_VAR_DIR="$2" + shift 2 + ;; + -u) + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then + print_usage "Username is required when using the $1 option!" + exit 1 + fi + SOLR_USER="$2" + shift 2 + ;; + -s) + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then + print_usage "Service name is required when using the $1 option!" + exit 1 + fi + SOLR_SERVICE="$2" + shift 2 + ;; + -p) + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then + print_usage "Port is required when using the $1 option!" + exit 1 + fi + SOLR_PORT="$2" + shift 2 + ;; + -help|-usage) + print_usage "" + exit 0 + ;; + --) + shift + break + ;; + *) + if [ "$1" != "" ]; then + print_usage "Unrecognized or misplaced argument: $1!" + exit 1 + else + break # out-of-args, stop looping + fi + ;; + esac + done +fi + +if [ -z "$SOLR_EXTRACT_DIR" ]; then + SOLR_EXTRACT_DIR=/opt +fi + +if [ ! -d "$SOLR_EXTRACT_DIR" ]; then + print_usage "Installation directory $SOLR_EXTRACT_DIR not found! Please create it before running this script." + exit 1 +fi + +if [ -z "$SOLR_VAR_DIR" ]; then + SOLR_VAR_DIR=/var/solr +fi + +if [ -z "$SOLR_USER" ]; then + SOLR_USER=solr +fi + +if [ -z "$SOLR_SERVICE" ]; then + SOLR_SERVICE=solr +fi + +if [ -z "$SOLR_PORT" ]; then + SOLR_PORT=8983 +fi + +if [ -f "/etc/init.d/$SOLR_SERVICE" ]; then + echo -e "\nERROR: /etc/init.d/$SOLR_SERVICE already exists! Perhaps solr is already setup as a service on this host?\n" 1>&2 + exit 1 +fi + +if [ -e "$SOLR_EXTRACT_DIR/$SOLR_SERVICE" ]; then + print_usage "$SOLR_EXTRACT_DIR/$SOLR_SERVICE already exists! Please move this directory / link or choose a different service name using the -s option." + exit 1 +fi + +solr_uid=`id -u $SOLR_USER` +if [ $? -ne 0 ]; then + echo "Creating new user: $SOLR_USER" + if [ "$distro" == "RedHat" ]; then + adduser $SOLR_USER + elif [ "$distro" == "SUSE" ]; then + useradd -m $SOLR_USER + else + adduser --system --shell /bin/bash --group --disabled-password --home /home/$SOLR_USER $SOLR_USER + fi +fi + +SOLR_INSTALL_DIR=$SOLR_EXTRACT_DIR/$SOLR_DIR +if [ ! -d "$SOLR_INSTALL_DIR" ]; then + + echo "Extracting $SOLR_ARCHIVE to $SOLR_EXTRACT_DIR" + + if $is_tar ; then + tar zxf $SOLR_ARCHIVE -C $SOLR_EXTRACT_DIR + else + unzip -q $SOLR_ARCHIVE -d $SOLR_EXTRACT_DIR + fi + + if [ ! -d "$SOLR_INSTALL_DIR" ]; then + echo -e "\nERROR: Expected directory $SOLR_INSTALL_DIR not found after extracting $SOLR_ARCHIVE ... script fails.\n" 1>&2 + exit 1 + fi + + chown -R $SOLR_USER: $SOLR_INSTALL_DIR +else + echo -e "\nWARNING: $SOLR_INSTALL_DIR already exists! Skipping extract ...\n" +fi + +# create a symlink for easier scripting +ln -s $SOLR_INSTALL_DIR $SOLR_EXTRACT_DIR/$SOLR_SERVICE +chown -h $SOLR_USER: $SOLR_EXTRACT_DIR/$SOLR_SERVICE + +mkdir -p $SOLR_VAR_DIR/data +mkdir -p $SOLR_VAR_DIR/logs +cp $SOLR_INSTALL_DIR/server/solr/solr.xml $SOLR_VAR_DIR/data/ +cp $SOLR_INSTALL_DIR/bin/solr.in.sh $SOLR_VAR_DIR/ +cp $SOLR_INSTALL_DIR/server/resources/log4j.properties $SOLR_VAR_DIR/log4j.properties +sed_expr="s#solr.log=.*#solr.log=\${solr.solr.home}/../logs#" +sed -i -e "$sed_expr" $SOLR_VAR_DIR/log4j.properties +chown -R $SOLR_USER: $SOLR_VAR_DIR + +echo "SOLR_PID_DIR=$SOLR_VAR_DIR +SOLR_HOME=$SOLR_VAR_DIR/data +LOG4J_PROPS=$SOLR_VAR_DIR/log4j.properties +SOLR_LOGS_DIR=$SOLR_VAR_DIR/logs +SOLR_PORT=$SOLR_PORT +" >> $SOLR_VAR_DIR/solr.in.sh + +echo "Creating /etc/init.d/$SOLR_SERVICE script ..." +cp $SOLR_INSTALL_DIR/bin/init.d/solr /etc/init.d/$SOLR_SERVICE +chmod 744 /etc/init.d/$SOLR_SERVICE +chown root:root /etc/init.d/$SOLR_SERVICE + +# do some basic variable substitution on the init.d script +sed_expr1="s#SOLR_INSTALL_DIR=.*#SOLR_INSTALL_DIR=$SOLR_EXTRACT_DIR/$SOLR_SERVICE#" +sed_expr2="s#SOLR_ENV=.*#SOLR_ENV=$SOLR_VAR_DIR/solr.in.sh#" +sed_expr3="s#RUNAS=.*#RUNAS=$SOLR_USER#" +sed_expr4="s#Provides:.*#Provides: $SOLR_SERVICE#" +sed -i -e "$sed_expr1" -e "$sed_expr2" -e "$sed_expr3" -e "$sed_expr4" /etc/init.d/$SOLR_SERVICE + +if [[ "$distro" == "RedHat" || "$distro" == "SUSE" ]]; then + chkconfig $SOLR_SERVICE on +else + update-rc.d $SOLR_SERVICE defaults +fi + +service $SOLR_SERVICE start +sleep 5 +service $SOLR_SERVICE status + +echo "Service $SOLR_SERVICE installed." diff --git a/solr/bin/oom_solr.sh b/solr/bin/oom_solr.sh index 705280324c9..5ecba6bc301 100755 --- a/solr/bin/oom_solr.sh +++ b/solr/bin/oom_solr.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with @@ -16,14 +16,15 @@ # limitations under the License. SOLR_PORT=$1 -SOLR_PID=`ps waux | grep start.jar | grep $SOLR_PORT | grep -v grep | awk '{print $2}' | sort -r` -if [ "$SOLR_PID" == "" ]; then +SOLR_LOGS_DIR=$2 +SOLR_PID=`ps auxww | grep start.jar | grep $SOLR_PORT | grep -v grep | awk '{print $2}' | sort -r` +if [ -z "$SOLR_PID" ]; then echo "Couldn't find Solr process running on port $SOLR_PORT!" exit fi -NOW=$(date +"%F%T") +NOW=$(date +"%F_%H_%M_%S") ( echo "Running OOM killer script for process $SOLR_PID for Solr on port $SOLR_PORT" kill -9 $SOLR_PID echo "Killed process $SOLR_PID" -) | tee solr_oom_killer-$SOLR_PORT-$NOW.log +) | tee $SOLR_LOGS_DIR/solr_oom_killer-$SOLR_PORT-$NOW.log diff --git a/solr/bin/solr b/solr/bin/solr index e6977f199ee..41c8315eaac 100755 --- a/solr/bin/solr +++ b/solr/bin/solr @@ -20,12 +20,13 @@ # Use solr -help to see available command-line options. In addition # to passing command-line options, this script looks for an include # file named solr.in.sh to set environment variables. Specifically, -# the following locations are searched: +# the following locations are searched in this order: # # ./ # $HOME/.solr.in.sh # /usr/share/solr # /usr/local/share/solr +# /var/solr/ # /opt/solr # # Another option is to specify the full path to the include file in the @@ -74,23 +75,28 @@ SOLR_TIP=`cd "$SOLR_TIP"; pwd` DEFAULT_SERVER_DIR=$SOLR_TIP/server # If an include wasn't specified in the environment, then search for one... -if [ "x$SOLR_INCLUDE" == "x" ]; then - # Locations (in order) to use when searching for an include file. - for include in "`dirname "$0"`/solr.in.sh" \ - "$HOME/.solr.in.sh" \ - /usr/share/solr/solr.in.sh \ - /usr/local/share/solr/solr.in.sh \ - /opt/solr/solr.in.sh; do - if [ -r "$include" ]; then - . "$include" - break - fi - done +if [ -z "$SOLR_INCLUDE" ]; then + # Locations (in order) to use when searching for an include file. + for include in "`dirname "$0"`/solr.in.sh" \ + "$HOME/.solr.in.sh" \ + /usr/share/solr/solr.in.sh \ + /usr/local/share/solr/solr.in.sh \ + /var/solr/solr.in.sh \ + /opt/solr/solr.in.sh; do + if [ -r "$include" ]; then + . "$include" + break + fi + done elif [ -r "$SOLR_INCLUDE" ]; then - . "$SOLR_INCLUDE" + . "$SOLR_INCLUDE" fi -if [ "$SOLR_JAVA_HOME" != "" ]; then +if [ -z "$SOLR_PID_DIR" ]; then + SOLR_PID_DIR=$SOLR_TIP/bin +fi + +if [ -n "$SOLR_JAVA_HOME" ]; then JAVA=$SOLR_JAVA_HOME/bin/java elif [ -n "$JAVA_HOME" ]; then for java in "$JAVA_HOME"/bin/amd64/java "$JAVA_HOME"/bin/java; do @@ -114,10 +120,10 @@ function print_usage() { echo -e "\nERROR: $ERROR_MSG\n" fi - if [ "$CMD" == "" ]; then + if [ -z "$CMD" ]; then echo "" echo "Usage: solr COMMAND OPTIONS" - echo " where COMMAND is one of: start, stop, restart, healthcheck, create_core, create_collection" + echo " where COMMAND is one of: start, stop, restart, status, healthcheck, create_core, create_collection" echo "" echo " Standalone server example (start Solr running in the background on port 8984):" echo "" @@ -158,7 +164,7 @@ function print_usage() { echo " -s Sets the solr.solr.home system property; Solr will create core directories under" echo " this directory. This allows you to run multiple Solr instances on the same host" echo " while reusing the same server directory set using the -d parameter. If set, the" - echo " specified directory should contain a solr.xml file. The default value is example/solr." + echo " specified directory should contain a solr.xml file. The default value is server/solr." echo " This parameter is ignored when running examples (-e), as the solr.solr.home depends" echo " on which example is run." echo "" @@ -187,7 +193,7 @@ function print_usage() { echo "" echo " -all Find and stop all running Solr servers on this host" echo "" - echo " NOTE: To see if any Solr servers are running, do: solr -i" + echo " NOTE: To see if any Solr servers are running, do: solr status" echo "" elif [ "$CMD" == "healthcheck" ]; then echo "" @@ -197,6 +203,12 @@ function print_usage() { echo "" echo " -z ZooKeeper connection string; default is localhost:9983" echo "" + elif [ "$CMD" == "status" ]; then + echo "" + echo "Usage: solr status" + echo "" + echo " NOTE: This command will show the status of all running Solr servers" + echo "" elif [ "$CMD" == "create_core" ]; then echo "" echo "Usage: solr create_core [-n name] [-c configset]" @@ -232,12 +244,11 @@ function print_usage() { } # end print_usage # used to show the script is still alive when waiting on work to complete -spinner() -{ +function spinner() { local pid=$1 local delay=0.5 local spinstr='|/-\' - while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do + while [ "$(ps aux | awk '{print $2}' | grep $pid)" ]; do local temp=${spinstr#?} printf " [%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} @@ -250,8 +261,8 @@ spinner() # given a port, find the pid for a Solr process function solr_pid_by_port() { THE_PORT="$1" - if [ -e "$SOLR_TIP/bin/solr-$THE_PORT.pid" ]; then - PID=`cat $SOLR_TIP/bin/solr-$THE_PORT.pid` + if [ -e "$SOLR_PID_DIR/solr-$THE_PORT.pid" ]; then + PID=`cat $SOLR_PID_DIR/solr-$THE_PORT.pid` CHECK_PID=`ps auxww | awk '{print $2}' | grep $PID | sort -r | tr -d ' '` if [ "$CHECK_PID" != "" ]; then local solrPID=$PID @@ -294,26 +305,27 @@ function run_tool() { # get information about any Solr nodes running on this host function get_info() { # first, see if Solr is running - numSolrs=`find $SOLR_TIP/bin -name "solr-*.pid" -type f | wc -l | tr -d ' '` + numSolrs=`find $SOLR_PID_DIR -name "solr-*.pid" -type f | wc -l | tr -d ' '` if [ "$numSolrs" != "0" ]; then echo -e "\nFound $numSolrs Solr nodes: " - for PIDF in `find $SOLR_TIP/bin -name "solr-*.pid" -type f` + for PIDF in `find $SOLR_PID_DIR -name "solr-*.pid" -type f` do ID=`cat $PIDF` port=`jetty_port "$ID"` if [ "$port" != "" ]; then - echo "" - echo "Solr process $ID running on port $port" + echo -e "\nSolr process $ID running on port $port" run_tool status -solr http://localhost:$port/solr echo "" - fi + else + echo -e "\nSolr process $ID from $PIDF not found." + fi done else # no pid files but check using ps just to be sure - numSolrs=`ps auxww | grep java | grep start.jar | wc -l | sed -e 's/^[ \t]*//'` + numSolrs=`ps auxww | grep start.jar | grep solr.solr.home | grep -v grep | wc -l | sed -e 's/^[ \t]*//'` if [ "$numSolrs" != "0" ]; then echo -e "\nFound $numSolrs Solr nodes: " - for ID in `ps auxww | grep java | grep start.jar | awk '{print $2}' | sort -r` + for ID in `ps auxww | grep start.jar | grep solr.solr.home | grep -v grep | awk '{print $2}' | sort -r` do port=`jetty_port "$ID"` if [ "$port" != "" ]; then @@ -345,7 +357,7 @@ function stop_solr() { $JAVA -jar $DIR/start.jar STOP.PORT=$STOP_PORT STOP.KEY=$STOP_KEY --stop || true (sleep 5) & spinner $! - rm -f $SOLR_TIP/bin/solr-$SOLR_PORT.pid + rm -f $SOLR_PID_DIR/solr-$SOLR_PORT.pid else echo -e "No Solr nodes found to stop." exit 0 @@ -356,7 +368,7 @@ function stop_solr() { echo -e "Solr process $SOLR_PID is still running; forcefully killing it now." kill -9 $SOLR_PID echo "Killed process $SOLR_PID" - rm -f $SOLR_TIP/bin/solr-$SOLR_PORT.pid + rm -f $SOLR_PID_DIR/solr-$SOLR_PORT.pid sleep 1 fi @@ -373,7 +385,7 @@ if [ $# -eq 1 ]; then print_usage "" exit ;; - -info|-i) + -info|-i|status) get_info exit ;; @@ -395,6 +407,13 @@ else exit fi +if [ "$SCRIPT_CMD" == "status" ]; then + # hacky - the script hits this if the user passes additional args with the status command, + # which is not supported but also not worth complaining about either + get_info + exit +fi + # run a healthcheck and exit if requested if [ "$SCRIPT_CMD" == "healthcheck" ]; then @@ -402,7 +421,7 @@ if [ "$SCRIPT_CMD" == "healthcheck" ]; then while true; do case $1 in -c|-collection) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Collection name is required when using the $1 option!" exit 1 fi @@ -410,7 +429,7 @@ if [ "$SCRIPT_CMD" == "healthcheck" ]; then shift 2 ;; -z|-zkhost) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "ZooKeepeer connection string is required when using the $1 option!" exit 1 fi @@ -437,11 +456,11 @@ if [ "$SCRIPT_CMD" == "healthcheck" ]; then done fi - if [ "$ZK_HOST" == "" ]; then + if [ -z "$ZK_HOST" ]; then ZK_HOST=localhost:9983 fi - if [ "$HEALTHCHECK_COLLECTION" == "" ]; then + if [ -z "$HEALTHCHECK_COLLECTION" ]; then echo "collection parameter is required!" print_usage "healthcheck" exit 1 @@ -466,7 +485,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; while true; do case $1 in -n|-name) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "$CREATE_TYPE name is required when using the $1 option!" exit 1 fi @@ -474,7 +493,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; shift 2 ;; -c|-configset) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Configset name is required when using the $1 option!" exit 1 fi @@ -482,7 +501,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; shift 2 ;; -s|-shards) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Shard count is required when using the $1 option!" exit 1 fi @@ -490,7 +509,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; shift 2 ;; -rf|-replicationFactor) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Replication factor is required when using the $1 option!" exit 1 fi @@ -498,7 +517,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; shift 2 ;; -p|-port) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Solr port is required when using the $1 option!" exit 1 fi @@ -525,17 +544,17 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; done fi - if [ "$CREATE_CONFIGSET" == "" ]; then + if [ -z "$CREATE_CONFIGSET" ]; then CREATE_CONFIGSET=data_driven_schema_configs fi - if [ "$CREATE_NAME" == "" ]; then + if [ -z "$CREATE_NAME" ]; then echo "$CREATE_TYPE name is required!" print_usage "$SCRIPT_CMD" exit 1 fi - if [ "$CREATE_PORT" == "" ]; then + if [ -z "$CREATE_PORT" ]; then for ID in `ps auxww | grep java | grep start.jar | awk '{print $2}' | sort -r` do port=`jetty_port "$ID"` @@ -546,7 +565,7 @@ if [[ "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; done fi - if [ "$CREATE_PORT" == "" ]; then + if [ -z "$CREATE_PORT" ]; then echo "Failed to determine the port of a local Solr instance, cannot create $CREATE_TYPE $CREATE_NAME" exit 1 fi @@ -564,7 +583,7 @@ fi # verify the command given is supported -if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ]; then +if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ] && [ "$SCRIPT_CMD" != "status" ]; then print_usage "" "$SCRIPT_CMD is not a valid command!" exit 1 fi @@ -581,7 +600,7 @@ if [ $# -gt 0 ]; then shift ;; -d|-dir) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Server directory is required when using the $1 option!" exit 1 fi @@ -601,7 +620,7 @@ if [ $# -gt 0 ]; then shift 2 ;; -s|-solr.home) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Solr home directory is required when using the $1 option!" exit 1 fi @@ -610,7 +629,7 @@ if [ $# -gt 0 ]; then shift 2 ;; -e|-example) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Example name is required when using the $1 option!" exit 1 fi @@ -622,7 +641,7 @@ if [ $# -gt 0 ]; then shift ;; -h|-host) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Hostname is required when using the $1 option!" exit 1 fi @@ -630,7 +649,7 @@ if [ $# -gt 0 ]; then shift 2 ;; -m|-memory) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Memory setting is required when using the $1 option!" exit 1 fi @@ -638,7 +657,7 @@ if [ $# -gt 0 ]; then shift 2 ;; -p|-port) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "Port number is required when using the $1 option!" exit 1 fi @@ -646,11 +665,12 @@ if [ $# -gt 0 ]; then shift 2 ;; -z|-zkhost) - if [[ "$2" == "" || "${2:0:1}" == "-" ]]; then + if [[ -z "$2" || "${2:0:1}" == "-" ]]; then print_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!" exit 1 fi ZK_HOST="$2" + SOLR_MODE="solrcloud" shift 2 ;; -a|-addlopts) @@ -711,7 +731,7 @@ else SOLR_HOST_ARG="" fi -if [ "$SOLR_SERVER_DIR" == "" ]; then +if [ -z "$SOLR_SERVER_DIR" ]; then SOLR_SERVER_DIR=$DEFAULT_SERVER_DIR fi @@ -740,7 +760,7 @@ if [ "$EXAMPLE" != "" ]; then while true do CLOUD_NUM_NODES=`echo $USER_INPUT | tr -d ' '` - if [ "$CLOUD_NUM_NODES" == "" ]; then + if [ -z "$CLOUD_NUM_NODES" ]; then CLOUD_NUM_NODES=2 fi if [[ $CLOUD_NUM_NODES > 4 || $CLOUD_NUM_NODES < 1 ]]; then @@ -760,7 +780,7 @@ if [ "$EXAMPLE" != "" ]; then CLOUD_PORT=`echo $USER_INPUT | tr -d ' '` # handle the default selection or empty input - if [ "$CLOUD_PORT" == "" ]; then + if [ -z "$CLOUD_PORT" ]; then CLOUD_PORT=${CLOUD_PORTS[$s]} fi @@ -840,15 +860,15 @@ if [[ "$FG" == "true" && "$EXAMPLE" != "" ]]; then echo -e "\nWARNING: Foreground mode (-f) not supported when running examples.\n" fi -if [ "$STOP_KEY" == "" ]; then +if [ -z "$STOP_KEY" ]; then STOP_KEY="solrrocks" fi # stop all if no port specified -if [[ "$SCRIPT_CMD" == "stop" && "$SOLR_PORT" == "" ]]; then +if [[ "$SCRIPT_CMD" == "stop" && -z "$SOLR_PORT" ]]; then if $stop_all; then none_stopped=true - for PIDF in `find $SOLR_TIP/bin -name "solr-*.pid" -type f` + for PIDF in `find $SOLR_PID_DIR -name "solr-*.pid" -type f` do NEXT_PID=`cat $PIDF` port=`jetty_port "$NEXT_PID"` @@ -862,17 +882,33 @@ if [[ "$SCRIPT_CMD" == "stop" && "$SOLR_PORT" == "" ]]; then echo -e "\nNo Solr nodes found to stop.\n" fi else - echo -e "\nERROR: Must either specify a port using -p or -all to stop all Solr nodes on this host.\n" - exit 1 + # not stopping all and don't have a port, but if we can find the pid file for the default port 8983, then use that + none_stopped=true + if [ -e "$SOLR_PID_DIR/solr-8983.pid" ]; then + PID=`cat $SOLR_PID_DIR/solr-8983.pid` + CHECK_PID=`ps auxww | awk '{print $2}' | grep $PID | sort -r | tr -d ' '` + if [ "$CHECK_PID" != "" ]; then + port=`jetty_port "$CHECK_PID"` + if [ "$port" != "" ]; then + stop_solr "$SOLR_SERVER_DIR" "$port" "$STOP_KEY" "$CHECK_PID" + none_stopped=false + fi + rm -f $SOLR_PID_DIR/solr-8983.pid + fi + fi + if $none_stopped; then + echo -e "\nMust either specify a port using -p or -all to stop all Solr nodes on this host.\nUse the status command to see if any Solr nodes are running." + exit 1 + fi fi exit fi -if [ "$SOLR_PORT" == "" ]; then +if [ -z "$SOLR_PORT" ]; then SOLR_PORT="8983" fi -if [ "$STOP_PORT" == "" ]; then +if [ -z "$STOP_PORT" ]; then STOP_PORT=`expr $SOLR_PORT - 1000` fi @@ -880,20 +916,20 @@ if [[ "$SCRIPT_CMD" == "start" ]]; then # see if Solr is already running SOLR_PID=`solr_pid_by_port "$SOLR_PORT"` - if [ "$SOLR_PID" == "" ]; 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 | grep $SOLR_PORT | grep -v grep | awk '{print $2}' | sort -r` fi if [ "$SOLR_PID" != "" ]; then - echo -e "\nPort $SOLR_PORT is already being used by another process (pid: $SOLR_PID)\n" + echo -e "\nPort $SOLR_PORT is already being used by another process (pid: $SOLR_PID)\nPlease choose a different port using the -p option.\n" exit 1 fi else # either stop or restart # see if Solr is already running SOLR_PID=`solr_pid_by_port "$SOLR_PORT"` - if [ "$SOLR_PID" == "" ]; 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 | grep $SOLR_PORT | grep -v grep | awk '{print $2}' | sort -r` fi @@ -907,11 +943,12 @@ else fi fi -if [ "$SOLR_HOME" == "" ]; then +if [ -z "$SOLR_HOME" ]; then SOLR_HOME="$SOLR_SERVER_DIR/solr" else if [[ $SOLR_HOME != /* ]] && [[ -d "$SOLR_SERVER_DIR/$SOLR_HOME" ]]; then SOLR_HOME="$SOLR_SERVER_DIR/$SOLR_HOME" + SOLR_PID_DIR=$SOLR_HOME elif [[ $SOLR_HOME != /* ]] && [[ -d "`pwd`/$SOLR_HOME" ]]; then SOLR_HOME="`pwd`/$SOLR_HOME" fi @@ -919,11 +956,16 @@ fi # This is quite hacky, but examples rely on a different log4j.properties # so that we can write logs for examples to $SOLR_HOME/../logs -SOLR_LOGS_DIR=$SOLR_SERVER_DIR/logs +if [ -z "$SOLR_LOGS_DIR" ]; then + SOLR_LOGS_DIR=$SOLR_SERVER_DIR/logs +fi EXAMPLE_DIR=$SOLR_TIP/example if [ "${SOLR_HOME:0:${#EXAMPLE_DIR}}" = $EXAMPLE_DIR ]; then LOG4J_PROPS=$EXAMPLE_DIR/resources/log4j.properties SOLR_LOGS_DIR=$SOLR_HOME/../logs +fi + +if [ -n "$LOG4J_PROPS" ]; then LOG4J_CONFIG="-Dlog4j.configuration=file:$LOG4J_PROPS" fi @@ -964,7 +1006,7 @@ if [ "$GC_LOG_OPTS" != "" ]; then fi if [ "$SOLR_MODE" == "solrcloud" ]; then - if [ "$ZK_CLIENT_TIMEOUT" == "" ]; then + if [ -z "$ZK_CLIENT_TIMEOUT" ]; then ZK_CLIENT_TIMEOUT="15000" fi @@ -990,7 +1032,7 @@ fi # These are useful for attaching remove profilers like VisualVM/JConsole if [ "$ENABLE_REMOTE_JMX_OPTS" == "true" ]; then - if [ "$RMI_PORT" == "" ]; then + if [ -z "$RMI_PORT" ]; then RMI_PORT=1$SOLR_PORT fi @@ -1013,11 +1055,11 @@ if [ "$SOLR_HEAP" != "" ]; then SOLR_JAVA_MEM="-Xms$SOLR_HEAP -Xmx$SOLR_HEAP" fi -if [ "$SOLR_JAVA_MEM" == "" ]; then +if [ -z "$SOLR_JAVA_MEM" ]; then SOLR_JAVA_MEM="-Xms512m -Xmx512m" fi -if [ "$SOLR_TIMEZONE" == "" ]; then +if [ -z "$SOLR_TIMEZONE" ]; then SOLR_TIMEZONE="UTC" fi @@ -1099,10 +1141,10 @@ $SOLR_OPTS" if [ "$run_in_foreground" == "true" ]; then echo -e "\nStarting Solr$IN_CLOUD_MODE on port $SOLR_PORT from $SOLR_SERVER_DIR\n" - $JAVA $SOLR_START_OPTS $SOLR_ADDL_ARGS -XX:OnOutOfMemoryError="$SOLR_TIP/bin/oom_solr.sh $SOLR_PORT" -jar start.jar + $JAVA $SOLR_START_OPTS $SOLR_ADDL_ARGS -jar start.jar else # run Solr in the background - nohup $JAVA $SOLR_START_OPTS $SOLR_ADDL_ARGS -XX:OnOutOfMemoryError="$SOLR_TIP/bin/oom_solr.sh $SOLR_PORT" -jar start.jar 1>$SOLR_LOGS_DIR/solr-$SOLR_PORT-console.log 2>&1 & echo $! > $SOLR_TIP/bin/solr-$SOLR_PORT.pid + nohup $JAVA $SOLR_START_OPTS $SOLR_ADDL_ARGS -XX:OnOutOfMemoryError="$SOLR_TIP/bin/oom_solr.sh $SOLR_PORT $SOLR_LOGS_DIR" -jar start.jar 1>$SOLR_LOGS_DIR/solr-$SOLR_PORT-console.log 2>&1 & echo $! > $SOLR_PID_DIR/solr-$SOLR_PORT.pid # no lsof on cygwin though if [ "$hasLsof" != "" ]; then @@ -1112,7 +1154,7 @@ $SOLR_OPTS" while true do running=`lsof -Pni:$SOLR_PORT` - if [ "$running" == "" ]; then + if [ -z "$running" ]; then if [ $loops -lt 6 ]; then sleep 5 loops=$[$loops+1] @@ -1184,7 +1226,7 @@ else # if user did not define a specific -z parameter, assume embedded in first cloud node we launched above zk_host=$ZK_HOST - if [ "$zk_host" == "" ]; then + if [ -z "$zk_host" ]; then zk_port=$[$SOLR_PORT+1000] zk_host=localhost:$zk_port fi @@ -1213,7 +1255,7 @@ else CLOUD_COLLECTION=`echo $USER_INPUT | tr -d ' '` # handle the default selection or empty input - if [ "$CLOUD_COLLECTION" == "" ]; then + if [ -z "$CLOUD_COLLECTION" ]; then CLOUD_COLLECTION=gettingstarted fi echo $CLOUD_COLLECTION @@ -1224,7 +1266,7 @@ else CLOUD_NUM_SHARDS=`echo $USER_INPUT | tr -d ' '` # handle the default selection or empty input - if [ "$CLOUD_NUM_SHARDS" == "" ]; then + if [ -z "$CLOUD_NUM_SHARDS" ]; then CLOUD_NUM_SHARDS=2 fi echo $CLOUD_NUM_SHARDS @@ -1235,7 +1277,7 @@ else CLOUD_REPFACT=`echo $USER_INPUT | tr -d ' '` # handle the default selection or empty input - if [ "$CLOUD_REPFACT" == "" ]; then + if [ -z "$CLOUD_REPFACT" ]; then CLOUD_REPFACT=2 fi echo $CLOUD_REPFACT @@ -1247,7 +1289,7 @@ else CLOUD_CONFIG=`echo $USER_INPUT | tr -d ' '` # handle the default selection or empty input - if [ "$CLOUD_CONFIG" == "" ]; then + if [ -z "$CLOUD_CONFIG" ]; then CLOUD_CONFIG=data_driven_schema_configs fi fi diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd index 7efa367fa58..8c670e123fd 100644 --- a/solr/bin/solr.cmd +++ b/solr/bin/solr.cmd @@ -64,6 +64,7 @@ IF "%1"=="-usage" goto usage IF "%1"=="/?" goto usage IF "%1"=="-i" goto get_info IF "%1"=="-info" goto get_info +IF "%1"=="status" goto get_info REM Only allow the command to be the first argument, assume start if not supplied IF "%1"=="start" goto set_script_cmd diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd index 607ae09464d..d8ab1ba7f09 100644 --- a/solr/bin/solr.in.cmd +++ b/solr/bin/solr.in.cmd @@ -73,3 +73,9 @@ REM set SOLR_OPTS=%SOLR_OPTS% -Dsolr.autoSoftCommit.maxTime=3000 REM set SOLR_OPTS=%SOLR_OPTS% -Dsolr.autoCommit.maxTime=60000 REM set SOLR_OPTS=%SOLR_OPTS% -Dsolr.clustering.enabled=true +REM Path to a directory where Solr creates index files, the specified directory +REM must contain a solr.xml; by default, Solr will use server/solr +REM set SOLR_HOME= + +REM Sets the port Solr binds to, default is 8983 +REM set SOLR_PORT=8983 diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh index b61d9fe1f21..9f4114ba7f0 100644 --- a/solr/bin/solr.in.sh +++ b/solr/bin/solr.in.sh @@ -70,3 +70,24 @@ ENABLE_REMOTE_JMX_OPTS="false" #SOLR_OPTS="$SOLR_OPTS -Dsolr.autoSoftCommit.maxTime=3000" #SOLR_OPTS="$SOLR_OPTS -Dsolr.autoCommit.maxTime=60000" #SOLR_OPTS="$SOLR_OPTS -Dsolr.clustering.enabled=true" + +# Location where the bin/solr script will save PID files for running instances +# If not set, the script will create PID files in $SOLR_TIP/bin +#SOLR_PID_DIR= + +# Path to a directory where Solr creates index files, the specified directory +# must contain a solr.xml; by default, Solr will use server/solr +#SOLR_HOME= + +# Solr provides a default Log4J configuration properties file in server/resources +# however, you may want to customize the log settings and file appender location +# so you can point the script to use a different log4j.properties file +#LOG4J_PROPS=/var/solr/log4j.properties + +# Location where Solr should write logs to; should agree with the file appender +# settings in server/resources/log4j.properties +#SOLR_LOGS_DIR= + +# Sets the port Solr binds to, default is 8983 +#SOLR_PORT=8983 + diff --git a/solr/build.xml b/solr/build.xml index e6a6f1b80ef..852b7b2a41f 100644 --- a/solr/build.xml +++ b/solr/build.xml @@ -299,6 +299,9 @@ + + + @@ -482,7 +485,7 @@ + includes="bin/** server/**/*.sh example/**/*.sh example/**/bin/" />