From 874bcd9a8b380f44159272235135f3dcb8b8d988 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 24 May 2024 10:20:50 +0800 Subject: [PATCH 1/4] fix: match decode plugin config map failed case --- apps/emqx_plugins/src/emqx_plugins.erl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/emqx_plugins/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl index 42372f2ec..e1eb6d771 100644 --- a/apps/emqx_plugins/src/emqx_plugins.erl +++ b/apps/emqx_plugins/src/emqx_plugins.erl @@ -1235,8 +1235,7 @@ ensure_config_map(NameVsn) -> {ok, ConfigJsonMap} -> case with_plugin_avsc(NameVsn) of true -> - {ok, AvroValue} = decode_plugin_config_map(NameVsn, ConfigJsonMap), - put_config(NameVsn, ConfigJsonMap, AvroValue); + do_ensure_config_map(NameVsn, ConfigJsonMap); false -> put_config(NameVsn, ConfigJsonMap, ?plugin_without_config_schema) end; @@ -1245,6 +1244,19 @@ ensure_config_map(NameVsn) -> ok end. +do_ensure_config_map(NameVsn, ConfigJsonMap) -> + case decode_plugin_config_map(NameVsn, ConfigJsonMap) of + {ok, AvroValue} -> + put_config(NameVsn, ConfigJsonMap, AvroValue); + {error, Reason} -> + ?SLOG(error, #{ + msg => "plugin_config_validation_failed", + name_vsn => NameVsn, + reason => Reason + }), + ok + end. + %% @private Backup the current config to a file with a timestamp suffix and %% then save the new config to the config file. backup_and_write_hocon_bin(NameVsn, HoconBin) -> From 43506495ae8a22b569f7160d024760277032181a Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 24 May 2024 12:04:03 +0800 Subject: [PATCH 2/4] fix: ensure plugin configured states after join cluster --- apps/emqx_plugins/src/emqx_plugins.erl | 52 ++++++++++++++++++-------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/apps/emqx_plugins/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl index e1eb6d771..73f4694c2 100644 --- a/apps/emqx_plugins/src/emqx_plugins.erl +++ b/apps/emqx_plugins/src/emqx_plugins.erl @@ -1123,9 +1123,31 @@ for_plugins(ActionFun) -> ok end. -maybe_post_op_after_installed(NameVsn) -> +maybe_post_op_after_installed(NameVsn0) -> + NameVsn = wrap_to_list(NameVsn0), _ = maybe_load_config_schema(NameVsn), - _ = ensure_state(NameVsn, no_move, false, global), + ok = maybe_ensure_state(NameVsn). + +maybe_ensure_state(NameVsn) -> + EnsureStateFun = fun(#{name_vsn := NV, enable := Bool}, AccIn) -> + case NV of + NameVsn -> + %% Configured, using existed cluster config + ensure_state(NV, no_move, Bool, global), + AccIn#{ensured => true}; + _ -> + AccIn + end + end, + case lists:foldl(EnsureStateFun, #{ensured => false}, configured()) of + #{ensured := true} -> + ok; + #{ensured := false} -> + ?SLOG(info, #{msg => "plugin_not_configured", name_vsn => NameVsn}), + %% Clean installation, no config, ensure with `Enable = false` + _ = ensure_state(NameVsn, no_move, false, global), + ok + end, ok. maybe_load_config_schema(NameVsn) -> @@ -1137,7 +1159,7 @@ maybe_load_config_schema(NameVsn) -> _ = maybe_create_config_dir(NameVsn). do_load_config_schema(NameVsn, AvscPath) -> - case emqx_plugins_serde:add_schema(NameVsn, AvscPath) of + case emqx_plugins_serde:add_schema(bin(NameVsn), AvscPath) of ok -> ok; {error, already_exists} -> ok; {error, _Reason} -> ok @@ -1345,23 +1367,23 @@ read_file_fun(Path, ErrMsg, #{read_mode := ?JSON_MAP}) -> %% Directorys -spec plugin_dir(name_vsn()) -> string(). plugin_dir(NameVsn) -> - wrap_list_path(filename:join([install_dir(), NameVsn])). + wrap_to_list(filename:join([install_dir(), NameVsn])). -spec plugin_priv_dir(name_vsn()) -> string(). plugin_priv_dir(NameVsn) -> case read_plugin_info(NameVsn, #{fill_readme => false}) of {ok, #{<<"name">> := Name, <<"metadata_vsn">> := Vsn}} -> AppDir = make_name_vsn_string(Name, Vsn), - wrap_list_path(filename:join([plugin_dir(NameVsn), AppDir, "priv"])); + wrap_to_list(filename:join([plugin_dir(NameVsn), AppDir, "priv"])); _ -> - wrap_list_path(filename:join([install_dir(), NameVsn, "priv"])) + wrap_to_list(filename:join([install_dir(), NameVsn, "priv"])) end. -spec plugin_config_dir(name_vsn()) -> string() | {error, Reason :: string()}. plugin_config_dir(NameVsn) -> case parse_name_vsn(NameVsn) of {ok, NameAtom, _Vsn} -> - wrap_list_path(filename:join([emqx:data_dir(), "plugins", atom_to_list(NameAtom)])); + wrap_to_list(filename:join([emqx:data_dir(), "plugins", atom_to_list(NameAtom)])); {error, Reason} -> ?SLOG(warning, #{ msg => "failed_to_generate_plugin_config_dir_for_plugin", @@ -1374,32 +1396,32 @@ plugin_config_dir(NameVsn) -> %% Files -spec pkg_file_path(name_vsn()) -> string(). pkg_file_path(NameVsn) -> - wrap_list_path(filename:join([install_dir(), bin([NameVsn, ".tar.gz"])])). + wrap_to_list(filename:join([install_dir(), bin([NameVsn, ".tar.gz"])])). -spec info_file_path(name_vsn()) -> string(). info_file_path(NameVsn) -> - wrap_list_path(filename:join([plugin_dir(NameVsn), "release.json"])). + wrap_to_list(filename:join([plugin_dir(NameVsn), "release.json"])). -spec avsc_file_path(name_vsn()) -> string(). avsc_file_path(NameVsn) -> - wrap_list_path(filename:join([plugin_priv_dir(NameVsn), "config_schema.avsc"])). + wrap_to_list(filename:join([plugin_priv_dir(NameVsn), "config_schema.avsc"])). -spec plugin_config_file(name_vsn()) -> string(). plugin_config_file(NameVsn) -> - wrap_list_path(filename:join([plugin_config_dir(NameVsn), "config.hocon"])). + wrap_to_list(filename:join([plugin_config_dir(NameVsn), "config.hocon"])). %% should only used when plugin installing -spec default_plugin_config_file(name_vsn()) -> string(). default_plugin_config_file(NameVsn) -> - wrap_list_path(filename:join([plugin_priv_dir(NameVsn), "config.hocon"])). + wrap_to_list(filename:join([plugin_priv_dir(NameVsn), "config.hocon"])). -spec i18n_file_path(name_vsn()) -> string(). i18n_file_path(NameVsn) -> - wrap_list_path(filename:join([plugin_priv_dir(NameVsn), "config_i18n.json"])). + wrap_to_list(filename:join([plugin_priv_dir(NameVsn), "config_i18n.json"])). -spec readme_file(name_vsn()) -> string(). readme_file(NameVsn) -> - wrap_list_path(filename:join([plugin_dir(NameVsn), "README.md"])). + wrap_to_list(filename:join([plugin_dir(NameVsn), "README.md"])). running_apps() -> lists:map( @@ -1431,5 +1453,5 @@ bin(A) when is_atom(A) -> atom_to_binary(A, utf8); bin(L) when is_list(L) -> unicode:characters_to_binary(L, utf8); bin(B) when is_binary(B) -> B. -wrap_list_path(Path) -> +wrap_to_list(Path) -> binary_to_list(iolist_to_binary(Path)). From 6798a26ecb48d676fd848767246b157ad8e70802 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 24 May 2024 12:04:44 +0800 Subject: [PATCH 3/4] chore: bump dashboard tag to e1.7.0-beta.11 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d1726f737..431da3ad9 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ endif # Dashboard version # from https://github.com/emqx/emqx-dashboard5 export EMQX_DASHBOARD_VERSION ?= v1.9.0-beta.1 -export EMQX_EE_DASHBOARD_VERSION ?= e1.7.0-beta.9 +export EMQX_EE_DASHBOARD_VERSION ?= e1.7.0-beta.11 -include default-profile.mk PROFILE ?= emqx From 5b60f6a5b2ce5e4cfacbd5ade4adf8517b91dea0 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 24 May 2024 14:29:02 +0800 Subject: [PATCH 4/4] fix: make dialyzer happy --- apps/emqx_plugins/src/emqx_plugins.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/emqx_plugins/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl index 73f4694c2..961855e17 100644 --- a/apps/emqx_plugins/src/emqx_plugins.erl +++ b/apps/emqx_plugins/src/emqx_plugins.erl @@ -556,6 +556,7 @@ ensure_state(NameVsn, Position, State, ConfLocation) -> fun() -> ensure_configured(Item, Position, ConfLocation) end ); {error, Reason} -> + ?SLOG(error, #{msg => "ensure_plugin_states_failed", reason => Reason}), {error, Reason} end. @@ -1133,7 +1134,7 @@ maybe_ensure_state(NameVsn) -> case NV of NameVsn -> %% Configured, using existed cluster config - ensure_state(NV, no_move, Bool, global), + _ = ensure_state(NV, no_move, Bool, global), AccIn#{ensured => true}; _ -> AccIn