Skip to content

Commit

Permalink
SOLR-17359: Move Zk Arg parsing into Java Code (#2593)
Browse files Browse the repository at this point in the history
* Move Zk Arg parsing into Java Code from the bin/solr shell and bin/solr.cmd command scripts, making testing life easier on Windows.

* Improved the output of -h to make usage information look nicer

* restructure control flow so that we don't check for each script command by name and THEN call the java code, instead only look for the three exceptions, start, stop, restart.

* Resolve Executing a command incorrectly gives a message which is not clear. Eg: >solr zk ls

---------

Co-authored-by: Rahul Goswami <[email protected]>
  • Loading branch information
epugh and rahulgoswami authored Aug 14, 2024
1 parent 90dc8d9 commit 463e093
Show file tree
Hide file tree
Showing 29 changed files with 467 additions and 917 deletions.
2 changes: 1 addition & 1 deletion solr/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Dependency Upgrades

Other Changes
---------------------
(No changes)
* SOLR-17359: Move Zk Arg parsing into Java Code from bin/solr scripts. (Eric Pugh, Rahul Goswami)

================== 9.7.0 ==================
New Features
Expand Down
342 changes: 6 additions & 336 deletions solr/bin/solr
Original file line number Diff line number Diff line change
Expand Up @@ -443,115 +443,9 @@ function print_usage() {
echo ""
echo " NOTE: To see if any Solr servers are running, do: solr status"
echo ""
elif [ "$CMD" == "zk" ]; then
print_short_zk_usage ""
echo " Can be run on remote (non-Solr) hosts, as long as valid ZK_HOST information is provided"
echo " Be sure to check the Solr logs in case of errors."
echo ""
echo " -z zkHost Optional Zookeeper connection string for all commands. If specified it"
echo " overrides the 'ZK_HOST=...'' defined in solr.in.sh."
echo ""
echo " -s solrUrl Optional Solr URL to look up the correct zkHost connection string via."
echo ""
echo " -v/--verbose Enable more verbose output for this script."
echo ""
echo " upconfig uploads a configset from the local machine to Zookeeper."
echo ""
echo " downconfig downloads a configset from Zookeeper to the local machine."
echo ""
echo " -n <configName> Name of the configset in Zookeeper that will be the destination of"
echo " 'upconfig' and the source for 'downconfig'."
echo ""
echo " -d <confdir> The local directory the configuration will be uploaded from for"
echo " 'upconfig' or downloaded to for 'downconfig'. If 'confdir' is a child of"
echo " ...solr/server/solr/configsets' then the configs will be copied from/to"
echo " that directory. Otherwise it is interpreted as a simple local path."
echo ""
echo " cp copies files or folders to/from Zookeeper or Zookeeper -> Zookeeper"
echo ""
echo " -r Recursively copy <src> to <dst>. Command will fail if <src> has children and "
echo " -r is not specified. Optional"
echo ""
echo " <src>, <dest> : [file:][/]path/to/local/file or zk:/path/to/zk/node"
echo " NOTE: <src> and <dest> may both be Zookeeper resources prefixed by 'zk:'"
echo " When <src> is a zk resource, <dest> may be '.'"
echo " If <dest> ends with '/', then <dest> will be a local folder or parent znode and the last"
echo " element of the <src> path will be appended unless <src> also ends in a slash. "
echo " <dest> may be zk:, which may be useful when using the cp -r form to backup/restore "
echo " the entire zk state."
echo " You must enclose local paths that end in a wildcard in quotes or just"
echo " end the local path in a slash. That is,"
echo " 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181' is equivalent to"
echo " 'bin/solr zk cp -r \"/some/dir/*\" zk:/ -z localhost:2181'"
echo " but 'bin/solr zk cp -r /some/dir/* zk:/ -z localhost:2181' will throw an error"
echo ""
echo " here's an example of backup/restore for a ZK configuration:"
echo " to copy to local: 'bin/solr zk cp -r zk:/ /some/dir -z localhost:2181'"
echo " to restore to ZK: 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181'"
echo ""
echo " The 'file:' prefix is stripped, thus 'file:/wherever' specifies an absolute local path and"
echo " 'file:somewhere' specifies a relative local path. All paths on Zookeeper are absolute."
echo ""
echo " Zookeeper nodes CAN have data, so moving a single file to a parent znode"
echo " will overlay the data on the parent Znode so specifying the trailing slash"
echo " can be important."
echo ""
echo " Wildcards are supported when copying from local, trailing only and must be quoted."
echo ""
echo " rm deletes files or folders on Zookeeper"
echo ""
echo " -r Recursively delete if <path> is a directory. Command will fail if <path>"
echo " has children and -r is not specified. Optional"
echo " <path> : [zk:]/path/to/zk/node. <path> may not be the root ('/')"
echo ""
echo " mv moves (renames) znodes on Zookeeper"
echo ""
echo " <src>, <dest> : Zookeeper nodes, the 'zk:' prefix is optional."
echo " If <dest> ends with '/', then <dest> will be a parent znode"
echo " and the last element of the <src> path will be appended."
echo " Zookeeper nodes CAN have data, so moving a single file to a parent znode"
echo " will overlay the data on the parent Znode so specifying the trailing slash"
echo " is important."
echo ""
echo " ls lists the znodes on Zookeeper"
echo ""
echo " -r Recursively descends the path listing all znodes. Optional"
echo " <path>: The Zookeeper path to use as the root."
echo ""
echo " Only the node names are listed, not data"
echo ""
echo " mkroot makes a znode in Zookeeper with no data. Can be used to make a path of arbitrary"
echo " depth but primarily intended to create a 'chroot'."
echo ""
echo " <path>: The Zookeeper path to create. Leading slash is assumed if not present."
echo " Intermediate nodes are created as needed if not present."
echo ""
fi
} # end print_usage

function print_short_zk_usage() {

if [ "$1" != "" ]; then
echo -e "\nERROR: $1\n"
fi

echo " Usage: solr zk upconfig|downconfig -d <confdir> -n <configName> [-z zkHost] [-s solrUrl]"
echo " solr zk cp [-r] <src> <dest> [-z zkHost] [-s solrUrl]"
echo " solr zk rm [-r] <path> [-z zkHost] [-s solrUrl]"
echo " solr zk mv <src> <dest> [-z zkHost] [-s solrUrl]"
echo " solr zk ls [-r] <path> [-z zkHost] [-s solrUrl]"
echo " solr zk mkroot <path> [-z zkHost] [-s solrUrl]"
echo " solr zk linkconfig --conf-name <confname> -c <collection> [-z zkHost] [-s solrUrl]"
echo " solr zk updateacls <path> [-z zkHost] [-s solrUrl]"
echo ""

if [ "$1" == "" ]; then
echo "Type bin/solr zk --help for full usage help"
else
exit 1
fi
}

# used to show the script is still alive when waiting on work to complete
function spinner() {
local pid=$1
Expand Down Expand Up @@ -747,42 +641,6 @@ if [ "$SCRIPT_CMD" == "status" ]; then
exit $?
fi

# assert tool
if [ "$SCRIPT_CMD" == "assert" ]; then
run_tool assert "$@"
exit $?
fi

# healthcheck tool
if [ "$SCRIPT_CMD" == "healthcheck" ]; then
run_tool healthcheck "$@"
exit $?
fi

# config tool
if [ "$SCRIPT_CMD" == "config" ]; then
run_tool config "$@"
exit $?
fi

# create a core or collection
if [[ "$SCRIPT_CMD" == "create" ]]; then
run_tool $SCRIPT_CMD $@
exit $?
fi

# delete a core or collection
if [[ "$SCRIPT_CMD" == "delete" ]]; then
run_tool $SCRIPT_CMD $@
exit $?
fi

# manage packages
if [[ "$SCRIPT_CMD" == "package" ]]; then
run_tool $SCRIPT_CMD $@
exit $?
fi

# configure authentication
if [[ "$SCRIPT_CMD" == "auth" ]]; then
: "${SOLR_SERVER_DIR:=$DEFAULT_SERVER_DIR}"
Expand Down Expand Up @@ -817,208 +675,20 @@ if [[ "$SCRIPT_CMD" == "auth" ]]; then
exit $?
fi

# Prevent any zk subcommands from going through with out invoking zk command
if [[ "$SCRIPT_CMD" == "upconfig" || $SCRIPT_CMD == "downconfig" || $SCRIPT_CMD == "cp" || $SCRIPT_CMD == "rm" || $SCRIPT_CMD == "mv" || $SCRIPT_CMD == "ls" || $SCRIPT_CMD == "mkroot" || $SCRIPT_CMD == "linkconfig" || $SCRIPT_CMD == "updateacls" ]]; then
print_short_zk_usage "You must invoke this subcommand using the zk command. bin/solr zk $SCRIPT_CMD."
exit $?
fi

ZK_RECURSE=false
# Zookeeper file maintenance (upconfig, downconfig, files up/down etc.)
# It's a little clumsy to have the parsing go round and round for upconfig and downconfig, but that's
# necessary for back-compat
if [[ "$SCRIPT_CMD" == "zk" ]]; then

VERBOSE=""
ZK_SOLR_URL=""

if [ $# -gt 0 ]; then
while true; do
case "${1:-}" in
upconfig|downconfig|cp|rm|mv|ls|mkroot|linkconfig|updateacls)
ZK_OP=$1
shift 1
;;
-z|--zk-host|-zkHost|--zkHost)
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
print_short_zk_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
fi
ZK_HOST="$2"
shift 2
;;
-s|--solr-url|-solrUrl)
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
print_short_zk_usage "$SCRIPT_CMD" "Solr Url is required when using the $1 option!"
fi
ZK_SOLR_URL="$2"
shift 2
;;
-n|--confname|--conf-name)
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
print_short_zk_usage "$SCRIPT_CMD" "Configuration name is required when using the $1 option!"
fi
CONFIGSET_CONFNAME="$2"
shift 2
;;
-d|--confdir|--conf-dir)
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
print_short_zk_usage "$SCRIPT_CMD" "Configuration directory is required when using the $1 option!"
fi
CONFIGSET_CONFDIR="$2"
shift 2
;;
--solr-home)
ZK_SOLR_HOME="$2"
shift 2
;;
-r)
ZK_RECURSE="true"
shift
;;
-c|-collection)
ZK_COLLECTION="$2"
shift
;;
-V|-verbose|--verbose)
VERBOSE="--verbose"
shift
;;
--help|-h|-help)
print_usage "$SCRIPT_CMD"
exit 0
;;
--)
shift
break
;;
*) # Pick up <src> <dst> or <path> params for rm, ls, cp, mv, mkroot.
if [ -z "${1:-}" ]; then
break # out-of-args, stop looping
fi
if [ -z "${ZK_SRC:-}" ]; then
ZK_SRC=$1
else
if [ -z "${ZK_DST:-}" ]; then
ZK_DST=$1
else
print_short_zk_usage "Unrecognized or misplaced command $1. 'cp' with trailing asterisk requires quoting, see help text."
fi
fi
shift
;;
esac
done
fi

