API to restart a crashed vhost.
Administrator should be able to restart vhosts if they believe it can be recovered. Added buttons to vhost status tables and the new HTTP API endpoint: /vhosts/:vhost/start/:node Part of rabbitmq/rabbitmq-server#1321 [#149484305]
This commit is contained in:
parent
179e99bd93
commit
7f54319279
|
|
@ -235,6 +235,7 @@ table.two-col-layout > tbody > tr > td { width: 50%; vertical-align: top; }
|
|||
|
||||
input[type=submit], button { padding: 8px; border-radius: 5px; -moz-border-radius: 5px; color: black !important; text-decoration: none; cursor: pointer; font-weight: normal; }
|
||||
table.list input[type=submit], table.list button { padding: 4px; }
|
||||
table.mini input[type=submit], table.mini button { padding: 4px; }
|
||||
|
||||
input[type=submit], button {
|
||||
background: #ddf;
|
||||
|
|
|
|||
|
|
@ -282,6 +282,9 @@ dispatcher_add(function(sammy) {
|
|||
}
|
||||
}
|
||||
});
|
||||
sammy.post('#/restart_vhost', function(){
|
||||
if(sync_post(this, '/vhosts/:vhost/start/:node')) update();
|
||||
})
|
||||
sammy.del('#/limits', function() {
|
||||
if (sync_delete(this, '/vhost-limits/:vhost/:name')) update();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,7 +27,15 @@
|
|||
<% for (var node in vhost.cluster_state) { %>
|
||||
<tr>
|
||||
<th><%= fmt_escape_html(node) %> :</th>
|
||||
<td><%= vhost.cluster_state[node] %></td>
|
||||
<td><%= vhost.cluster_state[node] %>
|
||||
<% if (vhost.cluster_state[node] == "stopped"){ %>
|
||||
<form action="#/restart_vhost" method="post">
|
||||
<input type="hidden" name="node" value="<%= node %>"/>
|
||||
<input type="hidden" name="vhost" value="<%= vhost.name %>"/>
|
||||
<input type="submit" value="Restart"/>
|
||||
</form>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -69,7 +69,16 @@
|
|||
%>
|
||||
<tr>
|
||||
<td><%= node %></td>
|
||||
<td><%= state %></td>
|
||||
<td>
|
||||
<%= state %>
|
||||
<% if (state == "stopped"){ %>
|
||||
<form action="#/restart_vhost" method="post" class="confirm">
|
||||
<input type="hidden" name="node" value="<%= node %>"/>
|
||||
<input type="hidden" name="vhost" value="<%= vhost.name %>"/>
|
||||
<input type="submit" value="Restart"/>
|
||||
</form>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ dispatcher() ->
|
|||
{"/bindings/:vhost/e/:source/:dtype/:destination/:props", rabbit_mgmt_wm_binding, []},
|
||||
{"/vhosts", rabbit_mgmt_wm_vhosts, []},
|
||||
{"/vhosts/:vhost", rabbit_mgmt_wm_vhost, []},
|
||||
{"/vhosts/:vhost/start/:node", rabbit_mgmt_wm_vhost_restart, []},
|
||||
{"/vhosts/:vhost/permissions", rabbit_mgmt_wm_permissions_vhost, []},
|
||||
{"/vhosts/:vhost/topic-permissions", rabbit_mgmt_wm_topic_permissions_vhost, []},
|
||||
%% /connections/:connection is already taken, we cannot use our standard scheme here
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
%% 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 Management Plugin.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2011-2012 GoPivotal, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_mgmt_wm_vhost_restart).
|
||||
|
||||
-export([init/3, rest_init/2, resource_exists/2, is_authorized/2,
|
||||
allowed_methods/2, content_types_accepted/2, accept_content/2]).
|
||||
-export([variances/2]).
|
||||
|
||||
-include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
init(_, _, _) -> {upgrade, protocol, cowboy_rest}.
|
||||
|
||||
rest_init(Req, _Config) ->
|
||||
{ok, rabbit_mgmt_cors:set_headers(Req, ?MODULE), #context{}}.
|
||||
|
||||
variances(Req, Context) ->
|
||||
{[<<"accept-encoding">>, <<"origin">>], Req, Context}.
|
||||
|
||||
allowed_methods(ReqData, Context) ->
|
||||
{[<<"POST">>, <<"OPTIONS">>], ReqData, Context}.
|
||||
|
||||
resource_exists(ReqData, Context) ->
|
||||
VHost = id(ReqData),
|
||||
{rabbit_vhost:exists(VHost), ReqData, Context}.
|
||||
|
||||
content_types_accepted(ReqData, Context) ->
|
||||
{[{'*', accept_content}], ReqData, Context}.
|
||||
|
||||
accept_content(ReqData, Context) ->
|
||||
VHost = id(ReqData),
|
||||
NodeB = rabbit_mgmt_util:id(node, ReqData),
|
||||
Node = binary_to_atom(NodeB, utf8),
|
||||
case rabbit_vhost_sup_sup:start_vhost(VHost, Node) of
|
||||
{ok, _} ->
|
||||
{true, ReqData, Context};
|
||||
{error, {already_started, _}} ->
|
||||
{true, ReqData, Context};
|
||||
{error, Err} ->
|
||||
Message = io_lib:format("Request to node ~s failed with ~p",
|
||||
[Node, Err]),
|
||||
rabbit_mgmt_util:bad_request(list_to_binary(Message), ReqData, Context)
|
||||
end.
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
rabbit_mgmt_util:is_authorized_admin(ReqData, Context).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
id(ReqData) ->
|
||||
rabbit_mgmt_util:id(vhost, ReqData).
|
||||
|
|
@ -334,6 +334,19 @@ vhosts_test(Config) ->
|
|||
%% Check individually
|
||||
assert_item(#{name => <<"/">>}, http_get(Config, "/vhosts/%2f", ?OK)),
|
||||
assert_item(#{name => <<"myvhost">>},http_get(Config, "/vhosts/myvhost")),
|
||||
|
||||
%% Crash it
|
||||
rabbit_ct_broker_helpers:force_vhost_failure(Config, <<"myvhost">>),
|
||||
[NodeData] = http_get(Config, "/nodes"),
|
||||
Node = binary_to_atom(maps:get(name, NodeData), utf8),
|
||||
assert_item(#{name => <<"myvhost">>, cluster_state => #{Node => <<"stopped">>}},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
|
||||
%% Restart it
|
||||
http_post(Config, "/vhosts/myvhost/start/" ++ atom_to_list(Node), [], {group, '2xx'}),
|
||||
assert_item(#{name => <<"myvhost">>, cluster_state => #{Node => <<"running">>}},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
|
||||
%% Delete it
|
||||
http_delete(Config, "/vhosts/myvhost", {group, '2xx'}),
|
||||
%% It's not there
|
||||
|
|
@ -344,17 +357,15 @@ vhosts_test(Config) ->
|
|||
|
||||
vhosts_trace_test(Config) ->
|
||||
http_put(Config, "/vhosts/myvhost", none, {group, '2xx'}),
|
||||
?assertMatch(#{name := <<"myvhost">>, tracing := false, cluster_state := _},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
Disabled = #{name => <<"myvhost">>, tracing => false},
|
||||
Enabled = #{name => <<"myvhost">>, tracing => true},
|
||||
assert_item(Disabled, http_get(Config, "/vhosts/myvhost")),
|
||||
http_put(Config, "/vhosts/myvhost", [{tracing, true}], {group, '2xx'}),
|
||||
?assertMatch(#{name := <<"myvhost">>, tracing := true, cluster_state := _},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
assert_item(Enabled, http_get(Config, "/vhosts/myvhost")),
|
||||
http_put(Config, "/vhosts/myvhost", [{tracing, true}], {group, '2xx'}),
|
||||
?assertMatch(#{name := <<"myvhost">>, tracing := true},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
assert_item(Enabled, http_get(Config, "/vhosts/myvhost")),
|
||||
http_put(Config, "/vhosts/myvhost", [{tracing, false}], {group, '2xx'}),
|
||||
?assertMatch(#{name := <<"myvhost">>, tracing := false},
|
||||
http_get(Config, "/vhosts/myvhost")),
|
||||
assert_item(Disabled, http_get(Config, "/vhosts/myvhost")),
|
||||
http_delete(Config, "/vhosts/myvhost", {group, '2xx'}),
|
||||
|
||||
passed.
|
||||
|
|
@ -809,9 +820,9 @@ queues_test(Config) ->
|
|||
|
||||
rabbit_ct_broker_helpers:force_vhost_failure(Config, <<"downvhost">>),
|
||||
%% The vhost is down
|
||||
#{name := <<"downvhost">>, tracing := false, cluster_state := DownClusterState} =
|
||||
http_get(Config, "/vhosts/downvhost"),
|
||||
?assertEqual([<<"stopped">>], lists:usort(maps:values(DownClusterState))),
|
||||
Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
|
||||
DownVHost = #{name => <<"downvhost">>, tracing => false, cluster_state => #{Node => <<"stopped">>}},
|
||||
assert_item(DownVHost, http_get(Config, "/vhosts/downvhost")),
|
||||
|
||||
DownQueues = http_get(Config, "/queues/downvhost"),
|
||||
DownQueue = http_get(Config, "/queues/downvhost/foo"),
|
||||
|
|
|
|||
Loading…
Reference in New Issue