Merge pull request #9750 from zhongwencool/bootstrap-app-env

fix: save app's env when bootstrapping and reloading
This commit is contained in:
Zaiming (Stone) Shi 2023-01-14 07:33:13 +01:00 committed by GitHub
commit 002f5dbd89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 15 deletions

1
.gitignore vendored
View File

@ -67,6 +67,7 @@ mix.lock
apps/emqx/test/emqx_static_checks_data/master.bpapi apps/emqx/test/emqx_static_checks_data/master.bpapi
# rendered configurations # rendered configurations
*.conf.rendered *.conf.rendered
*.conf.rendered.*
lux_logs/ lux_logs/
/.prepare /.prepare
bom.json bom.json

View File

@ -18,7 +18,7 @@
-behaviour(emqx_config_handler). -behaviour(emqx_config_handler).
%% API %% API
-export([add_handler/0, remove_handler/0]). -export([add_handler/0, remove_handler/0, refresh_config/0]).
-export([post_config_update/5]). -export([post_config_update/5]).
-define(LOG, [log]). -define(LOG, [log]).
@ -31,6 +31,21 @@ remove_handler() ->
ok = emqx_config_handler:remove_handler(?LOG), ok = emqx_config_handler:remove_handler(?LOG),
ok. ok.
%% refresh logger config when booting, the override config may have changed after node start.
%% Kernel's app env is confirmed before the node starts,
%% but we only copy cluster-override.conf from other node after this node starts,
%% so we need to refresh the logger config after this node starts.
%% It will not affect the logger config when cluster-override.conf is unchanged.
refresh_config() ->
case emqx:get_raw_config(?LOG, undefined) of
%% no logger config when CT is running.
undefined ->
ok;
Log ->
{ok, _} = emqx:update_config(?LOG, Log),
ok
end.
post_config_update(?LOG, _Req, _NewConf, _OldConf, AppEnvs) -> post_config_update(?LOG, _Req, _NewConf, _OldConf, AppEnvs) ->
Kernel = proplists:get_value(kernel, AppEnvs), Kernel = proplists:get_value(kernel, AppEnvs),
NewHandlers = proplists:get_value(logger, Kernel, []), NewHandlers = proplists:get_value(logger, Kernel, []),

View File

