24
1
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:
Badlop 2010-08-11 23:31:22 +02:00
parent bee01cfd1e
commit 6e65f0694e
2 changed files with 56 additions and 17 deletions

View File

@ -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;

View File

@ -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.