if [ -z "$ZK_OP" ]; then
print_short_zk_usage "Zookeeper operation (one of 'upconfig', 'downconfig', 'rm', 'mv', 'cp', 'ls', 'mkroot', 'linkconfig', 'updateacls') is required!"
fi

if [[ "$ZK_OP" == "upconfig" || "$ZK_OP" == "downconfig" ]]; then
if [ -z "$CONFIGSET_CONFDIR" ]; then
print_short_zk_usage "Local directory of the configset (-d) argument is required!"
fi

if [ -z "$CONFIGSET_CONFNAME" ]; then
print_short_zk_usage "Configset name on Zookeeper (-n) argument is required!"
fi
fi

if [[ "$ZK_OP" == "cp" || "$ZK_OP" == "mv" ]]; then
if [[ -z "$ZK_SRC" || -z "$ZK_DST" ]]; then
print_short_zk_usage "<source> and <destination> must be specified when using either the 'mv' or 'cp' commands."
fi
if [[ "$ZK_OP" == "cp" && "${ZK_SRC:0:3}" != "zk:" && "${ZK_DST:0:3}" != "zk:" ]]; then
print_short_zk_usage "One of the source or destination paths must be prefixed by 'zk:' for the 'cp' command."
fi
fi

if [[ "$ZK_OP" == "mkroot" ]]; then
if [[ -z "$ZK_SRC" ]]; then
print_short_zk_usage "<path> must be specified when using the 'mkroot' command."
fi
fi

