浏览代码

Merge pull request #13111 from JimMoen/fix-plugin-install-badmatch

fix: match decode plugin config map failed case
JianBo He 1 年之前
父节点
当前提交
1899cf2daf
共有 2 个文件被更改,包括 53 次插入18 次删除
  1. 1 1
      Makefile
  2. 52 17
      apps/emqx_plugins/src/emqx_plugins.erl

+ 1 - 1
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

+ 52 - 17
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)).