|
|
@@ -15,17 +15,18 @@
|
|
|
%%--------------------------------------------------------------------
|
|
|
-module(emqx_config).
|
|
|
|
|
|
--compile({no_auto_import, [get/0, get/1, put/2]}).
|
|
|
+-compile({no_auto_import, [get/0, get/1, put/2, erase/1]}).
|
|
|
|
|
|
--export([ init_load/2
|
|
|
- , read_override_conf/0
|
|
|
+-export([ init_load/1
|
|
|
+ , init_load/2
|
|
|
+ , read_override_conf/1
|
|
|
, check_config/2
|
|
|
, fill_defaults/1
|
|
|
, fill_defaults/2
|
|
|
- , save_configs/4
|
|
|
+ , save_configs/5
|
|
|
, save_to_app_env/1
|
|
|
, save_to_config_map/2
|
|
|
- , save_to_override_conf/1
|
|
|
+ , save_to_override_conf/2
|
|
|
]).
|
|
|
|
|
|
-export([ get_root/1
|
|
|
@@ -41,6 +42,7 @@
|
|
|
, find_raw/1
|
|
|
, put/1
|
|
|
, put/2
|
|
|
+ , erase/1
|
|
|
]).
|
|
|
|
|
|
-export([ get_raw/1
|
|
|
@@ -96,7 +98,8 @@
|
|
|
%% persistent:
|
|
|
%% save the updated config to the emqx_override.conf file
|
|
|
%% defaults to `true`
|
|
|
- persistent => boolean()
|
|
|
+ persistent => boolean(),
|
|
|
+ override_to => local | cluster
|
|
|
}.
|
|
|
-type update_args() :: {update_cmd(), Opts :: update_opts()}.
|
|
|
-type update_stage() :: pre_config_update | post_config_update.
|
|
|
@@ -199,6 +202,10 @@ put(Config) ->
|
|
|
?MODULE:put([RootName], RootValue)
|
|
|
end, ok, Config).
|
|
|
|
|
|
+erase(RootName) ->
|
|
|
+ persistent_term:erase(?PERSIS_KEY(?CONF, bin(RootName))),
|
|
|
+ persistent_term:erase(?PERSIS_KEY(?RAW_CONF, bin(RootName))).
|
|
|
+
|
|
|
-spec put(emqx_map_lib:config_key_path(), term()) -> ok.
|
|
|
put(KeyPath, Config) -> do_put(?CONF, KeyPath, Config).
|
|
|
|
|
|
@@ -237,13 +244,17 @@ put_raw(KeyPath, Config) -> do_put(?RAW_CONF, KeyPath, Config).
|
|
|
%%============================================================================
|
|
|
%% Load/Update configs From/To files
|
|
|
%%============================================================================
|
|
|
+init_load(SchemaMod) ->
|
|
|
+ ConfFiles = application:get_env(emqx, config_files, []),
|
|
|
+ init_load(SchemaMod, ConfFiles).
|
|
|
|
|
|
%% @doc Initial load of the given config files.
|
|
|
%% NOTE: The order of the files is significant, configs from files orderd
|
|
|
%% in the rear of the list overrides prior values.
|
|
|
-spec init_load(module(), [string()] | binary() | hocon:config()) -> ok.
|
|
|
init_load(SchemaMod, Conf) when is_list(Conf) orelse is_binary(Conf) ->
|
|
|
- ParseOptions = #{format => map},
|
|
|
+ IncDir = include_dirs(),
|
|
|
+ ParseOptions = #{format => map, include_dirs => IncDir},
|
|
|
Parser = case is_binary(Conf) of
|
|
|
true -> fun hocon:binary/2;
|
|
|
false -> fun hocon:files/2
|
|
|
@@ -253,21 +264,20 @@ init_load(SchemaMod, Conf) when is_list(Conf) orelse is_binary(Conf) ->
|
|
|
init_load(SchemaMod, RawRichConf);
|
|
|
{error, Reason} ->
|
|
|
?SLOG(error, #{msg => failed_to_load_hocon_conf,
|
|
|
- reason => Reason
|
|
|
+ reason => Reason,
|
|
|
+ include_dirs => IncDir
|
|
|
}),
|
|
|
error(failed_to_load_hocon_conf)
|
|
|
end;
|
|
|
init_load(SchemaMod, RawConf0) when is_map(RawConf0) ->
|
|
|
ok = save_schema_mod_and_names(SchemaMod),
|
|
|
- %% override part of the input conf using emqx_override.conf
|
|
|
- RawConf = merge_with_override_conf(RawConf0),
|
|
|
%% check and save configs
|
|
|
- {_AppEnvs, CheckedConf} = check_config(SchemaMod, RawConf),
|
|
|
+ {_AppEnvs, CheckedConf} = check_config(SchemaMod, RawConf0),
|
|
|
ok = save_to_config_map(maps:with(get_atom_root_names(), CheckedConf),
|
|
|
- maps:with(get_root_names(), RawConf)).
|
|
|
+ maps:with(get_root_names(), RawConf0)).
|
|
|
|
|
|
-merge_with_override_conf(RawConf) ->
|
|
|
- maps:merge(RawConf, maps:with(maps:keys(RawConf), read_override_conf())).
|
|
|
+include_dirs() ->
|
|
|
+ [filename:join(application:get_env(emqx, data_dir, "data/"), "configs") ++ "/"].
|
|
|
|
|
|
-spec check_config(module(), raw_config()) -> {AppEnvs, CheckedConf}
|
|
|
when AppEnvs :: app_envs(), CheckedConf :: config().
|
|
|
@@ -299,9 +309,18 @@ fill_defaults(SchemaMod, RawConf) ->
|
|
|
#{nullable => true, only_fill_defaults => true},
|
|
|
root_names_from_conf(RawConf)).
|
|
|
|
|
|
--spec read_override_conf() -> raw_config().
|
|
|
-read_override_conf() ->
|
|
|
- load_hocon_file(emqx_override_conf_name(), map).
|
|
|
+-spec read_override_conf(map()) -> raw_config().
|
|
|
+read_override_conf(#{} = Opts) ->
|
|
|
+ File = override_conf_file(Opts),
|
|
|
+ load_hocon_file(File, map).
|
|
|
+
|
|
|
+override_conf_file(Opts) ->
|
|
|
+ Key =
|
|
|
+ case maps:get(override_to, Opts, local) of
|
|
|
+ local -> local_override_conf_file;
|
|
|
+ cluster -> cluster_override_conf_file
|
|
|
+ end,
|
|
|
+ application:get_env(emqx, Key, undefined).
|
|
|
|
|
|
-spec save_schema_mod_and_names(module()) -> ok.
|
|
|
save_schema_mod_and_names(SchemaMod) ->
|
|
|
@@ -330,14 +349,13 @@ get_root_names() ->
|
|
|
get_atom_root_names() ->
|
|
|
[atom(N) || N <- get_root_names()].
|
|
|
|
|
|
--spec save_configs(app_envs(), config(), raw_config(), raw_config()) -> ok | {error, term()}.
|
|
|
-save_configs(_AppEnvs, Conf, RawConf, OverrideConf) ->
|
|
|
+-spec save_configs(app_envs(), config(), raw_config(), raw_config(), update_opts()) -> ok | {error, term()}.
|
|
|
+save_configs(_AppEnvs, Conf, RawConf, OverrideConf, Opts) ->
|
|
|
%% We may need also support hot config update for the apps that use application envs.
|
|
|
%% 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),
|
|
|
- %% TODO: merge RawConf to OverrideConf can be done here
|
|
|
- save_to_override_conf(OverrideConf).
|
|
|
+ save_to_override_conf(OverrideConf, Opts).
|
|
|
|
|
|
-spec save_to_app_env([tuple()]) -> ok.
|
|
|
save_to_app_env(AppEnvs) ->
|
|
|
@@ -350,11 +368,11 @@ save_to_config_map(Conf, RawConf) ->
|
|
|
?MODULE:put(Conf),
|
|
|
?MODULE:put_raw(RawConf).
|
|
|
|
|
|
--spec save_to_override_conf(raw_config()) -> ok | {error, term()}.
|
|
|
-save_to_override_conf(undefined) ->
|
|
|
+-spec save_to_override_conf(raw_config(), update_opts()) -> ok | {error, term()}.
|
|
|
+save_to_override_conf(undefined, _) ->
|
|
|
ok;
|
|
|
-save_to_override_conf(RawConf) ->
|
|
|
- case emqx_override_conf_name() of
|
|
|
+save_to_override_conf(RawConf, Opts) ->
|
|
|
+ case override_conf_file(Opts) of
|
|
|
undefined -> ok;
|
|
|
FileName ->
|
|
|
ok = filelib:ensure_dir(FileName),
|
|
|
@@ -371,14 +389,12 @@ save_to_override_conf(RawConf) ->
|
|
|
load_hocon_file(FileName, LoadType) ->
|
|
|
case filelib:is_regular(FileName) of
|
|
|
true ->
|
|
|
- {ok, Raw0} = hocon:load(FileName, #{format => LoadType}),
|
|
|
+ Opts = #{include_dirs => include_dirs(), format => LoadType},
|
|
|
+ {ok, Raw0} = hocon:load(FileName, Opts),
|
|
|
Raw0;
|
|
|
false -> #{}
|
|
|
end.
|
|
|
|
|
|
-emqx_override_conf_name() ->
|
|
|
- application:get_env(emqx, override_conf_file, undefined).
|
|
|
-
|
|
|
do_get(Type, KeyPath) ->
|
|
|
Ref = make_ref(),
|
|
|
Res = do_get(Type, KeyPath, Ref),
|