@ -333,7 +333,8 @@ init_load(SchemaMod, RawConf, Opts) when is_map(RawConf) ->
RootNames = get_root_names(), RootNames = get_root_names(),
RawConfAll = raw_conf_with_default(SchemaMod, RootNames, RawConfWithOverrides, Opts), RawConfAll = raw_conf_with_default(SchemaMod, RootNames, RawConfWithOverrides, Opts),
%% check configs against the schema %% check configs against the schema
{_AppEnvs, CheckedConf} = check_config(SchemaMod, RawConfAll, #{}), {AppEnvs, CheckedConf} = check_config(SchemaMod, RawConfAll, #{}),
save_to_app_env(AppEnvs),
ok = save_to_config_map(CheckedConf, RawConfAll). ok = save_to_config_map(CheckedConf, RawConfAll).
%% keep the raw and non-raw conf has the same keys to make update raw conf easier. %% keep the raw and non-raw conf has the same keys to make update raw conf easier.
@ -534,23 +535,21 @@ get_root_names() ->
maps:get(names, persistent_term:get(?PERSIS_SCHEMA_MODS, #{names => []})). maps:get(names, persistent_term:get(?PERSIS_SCHEMA_MODS, #{names => []})).
-spec save_configs(app_envs(), config(), raw_config(), raw_config(), update_opts()) -> ok. -spec save_configs(app_envs(), config(), raw_config(), raw_config(), update_opts()) -> ok.
save_configs(_AppEnvs, Conf, RawConf, OverrideConf, Opts) -> save_configs(AppEnvs, Conf, RawConf, OverrideConf, Opts) ->
%% We first try to save to override.conf, because saving to files is more error prone %% We first try to save to override.conf, because saving to files is more error prone
%% than saving into memory. %% than saving into memory.
ok = save_to_override_conf(OverrideConf, Opts), ok = save_to_override_conf(OverrideConf, Opts),
%% We may need also support hot config update for the apps that use application envs. save_to_app_env(AppEnvs),
%% If that is the case uncomment the following line to update the configs to app env
%save_to_app_env(_AppEnvs),
save_to_config_map(Conf, RawConf). save_to_config_map(Conf, RawConf).
%% we ignore kernel app env,
%% because the old app env will be used in emqx_config_logger:post_config_update/5
-define(IGNORE_APPS, [kernel]).
-spec save_to_app_env([tuple()]) -> ok. -spec save_to_app_env([tuple()]) -> ok.
save_to_app_env(AppEnvs) -> save_to_app_env(AppEnvs0) ->
lists:foreach( AppEnvs = lists:filter(fun({App, _}) -> not lists:member(App, ?IGNORE_APPS) end, AppEnvs0),
fun({AppName, Envs}) -> application:set_env(AppEnvs).
[application:set_env(AppName, Par, Val) || {Par, Val} <- Envs]
end,
AppEnvs
).
-spec save_to_config_map(config(), raw_config()) -> ok. -spec save_to_config_map(config(), raw_config()) -> ok.
save_to_config_map(Conf, RawConf) -> save_to_config_map(Conf, RawConf) ->
@ -582,6 +581,7 @@ save_to_override_conf(RawConf, Opts) ->
add_handlers() -> add_handlers() ->
ok = emqx_config_logger:add_handler(), ok = emqx_config_logger:add_handler(),
emqx_sys_mon:add_handler(), emqx_sys_mon:add_handler(),
emqx_config_logger:refresh_config(),
ok. ok.
remove_handlers() -> remove_handlers() ->

View File

@ -408,7 +408,9 @@ catch_call(F) ->
C:E:S -> C:E:S ->
{crashed, {C, E, S}} {crashed, {C, E, S}}
end. end.
force_set_config_file_paths(emqx_conf, Paths) -> force_set_config_file_paths(emqx_conf, [Path] = Paths) ->
Bin = iolist_to_binary(io_lib:format("node.config_files = [~p]~n", [Path])),
ok = file:write_file(Path, Bin, [append]),
application:set_env(emqx, config_files, Paths); application:set_env(emqx, config_files, Paths);
force_set_config_file_paths(emqx, Paths) -> force_set_config_file_paths(emqx, Paths) ->
application:set_env(emqx, config_files, Paths); application:set_env(emqx, config_files, Paths);

View File

@ -463,7 +463,7 @@ fields("node") ->
)}, )},
{"config_files", {"config_files",
sc( sc(
list(string()), hoconsc:array(string()),
#{ #{
mapping => "emqx.config_files", mapping => "emqx.config_files",
default => undefined, default => undefined,

View File

@ -92,6 +92,14 @@ set_data_dir_env() ->
Node = atom_to_list(node()), Node = atom_to_list(node()),
%% will create certs and authz dir %% will create certs and authz dir
ok = filelib:ensure_dir(Node ++ "/configs/"), ok = filelib:ensure_dir(Node ++ "/configs/"),
{ok, [ConfigFile]} = application:get_env(emqx, config_files),
NewConfigFile = ConfigFile ++ "." ++ Node,
{ok, _} = file:copy(ConfigFile, NewConfigFile),
Bin = iolist_to_binary(io_lib:format("node.config_files = [~p]~n", [NewConfigFile])),
ok = file:write_file(NewConfigFile, Bin, [append]),
DataDir = iolist_to_binary(io_lib:format("node.data_dir = ~p~n", [Node])),
ok = file:write_file(NewConfigFile, DataDir, [append]),
application:set_env(emqx, config_files, [NewConfigFile]),
application:set_env(emqx, data_dir, Node), application:set_env(emqx, data_dir, Node),
application:set_env(emqx, cluster_override_conf_file, Node ++ "/configs/cluster-override.conf"), application:set_env(emqx, cluster_override_conf_file, Node ++ "/configs/cluster-override.conf"),
ok. ok.