fix: ensure default values for `loaded_{plugins,modules}`
Fixes #7455 . This tries to populate `loaded_{plugins,modules}` files with default values before loading them, in case they don't exist.
This commit is contained in:
parent
bbda2e4dfa
commit
aa19283ff2
|
@ -43,6 +43,7 @@ load() ->
|
|||
case emqx:get_env(modules_loaded_file) of
|
||||
undefined -> ok;
|
||||
File ->
|
||||
ensure_loaded_modules_file(File),
|
||||
load_modules(File)
|
||||
end.
|
||||
|
||||
|
@ -58,6 +59,31 @@ load(ModuleName) ->
|
|||
emqx_modules:load_module(ModuleName, true)
|
||||
end.
|
||||
|
||||
%% @doc Creates a `loaded_modules' file with default values if one
|
||||
%% doesn't exist.
|
||||
-spec ensure_loaded_modules_file(file:filename()) -> ok.
|
||||
ensure_loaded_modules_file(Filepath) ->
|
||||
case filelib:is_regular(Filepath) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
do_ensure_loaded_modules_file(Filepath)
|
||||
end.
|
||||
|
||||
do_ensure_loaded_modules_file(Filepath) ->
|
||||
DefaultModules = [emqx_mod_acl_internal, emqx_mod_presence],
|
||||
Res = file:write_file(Filepath,
|
||||
[io_lib:format("{~p, true}.~n", [Mod])
|
||||
|| Mod <- DefaultModules]),
|
||||
case Res of
|
||||
ok ->
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
?LOG(error, "Could not write default loaded_modules file ~p ; Error: ~p",
|
||||
[Filepath, Reason]),
|
||||
ok
|
||||
end.
|
||||
|
||||
%% @doc Unload all the extended modules.
|
||||
-spec(unload() -> ok).
|
||||
unload() ->
|
||||
|
@ -175,8 +201,10 @@ write_loaded(false) -> ok.
|
|||
|
||||
%%--------------------------------------------------------------------
|
||||
%% @doc Modules Command
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
cli(["list"]) ->
|
||||
lists:foreach(fun({Name, Active}) ->
|
||||
lists:foreach(fun({Name, Active}) ->
|
||||
emqx_ctl:print("Module(~s, description=~s, active=~s)~n",
|
||||
[Name, Name:description(), Active])
|
||||
end, emqx_modules:list());
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-define(CONTENT_TYPE, "application/x-www-form-urlencoded").
|
||||
|
||||
|
@ -44,6 +45,32 @@ end_per_suite(_Config) ->
|
|||
emqx_ct_http:delete_default_app(),
|
||||
emqx_ct_helpers:stop_apps([emqx_modules, emqx_management]).
|
||||
|
||||
init_per_testcase(t_ensure_default_loaded_modules_file, Config) ->
|
||||
LoadedModulesFilepath = application:get_env(emqx, modules_loaded_file),
|
||||
ok = application:stop(emqx_modules),
|
||||
TmpFilepath = filename:join(["/", "tmp", "loaded_modules_tmp"]),
|
||||
case file:delete(TmpFilepath) of
|
||||
ok -> ok;
|
||||
{error, enoent} -> ok
|
||||
end,
|
||||
application:set_env(emqx, modules_loaded_file, TmpFilepath),
|
||||
[ {loaded_modules_filepath, LoadedModulesFilepath}
|
||||
, {tmp_filepath, TmpFilepath}
|
||||
| Config];
|
||||
init_per_testcase(_TestCase, Config) ->
|
||||
Config.
|
||||
|
||||
end_per_testcase(t_ensure_default_loaded_modules_file, Config) ->
|
||||
LoadedModulesFilepath = ?config(loaded_modules_filepath, Config),
|
||||
TmpFilepath = ?config(tmp_filepath, Config),
|
||||
file:delete(TmpFilepath),
|
||||
ok = application:stop(emqx_modules),
|
||||
application:set_env(emqx, modules_loaded_file, LoadedModulesFilepath),
|
||||
ok = application:start(emqx_modules),
|
||||
ok;
|
||||
end_per_testcase(_TestCase, _Config) ->
|
||||
ok.
|
||||
|
||||
t_load(_) ->
|
||||
?assertEqual(ok, emqx_modules:unload()),
|
||||
?assertEqual(ok, emqx_modules:load()),
|
||||
|
@ -52,6 +79,19 @@ t_load(_) ->
|
|||
?assertEqual(ignore, emqx_modules:reload(emqx_mod_rewrite)),
|
||||
?assertEqual(ok, emqx_modules:reload(emqx_mod_acl_internal)).
|
||||
|
||||
t_ensure_default_loaded_modules_file(_Config) ->
|
||||
ok = application:start(emqx_modules),
|
||||
?assertEqual(
|
||||
[ {emqx_mod_acl_internal,true}
|
||||
, {emqx_mod_delayed,false}
|
||||
, {emqx_mod_presence,true}
|
||||
, {emqx_mod_rewrite,false}
|
||||
, {emqx_mod_subscription,false}
|
||||
, {emqx_mod_topic_metrics,false}
|
||||
],
|
||||
lists:sort(emqx_modules:list())),
|
||||
ok.
|
||||
|
||||
t_list(_) ->
|
||||
?assertMatch([{_, _} | _ ], emqx_modules:list()).
|
||||
|
||||
|
|
|
@ -215,7 +215,21 @@ load_plugin_conf(AppName, PluginDir) ->
|
|||
end, AppsEnv).
|
||||
|
||||
ensure_file(File) ->
|
||||
case filelib:is_file(File) of false -> write_loaded([]); true -> ok end.
|
||||
case filelib:is_file(File) of
|
||||
false ->
|
||||
DefaultPlugins = [ {emqx_management, true}
|
||||
, {emqx_dashboard, true}
|
||||
, {emqx_modules, false}
|
||||
, {emqx_recon, true}
|
||||
, {emqx_retainer, true}
|
||||
, {emqx_telemetry, true}
|
||||
, {emqx_rule_engine, true}
|
||||
, {emqx_bridge_mqtt, false}
|
||||
],
|
||||
write_loaded(DefaultPlugins);
|
||||
true ->
|
||||
ok
|
||||
end.
|
||||
|
||||
with_loaded_file(File, SuccFun) ->
|
||||
case read_loaded(File) of
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
all() -> emqx_ct:all(?MODULE).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
|
||||
%% Compile extra plugin code
|
||||
|
||||
DataPath = proplists:get_value(data_dir, Config),
|
||||
|
@ -47,7 +47,35 @@ set_special_cfg(PluginsDir) ->
|
|||
ok.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
emqx_ct_helpers:stop_apps([]).
|
||||
emqx_ct_helpers:stop_apps([]),
|
||||
file:delete(get(loaded_file)).
|
||||
|
||||
init_per_testcase(t_ensure_default_loaded_plugins_file, Config) ->
|
||||
{ok, LoadedPluginsFilepath} = application:get_env(emqx, plugins_loaded_file),
|
||||
TmpFilepath = filename:join(["/", "tmp", "loaded_plugins_tmp"]),
|
||||
case file:delete(TmpFilepath) of
|
||||
ok -> ok;
|
||||
{error, enoent} -> ok
|
||||
end,
|
||||
application:set_env(emqx, plugins_loaded_file, TmpFilepath),
|
||||
[ {loaded_plugins_filepath, LoadedPluginsFilepath}
|
||||
, {tmp_filepath, TmpFilepath}
|
||||
| Config];
|
||||
init_per_testcase(_TestCase, Config) ->
|
||||
Config.
|
||||
|
||||
end_per_testcase(t_ensure_default_loaded_plugins_file, Config) ->
|
||||
LoadedPluginsFilepath = ?config(loaded_plugins_filepath, Config),
|
||||
TmpFilepath = ?config(tmp_filepath, Config),
|
||||
file:delete(TmpFilepath),
|
||||
emqx_plugins:unload(),
|
||||
application:set_env(emqx, plugins_loaded_file, LoadedPluginsFilepath),
|
||||
%% need to purge the plugin to avoid inter-testcase dependencies.
|
||||
code:purge(emqx_mini_plugin_app),
|
||||
ok;
|
||||
end_per_testcase(_TestCase, _Config) ->
|
||||
emqx_plugins:unload(),
|
||||
ok.
|
||||
|
||||
t_load(_) ->
|
||||
?assertEqual(ok, emqx_plugins:load()),
|
||||
|
@ -61,6 +89,25 @@ t_load(_) ->
|
|||
?assertEqual(ignore, emqx_plugins:load()),
|
||||
?assertEqual(ignore, emqx_plugins:unload()).
|
||||
|
||||
t_ensure_default_loaded_plugins_file(Config) ->
|
||||
%% this will trigger it to write the default plugins to the
|
||||
%% inexistent file; but it won't truly load them in this test
|
||||
%% because there are no config files in `expand_plugins_dir'.
|
||||
TmpFilepath = ?config(tmp_filepath, Config),
|
||||
ok = emqx_plugins:load(),
|
||||
{ok, Contents} = file:consult(TmpFilepath),
|
||||
?assertEqual(
|
||||
[ {emqx_bridge_mqtt, false}
|
||||
, {emqx_dashboard, true}
|
||||
, {emqx_management, true}
|
||||
, {emqx_modules, false}
|
||||
, {emqx_recon, true}
|
||||
, {emqx_retainer, true}
|
||||
, {emqx_rule_engine, true}
|
||||
, {emqx_telemetry, true}
|
||||
],
|
||||
lists:sort(Contents)),
|
||||
ok.
|
||||
|
||||
t_init_config(_) ->
|
||||
ConfFile = "emqx_mini_plugin.config",
|
||||
|
|
Loading…
Reference in New Issue