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 diff --git a/apps/emqx_plugins/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl index 42372f2ec..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. @@ -1123,9 +1124,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 +1160,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 @@ -1235,8 +1258,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 +1267,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) -> @@ -1333,23 +1368,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", @@ -1362,32 +1397,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( @@ -1419,5 +1454,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)).