CONNECTION_PARAMS=""

if [[ -z "$ZK_HOST" ]]; then
if [[ -z "$ZK_SOLR_URL" ]]; then
CONNECTION_PARAMS=""
else
CONNECTION_PARAMS="--solr-url ${ZK_SOLR_URL}"
fi

else
CONNECTION_PARAMS="--zk-host ${ZK_HOST}"
fi

case "$ZK_OP" in
upconfig)
run_tool "$ZK_OP" --conf-name "$CONFIGSET_CONFNAME" --conf-dir "$CONFIGSET_CONFDIR" $CONNECTION_PARAMS $VERBOSE
;;
downconfig)
run_tool "$ZK_OP" --conf-name "$CONFIGSET_CONFNAME" --conf-dir "$CONFIGSET_CONFDIR" $CONNECTION_PARAMS $VERBOSE
;;
rm)
if [ -z "$ZK_SRC" ]; then
print_short_zk_usage "Zookeeper path to remove must be specified when using the 'rm' command"
fi
run_tool "$ZK_OP" --path "$ZK_SRC" $CONNECTION_PARAMS --recurse "$ZK_RECURSE" $VERBOSE
;;
mv)
run_tool "$ZK_OP" --source "$ZK_SRC" --destination "$ZK_DST" $CONNECTION_PARAMS $VERBOSE
;;
cp)
if [ -z "$ZK_SOLR_HOME" ]; then
run_tool "$ZK_OP" --source "$ZK_SRC" --destination "$ZK_DST" $CONNECTION_PARAMS --recurse "$ZK_RECURSE" $VERBOSE
else
run_tool "$ZK_OP" --source "$ZK_SRC" --destination "$ZK_DST" $CONNECTION_PARAMS --recurse "$ZK_RECURSE" $VERBOSE --solr-home "$ZK_SOLR_HOME"
fi

