summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Fedotov <dfedotov@pivotal.io>2017-09-29 10:04:24 +0100
committerDaniil Fedotov <dfedotov@pivotal.io>2017-09-29 10:04:24 +0100
commit08942e7dcb06ad79e3bc0559e2acacabc6e9c985 (patch)
tree57b587e4c980255224d4a88abbc1fc948aba8cdd
parentf9ce80bac08680a8651acec46747084410acfee6 (diff)
downloadrabbitmq-server-git-08942e7dcb06ad79e3bc0559e2acacabc6e9c985.tar.gz
Remove rabbit_cli module
-rw-r--r--include/rabbit_cli.hrl74
-rw-r--r--src/rabbit_cli.erl286
-rw-r--r--src/rabbit_mnesia_rename.erl13
-rw-r--r--test/unit_SUITE.erl100
4 files changed, 12 insertions, 461 deletions
diff --git a/include/rabbit_cli.hrl b/include/rabbit_cli.hrl
deleted file mode 100644
index 12fa5b4dd8..0000000000
--- a/include/rabbit_cli.hrl
+++ /dev/null
@@ -1,74 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (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.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
-%% limitations under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developer of the Original Code is Pivotal Software, Inc.
-%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
-%%
-
--define(NODE_OPT, "-n").
--define(QUIET_OPT, "-q").
--define(VHOST_OPT, "-p").
--define(TIMEOUT_OPT, "-t").
-
--define(VERBOSE_OPT, "-v").
--define(MINIMAL_OPT, "-m").
--define(ENABLED_OPT, "-E").
--define(ENABLED_ALL_OPT, "-e").
-
--define(PRIORITY_OPT, "--priority").
--define(APPLY_TO_OPT, "--apply-to").
--define(RAM_OPT, "--ram").
--define(OFFLINE_OPT, "--offline").
--define(ONLINE_OPT, "--online").
--define(LOCAL_OPT, "--local").
-
--define(DECODE_OPT, "--decode").
--define(CIPHER_OPT, "--cipher").
--define(HASH_OPT, "--hash").
--define(ITERATIONS_OPT, "--iterations").
--define(LIST_CIPHERS_OPT, "--list-ciphers").
--define(LIST_HASHES_OPT, "--list-hashes").
-
--define(NODE_DEF(Node), {?NODE_OPT, {option, Node}}).
--define(QUIET_DEF, {?QUIET_OPT, flag}).
--define(VHOST_DEF, {?VHOST_OPT, {option, "/"}}).
--define(TIMEOUT_DEF, {?TIMEOUT_OPT, {option, use_default}}).
-
--define(VERBOSE_DEF, {?VERBOSE_OPT, flag}).
--define(MINIMAL_DEF, {?MINIMAL_OPT, flag}).
--define(ENABLED_DEF, {?ENABLED_OPT, flag}).
--define(ENABLED_ALL_DEF, {?ENABLED_ALL_OPT, flag}).
-
--define(PRIORITY_DEF, {?PRIORITY_OPT, {option, "0"}}).
--define(APPLY_TO_DEF, {?APPLY_TO_OPT, {option, "all"}}).
--define(RAM_DEF, {?RAM_OPT, flag}).
--define(OFFLINE_DEF, {?OFFLINE_OPT, flag}).
--define(ONLINE_DEF, {?ONLINE_OPT, flag}).
--define(LOCAL_DEF, {?LOCAL_OPT, flag}).
--define(DECODE_DEF, {?DECODE_OPT, flag}).
--define(CIPHER_DEF, {?CIPHER_OPT, {option, atom_to_list(rabbit_pbe:default_cipher())}}).
--define(HASH_DEF, {?HASH_OPT, {option, atom_to_list(rabbit_pbe:default_hash())}}).
--define(ITERATIONS_DEF, {?ITERATIONS_OPT, {option, integer_to_list(rabbit_pbe:default_iterations())}}).
--define(LIST_CIPHERS_DEF, {?LIST_CIPHERS_OPT, flag}).
--define(LIST_HASHES_DEF, {?LIST_HASHES_OPT, flag}).
-
-
-%% Subset of standartized exit codes from sysexits.h, see
-%% https://github.com/rabbitmq/rabbitmq-server/issues/396 for discussion.
--define(EX_OK , 0).
--define(EX_USAGE , 64). % Bad command-line arguments.
--define(EX_DATAERR , 65). % Wrong data in command-line arguments.
--define(EX_NOUSER , 67). % The user specified does not exist.
--define(EX_UNAVAILABLE, 69). % Could not connect to the target node.
--define(EX_SOFTWARE , 70). % Failed to execute command.
--define(EX_TEMPFAIL , 75). % Temporary error (e.g. something has timed out).
--define(EX_CONFIG , 78). % Misconfiguration detected
diff --git a/src/rabbit_cli.erl b/src/rabbit_cli.erl
deleted file mode 100644
index f9bc4683bc..0000000000
--- a/src/rabbit_cli.erl
+++ /dev/null
@@ -1,286 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (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.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
-%% limitations under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developer of the Original Code is GoPivotal, Inc.
-%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
-%%
-
--module(rabbit_cli).
--include("rabbit_cli.hrl").
-
--export([main/3, start_distribution/0, start_distribution/1,
- parse_arguments/4, mutually_exclusive_flags/3]).
-
-%%----------------------------------------------------------------------------
-
--type option_name() :: string().
--type option_value() :: string() | node() | boolean().
--type optdef() :: flag | {option, string()}.
--type parse_result() :: {'ok', {atom(), [{option_name(), option_value()}], [string()]}} |
- 'no_command'.
-
--spec main
- (fun (([string()], string()) -> parse_result()),
- fun ((atom(), atom(), [any()], [any()]) -> any()),
- atom()) ->
- no_return().
--spec start_distribution() -> {'ok', pid()} | {'error', any()}.
--spec start_distribution(string()) -> {'ok', pid()} | {'error', any()}.
--spec usage(atom()) -> no_return().
--spec parse_arguments
- ([{atom(), [{string(), optdef()}]} | atom()],
- [{string(), optdef()}], string(), [string()]) ->
- parse_result().
-
--spec mutually_exclusive_flags([{option_name(), option_value()}], term(), [{option_name(), term()}]) -> {ok, term()} | {error, string()}.
-
-ensure_cli_distribution() ->
- case start_distribution() of
- {ok, _} ->
- ok;
- {error, Error} ->
- print_error("Failed to initialize erlang distribution: ~p.",
- [Error]),
- rabbit_misc:quit(?EX_TEMPFAIL)
- end.
-
-%%----------------------------------------------------------------------------
-
-main(ParseFun, DoFun, UsageMod) ->
- error_logger:tty(false),
- ensure_cli_distribution(),
- {ok, [[NodeStr|_]|_]} = init:get_argument(nodename),
- {Command, Opts, Args} =
- case ParseFun(init:get_plain_arguments(), NodeStr) of
- {ok, Res} -> Res;
- no_command -> print_error("could not recognise command", []),
- usage(UsageMod)
- end,
- Node = proplists:get_value(?NODE_OPT, Opts),
- PrintInvalidCommandError =
- fun () ->
- print_error("invalid command '~s'",
- [string:join([atom_to_list(Command) | Args], " ")])
- end,
-
- %% The reason we don't use a try/catch here is that rpc:call turns
- %% thrown errors into normal return values
- case catch DoFun(Command, Node, Args, Opts) of
- ok ->
- rabbit_misc:quit(?EX_OK);
- {ok, Result} ->
- rabbit_control_misc:print_cmd_result(Command, Result),
- rabbit_misc:quit(?EX_OK);
- {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} -> %% < R15
- PrintInvalidCommandError(),
- usage(UsageMod);
- {'EXIT', {function_clause, [{?MODULE, action, _, _} | _]}} -> %% >= R15
- PrintInvalidCommandError(),
- usage(UsageMod);
- {error, {missing_dependencies, Missing, Blame}} ->
- print_error("dependent plugins ~p not found; used by ~p.",
- [Missing, Blame]),
- rabbit_misc:quit(?EX_CONFIG);
- {'EXIT', {badarg, _}} ->
- print_error("invalid parameter: ~p", [Args]),
- usage(UsageMod, ?EX_DATAERR);
- {error, {Problem, Reason}} when is_atom(Problem), is_binary(Reason) ->
- %% We handle this common case specially to avoid ~p since
- %% that has i18n issues
- print_error("~s: ~s", [Problem, Reason]),
- rabbit_misc:quit(?EX_SOFTWARE);
- {error, Reason} ->
- print_error("~p", [Reason]),
- rabbit_misc:quit(?EX_SOFTWARE);
- {error_string, Reason} ->
- print_error("~s", [Reason]),
- rabbit_misc:quit(?EX_SOFTWARE);
- {badrpc, {'EXIT', Reason}} ->
- print_error("~p", [Reason]),
- rabbit_misc:quit(?EX_SOFTWARE);
- {badrpc, Reason} ->
- case Reason of
- timeout ->
- print_error("operation ~w on node ~w timed out", [Command, Node]),
- rabbit_misc:quit(?EX_TEMPFAIL);
- _ ->
- print_error("unable to connect to node ~w: ~w", [Node, Reason]),
- print_badrpc_diagnostics([Node]),
- case Command of
- stop -> rabbit_misc:quit(?EX_OK);
- _ -> rabbit_misc:quit(?EX_UNAVAILABLE)
- end
- end;
- {badrpc_multi, Reason, Nodes} ->
- print_error("unable to connect to nodes ~p: ~w", [Nodes, Reason]),
- print_badrpc_diagnostics(Nodes),
- rabbit_misc:quit(?EX_UNAVAILABLE);
- function_clause ->
- print_error("operation ~w used with invalid parameter: ~p",
- [Command, Args]),
- usage(UsageMod);
- {refused, Username, _, _} ->
- print_error("failed to authenticate user \"~s\"", [Username]),
- rabbit_misc:quit(?EX_NOUSER);
- Other ->
- print_error("~p", [Other]),
- rabbit_misc:quit(?EX_SOFTWARE)
- end.
-
-start_distribution_anon(0, LastError) ->
- {error, LastError};
-start_distribution_anon(TriesLeft, _) ->
- NameCandidate = generate_cli_node_name(),
- case net_kernel:start([NameCandidate, name_type()]) of
- {ok, _} = Result ->
- Result;
- {error, Reason} ->
- start_distribution_anon(TriesLeft - 1, Reason)
- end.
-
-%% Tries to start distribution with random name chosen from limited list of candidates - to
-%% prevent atom table pollution on target nodes.
-start_distribution() ->
- rabbit_nodes:ensure_epmd(),
- start_distribution_anon(10, undefined).
-
-start_distribution(Name) ->
- rabbit_nodes:ensure_epmd(),
- net_kernel:start([Name, name_type()]).
-
-name_type() ->
- case os:getenv("RABBITMQ_USE_LONGNAME") of
- "true" -> longnames;
- _ -> shortnames
- end.
-
-generate_cli_node_name() ->
- Base = rabbit_misc:format("rabbitmq-cli-~2..0b", [rand:uniform(100)]),
- NameAsList =
- case {name_type(), inet_db:res_option(domain)} of
- {longnames, []} ->
- %% Distribution will fail to start if it's unable to
- %% determine FQDN of a node (with at least one dot in
- %% a name).
- %% CLI is always an initiator of connection, so it
- %% doesn't matter if the name will not resolve.
- Base ++ "@" ++ inet_db:gethostname() ++ ".no-domain";
- _ ->
- Base
- end,
- list_to_atom(NameAsList).
-
-usage(Mod) ->
- usage(Mod, ?EX_USAGE).
-
-usage(Mod, ExitCode) ->
- io:format("~s", [Mod:usage()]),
- rabbit_misc:quit(ExitCode).
-
-%%----------------------------------------------------------------------------
-
-parse_arguments(Commands, GlobalDefs, NodeOpt, CmdLine) ->
- case parse_arguments(Commands, GlobalDefs, CmdLine) of
- {ok, {Cmd, Opts0, Args}} ->
- Opts = [case K of
- NodeOpt -> {NodeOpt, rabbit_nodes:make(V)};
- _ -> {K, V}
- end || {K, V} <- Opts0],
- {ok, {Cmd, Opts, Args}};
- E ->
- E
- end.
-
-%% Takes:
-%% * A list of [{atom(), [{string(), optdef()]} | atom()], where the atom()s
-%% are the accepted commands and the optional [string()] is the list of
-%% accepted options for that command
-%% * A list [{string(), optdef()}] of options valid for all commands
-%% * The list of arguments given by the user
-%%
-%% Returns either {ok, {atom(), [{string(), string()}], [string()]} which are
-%% respectively the command, the key-value pairs of the options and the leftover
-%% arguments; or no_command if no command could be parsed.
-parse_arguments(Commands, GlobalDefs, As) ->
- lists:foldl(maybe_process_opts(GlobalDefs, As), no_command, Commands).
-
-maybe_process_opts(GDefs, As) ->
- fun({C, Os}, no_command) ->
- process_opts(atom_to_list(C), dict:from_list(GDefs ++ Os), As);
- (C, no_command) ->
- (maybe_process_opts(GDefs, As))({C, []}, no_command);
- (_, {ok, Res}) ->
- {ok, Res}
- end.
-
-process_opts(C, Defs, As0) ->
- KVs0 = dict:map(fun (_, flag) -> false;
- (_, {option, V}) -> V
- end, Defs),
- process_opts(Defs, C, As0, not_found, KVs0, []).
-
-%% Consume flags/options until you find the correct command. If there are no
-%% arguments or the first argument is not the command we're expecting, fail.
-%% Arguments to this are: definitions, cmd we're looking for, args we
-%% haven't parsed, whether we have found the cmd, options we've found,
-%% plain args we've found.
-process_opts(_Defs, C, [], found, KVs, Outs) ->
- {ok, {list_to_atom(C), dict:to_list(KVs), lists:reverse(Outs)}};
-process_opts(_Defs, _C, [], not_found, _, _) ->
- no_command;
-process_opts(Defs, C, [A | As], Found, KVs, Outs) ->
- OptType = case dict:find(A, Defs) of
- error -> none;
- {ok, flag} -> flag;
- {ok, {option, _}} -> option
- end,
- case {OptType, C, Found} of
- {flag, _, _} -> process_opts(
- Defs, C, As, Found, dict:store(A, true, KVs),
- Outs);
- {option, _, _} -> case As of
- [] -> no_command;
- [V | As1] -> process_opts(
- Defs, C, As1, Found,
- dict:store(A, V, KVs), Outs)
- end;
- {none, A, _} -> process_opts(Defs, C, As, found, KVs, Outs);
- {none, _, found} -> process_opts(Defs, C, As, found, KVs, [A | Outs]);
- {none, _, _} -> no_command
- end.
-
-mutually_exclusive_flags(CurrentOptionValues, Default, FlagsAndValues) ->
- PresentFlags = lists:filtermap(fun({OptName, _} = _O) ->
- proplists:get_bool(OptName, CurrentOptionValues)
- end,
- FlagsAndValues),
- case PresentFlags of
- [] ->
- {ok, Default};
- [{_, Value}] ->
- {ok, Value};
- _ ->
- Names = [ [$', N, $'] || {N, _} <- PresentFlags ],
- CommaSeparated = string:join(lists:droplast(Names), ", "),
- AndOneMore = lists:last(Names),
- Msg = io_lib:format("Options ~s and ~s are mutually exclusive", [CommaSeparated, AndOneMore]),
- {error, lists:flatten(Msg)}
- end.
-
-%%----------------------------------------------------------------------------
-
-fmt_stderr(Format, Args) -> rabbit_misc:format_stderr(Format ++ "~n", Args).
-
-print_error(Format, Args) -> fmt_stderr("Error: " ++ Format, Args).
-
-print_badrpc_diagnostics(Nodes) ->
- fmt_stderr(rabbit_nodes:diagnostics(Nodes), []).
diff --git a/src/rabbit_mnesia_rename.erl b/src/rabbit_mnesia_rename.erl
index 43a11bcb4f..323c006262 100644
--- a/src/rabbit_mnesia_rename.erl
+++ b/src/rabbit_mnesia_rename.erl
@@ -274,8 +274,19 @@ become(BecomeNode) ->
pong -> exit({node_running, BecomeNode});
pang -> ok = net_kernel:stop(),
io:format(" * Impersonating node: ~s...", [BecomeNode]),
- {ok, _} = rabbit_cli:start_distribution(BecomeNode),
+ {ok, _} = start_distribution(BecomeNode),
io:format(" done~n", []),
Dir = mnesia:system_info(directory),
io:format(" * Mnesia directory : ~s~n", [Dir])
end.
+
+start_distribution(Name) ->
+ rabbit_nodes:ensure_epmd(),
+ net_kernel:start([Name, name_type()]).
+
+name_type() ->
+ case os:getenv("RABBITMQ_USE_LONGNAME") of
+ "true" -> longnames;
+ _ -> shortnames
+ end.
+
diff --git a/test/unit_SUITE.erl b/test/unit_SUITE.erl
index 29c72eacac..8daa85b8f3 100644
--- a/test/unit_SUITE.erl
+++ b/test/unit_SUITE.erl
@@ -31,7 +31,6 @@ all() ->
groups() ->
[
{parallel_tests, [parallel], [
- arguments_parser,
auth_backend_internal_expand_topic_permission,
{basic_header_handling, [parallel], [
write_table_with_invalid_existing_type,
@@ -44,7 +43,6 @@ groups() ->
content_transcoding,
decrypt_config,
listing_plugins_from_multiple_directories,
- mutually_exclusive_flags_parsing,
rabbitmqctl_encode,
pg_local,
pmerge,
@@ -99,104 +97,6 @@ end_per_testcase(_TC, _Config) ->
ok.
%% -------------------------------------------------------------------
-%% Argument parsing.
-%% -------------------------------------------------------------------
-
-arguments_parser(_Config) ->
- GlobalOpts1 = [{"-f1", flag}, {"-o1", {option, "foo"}}],
- Commands1 = [command1, {command2, [{"-f2", flag}, {"-o2", {option, "bar"}}]}],
-
- GetOptions =
- fun (Args) ->
- rabbit_cli:parse_arguments(Commands1, GlobalOpts1, "-n", Args)
- end,
-
- check_parse_arguments(no_command, GetOptions, []),
- check_parse_arguments(no_command, GetOptions, ["foo", "bar"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "foo"}], []}},
- GetOptions, ["command1"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "blah"}], []}},
- GetOptions, ["command1", "-o1", "blah"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", true}, {"-o1", "foo"}], []}},
- GetOptions, ["command1", "-f1"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "blah"}], []}},
- GetOptions, ["-o1", "blah", "command1"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "blah"}], ["quux"]}},
- GetOptions, ["-o1", "blah", "command1", "quux"]),
- check_parse_arguments(
- {ok, {command1, [{"-f1", true}, {"-o1", "blah"}], ["quux", "baz"]}},
- GetOptions, ["command1", "quux", "-f1", "-o1", "blah", "baz"]),
- %% For duplicate flags, the last one counts
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "second"}], []}},
- GetOptions, ["-o1", "first", "command1", "-o1", "second"]),
- %% If the flag "eats" the command, the command won't be recognised
- check_parse_arguments(no_command, GetOptions,
- ["-o1", "command1", "quux"]),
- %% If a flag eats another flag, the eaten flag won't be recognised
- check_parse_arguments(
- {ok, {command1, [{"-f1", false}, {"-o1", "-f1"}], []}},
- GetOptions, ["command1", "-o1", "-f1"]),
-
- %% Now for some command-specific flags...
- check_parse_arguments(
- {ok, {command2, [{"-f1", false}, {"-f2", false},
- {"-o1", "foo"}, {"-o2", "bar"}], []}},
- GetOptions, ["command2"]),
-
- check_parse_arguments(
- {ok, {command2, [{"-f1", false}, {"-f2", true},
- {"-o1", "baz"}, {"-o2", "bar"}], ["quux", "foo"]}},
- GetOptions, ["-f2", "command2", "quux", "-o1", "baz", "foo"]),
-
- passed.
-
-check_parse_arguments(ExpRes, Fun, As) ->
- SortRes =
- fun (no_command) -> no_command;
- ({ok, {C, KVs, As1}}) -> {ok, {C, lists:sort(KVs), As1}}
- end,
-
- true = SortRes(ExpRes) =:= SortRes(Fun(As)).
-
-mutually_exclusive_flags_parsing(_Config) ->
- Matcher = fun ({ok, Value}, {ok, Value}) -> true;
- ({error, Value}, {error, Pattern}) ->
- case re:run(Value, Pattern) of
- {match, _} -> true;
- _ -> false
- end;
- (_, _) -> false
- end,
- Spec = [{"--online", online}
- ,{"--offline", offline}
- ,{"--local", local}],
- Default = all,
- Cases =[{["--online"], {ok, online}}
- ,{[], {ok, Default}}
- ,{["--offline"], {ok, offline}}
- ,{["--local"], {ok, local}}
- ,{["--offline", "--local"], {error, "mutually exclusive"}}
- ,{["--offline", "--online"], {error, "mutually exclusive"}}
- ,{["--offline", "--local", "--online"], {error, "mutually exclusive"}}
- ],
- lists:foreach(fun({Opts, Expected}) ->
- ExpandedOpts = [ {Opt, true} || Opt <- Opts ],
- Got = rabbit_cli:mutually_exclusive_flags(ExpandedOpts, all, Spec),
- case Matcher(Got, Expected) of
- true ->
- ok;
- false ->
- exit({no_match, Got, Expected, {opts, Opts}})
- end
- end, Cases).
-
-%% -------------------------------------------------------------------
%% basic_header_handling.
%% -------------------------------------------------------------------
-define(XDEATH_TABLE,