summaryrefslogtreecommitdiff
path: root/src/rabbit_control_main.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rabbit_control_main.erl')
-rw-r--r--src/rabbit_control_main.erl61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index 451f4d70..70fe10e6 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -54,6 +54,7 @@
change_cluster_node_type,
update_cluster_nodes,
{forget_cluster_node, [?OFFLINE_DEF]},
+ force_boot,
cluster_status,
{sync_queue, [?VHOST_DEF]},
{cancel_sync_queue, [?VHOST_DEF]},
@@ -114,6 +115,12 @@
{"Policies", rabbit_policy, list_formatted, info_keys},
{"Parameters", rabbit_runtime_parameters, list_formatted, info_keys}]).
+-define(COMMANDS_NOT_REQUIRING_APP,
+ [stop, stop_app, start_app, wait, reset, force_reset, rotate_logs,
+ join_cluster, change_cluster_node_type, update_cluster_nodes,
+ forget_cluster_node, cluster_status, status, environment, eval,
+ force_boot]).
+
%%----------------------------------------------------------------------------
-ifdef(use_specs).
@@ -131,6 +138,7 @@
%%----------------------------------------------------------------------------
start() ->
+ start_distribution(),
{ok, [[NodeStr|_]|_]} = init:get_argument(nodename),
{Command, Opts, Args} =
case parse_arguments(init:get_plain_arguments(), NodeStr) of
@@ -154,7 +162,7 @@ start() ->
%% The reason we don't use a try/catch here is that rpc:call turns
%% thrown errors into normal return values
- case catch action(Command, Node, Args, Opts, Inform) of
+ case catch do_action(Command, Node, Args, Opts, Inform) of
ok ->
case Quiet of
true -> ok;
@@ -249,6 +257,15 @@ parse_arguments(CmdLine, NodeStr) ->
%%----------------------------------------------------------------------------
+do_action(Command, Node, Args, Opts, Inform) ->
+ case lists:member(Command, ?COMMANDS_NOT_REQUIRING_APP) of
+ false -> case ensure_app_running(Node) of
+ ok -> action(Command, Node, Args, Opts, Inform);
+ E -> E
+ end;
+ true -> action(Command, Node, Args, Opts, Inform)
+ end.
+
action(stop, Node, Args, _Opts, Inform) ->
Inform("Stopping and halting node ~p", [Node]),
Res = call(Node, {rabbit, stop_and_halt, []}),
@@ -302,8 +319,19 @@ action(forget_cluster_node, Node, [ClusterNodeS], Opts, Inform) ->
ClusterNode = list_to_atom(ClusterNodeS),
RemoveWhenOffline = proplists:get_bool(?OFFLINE_OPT, Opts),
Inform("Removing node ~p from cluster", [ClusterNode]),
- rpc_call(Node, rabbit_mnesia, forget_cluster_node,
- [ClusterNode, RemoveWhenOffline]);
+ case RemoveWhenOffline of
+ true -> become(Node),
+ rabbit_mnesia:forget_cluster_node(ClusterNode, true);
+ false -> rpc_call(Node, rabbit_mnesia, forget_cluster_node,
+ [ClusterNode, false])
+ end;
+
+action(force_boot, Node, [], _Opts, Inform) ->
+ Inform("Forcing boot for Mnesia dir ~s", [mnesia:system_info(directory)]),
+ case rabbit:is_running(Node) of
+ false -> rabbit_mnesia:force_load_next_boot();
+ true -> {error, rabbit_running}
+ end;
action(sync_queue, Node, [Q], Opts, Inform) ->
VHost = proplists:get_value(?VHOST_OPT, Opts),
@@ -650,6 +678,22 @@ exit_loop(Port) ->
{Port, _} -> exit_loop(Port)
end.
+start_distribution() ->
+ CtlNodeName = rabbit_misc:format("rabbitmqctl-~s", [os:getpid()]),
+ {ok, _} = net_kernel:start([list_to_atom(CtlNodeName), shortnames]).
+
+become(BecomeNode) ->
+ case net_adm:ping(BecomeNode) of
+ pong -> exit({node_running, BecomeNode});
+ pang -> io:format(" * Impersonating node: ~s...", [BecomeNode]),
+ error_logger:tty(false),
+ ok = net_kernel:stop(),
+ {ok, _} = net_kernel:start([BecomeNode, shortnames]),
+ io:format(" done~n", []),
+ Dir = mnesia:system_info(directory),
+ io:format(" * Mnesia directory : ~s~n", [Dir])
+ end.
+
%%----------------------------------------------------------------------------
default_if_empty(List, Default) when is_list(List) ->
@@ -715,6 +759,17 @@ unsafe_rpc(Node, Mod, Fun, Args) ->
Normal -> Normal
end.
+ensure_app_running(Node) ->
+ case call(Node, {rabbit, is_running, []}) of
+ true -> ok;
+ false -> {error_string,
+ rabbit_misc:format(
+ "rabbit application is not running on node ~s.~n"
+ " * Suggestion: start it with \"rabbitmqctl start_app\" "
+ "and try again", [Node])};
+ Other -> Other
+ end.
+
call(Node, {Mod, Fun, Args}) ->
rpc_call(Node, Mod, Fun, lists:map(fun list_to_binary_utf8/1, Args)).