;;
ls)
if [ -z "$ZK_SRC" ]; then
print_short_zk_usage "Zookeeper path to list must be specified when using the 'ls' command"
fi
run_tool "$ZK_OP" --path "$ZK_SRC" --recurse "$ZK_RECURSE" $CONNECTION_PARAMS $VERBOSE
;;
mkroot)
if [ -z "$ZK_SRC" ]; then
print_short_zk_usage "Zookeeper path to list must be specified when using the 'mkroot' command"
fi
run_tool "$ZK_OP" --path "$ZK_SRC" $CONNECTION_PARAMS $VERBOSE
;;
linkconfig)
run_tool "$ZK_OP" --conf-name "$CONFIGSET_CONFNAME" -c "$ZK_COLLECTION" $CONNECTION_PARAMS $VERBOSE
;;
updateacls)
run_tool "$ZK_OP" --path "$ZK_SRC" $CONNECTION_PARAMS $VERBOSE
;;
*)
print_short_zk_usage "Unrecognized Zookeeper operation $ZK_OP"
;;
esac

exit $?
fi

if [[ "$SCRIPT_CMD" == "api" ]]; then
run_tool api "$@"
exit $?
fi

# verify the command given is supported
if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ] && [ "$SCRIPT_CMD" != "status" ]; then
# handoff this command to the SolrCLI and let it handle the option parsing and validation
# at this point all tools that have a custom run process, like "status" and "auth" have been run and exited.
# Unless a command is one of the ones in the if clause below, we will just run it with the default run_tool function and then exit.
if [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "restart" ]; then
# hand off the command to the SolrCLI and let it handle the option parsing and validation
run_tool "$SCRIPT_CMD" "$@"
ret=$?
if [ $ret -ne 0 ]; then
print_usage ""
exit $ret
fi
exit 0
fi

# Everything below here is to support start, stop and restart.

#Check current Ulimits for Open Files and Max Processes. Warn if they are below the recommended values.

: "${SOLR_RECOMMENDED_MAX_PROCESSES:=65000}"
Expand Down
Loading

0 comments on commit 463e093

Please sign in to comment.