This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 463e093d336 SOLR-17359: Move Zk Arg parsing into Java Code (#2593)
463e093d336 is described below
commit 463e093d336ff129e7b4fbe736cc3a2bb4725d39
Author: Eric Pugh <[email protected]>
AuthorDate: Wed Aug 14 06:28:22 2024 -0400
SOLR-17359: Move Zk Arg parsing into Java Code (#2593)
* 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]>
---
solr/CHANGES.txt | 2 +-
solr/bin/solr | 342 +--------------------
solr/bin/solr.cmd | 121 +-------
.../org/apache/solr/cli/ConfigSetDownloadTool.java | 49 ++-
.../org/apache/solr/cli/ConfigSetUploadTool.java | 47 ++-
.../src/java/org/apache/solr/cli/CreateTool.java | 2 +-
.../java/org/apache/solr/cli/LinkConfigTool.java | 5 +
.../src/java/org/apache/solr/cli/PackageTool.java | 2 -
.../core/src/java/org/apache/solr/cli/SolrCLI.java | 58 +++-
solr/core/src/java/org/apache/solr/cli/Tool.java | 2 +-
.../java/org/apache/solr/cli/UpdateACLTool.java | 18 +-
.../src/java/org/apache/solr/cli/ZkCpTool.java | 70 ++++-
.../src/java/org/apache/solr/cli/ZkLsTool.java | 17 +-
.../src/java/org/apache/solr/cli/ZkMkrootTool.java | 27 +-
.../src/java/org/apache/solr/cli/ZkMvTool.java | 41 ++-
.../src/java/org/apache/solr/cli/ZkRmTool.java | 16 +-
.../src/java/org/apache/solr/cli/ZkToolHelp.java | 84 +++++
.../org/apache/solr/cli/SolrCLIZkToolsTest.java | 309 +++----------------
.../org/apache/solr/cli/ZkSubcommandsTest.java | 110 ++-----
.../cases/cloud_multi_node_embedded_zk/test.sh | 2 +-
solr/packaging/test/test_create_collection.bats | 2 +-
solr/packaging/test/test_help.bats | 3 +-
solr/packaging/test/test_ssl.bats | 14 +-
solr/packaging/test/test_zk.bats | 29 +-
.../pages/solr-control-script-reference.adoc | 4 +-
.../pages/zookeeper-utilities.adoc | 2 +-
.../getting-started/pages/tutorial-diy.adoc | 2 +-
.../getting-started/pages/tutorial-films.adoc | 2 +-
.../pages/tutorial-techproducts.adoc | 2 +-
29 files changed, 467 insertions(+), 917 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 8328743d647..1ab51dfa331 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -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
diff --git a/solr/bin/solr b/solr/bin/solr
index 7e1629724f2..e1873bce4f6 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -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
@@ -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}"
@@ -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}"
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index 58fb4e6599e..a07b4575c7d 100755
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -258,6 +258,7 @@ IF "%1"=="version" goto run_solrcli
IF "%1"=="-v" goto run_solrcli
IF "%1"=="-version" goto run_solrcli
IF "%1"=="assert" goto run_solrcli
+IF "%1"=="zk" goto run_solrcli
IF "%1"=="export" goto run_solrcli
IF "%1"=="package" goto run_solrcli
IF "%1"=="auth" goto run_solrcli
@@ -272,12 +273,7 @@ IF "%1"=="healthcheck" goto run_solrcli
IF "%1"=="create" goto run_solrcli
IF "%1"=="delete" goto run_solrcli
IF "%1"=="postlogs" goto run_solrcli
-IF "%1"=="zk" (
- set SCRIPT_CMD=zk
- SHIFT
- set ZK_RECURSE=false
- goto parse_zk_args
-)
+
IF "%1"=="auth" (
set SCRIPT_CMD=auth
SHIFT
@@ -302,7 +298,7 @@ IF "%SCRIPT_CMD%"=="healthcheck" goto run_solrcli
IF "%SCRIPT_CMD%"=="create" goto run_solrcli
IF "%SCRIPT_CMD%"=="delete" goto run_solrcli
IF "%SCRIPT_CMD%"=="cluster" goto run_solrcli
-IF "%SCRIPT_CMD%"=="zk" goto zk_usage
+IF "%SCRIPT_CMD%"=="zk" goto run_solrcli
IF "%SCRIPT_CMD%"=="auth" goto run_solrcli
IF "%SCRIPT_CMD%"=="package" goto run_solrcli
IF "%SCRIPT_CMD%"=="status" goto run_solrcli
@@ -388,110 +384,6 @@ goto done
@echo.
goto done
-:zk_usage
-set ZK_FULL=true
-goto zk_short_usage
-:zk_full_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.cmd.
-echo.
-echo -s solrUrl Optional Solr URL to look up the correct
zkHost connection string via.
-echo.
-echo -V Enable more verbose output.
-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 -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 -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 ^<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 -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.
-
-goto done
-
-:zk_short_usage
-IF NOT "!ERROR_MSG!"=="" (
- echo ERROR: !ERROR_MSG!
- echo.
-)
-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 "%ZK_FULL%"=="true" (
- goto zk_full_usage
-) ELSE (
- echo Type bin/solr zk --help for full usage help
-)
-goto done
REM Really basic command-line arg parsing
:parse_args
@@ -512,6 +404,7 @@ IF "%1"=="-v" goto set_debug
IF "%1"=="-q" goto set_warn
IF "%1"=="-c" goto set_cloud_mode
IF "%1"=="-cloud" goto set_cloud_mode
+IF "%1"=="--cloud" goto set_cloud_mode
IF "%1"=="-d" goto set_server_dir
IF "%1"=="--dir" goto set_server_dir
IF "%1"=="-s" goto set_solr_home_dir
@@ -1411,12 +1304,6 @@ IF "%1"=="-V" (
goto set_collection_zk
) ELSE IF "%1"=="-z" (
goto set_config_zk
-) ELSE IF "%1"=="/?" (
- goto zk_usage
-) ELSE IF "%1"=="-h" (
- goto zk_usage
-) ELSE IF "%1"=="-help" (
- goto zk_usage
) ELSE IF "!ZK_SRC!"=="" (
if not "%~1"=="" (
goto set_zk_src
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
b/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
index 87ca00c1705..d9322485dc7 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
@@ -23,6 +23,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DeprecatedAttributes;
import org.apache.commons.cli.Option;
import org.apache.solr.common.cloud.SolrZkClient;
import org.slf4j.Logger;
@@ -43,18 +44,44 @@ public class ConfigSetDownloadTool extends ToolBase {
@Override
public List<Option> getOptions() {
return List.of(
- Option.builder()
+ Option.builder("n")
.longOpt("conf-name")
.hasArg()
.argName("NAME")
- .required(true)
+ .required(false) // should be true, but we have deprecated option
as well.
.desc("Configset name in ZooKeeper.")
.build(),
Option.builder()
+ .longOpt("confname")
+ .hasArg()
+ .argName("NAME")
+ .deprecated(
+ DeprecatedAttributes.builder()
+ .setForRemoval(true)
+ .setSince("9.8")
+ .setDescription("Use --conf-name instead")
+ .get())
+ .required(false)
+ .desc("Configset name in ZooKeeper.")
+ .build(),
+ Option.builder("d")
.longOpt("conf-dir")
.hasArg()
.argName("DIR")
- .required(true)
+ .required(false) // should be true, but we have deprecated option
as well.
+ .desc("Local directory with configs.")
+ .build(),
+ Option.builder()
+ .longOpt("confdir")
+ .hasArg()
+ .argName("NAME")
+ .deprecated(
+ DeprecatedAttributes.builder()
+ .setForRemoval(true)
+ .setSince("9.8")
+ .setDescription("Use --conf-dir instead")
+ .get())
+ .required(false)
.desc("Local directory with configs.")
.build(),
SolrCLI.OPTION_SOLRURL,
@@ -69,6 +96,11 @@ public class ConfigSetDownloadTool extends ToolBase {
return "downconfig";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk downconfig [-d <DIR>] [-n <NAME>] [-s <HOST>] [-u
<credentials>] [-z <HOST>]";
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
@@ -76,8 +108,15 @@ public class ConfigSetDownloadTool extends ToolBase {
try (SolrZkClient zkClient = SolrCLI.getSolrZkClient(cli, zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
- String confName = cli.getOptionValue("conf-name");
- String confDir = cli.getOptionValue("conf-dir");
+ String confName =
+ cli.hasOption("conf-name")
+ ? cli.getOptionValue("conf-name")
+ : cli.getOptionValue("confname");
+ String confDir =
+ cli.hasOption("conf-dir")
+ ? cli.getOptionValue("conf-dir")
+ : cli.getOptionValue("confdir");
+
Path configSetPath = Paths.get(confDir);
// we try to be nice about having the "conf" in the directory, and we
create it if it's not
// there.
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
index bc0dde9c3f4..84faa2f2d2d 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
@@ -22,6 +22,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DeprecatedAttributes;
import org.apache.commons.cli.Option;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkMaintenanceUtils;
@@ -49,14 +50,40 @@ public class ConfigSetUploadTool extends ToolBase {
.longOpt("conf-name")
.hasArg()
.argName("NAME")
- .required(true)
+ .required(false) // should be true, but we have deprecated option
as well.
+ .desc("Configset name in ZooKeeper.")
+ .build(),
+ Option.builder()
+ .longOpt("confname")
+ .hasArg()
+ .argName("NAME")
+ .deprecated(
+ DeprecatedAttributes.builder()
+ .setForRemoval(true)
+ .setSince("9.8")
+ .setDescription("Use --conf-name instead")
+ .get())
+ .required(false)
.desc("Configset name in ZooKeeper.")
.build(),
Option.builder("d")
.longOpt("conf-dir")
.hasArg()
.argName("DIR")
- .required(true)
+ .required(false) // should be true, but we have deprecated option
as well.
+ .desc("Local directory with configs.")
+ .build(),
+ Option.builder()
+ .longOpt("confdir")
+ .hasArg()
+ .argName("DIR")
+ .deprecated(
+ DeprecatedAttributes.builder()
+ .setForRemoval(true)
+ .setSince("9.8")
+ .setDescription("Use --conf-dir instead")
+ .get())
+ .required(false)
.desc("Local directory with configs.")
.build(),
SolrCLI.OPTION_SOLRURL,
@@ -71,6 +98,11 @@ public class ConfigSetUploadTool extends ToolBase {
return "upconfig";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk upconfig [-d <DIR>] [-n <NAME>] [-s <HOST>] [-u
<credentials>] [-z <HOST>]";
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
@@ -79,14 +111,17 @@ public class ConfigSetUploadTool extends ToolBase {
final String solrInstallDir = System.getProperty("solr.install.dir");
Path solrInstallDirPath = Paths.get(solrInstallDir);
- String confName = cli.getOptionValue("conf-name");
+ String confName =
+ cli.hasOption("conf-name")
+ ? cli.getOptionValue("conf-name")
+ : cli.getOptionValue("confname");
+ String confDir =
+ cli.hasOption("conf-dir") ? cli.getOptionValue("conf-dir") :
cli.getOptionValue("confdir");
try (SolrZkClient zkClient = SolrCLI.getSolrZkClient(cli, zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
final Path configsetsDirPath =
SolrCLI.getConfigSetsDir(solrInstallDirPath);
- Path confPath =
- ConfigSetService.getConfigsetPath(
- cli.getOptionValue("conf-dir"), configsetsDirPath.toString());
+ Path confPath = ConfigSetService.getConfigsetPath(confDir,
configsetsDirPath.toString());
echo(
"Uploading "
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
index 61031ae5cc9..e678e44d725 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
@@ -76,7 +76,7 @@ public class CreateTool extends ToolBase {
.required(true)
.desc("Name of collection or core to create.")
.build(),
- Option.builder("s")
+ Option.builder("sh")
.longOpt("shards")
.hasArg()
.argName("#")
diff --git a/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
b/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
index f94cd5a2b7f..1e48a890f3b 100644
--- a/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
@@ -42,6 +42,11 @@ public class LinkConfigTool extends ToolBase {
return "linkconfig";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk linkconfig -c <NAME> -n <NAME> [-z <HOST>]";
+ }
+
@Override
public List<Option> getOptions() {
return List.of(
diff --git a/solr/core/src/java/org/apache/solr/cli/PackageTool.java
b/solr/core/src/java/org/apache/solr/cli/PackageTool.java
index c3f4a3a9e96..26362ddf41a 100644
--- a/solr/core/src/java/org/apache/solr/cli/PackageTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/PackageTool.java
@@ -245,7 +245,6 @@ public class PackageTool extends ToolBase {
@Override
public String getHeader() {
StringBuilder sb = new StringBuilder();
- format(sb, "\n");
format(sb, "Package Manager\n---------------");
formatGreen(sb, "bin/solr package add-repo <repository-name>
<repository-url>");
format(sb, "Add a repository to Solr.");
@@ -293,7 +292,6 @@ public class PackageTool extends ToolBase {
sb,
" (b) Please make sure that all Solr nodes are started with
'-Denable.packages=true' parameter.");
format(sb, "\n");
- format(sb, "\n");
format(sb, "List of options:");
return sb.toString();
}
diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
index 07582cf3a29..b7a74bb21af 100755
--- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
@@ -37,6 +37,7 @@ import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
@@ -153,14 +154,11 @@ public class SolrCLI implements CLIO {
public static final Option OPTION_HELP =
Option.builder("h").longOpt("help").required(false).desc("Print this
message.").build();
- // should this be boolean or just an option?
public static final Option OPTION_RECURSE =
Option.builder("r")
.longOpt("recurse")
- .argName("recurse")
- .hasArg()
.required(false)
- .desc("Recurse (true|false), default is false.")
+ .desc("Apply the command recursively.")
.build();
public static final Option OPTION_CREDENTIALS =
@@ -198,7 +196,38 @@ public class SolrCLI implements CLIO {
// select the version tool to be run
args[0] = "version";
}
-
+ if (Arrays.asList(
+ "upconfig", "downconfig", "cp", "rm", "mv", "ls", "mkroot",
"linkconfig", "updateacls")
+ .contains(args[0])) {
+ // remap our arguments to invoke the zk short tool help
+ args = new String[] {"zk-tool-help", "--print-zk-subcommand-usage",
args[0]};
+ }
+ if (Objects.equals(args[0], "zk")) {
+ if (args.length == 1) {
+ // remap our arguments to invoke the ZK tool help.
+ args = new String[] {"zk-tool-help", "--print-long-zk-usage"};
+ } else if (args.length == 2) {
+ if (Arrays.asList("-h", "--help", "/?").contains(args[1])) {
+ // remap our arguments to invoke the ZK tool help.
+ args = new String[] {"zk-tool-help", "--print-long-zk-usage"};
+ } else {
+ // remap our arguments to invoke the zk sub command with help
+ String[] trimmedArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, trimmedArgs, 0, trimmedArgs.length);
+ args = trimmedArgs;
+
+ String[] remappedArgs = new String[args.length + 1];
+ System.arraycopy(args, 0, remappedArgs, 0, args.length);
+ remappedArgs[remappedArgs.length - 1] = "--help";
+ args = remappedArgs;
+ }
+ } else {
+ // chop the leading zk argument so we invoke the correct zk sub tool
+ String[] trimmedArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, trimmedArgs, 0, trimmedArgs.length);
+ args = trimmedArgs;
+ }
+ }
SSLConfigurationsFactory.current().init();
Tool tool = null;
@@ -295,6 +324,7 @@ public class SolrCLI implements CLIO {
else if ("run_example".equals(toolType)) return new RunExampleTool();
else if ("upconfig".equals(toolType)) return new ConfigSetUploadTool();
else if ("downconfig".equals(toolType)) return new ConfigSetDownloadTool();
+ else if ("zk-tool-help".equals(toolType)) return new ZkToolHelp();
else if ("rm".equals(toolType)) return new ZkRmTool();
else if ("mv".equals(toolType)) return new ZkMvTool();
else if ("cp".equals(toolType)) return new ZkCpTool();
@@ -339,7 +369,6 @@ public class SolrCLI implements CLIO {
/** Parses the command-line arguments passed by the user. */
public static CommandLine processCommandLineArgs(Tool tool, String[] args) {
List<Option> customOptions = tool.getOptions();
- String toolName = tool.getName();
Options options = new Options();
options.addOption(OPTION_HELP);
@@ -384,9 +413,8 @@ public class SolrCLI implements CLIO {
}
/** Prints tool help for a given tool */
- private static void printToolHelp(Tool tool) {
- HelpFormatter formatter = HelpFormatter.builder().get();
- formatter.setWidth(120);
+ public static void printToolHelp(Tool tool) {
+ HelpFormatter formatter = getFormatter();
Options optionsNoDeprecated = new Options();
tool.getOptions().stream()
.filter(option -> !option.isDeprecated())
@@ -394,7 +422,17 @@ public class SolrCLI implements CLIO {
String usageString = tool.getUsage() == null ? "bin/solr " +
tool.getName() : tool.getUsage();
boolean autoGenerateUsage = tool.getUsage() == null;
formatter.printHelp(
- usageString, tool.getHeader(), optionsNoDeprecated, tool.getFooter(),
autoGenerateUsage);
+ usageString,
+ "\n" + tool.getHeader(),
+ optionsNoDeprecated,
+ tool.getFooter(),
+ autoGenerateUsage);
+ }
+
+ public static HelpFormatter getFormatter() {
+ HelpFormatter formatter = HelpFormatter.builder().get();
+ formatter.setWidth(120);
+ return formatter;
}
/** Scans Jar files on the classpath for Tool implementations to activate. */
diff --git a/solr/core/src/java/org/apache/solr/cli/Tool.java
b/solr/core/src/java/org/apache/solr/cli/Tool.java
index aec76be8083..0edde7cdae2 100644
--- a/solr/core/src/java/org/apache/solr/cli/Tool.java
+++ b/solr/core/src/java/org/apache/solr/cli/Tool.java
@@ -39,7 +39,7 @@ public interface Tool {
* Optional header to display before the options in help output. Defaults to
'List of options:'
*/
default String getHeader() {
- return "\nList of options:";
+ return "List of options:";
}
/**
diff --git a/solr/core/src/java/org/apache/solr/cli/UpdateACLTool.java
b/solr/core/src/java/org/apache/solr/cli/UpdateACLTool.java
index 66804cecb48..f98959a89c7 100644
--- a/solr/core/src/java/org/apache/solr/cli/UpdateACLTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/UpdateACLTool.java
@@ -47,25 +47,21 @@ public class UpdateACLTool extends ToolBase {
return "updateacls";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk updateacls [-z <HOST>";
+ }
+
@Override
public List<Option> getOptions() {
- return List.of(
- Option.builder()
- .longOpt("path")
- .argName("PATH")
- .hasArg()
- .required(true)
- .desc("The path to update.")
- .build(),
- SolrCLI.OPTION_ZKHOST,
- SolrCLI.OPTION_ZKHOST_DEPRECATED);
+ return List.of(SolrCLI.OPTION_ZKHOST, SolrCLI.OPTION_ZKHOST_DEPRECATED);
}
@Override
public void runImpl(CommandLine cli) throws Exception {
- String path = cli.getOptionValue("path");
String zkHost = SolrCLI.getZkHost(cli);
+ String path = cli.getArgs()[0];
if (!ZkController.checkChrootPath(zkHost, true)) {
throw new IllegalStateException(
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
index fcac11dbc00..d7e52b7772b 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.cli;
+import static org.apache.solr.packagemanager.PackageUtils.format;
+
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationTargetException;
@@ -53,20 +55,6 @@ public class ZkCpTool extends ToolBase {
@Override
public List<Option> getOptions() {
return List.of(
- Option.builder()
- .longOpt("source")
- .hasArg()
- .argName("SRC")
- .required(true)
- .desc("Source file or directory, may be local or a Znode.")
- .build(),
- Option.builder()
- .longOpt("destination")
- .hasArg()
- .argName("DST")
- .required(true)
- .desc("Destination of copy, may be local or a Znode.")
- .build(),
Option.builder()
.longOpt("solr-home")
.argName("DIR")
@@ -87,15 +75,63 @@ public class ZkCpTool extends ToolBase {
return "cp";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk cp [-r ] [-s <HOST>] [--solr-home <DIR>] [-u
<credentials>] [-z <HOST>] source destination";
+ }
+
+ @Override
+ public String getHeader() {
+ StringBuilder sb = new StringBuilder();
+ format(sb, "cp copies files or folders to/from Zookeeper or Zookeeper ->
Zookeeper");
+ format(sb, "");
+ format(sb, "<src>, <dest> : [file:][/]path/to/local/file or
zk:/path/to/zk/node");
+ format(
+ sb,
+ " NOTE: <src> and <dest> may both be Zookeeper
resources prefixed by 'zk:'");
+ format(sb, "When <src> is a zk resource, <dest> may be '.'");
+ format(
+ sb,
+ "If <dest> ends with '/', then <dest> will be a local folder or parent
znode and the last");
+ format(sb, "element of the <src> path will be appended unless <src> also
ends in a slash. ");
+ format(
+ sb, "<dest> may be zk:, which may be useful when using the cp -r form
to backup/restore ");
+ format(sb, "the entire zk state.");
+ format(sb, "You must enclose local paths that end in a wildcard in quotes
or just");
+ format(sb, "end the local path in a slash. That is,");
+ format(sb, "'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181' is
equivalent to");
+ format(sb, "'bin/solr zk cp -r \"/some/dir/*\" zk:/ -z localhost:2181'");
+ format(sb, "but 'bin/solr zk cp -r /some/dir/* zk:/ -z localhost:2181'
will throw an error");
+ format(sb, "");
+ format(sb, "to copy to local: 'bin/solr zk cp -r zk:/ /some/dir -z
localhost:2181'");
+ format(sb, "to restore to ZK: 'bin/solr zk cp -r /some/dir/ zk:/ -z
localhost:2181'");
+ format(sb, "");
+ format(
+ sb,
+ "The 'file:' prefix is stripped, thus 'file:/wherever' specifies an
absolute local path and");
+ format(
+ sb,
+ "'file:somewhere' specifies a relative local path. All paths on
Zookeeper are absolute.");
+ format(sb, "");
+ format(sb, "Zookeeper nodes CAN have data, so moving a single file to a
parent znode");
+ format(sb, "will overlay the data on the parent Znode so specifying the
trailing slash");
+ format(sb, "can be important.");
+ format(sb, "");
+ format(
+ sb, "Wildcards are supported when copying from local, trailing only
and must be quoted.");
+ format(sb, "\nList of options:");
+ return sb.toString();
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
String zkHost = SolrCLI.getZkHost(cli);
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
- String src = cli.getOptionValue("source");
- String dst = cli.getOptionValue("destination");
- Boolean recurse = Boolean.parseBoolean(cli.getOptionValue("recurse"));
+ String src = cli.getArgs()[0];
+ String dst = cli.getArgs()[1];
+ boolean recurse = cli.hasOption("recurse");
echo("Copying from '" + src + "' to '" + dst + "'. ZooKeeper at " +
zkHost);
boolean srcIsZk = src.toLowerCase(Locale.ROOT).startsWith("zk:");
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkLsTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkLsTool.java
index dfd004ef7df..27907c691c7 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkLsTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkLsTool.java
@@ -40,13 +40,6 @@ public class ZkLsTool extends ToolBase {
@Override
public List<Option> getOptions() {
return List.of(
- Option.builder()
- .longOpt("path")
- .argName("PATH")
- .hasArg()
- .required(true)
- .desc("Path to list.")
- .build(),
SolrCLI.OPTION_RECURSE,
SolrCLI.OPTION_SOLRURL,
SolrCLI.OPTION_SOLRURL_DEPRECATED,
@@ -61,16 +54,22 @@ public class ZkLsTool extends ToolBase {
return "ls";
}
+ @Override
+ public String getUsage() {
+ // very brittle. Maybe add a getArgsUsage to append the "path"?
+ return "bin/solr zk ls [-r ] [-s <HOST>] [-u <credentials>] [-v] [-z
<HOST>] path";
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
String zkHost = SolrCLI.getZkHost(cli);
+ String znode = cli.getArgs()[0];
try (SolrZkClient zkClient = SolrCLI.getSolrZkClient(cli, zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
- String znode = cli.getOptionValue("path");
- Boolean recurse = Boolean.parseBoolean(cli.getOptionValue("recurse"));
+ boolean recurse = cli.hasOption("recurse");
echoIfVerbose(
"Getting listing for ZooKeeper node "
+ znode
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
index 436eb93de27..8fb343a4e65 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.cli;
+import static org.apache.solr.packagemanager.PackageUtils.format;
+
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.util.List;
@@ -41,19 +43,11 @@ public class ZkMkrootTool extends ToolBase {
public List<Option> getOptions() {
return List.of(
Option.builder()
- .longOpt("path")
- .argName("PATH")
- .hasArg()
- .required(true)
- .desc("Path to create.")
- .build(),
- Option.builder() // This appears not to be wired into bin/solr
commands.
.longOpt("fail-on-exists")
.hasArg()
.required(false)
.desc("Raise an error if the root exists. Defaults to false.")
.build(),
- SolrCLI.OPTION_RECURSE,
SolrCLI.OPTION_SOLRURL,
SolrCLI.OPTION_SOLRURL_DEPRECATED,
SolrCLI.OPTION_ZKHOST,
@@ -67,16 +61,31 @@ public class ZkMkrootTool extends ToolBase {
return "mkroot";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk mkroot [--fail-on-exists <arg>] [-s <HOST>] [-u
<credentials>] [-v] [-z <HOST>] path";
+ }
+
+ @Override
+ public String getHeader() {
+ StringBuilder sb = new StringBuilder();
+ format(
+ sb,
+ "mkroot makes a znode in Zookeeper with no data. Can be used to make a
path of arbitrary");
+ format(sb, "depth but primarily intended to create a 'chroot'.\n\nList of
options:");
+ return sb.toString();
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
String zkHost = SolrCLI.getZkHost(cli);
+ String znode = cli.getArgs()[0];
boolean failOnExists = cli.hasOption("fail-on-exists");
try (SolrZkClient zkClient = SolrCLI.getSolrZkClient(cli, zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
- String znode = cli.getOptionValue("path");
echo("Creating ZooKeeper path " + znode + " on ZooKeeper at " + zkHost);
zkClient.makePath(znode, failOnExists, true);
} catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkMvTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkMvTool.java
index 00a159a70bd..65e2fdc511b 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkMvTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkMvTool.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.cli;
+import static org.apache.solr.packagemanager.PackageUtils.format;
+
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.util.List;
@@ -42,21 +44,6 @@ public class ZkMvTool extends ToolBase {
@Override
public List<Option> getOptions() {
return List.of(
- Option.builder()
- .argName("SRC")
- .longOpt("source")
- .hasArg()
- .required(true)
- .desc("Source Znode to move from.")
- .build(),
- Option.builder()
- .argName("DST")
- .longOpt("destination")
- .hasArg()
- .required(true)
- .desc("Destination Znode to move to.")
- .build(),
- SolrCLI.OPTION_RECURSE,
SolrCLI.OPTION_SOLRURL,
SolrCLI.OPTION_SOLRURL_DEPRECATED,
SolrCLI.OPTION_ZKHOST,
@@ -70,6 +57,26 @@ public class ZkMvTool extends ToolBase {
return "mv";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk mv [-s <HOST>] [-u <credentials>] [-v] [-z <HOST>]
source destination";
+ }
+
+ @Override
+ public String getHeader() {
+ StringBuilder sb = new StringBuilder();
+ format(sb, "mv moves (renames) znodes on Zookeeper.");
+ format(sb, "");
+ format(sb, "<src>, <dest> : Zookeeper nodes, the 'zk:' prefix is
optional.");
+ format(sb, "If <dest> ends with '/', then <dest> will be a parent znode");
+ format(sb, "and the last element of the <src> path will be appended.");
+ format(sb, "Zookeeper nodes CAN have data, so moving a single file to a
parent znode");
+ format(sb, "will overlay the data on the parent Znode so specifying the
trailing slash");
+ format(sb, "is important.");
+ format(sb, "\nList of options:");
+ return sb.toString();
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
@@ -77,8 +84,8 @@ public class ZkMvTool extends ToolBase {
try (SolrZkClient zkClient = SolrCLI.getSolrZkClient(cli, zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...", cli);
- String src = cli.getOptionValue("source");
- String dst = cli.getOptionValue("destination");
+ String src = cli.getArgs()[0];
+ String dst = cli.getArgs()[1];
if (src.toLowerCase(Locale.ROOT).startsWith("file:")
|| dst.toLowerCase(Locale.ROOT).startsWith("file:")) {
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
index b00b769e33d..fbedfc77868 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
@@ -42,13 +42,6 @@ public class ZkRmTool extends ToolBase {
@Override
public List<Option> getOptions() {
return List.of(
- Option.builder()
- .longOpt("path")
- .argName("PATH")
- .hasArg()
- .required(true)
- .desc("Path to remove.")
- .build(),
SolrCLI.OPTION_RECURSE,
SolrCLI.OPTION_SOLRURL,
SolrCLI.OPTION_SOLRURL_DEPRECATED,
@@ -63,13 +56,18 @@ public class ZkRmTool extends ToolBase {
return "rm";
}
+ @Override
+ public String getUsage() {
+ return "bin/solr zk rm [-r ] [-s <HOST>] [-u <credentials>] [-v] [-z
<HOST>] path";
+ }
+
@Override
public void runImpl(CommandLine cli) throws Exception {
SolrCLI.raiseLogLevelUnlessVerbose(cli);
String zkHost = SolrCLI.getZkHost(cli);
- String target = cli.getOptionValue("path");
- boolean recurse = Boolean.parseBoolean(cli.getOptionValue("recurse"));
+ String target = cli.getArgs()[0];
+ boolean recurse = cli.hasOption("recurse");
String znode = target;
if (target.toLowerCase(Locale.ROOT).startsWith("zk:")) {
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
b/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
new file mode 100644
index 00000000000..14b541d3b33
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+package org.apache.solr.cli;
+
+import static org.apache.solr.cli.SolrCLI.print;
+
+import java.io.PrintStream;
+import java.util.List;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+
+/** Supports zk help information in the bin/solr script. */
+public class ZkToolHelp extends ToolBase {
+
+ public ZkToolHelp() {
+ this(CLIO.getOutStream());
+ }
+
+ public ZkToolHelp(PrintStream stdout) {
+ super(stdout);
+ }
+
+ @Override
+ public List<Option> getOptions() {
+ return List.of(
+ Option.builder()
+ .longOpt("print-zk-subcommand-usage")
+ .desc("Reminds user to prepend zk to invoke the command.")
+ .required(false)
+ .build(),
+ Option.builder()
+ .longOpt("print-long-zk-usage")
+ .required(false)
+ .desc("Invokes the detailed help for zk commands.")
+ .build());
+ }
+
+ @Override
+ public String getName() {
+ return "zk-tool-help";
+ }
+
+ @Override
+ public void runImpl(CommandLine cli) throws Exception {
+ SolrCLI.raiseLogLevelUnlessVerbose(cli);
+
+ if (cli.hasOption("print-zk-subcommand-usage")) {
+ String scriptCommand = cli.getArgs()[0];
+ print(
+ "You must invoke this subcommand using the zk command. bin/solr zk
"
+ + scriptCommand
+ + ".");
+ }
+ if (cli.hasOption("print-long-zk-usage")) {
+ print("usage:");
+ print(new ZkLsTool().getUsage());
+ print(new ZkCpTool().getUsage());
+ print(new ZkMvTool().getUsage());
+
+ print(new ConfigSetUploadTool().getUsage());
+ print(new ConfigSetDownloadTool().getUsage());
+ print(new ZkMkrootTool().getUsage());
+ print(new LinkConfigTool().getUsage());
+ print(new UpdateACLTool().getUsage());
+ print("");
+ print(
+ "Pass --help or -h after any COMMAND to see command-specific usage
information such as: ./solr zk ls --help");
+ }
+ }
+}
diff --git a/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
b/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
index 2470d01dbf8..60883139e88 100644
--- a/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
@@ -172,13 +172,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
AbstractDistribZkTestBase.copyConfigUp(configSet, "cloud-subdirs", "cp1",
zkAddr);
// Now copy it somewhere else on ZK.
- String[] args =
- new String[] {
- "--source", "zk:/configs/cp1",
- "--destination", "zk:/cp2",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ String[] args = new String[] {"--recurse", "--zk-host", zkAddr,
"zk:/configs/cp1", "zk:/cp2"};
ZkCpTool cpTool = new ZkCpTool();
@@ -190,14 +184,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
Path tmp = createTempDir("tmpNewPlace2");
args =
new String[] {
- "--source",
- "zk:/configs/cp1",
- "--destination",
- "file:" + tmp.toAbsolutePath(),
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr, "zk:/configs/cp1", "file:" +
tmp.toAbsolutePath()
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -208,14 +195,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
tmp = createTempDir("tmpNewPlace3");
args =
new String[] {
- "--source",
- "zk:/configs/cp1",
- "--destination",
- tmp.toAbsolutePath().toString(),
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr, "zk:/configs/cp1",
tmp.toAbsolutePath().toString()
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -225,14 +205,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
// try with local->zk
args =
new String[] {
- "--source",
- srcPathCheck.toAbsolutePath().toString(),
- "--destination",
- "zk:/cp3",
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr,
srcPathCheck.toAbsolutePath().toString(), "zk:/cp3"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -242,67 +215,27 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
// try with local->zk, file: specified
args =
new String[] {
- "--source",
- "file:" + srcPathCheck.toAbsolutePath(),
- "--destination",
- "zk:/cp4",
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr, "file:" +
srcPathCheck.toAbsolutePath(), "zk:/cp4"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should have succeeded.", 0, res);
verifyZkLocalPathsMatch(srcPathCheck, "/cp4");
- // try with recurse not specified
+ // try with recurse not specified, and therefore not happening
args =
- new String[] {
- "--source",
- "file:" + srcPathCheck.toAbsolutePath(),
- "--destination",
- "zk:/cp5Fail",
- "--zk-host",
- zkAddr,
- };
+ new String[] {"--zk-host", zkAddr, "file:" +
srcPathCheck.toAbsolutePath(), "zk:/cp5Fail"};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertTrue("Copy should NOT have succeeded, recurse not specified.", 0 !=
res);
- // try with recurse = false
- args =
- new String[] {
- "--source",
- "file:" + srcPathCheck.toAbsolutePath(),
- "--destination",
- "zk:/cp6Fail",
- "--recurse",
- "false",
- "--zk-host",
- zkAddr,
- };
-
- res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
- assertTrue("Copy should NOT have succeeded, recurse set to false.", 0 !=
res);
-
// NOTE: really can't test copying to '.' because the test framework
doesn't allow altering the
// source tree and at least IntelliJ's CWD is in the source tree.
// copy to local ending in separator
// src and cp3 and cp4 are valid
String localSlash = tmp.normalize() + File.separator + "cpToLocal" +
File.separator;
- args =
- new String[] {
- "--source",
- "zk:/cp3/schema.xml",
- "--destination",
- localSlash,
- "--recurse",
- "false",
- "--zk-host",
- zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "zk:/cp3/schema.xml",
localSlash};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should nave created intermediate directory locally.",
0, res);
@@ -314,14 +247,10 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
// src and cp3 are valid
args =
new String[] {
- "--source",
- "file:" + srcPathCheck.normalize().toAbsolutePath() + File.separator
+ "solrconfig.xml",
- "--destination",
- "zk:/powerup/",
- "--recurse",
- "false",
"--zk-host",
zkAddr,
+ "file:" + srcPathCheck.normalize().toAbsolutePath() + File.separator
+ "solrconfig.xml",
+ "zk:/powerup/"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -334,14 +263,10 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
// src and cp3 are valid
args =
new String[] {
- "--source",
- "file:" + srcPathCheck.normalize().toAbsolutePath() + File.separator
+ "solrconfig.xml",
- "--destination",
- "zk:/copyUpFile.xml",
- "--recurse",
- "false",
"--zk-host",
zkAddr,
+ "file:" + srcPathCheck.normalize().toAbsolutePath() + File.separator
+ "solrconfig.xml",
+ "zk:/copyUpFile.xml"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -355,17 +280,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
String localNamed =
tmp.normalize() + File.separator + "localnamed" + File.separator +
"renamed.txt";
- args =
- new String[] {
- "--source",
- "zk:/cp4/solrconfig.xml",
- "--destination",
- "file:" + localNamed,
- "--recurse",
- "false",
- "--zk-host",
- zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "zk:/cp4/solrconfig.xml",
"file:" + localNamed};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy to local named file should have succeeded.", 0, res);
@@ -383,13 +298,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertTrue("Should have found Apache Software Foundation in the file! ",
foundApache);
// Test copy from somwehere in ZK to the root of ZK.
- args =
- new String[] {
- "--source", "zk:/cp4/solrconfig.xml",
- "--destination", "zk:/",
- "--recurse", "false",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "zk:/cp4/solrconfig.xml",
"zk:/"};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy from somewhere in ZK to ZK root should have
succeeded.", 0, res);
@@ -400,14 +309,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
// source path to the dst
args =
new String[] {
- "--source",
- "file:" + srcPathCheck.toAbsolutePath(),
- "--destination",
- "zk:/cp7/",
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr, "file:" +
srcPathCheck.toAbsolutePath(), "zk:/cp7/"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -423,14 +325,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
// First, just copy the data up the cp7 since it's a directory.
args =
new String[] {
- "--source",
- "file:" + file.toAbsolutePath(),
- "--destination",
- "zk:/cp7/conf/stopwords/",
- "--recurse",
- "false",
- "--zk-host",
- zkAddr,
+ "--zk-host", zkAddr, "file:" + file.toAbsolutePath(),
"zk:/cp7/conf/stopwords/"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -446,16 +341,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
tmp = createTempDir("cp8");
args =
- new String[] {
- "--source",
- "zk:/cp7",
- "--destination",
- "file:" + tmp.toAbsolutePath(),
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
- };
+ new String[] {"--recurse", "--zk-host", zkAddr, "zk:/cp7", "file:" +
tmp.toAbsolutePath()};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should have succeeded.", 0, res);
@@ -465,16 +351,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
// Finally, copy up to cp8 and verify that the data is up there.
args =
- new String[] {
- "--source",
- "file:" + tmp.toAbsolutePath(),
- "--destination",
- "zk:/cp9",
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
- };
+ new String[] {"--recurse", "--zk-host", zkAddr, "file:" +
tmp.toAbsolutePath(), "zk:/cp9"};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should have succeeded.", 0, res);
@@ -490,14 +367,10 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
args =
new String[] {
- "--source",
- "file:" + emptyFile.toAbsolutePath(),
- "--destination",
- "zk:/cp7/conf/stopwords/emptyfile",
- "--recurse",
- "false",
"--zk-host",
zkAddr,
+ "file:" + emptyFile.toAbsolutePath(),
+ "zk:/cp7/conf/stopwords/emptyfile"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -507,14 +380,10 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
Path emptyDest = Paths.get(tmp2.toAbsolutePath().toString(), "emptyfile");
args =
new String[] {
- "--source",
- "zk:/cp7/conf/stopwords/emptyfile",
- "--destination",
- "file:" + emptyDest.toAbsolutePath(),
- "--recurse",
- "false",
"--zk-host",
zkAddr,
+ "zk:/cp7/conf/stopwords/emptyfile",
+ "file:" + emptyDest.toAbsolutePath()
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should have succeeded.", 0, res);
@@ -525,14 +394,11 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
args =
new String[] {
- "--source",
- "file:" + emptyFile.getParent().getParent().toString(),
- "--destination",
- "zk:/cp10",
"--recurse",
- "true",
"--zk-host",
zkAddr,
+ "file:" + emptyFile.getParent().getParent().toString(),
+ "zk:/cp10"
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
@@ -542,14 +408,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
tmp2 = createTempDir("cp10");
args =
new String[] {
- "--source",
- "zk:/cp10",
- "--destination",
- "file:" + tmp2.toAbsolutePath(),
- "--recurse",
- "true",
- "--zk-host",
- zkAddr,
+ "--recurse", "--zk-host", zkAddr, "zk:/cp10", "file:" +
tmp2.toAbsolutePath()
};
res = cpTool.runTool(SolrCLI.processCommandLineArgs(cpTool, args));
assertEquals("Copy should have succeeded.", 0, res);
@@ -569,12 +428,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
AbstractDistribZkTestBase.copyConfigUp(configSet, "cloud-subdirs", "mv1",
zkAddr);
// Now move it somewhere else.
- String[] args =
- new String[] {
- "--source", "zk:/configs/mv1",
- "--destination", "zk:/mv2",
- "--zk-host", zkAddr,
- };
+ String[] args = new String[] {"--zk-host", zkAddr, "zk:/configs/mv1",
"zk:/mv2"};
ZkMvTool mvTool = new ZkMvTool();
@@ -588,27 +442,14 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
// Files are in mv2
// Now fail if we specify "file:". Everything should still be in /mv2
- args =
- new String[] {
- "--source",
- "file:" + File.separator + "mv2",
- "--destination",
- "/mv3",
- "--zk-host",
- zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "file:" + File.separator +
"mv2", "/mv3"};
// Still in mv2
res = mvTool.runTool(SolrCLI.processCommandLineArgs(mvTool, args));
assertTrue("Move should NOT have succeeded with file: specified.", 0 !=
res);
// Let's move it to yet another place with no zk: prefix.
- args =
- new String[] {
- "--source", "/mv2",
- "--destination", "/mv4",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "/mv2", "/mv4"};
res = mvTool.runTool(SolrCLI.processCommandLineArgs(mvTool, args));
assertEquals("Move should have succeeded.", 0, res);
@@ -618,12 +459,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
// Now does the moved directory match the original on disk?
verifyZkLocalPathsMatch(srcPathCheck, "/mv4");
- args =
- new String[] {
- "--source", "/mv4/solrconfig.xml",
- "--destination", "/testmvsingle/solrconfig.xml",
- "-z", zkAddr,
- };
+ args = new String[] {"-z", zkAddr, "/mv4/solrconfig.xml",
"/testmvsingle/solrconfig.xml"};
res = mvTool.runTool(SolrCLI.processCommandLineArgs(mvTool, args));
assertEquals("Move should have succeeded.", 0, res);
@@ -634,12 +470,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
zkClient.makePath("/parentNode", true);
// what happens if the destination ends with a slash?
- args =
- new String[] {
- "--source", "/mv4/schema.xml",
- "--destination", "/parentnode/",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "/mv4/schema.xml",
"/parentnode/"};
res = mvTool.runTool(SolrCLI.processCommandLineArgs(mvTool, args));
assertEquals("Move should have succeeded.", 0, res);
@@ -661,10 +492,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
AbstractDistribZkTestBase.copyConfigUp(configSet, "cloud-subdirs",
"lister", zkAddr);
// Should only find a single level.
- String[] args =
- new String[] {
- "--path", "/configs", "--zk-host", zkAddr,
- };
+ String[] args = new String[] {"--zk-host", zkAddr, "/configs"};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, false,
StandardCharsets.UTF_8.name());
@@ -677,13 +505,8 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertTrue("Return should contain the conf directory",
content.contains("lister"));
assertFalse("Return should NOT contain a child node",
content.contains("solrconfig.xml"));
- // simple ls recurse=false
- args =
- new String[] {
- "--path", "/configs",
- "--recurse", "false",
- "--zk-host", zkAddr,
- };
+ // simple ls with no recursion
+ args = new String[] {"--zk-host", zkAddr, "/configs"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
content = baos.toString(StandardCharsets.UTF_8);
@@ -692,13 +515,8 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertTrue("Return should contain the conf directory",
content.contains("lister"));
assertFalse("Return should NOT contain a child node",
content.contains("solrconfig.xml"));
- // recurse=true
- args =
- new String[] {
- "--path", "/configs",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ // ls with recursion
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "/configs"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
content = baos.toString(StandardCharsets.UTF_8);
@@ -708,12 +526,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertTrue("Return should contain a child node",
content.contains("solrconfig.xml"));
// Saw a case where going from root didn't work, so test it.
- args =
- new String[] {
- "--path", "/",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "/"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
content = baos.toString(StandardCharsets.UTF_8);
@@ -722,10 +535,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertTrue("Return should contain the conf directory",
content.contains("lister"));
assertTrue("Return should contain a child node",
content.contains("solrconfig.xml"));
- args =
- new String[] {
- "--path", "/", "--zk-host", zkAddr,
- };
+ args = new String[] {"--zk-host", zkAddr, "/"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
content = baos.toString(StandardCharsets.UTF_8);
@@ -733,12 +543,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertFalse("Return should not contain /zookeeper",
content.contains("/zookeeper"));
// Saw a case where ending in slash didn't work, so test it.
- args =
- new String[] {
- "--path", "/configs/",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "/configs/"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
content = baos.toString(StandardCharsets.UTF_8);
@@ -758,40 +563,26 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase
{
AbstractDistribZkTestBase.copyConfigUp(configSet, "cloud-subdirs", "rm2",
zkAddr);
// Should fail if recurse not set.
- String[] args =
- new String[] {
- "--path", "/configs/rm1", "--zk-host", zkAddr,
- };
+ String[] args = new String[] {"--zk-host", zkAddr, "/configs/rm1"};
ZkRmTool tool = new ZkRmTool();
int res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
- assertTrue(
- "Should have failed to remove node with children unless --recurse is
set to true",
- res != 0);
+ assertTrue("Should have failed to remove node with children unless
--recurse is set", res != 0);
// Are we sure all the znodes are still there?
verifyZkLocalPathsMatch(srcPathCheck, "/configs/rm1");
- args =
- new String[] {
- "--path", "zk:/configs/rm1",
- "--recurse", "false",
- "--zk-host", zkAddr,
- };
+ // run without recurse specified
+ args = new String[] {"--zk-host", zkAddr, "zk:/configs/rm1"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
assertTrue(
"Should have failed to remove node with children if --recurse is set
to false", res != 0);
- args =
- new String[] {
- "--path", "/configs/rm1",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "/configs/rm1"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
assertEquals("Should have removed node /configs/rm1", res, 0);
@@ -799,12 +590,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
"Znode /configs/toremove really should be gone",
zkClient.exists("/configs/rm1", true));
// Check that zk prefix also works.
- args =
- new String[] {
- "--path", "zk:/configs/rm2",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "zk:/configs/rm2"};
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
assertEquals("Should have removed node /configs/rm2", res, 0);
@@ -812,12 +598,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
"Znode /configs/toremove2 really should be gone",
zkClient.exists("/configs/rm2", true));
// This should silently just refuse to do anything to the / or /zookeeper
- args =
- new String[] {
- "--path", "zk:/",
- "--recurse", "true",
- "--zk-host", zkAddr,
- };
+ args = new String[] {"--recurse", "--zk-host", zkAddr, "zk:/"};
AbstractDistribZkTestBase.copyConfigUp(configSet, "cloud-subdirs", "rm3",
zkAddr);
res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
diff --git a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
index 250cee1a955..5cf76769d99 100644
--- a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
@@ -128,13 +128,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- localFile.getAbsolutePath(),
- "--destination",
- "zk:/data.txt",
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), localFile.getAbsolutePath(),
"zk:/data.txt"
};
ZkCpTool tool = new ZkCpTool();
@@ -179,13 +173,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- localFile.getAbsolutePath(),
- "--destination",
- "zk:/state.json",
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), localFile.getAbsolutePath(),
"zk:/state.json"
};
ZkCpTool tool = new ZkCpTool();
assertEquals(0, runTool(args, tool));
@@ -209,13 +197,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
args =
new String[] {
- "cp",
- "--source",
- localFile.getAbsolutePath(),
- "--destination",
- "zk:/state.json",
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), localFile.getAbsolutePath(),
"zk:/state.json"
};
assertEquals(0, runTool(args, tool));
@@ -234,12 +216,10 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
"cp",
- "--source",
- SOLR_HOME + File.separator + "solr-stress-new.xml",
- "--destination",
- "zk:/foo.xml",
"-z",
- zkServer.getZkAddress()
+ zkServer.getZkAddress(),
+ SOLR_HOME + File.separator + "solr-stress-new.xml",
+ "zk:/foo.xml"
};
ZkCpTool tool = new ZkCpTool();
@@ -258,12 +238,10 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
"cp",
- "--source",
- SOLR_HOME + File.separator + "solr-stress-new.xml",
- "--destination",
- "zk:foo.xml",
"-z",
- zkServer.getZkAddress()
+ zkServer.getZkAddress(),
+ SOLR_HOME + File.separator + "solr-stress-new.xml",
+ "zk:foo.xml"
};
ZkCpTool tool = new ZkCpTool();
@@ -285,12 +263,10 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
"cp",
- "--source",
- SOLR_HOME + File.separator + "solr-stress-new.xml",
- "--destination",
- "zk:/state.json",
"-z",
- zkServer.getZkAddress()
+ zkServer.getZkAddress(),
+ SOLR_HOME + File.separator + "solr-stress-new.xml",
+ "zk:/state.json"
};
ZkCpTool tool = new ZkCpTool();
@@ -316,12 +292,10 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
"cp",
- "--source",
- SOLR_HOME + File.separator + "not-there.xml",
- "--destination",
- "zk:/foo.xml",
"-z",
- zkServer.getZkAddress()
+ zkServer.getZkAddress(),
+ SOLR_HOME + File.separator + "not-there.xml",
+ "zk:/foo.xml"
};
ZkCpTool tool = new ZkCpTool();
@@ -332,7 +306,8 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
public void testLs() throws Exception {
zkClient.makePath("/test/path", true);
- String[] args = new String[] {"ls", "--path", "/", "-r", "true", "-z",
zkServer.getZkAddress()};
+ // test what happens when path arg "/" isn't the last one.
+ String[] args = new String[] {"ls", "/", "-r", "true", "-z",
zkServer.getZkAddress()};
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
final PrintStream myOut = new PrintStream(byteStream, false,
StandardCharsets.UTF_8);
@@ -461,10 +436,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
}
// test reset zk
- args =
- new String[] {
- "rm", "--path", "zk:/configs/confsetone", "-r", "true", "-z",
zkServer.getZkAddress()
- };
+ args = new String[] {"rm", "-r", "-z", zkServer.getZkAddress(),
"zk:/configs/confsetone"};
ZkRmTool zkRmTool = new ZkRmTool();
assertEquals(0, runTool(args, zkRmTool));
@@ -482,13 +454,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- "zk:" + getNode,
- "--destination",
- localFile.getAbsolutePath(),
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), "zk:" + getNode,
localFile.getAbsolutePath()
};
ByteArrayOutputStream byteStream2 = new ByteArrayOutputStream();
@@ -521,13 +487,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- "zk:" + getNode,
- "--destination",
- localFile.getAbsolutePath(),
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), "zk:" + getNode,
localFile.getAbsolutePath()
};
ZkCpTool tool = new ZkCpTool();
@@ -549,13 +509,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- "zk:" + getNode,
- "--destination",
- file.toAbsolutePath().toString(),
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), "zk:" + getNode,
file.toAbsolutePath().toString()
};
ZkCpTool tool = new ZkCpTool();
@@ -581,13 +535,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String[] args =
new String[] {
- "cp",
- "--source",
- "zk:" + getNode,
- "--destination",
- file.toAbsolutePath().toString(),
- "-z",
- zkServer.getZkAddress()
+ "cp", "-z", zkServer.getZkAddress(), "zk:" + getNode,
file.toAbsolutePath().toString()
};
ZkCpTool tool = new ZkCpTool();
@@ -603,15 +551,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
File file = createTempFile("newfile", null).toFile();
String[] args =
- new String[] {
- "cp",
- "--source",
- "zk:" + getNode,
- "--destination",
- file.getAbsolutePath(),
- "-z",
- zkServer.getZkAddress()
- };
+ new String[] {"cp", "-z", zkServer.getZkAddress(), "zk:" + getNode,
file.getAbsolutePath()};
ZkCpTool tool = new ZkCpTool();
assertEquals(1, runTool(args, tool));
@@ -620,7 +560,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
@Test
public void testInvalidZKAddress() throws Exception {
- String[] args = new String[] {"ls", "--path", "/", "-r", "true", "-z",
"----------:33332"};
+ String[] args = new String[] {"ls", "/", "-r", "-z", "----------:33332"};
ByteArrayOutputStream byteStream2 = new ByteArrayOutputStream();
final PrintStream myOut2 = new PrintStream(byteStream2, false,
StandardCharsets.UTF_8);
@@ -667,7 +607,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME,
"pass");
- String[] args = new String[] {"updateacls", "--path", "/", "-z",
zkServer.getZkAddress()};
+ String[] args = new String[] {"updateacls", "/", "-z",
zkServer.getZkAddress()};
UpdateACLTool tool = new UpdateACLTool();
assertEquals(0, runTool(args, tool));
} finally {
diff --git a/solr/docker/tests/cases/cloud_multi_node_embedded_zk/test.sh
b/solr/docker/tests/cases/cloud_multi_node_embedded_zk/test.sh
index 2ee47103264..888b755e422 100755
--- a/solr/docker/tests/cases/cloud_multi_node_embedded_zk/test.sh
+++ b/solr/docker/tests/cases/cloud_multi_node_embedded_zk/test.sh
@@ -46,7 +46,7 @@ if ! grep -q "${solr_ip}:8983" <<<"$data"; then
fi
echo "Creating distributed collection"
-data=$(docker exec --user=solr "$container_name" solr create -c test -rf 1 -s
2)
+data=$(docker exec --user=solr "$container_name" solr create -c test -rf 1
--shards 2)
if ! grep -q "Created collection 'test'" <<<"$data"; then
echo "Test $TEST_NAME $tag failed; could not create distributed collection"
diff --git a/solr/packaging/test/test_create_collection.bats
b/solr/packaging/test/test_create_collection.bats
index 3ffa6bd0ff3..2bee792c4c3 100644
--- a/solr/packaging/test/test_create_collection.bats
+++ b/solr/packaging/test/test_create_collection.bats
@@ -99,7 +99,7 @@ teardown() {
}
@test "create multisharded collections when s provided" {
- run -0 solr create -c COLL_NAME -s 2 --solr-url http://localhost:${SOLR_PORT}
+ run -0 solr create -c COLL_NAME --shards 2 --solr-url
http://localhost:${SOLR_PORT}
assert_output --partial "Created collection 'COLL_NAME'"
assert_output --partial "2 shard(s)"
}
diff --git a/solr/packaging/test/test_help.bats
b/solr/packaging/test/test_help.bats
index fe9c87866f1..f131cba0bce 100644
--- a/solr/packaging/test/test_help.bats
+++ b/solr/packaging/test/test_help.bats
@@ -92,7 +92,8 @@ setup() {
@test "zk help flag prints help" {
run solr zk --help
- assert_output --partial 'Usage: solr zk'
+ assert_output --partial 'usage:'
+ assert_output --partial 'bin/solr zk ls'
refute_output --partial 'ERROR'
}
diff --git a/solr/packaging/test/test_ssl.bats
b/solr/packaging/test/test_ssl.bats
index d114c15e25d..702133e3fa7 100644
--- a/solr/packaging/test/test_ssl.bats
+++ b/solr/packaging/test/test_ssl.bats
@@ -54,7 +54,7 @@ teardown() {
solr start -c
solr assert --started https://localhost:${SOLR_PORT} --timeout 5000
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/test/select?q=*:*"
@@ -92,7 +92,7 @@ teardown() {
solr start -c
solr assert --started https://localhost:${SOLR_PORT} --timeout 5000
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/test/select?q=*:*"
@@ -217,7 +217,7 @@ teardown() {
export SOLR_SSL_TRUST_STORE=
export SOLR_SSL_TRUST_STORE_PASSWORD=
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/admin/collections?action=CLUSTERSTATUS"
@@ -335,7 +335,7 @@ teardown() {
solr assert --started https://localhost:${SOLR_PORT} --timeout 5000
solr assert --started https://localhost:${SOLR2_PORT} --timeout 5000
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/admin/collections?action=CLUSTERSTATUS"
@@ -472,7 +472,7 @@ teardown() {
solr assert --started https://localhost:${SOLR_PORT} --timeout 5000
solr assert --started https://localhost:${SOLR2_PORT} --timeout 5000
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/admin/collections?action=CLUSTERSTATUS"
@@ -536,11 +536,11 @@ teardown() {
solr assert --started https://localhost:${SOLR2_PORT} --timeout 5000
# "test" collection is two shards, meaning there must be communication
between shards for queries (handled by http shard handler factory)
- run solr create -c test -s 2
+ run solr create -c test --shards 2
assert_output --partial "Created collection 'test'"
# "test-single-shard" is one shard and one replica, this means that one of
the nodes will have to forward requests to the other
- run solr create -c test-single-shard -s 1
+ run solr create -c test-single-shard --shards 1
assert_output --partial "Created collection 'test-single-shard'"
run solr api --solr-url
"https://localhost:${SOLR_PORT}/solr/test/select?q=*:*"
diff --git a/solr/packaging/test/test_zk.bats b/solr/packaging/test/test_zk.bats
index 817a33e1054..87c2501beba 100644
--- a/solr/packaging/test/test_zk.bats
+++ b/solr/packaging/test/test_zk.bats
@@ -36,6 +36,23 @@ teardown() {
save_home_on_failure
}
+@test "short help" {
+ run solr zk ls -h
+ assert_output --partial "usage: bin/solr zk"
+}
+
+@test "short help is inferred" {
+ run solr zk ls
+ assert_output --partial "usage: bin/solr zk"
+}
+
+@test "long help" {
+ run solr zk -h
+ assert_output --partial "bin/solr zk ls"
+ assert_output --partial "bin/solr zk updateacls"
+ assert_output --partial "Pass --help or -h after any COMMAND"
+}
+
@test "running subcommands with zk is prevented" {
run solr ls / -z localhost:${ZK_PORT}
assert_output --partial "You must invoke this subcommand using the zk command"
@@ -54,7 +71,7 @@ teardown() {
# We do mapping in bin/solr script from -solrUrl to --solr-url that prevents
deprecation warning
#assert_output --partial "Deprecated for removal since 9.7: Use --solr-url
instead"
- run solr zk ls / -s http://localhost:${SOLR_PORT}
+ run solr zk ls / -url http://localhost:${SOLR_PORT}
assert_output --partial "aliases.json"
# We do mapping in bin/solr script from -solrUrl to --solr-url that prevents
deprecation warning
#assert_output --partial "Deprecated for removal since 9.7: Use --solr-url
instead"
@@ -98,6 +115,11 @@ teardown() {
sleep 1
run solr zk ls / -z localhost:${ZK_PORT}
assert_output --partial "myfile3.txt"
+
+ run solr zk cp zk:/ -r "${BATS_TEST_TMPDIR}/recursive_download/"
+ [ -e "${BATS_TEST_TMPDIR}/recursive_download/myfile.txt" ]
+ [ -e "${BATS_TEST_TMPDIR}/recursive_download/myfile2.txt" ]
+ [ -e "${BATS_TEST_TMPDIR}/recursive_download/myfile3.txt" ]
rm myfile.txt
rm myfile2.txt
@@ -115,7 +137,12 @@ teardown() {
sleep 1
run curl "http://localhost:${SOLR_PORT}/api/cluster/configs?omitHeader=true"
assert_output --partial '"configSets":["_default","techproducts2"]'
+}
+@test "downconfig" {
+ run solr zk downconfig -z localhost:${ZK_PORT} -n _default -d
"${BATS_TEST_TMPDIR}/downconfig"
+ assert_output --partial "Downloading"
+ refute_output --partial "ERROR"
}
diff --git
a/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
b/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
index 3a517224747..4f15f8de677 100644
---
a/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
+++
b/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
@@ -706,7 +706,7 @@ This defaults to the same name as the core or collection.
Number of shards to split a collection into.
Only applies when Solr is running in SolrCloud mode.
+
-*Example*: `bin/solr create -s 2`
+*Example*: `bin/solr create --shards 2`
`-rf <replicas>` or `--replication-factor <replicas>`::
+
@@ -1139,7 +1139,7 @@ This parameter is unnecessary if `SOLR_AUTH_TYPE` is
defined in `solr.in.sh` or
== ZooKeeper Operations
The `bin/solr` script allows certain operations affecting ZooKeeper.
-These operations are for SolrCloud mode only.
+These operations are for SolrCloud mode only. For more information see
xref:zookeeper-utilities.adoc[ZooKeeper Utilities].
The operations are available as sub-commands, which each have their own set of
options.
diff --git
a/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-utilities.adoc
b/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-utilities.adoc
index 864ccb1b1dd..fb2a54b0478 100644
---
a/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-utilities.adoc
+++
b/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-utilities.adoc
@@ -26,7 +26,7 @@ The ZooKeeper specific commands are provided by the
xref:solr-control-script-ref
== Using Solr's CLI with ZooKeeper
-Use the `help` option to get a list of available ZooKeeper specifc commands
from the script itself, as in `bin/solr zk -h`.
+Use the `help` option to get a list of available ZooKeeper specific commands
from the script itself, as in `bin/solr zk -h`.
== Solr CLI Examples
diff --git
a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-diy.adoc
b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-diy.adoc
index 6a1fc1d26d7..14d7d98adb2 100644
--- a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-diy.adoc
+++ b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-diy.adoc
@@ -37,7 +37,7 @@ In this example, the collection will be named "localDocs";
replace that name wit
[,console]
----
-$ bin/solr create -c localDocs -s 2 -rf 2
+$ bin/solr create -c localDocs --shards 2 -rf 2
----
Again, as we saw from Exercise 2 above, this will use the `_default` configset
and all the schemaless features it provides.
diff --git
a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-films.adoc
b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-films.adoc
index 69622b5c7cc..503f1fa8034 100644
--- a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-films.adoc
+++ b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-films.adoc
@@ -75,7 +75,7 @@ The data you're going to index is related to movies, so start
by creating a coll
[,console]
----
-$ bin/solr create -c films -s 2 -rf 2
+$ bin/solr create -c films --shards 2 -rf 2
----
Whoa, wait.
diff --git
a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-techproducts.adoc
b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-techproducts.adoc
index 77b4aaa4ca0..6877e453d90 100644
---
a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-techproducts.adoc
+++
b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-techproducts.adoc
@@ -488,7 +488,7 @@ And then create a new collection:
[,console]
----
-$ bin/solr create -c <yourCollection> -s 2 -rf 2
+$ bin/solr create -c <yourCollection> --shards 2 -rf 2
----
To stop both of the Solr nodes we started, issue the command: