Просмотр исходного кода

Merge pull request #9429 from zhongwencool/dont-save-zip-on-disk

fix: don't save cert/authz zip on disk when emqx start
zhongwencool 3 лет назад
Родитель
Сommit
e606f01b69

+ 11 - 6
apps/emqx_conf/src/emqx_conf_app.erl

@@ -62,10 +62,11 @@ sync_data_from_node() ->
     TargetDirs = lists:filter(fun(Type) -> filelib:is_dir(filename:join(Dir, Type)) end, [
         "authz", "certs"
     ]),
-    {ok, Zip} = zip:zip(atom_to_list(node()) ++ "_data.zip", TargetDirs, [{cwd, Dir}]),
-    Res = {ok, _Bin} = file:read_file(Zip),
-    _ = file:delete(Zip),
-    Res.
+    Name = "data.zip",
+    case zip:zip(Name, TargetDirs, [memory, {cwd, Dir}]) of
+        {ok, {Name, Bin}} -> {ok, Bin};
+        {error, Reason} -> {error, Reason}
+    end.
 
 %% ------------------------------------------------------------------------------
 %% Internal functions
@@ -195,8 +196,12 @@ conf_sort({ok, _}, {ok, _}) ->
 sync_data_from_node(Node) ->
     case emqx_conf_proto_v2:sync_data_from_node(Node) of
         {ok, DataBin} ->
-            {ok, Files} = zip:unzip(DataBin, [{cwd, emqx:data_dir()}]),
-            ?SLOG(debug, #{node => Node, msg => "sync_data_from_node_ok", files => Files}),
+            case zip:unzip(DataBin, [{cwd, emqx:data_dir()}]) of
+                {ok, []} ->
+                    ?SLOG(debug, #{node => Node, msg => "sync_data_from_node_ignore"});
+                {ok, Files} ->
+                    ?SLOG(debug, #{node => Node, msg => "sync_data_from_node_ok", files => Files})
+            end,
             ok;
         Error ->
             ?SLOG(emergency, #{node => Node, msg => "sync_data_from_node_failed", reason => Error}),

+ 69 - 0
apps/emqx_conf/test/emqx_conf_app_SUITE.erl

@@ -54,10 +54,78 @@ t_copy_conf_override_on_restarts(_Config) ->
         stop_cluster(Nodes)
     end.
 
+t_copy_data_dir(_Config) ->
+    net_kernel:start(['master1@127.0.0.1', longnames]),
+    ct:timetrap({seconds, 120}),
+    snabbkaffe:fix_ct_logging(),
+    Cluster = cluster([{core, copy1}, {core, copy2}, {core, copy3}]),
+
+    %% 1. Start all nodes
+    [First | Rest] = Nodes = start_cluster(Cluster),
+    try
+        assert_config_load_done(Nodes),
+        rpc:call(First, ?MODULE, create_data_dir, []),
+        {[ok, ok, ok], []} = rpc:multicall(Nodes, application, stop, [emqx_conf]),
+        {[ok, ok, ok], []} = rpc:multicall(Nodes, ?MODULE, set_data_dir_env, []),
+        ok = rpc:call(First, application, start, [emqx_conf]),
+        {[ok, ok], []} = rpc:multicall(Rest, application, start, [emqx_conf]),
+
+        assert_data_copy_done(Nodes),
+        stop_cluster(Nodes),
+        ok
+    after
+        stop_cluster(Nodes)
+    end.
+
 %%------------------------------------------------------------------------------
 %% Helper functions
 %%------------------------------------------------------------------------------
 
+create_data_dir() ->
+    Node = atom_to_list(node()),
+    ok = filelib:ensure_dir(Node ++ "/certs/"),
+    ok = filelib:ensure_dir(Node ++ "/authz/"),
+    ok = filelib:ensure_dir(Node ++ "/configs/"),
+    ok = file:write_file(Node ++ "/certs/fake-cert", list_to_binary(Node)),
+    ok = file:write_file(Node ++ "/authz/fake-authz", list_to_binary(Node)),
+    Telemetry = <<"telemetry.enable = false">>,
+    ok = file:write_file(Node ++ "/configs/cluster-override.conf", Telemetry).
+
+set_data_dir_env() ->
+    Node = atom_to_list(node()),
+    %% will create certs and authz dir
+    ok = filelib:ensure_dir(Node ++ "/configs/"),
+    application:set_env(emqx, data_dir, Node),
+    application:set_env(emqx, cluster_override_conf_file, Node ++ "/configs/cluster-override.conf"),
+    ok.
+
+assert_data_copy_done([First0 | Rest]) ->
+    First = atom_to_list(First0),
+    {ok, FakeCertFile} = file:read_file(First ++ "/certs/fake-cert"),
+    {ok, FakeAuthzFile} = file:read_file(First ++ "/authz/fake-authz"),
+    {ok, FakeOverrideFile} = file:read_file(First ++ "/configs/cluster-override.conf"),
+    lists:foreach(
+        fun(Node0) ->
+            Node = atom_to_list(Node0),
+            ?assertEqual(
+                {ok, FakeCertFile},
+                file:read_file(Node ++ "/certs/fake-cert"),
+                #{node => Node}
+            ),
+            ?assertEqual(
+                {ok, FakeOverrideFile},
+                file:read_file(Node ++ "/configs/cluster-override.conf"),
+                #{node => Node}
+            ),
+            ?assertEqual(
+                {ok, FakeAuthzFile},
+                file:read_file(Node ++ "/authz/fake-authz"),
+                #{node => Node}
+            )
+        end,
+        Rest
+    ).
+
 assert_config_load_done(Nodes) ->
     lists:foreach(
         fun(Node) ->
@@ -96,6 +164,7 @@ cluster(Specs) ->
         {env_handler, fun
             (emqx) ->
                 application:set_env(emqx, boot_modules, []),
+                io:format("~p~p~n", [node(), application:get_all_env(emqx)]),
                 ok;
             (_) ->
                 ok

+ 2 - 0
changes/v5.0.12-en.md

@@ -13,6 +13,8 @@
 
 - Add `limiter` update API [#9133](https://github.com/emqx/emqx/pull/9133).
 
+- Avoid creating temporary zip files when syncing data directory during cluster startup [#9429](https://github.com/emqx/emqx/pull/9429).
+
 ## Bug fixes
 
 - Fix that the obsolete SSL files aren't deleted after the ExHook config update [#9432](https://github.com/emqx/emqx/pull/9432).

+ 2 - 0
changes/v5.0.12-zh.md

@@ -13,6 +13,8 @@
 
 - 添加 `limiter` 更新 API [#9133](https://github.com/emqx/emqx/pull/9133)。
 
+- EMQX 集群启动时同步 data 目录不需要在磁盘上产生临时的zip文件 [#9429](https://github.com/emqx/emqx/pull/9429)。
+
 ## 修复
 
 - 修复 ExHook 更新 SSL 相关配置后,过时的 SSL 文件没有被删除的问题 [#9432](https://github.com/emqx/emqx/pull/9432)。