mirror of
https://github.com/processone/ejabberd.git
synced 2024-06-08 21:43:07 +02:00
New API to update host config on the fly (thanks to Juan Pablo Carlino)
Adds ejabberd_hosts:update_host_conf/2 to update a host with a new configuration on the fly. Typically this is useful to enable / disable specific modules for a given host without restarting the whole app. Also fixes a problem with mod_disco, after config refreshing to include global services if there are not locally available.
This commit is contained in:
parent
bee01cfd1e
commit
6e65f0694e
|
@ -33,6 +33,7 @@
|
|||
,running/1
|
||||
,registered/0
|
||||
,remove/1
|
||||
,update_host_conf/2
|
||||
]).
|
||||
|
||||
%% Host control API
|
||||
|
@ -87,6 +88,16 @@ register(Host, Config) when is_list(Host), is_list(Config) ->
|
|||
reload(),
|
||||
ok.
|
||||
|
||||
%% Updates host configuration
|
||||
update_host_conf(Host, Config) when is_list(Host), is_list(Config) ->
|
||||
true = jlib:is_nodename(Host),
|
||||
case registered(Host) of
|
||||
false -> {error, host_process_not_registered};
|
||||
true ->
|
||||
remove(Host),
|
||||
?MODULE:register(Host, Config)
|
||||
end.
|
||||
|
||||
%% Removes a vhost from the system,
|
||||
%% XXX deleting all ODBC data.
|
||||
remove(Host) when is_list(Host) ->
|
||||
|
@ -222,6 +233,18 @@ handle_info(reload, State = #state{state=wait_odbc}) ->
|
|||
?ERROR_MSG("Tried to reload vhosts while waiting for odbc startup.", []),
|
||||
handle_info(timeout, State);
|
||||
|
||||
handle_info({reload, Host}, State = #state{state=running}) ->
|
||||
try reload_host(Host)
|
||||
catch
|
||||
Class:Error ->
|
||||
StackTrace = erlang:get_stacktrace(),
|
||||
?ERROR_MSG("~p while synchonising running ~p with database: ~p~n~p", [Host, Class, Error, StackTrace])
|
||||
end,
|
||||
{noreply, State};
|
||||
handle_info({reload, Host}, State = #state{state=wait_odbc}) ->
|
||||
?ERROR_MSG("Tried to reload ~p while waiting for odbc startup.", [Host]),
|
||||
handle_info(timeout, State);
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
@ -264,6 +287,21 @@ reload_hosts(NewHosts) ->
|
|||
ejabberd_local:refresh_iq_handlers(),
|
||||
{DeletedHosts, AddedHosts}.
|
||||
|
||||
%% updates the configuration of an existing virtual host
|
||||
reload_host(Host) ->
|
||||
Config = get_host_config(odbc,Host),
|
||||
F = fun() ->
|
||||
mnesia:write_lock_table(local_config),
|
||||
ejabberd_config:configure_host(Host, Config),
|
||||
ok
|
||||
end,
|
||||
{atomic, ok} = mnesia:transaction(F),
|
||||
% restart host
|
||||
stop_host(Host),
|
||||
start_host(Host),
|
||||
ejabberd_local:refresh_iq_handlers(),
|
||||
ok.
|
||||
|
||||
%% Apply the vhost changes (new, removed vhosts, configuration) to mnesia
|
||||
update_config(AddHostConfig, RemoveHosts) ->
|
||||
F = fun() ->
|
||||
|
@ -321,7 +359,7 @@ stop_host(Host) ->
|
|||
?DEBUG("Stopping host ~p", [Host]),
|
||||
ejabberd_router:force_unregister_route(Host),
|
||||
lists:foreach(fun(Module) ->
|
||||
gen_mod:stop_module(Host, Module)
|
||||
gen_mod:stop_module_keep_config(Host, Module)
|
||||
end, gen_mod:loaded_modules(Host)),
|
||||
case auth_method(Host) of
|
||||
use_global_auth_method -> ok;
|
||||
|
|
|
@ -126,10 +126,8 @@ process_local_iq_items(From, To, #iq{type = get, payload = SubEl,
|
|||
lang = Lang} = IQ_Rec) ->
|
||||
Node = exmpp_xml:get_attribute_as_binary(SubEl, 'node', <<>>),
|
||||
|
||||
case ejabberd_hooks:run_fold(disco_local_items,
|
||||
exmpp_jid:prep_domain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
Host = exmpp_jid:prep_domain(To),
|
||||
case find_items(disco_local_items, Host, From, To, Node, Lang) of
|
||||
{result, Items} ->
|
||||
ANode = case Node of
|
||||
<<>> -> [];
|
||||
|
@ -156,10 +154,7 @@ process_local_iq_info(From, To, #iq{type = get, payload = SubEl,
|
|||
Host = exmpp_jid:prep_domain_as_list(To),
|
||||
Info = ejabberd_hooks:run_fold(disco_info, HostB, [],
|
||||
[Host, ?MODULE, Node, Lang]),
|
||||
case ejabberd_hooks:run_fold(disco_local_features,
|
||||
exmpp_jid:prep_domain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
case find_items(disco_local_features, HostB, From, To, Node, Lang) of
|
||||
{result, Features} ->
|
||||
ANode = case Node of
|
||||
<<>> -> [];
|
||||
|
@ -290,10 +285,8 @@ get_vh_services(Host) ->
|
|||
process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
|
||||
lang = Lang} = IQ_Rec) ->
|
||||
Node = exmpp_xml:get_attribute_as_binary(SubEl, 'node', <<>>),
|
||||
case ejabberd_hooks:run_fold(disco_sm_items,
|
||||
exmpp_jid:prep_domain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
Host = exmpp_jid:prep_domain(To),
|
||||
case find_items(disco_sm_items, Host, From, To, Node, Lang) of
|
||||
{result, Items} ->
|
||||
ANode = case Node of
|
||||
<<>> -> [];
|
||||
|
@ -374,10 +367,8 @@ process_sm_iq_info(From, To, #iq{type = get, payload = SubEl,
|
|||
exmpp_jid:prep_domain(To),
|
||||
[],
|
||||
[From, To, Node, Lang]),
|
||||
case ejabberd_hooks:run_fold(disco_sm_features,
|
||||
exmpp_jid:prep_domain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
Host = exmpp_jid:prep_domain(To),
|
||||
case find_items(disco_sm_features, Host, From, To, Node, Lang) of
|
||||
{result, Features} ->
|
||||
ANode = case Node of
|
||||
<<>> -> [];
|
||||
|
@ -496,3 +487,13 @@ values_to_xml(Values) ->
|
|||
end,
|
||||
Values
|
||||
).
|
||||
|
||||
%%%%%% private functions
|
||||
find_items(Hook, global, From, To, Node, Lang) ->
|
||||
ejabberd_hooks:run_fold(Hook, global, empty, [From, To, Node, Lang]);
|
||||
find_items(Hook, Host, From, To, Node, Lang) ->
|
||||
case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, Node, Lang]) of
|
||||
empty ->
|
||||
find_items(Hook, global, From, To, Node, Lang);
|
||||
Items -> Items
|
||||
end.
|
||||
|
|
Loading…
Reference in New Issue
Block a user