Merge pull request #10422 from thalesmg/fix-plugin-sync-single-node-v50
fix(plugins): attempt to extract plugin from current node on startup
This commit is contained in:
commit
6a1ef5e68a
|
@ -764,6 +764,7 @@ setup_node(Node, Opts) when is_map(Opts) ->
|
||||||
load_apps => LoadApps,
|
load_apps => LoadApps,
|
||||||
apps => Apps,
|
apps => Apps,
|
||||||
env => Env,
|
env => Env,
|
||||||
|
join_to => JoinTo,
|
||||||
start_apps => StartApps
|
start_apps => StartApps
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_plugins, [
|
{application, emqx_plugins, [
|
||||||
{description, "EMQX Plugin Management"},
|
{description, "EMQX Plugin Management"},
|
||||||
{vsn, "0.1.3"},
|
{vsn, "0.1.4"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{mod, {emqx_plugins_app, []}},
|
{mod, {emqx_plugins_app, []}},
|
||||||
{applications, [kernel, stdlib, emqx]},
|
{applications, [kernel, stdlib, emqx]},
|
||||||
|
|
|
@ -479,22 +479,39 @@ ensure_exists_and_installed(NameVsn) ->
|
||||||
case filelib:is_dir(dir(NameVsn)) of
|
case filelib:is_dir(dir(NameVsn)) of
|
||||||
true ->
|
true ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
false ->
|
||||||
Nodes = [N || N <- mria:running_nodes(), N /= node()],
|
%% Do we have the package, but it's not extracted yet?
|
||||||
case get_from_any_node(Nodes, NameVsn, []) of
|
case get_tar(NameVsn) of
|
||||||
{ok, TarContent} ->
|
{ok, TarContent} ->
|
||||||
ok = file:write_file(pkg_file(NameVsn), TarContent),
|
ok = file:write_file(pkg_file(NameVsn), TarContent),
|
||||||
ok = do_ensure_installed(NameVsn);
|
ok = do_ensure_installed(NameVsn);
|
||||||
{error, NodeErrors} ->
|
_ ->
|
||||||
?SLOG(error, #{
|
%% If not, try to get it from the cluster.
|
||||||
msg => "failed_to_copy_plugin_from_other_nodes",
|
do_get_from_cluster(NameVsn)
|
||||||
name_vsn => NameVsn,
|
|
||||||
node_errors => NodeErrors
|
|
||||||
}),
|
|
||||||
{error, plugin_not_found}
|
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
do_get_from_cluster(NameVsn) ->
|
||||||
|
Nodes = [N || N <- mria:running_nodes(), N /= node()],
|
||||||
|
case get_from_any_node(Nodes, NameVsn, []) of
|
||||||
|
{ok, TarContent} ->
|
||||||
|
ok = file:write_file(pkg_file(NameVsn), TarContent),
|
||||||
|
ok = do_ensure_installed(NameVsn);
|
||||||
|
{error, NodeErrors} when Nodes =/= [] ->
|
||||||
|
?SLOG(error, #{
|
||||||
|
msg => "failed_to_copy_plugin_from_other_nodes",
|
||||||
|
name_vsn => NameVsn,
|
||||||
|
node_errors => NodeErrors
|
||||||
|
}),
|
||||||
|
{error, plugin_not_found};
|
||||||
|
{error, _} ->
|
||||||
|
?SLOG(error, #{
|
||||||
|
msg => "no_nodes_to_copy_plugin_from",
|
||||||
|
name_vsn => NameVsn
|
||||||
|
}),
|
||||||
|
{error, plugin_not_found}
|
||||||
|
end.
|
||||||
|
|
||||||
get_from_any_node([], _NameVsn, Errors) ->
|
get_from_any_node([], _NameVsn, Errors) ->
|
||||||
{error, Errors};
|
{error, Errors};
|
||||||
get_from_any_node([Node | T], NameVsn, Errors) ->
|
get_from_any_node([Node | T], NameVsn, Errors) ->
|
||||||
|
|
|
@ -45,7 +45,10 @@ all() ->
|
||||||
|
|
||||||
groups() ->
|
groups() ->
|
||||||
[
|
[
|
||||||
{copy_plugin, [sequence], [group_t_copy_plugin_to_a_new_node]},
|
{copy_plugin, [sequence], [
|
||||||
|
group_t_copy_plugin_to_a_new_node,
|
||||||
|
group_t_copy_plugin_to_a_new_node_single_node
|
||||||
|
]},
|
||||||
{create_tar_copy_plugin, [sequence], [group_t_copy_plugin_to_a_new_node]}
|
{create_tar_copy_plugin, [sequence], [group_t_copy_plugin_to_a_new_node]}
|
||||||
].
|
].
|
||||||
|
|
||||||
|
@ -601,6 +604,78 @@ group_t_copy_plugin_to_a_new_node(Config) ->
|
||||||
rpc:call(CopyToNode, emqx_plugins, describe, [NameVsn])
|
rpc:call(CopyToNode, emqx_plugins, describe, [NameVsn])
|
||||||
).
|
).
|
||||||
|
|
||||||
|
%% checks that we can start a cluster with a lone node.
|
||||||
|
group_t_copy_plugin_to_a_new_node_single_node({init, Config}) ->
|
||||||
|
PrivDataDir = ?config(priv_dir, Config),
|
||||||
|
ToInstallDir = filename:join(PrivDataDir, "plugins_copy_to"),
|
||||||
|
file:del_dir_r(ToInstallDir),
|
||||||
|
ok = filelib:ensure_path(ToInstallDir),
|
||||||
|
#{package := Package, release_name := PluginName} = get_demo_plugin_package(ToInstallDir),
|
||||||
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
|
[{CopyTo, CopyToOpts}] =
|
||||||
|
emqx_common_test_helpers:emqx_cluster(
|
||||||
|
[
|
||||||
|
{core, plugins_copy_to}
|
||||||
|
],
|
||||||
|
#{
|
||||||
|
apps => [emqx_conf, emqx_plugins],
|
||||||
|
env => [
|
||||||
|
{emqx, init_config_load_done, false},
|
||||||
|
{emqx, boot_modules, []}
|
||||||
|
],
|
||||||
|
env_handler => fun
|
||||||
|
(emqx_plugins) ->
|
||||||
|
ok = emqx_plugins:put_config(install_dir, ToInstallDir),
|
||||||
|
%% this is to simulate an user setting the state
|
||||||
|
%% via environment variables before starting the node
|
||||||
|
ok = emqx_plugins:put_config(
|
||||||
|
states,
|
||||||
|
[#{name_vsn => NameVsn, enable => true}]
|
||||||
|
),
|
||||||
|
ok;
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
priv_data_dir => PrivDataDir,
|
||||||
|
schema_mod => emqx_conf_schema,
|
||||||
|
peer_mod => slave,
|
||||||
|
load_schema => true
|
||||||
|
}
|
||||||
|
),
|
||||||
|
[
|
||||||
|
{to_install_dir, ToInstallDir},
|
||||||
|
{copy_to_node_name, CopyTo},
|
||||||
|
{copy_to_opts, CopyToOpts},
|
||||||
|
{name_vsn, NameVsn},
|
||||||
|
{plugin_name, PluginName}
|
||||||
|
| Config
|
||||||
|
];
|
||||||
|
group_t_copy_plugin_to_a_new_node_single_node({'end', Config}) ->
|
||||||
|
CopyToNode = proplists:get_value(copy_to_node, Config),
|
||||||
|
ok = emqx_common_test_helpers:stop_slave(CopyToNode),
|
||||||
|
ok = file:del_dir_r(proplists:get_value(to_install_dir, Config)),
|
||||||
|
ok;
|
||||||
|
group_t_copy_plugin_to_a_new_node_single_node(Config) ->
|
||||||
|
CopyTo = ?config(copy_to_node_name, Config),
|
||||||
|
CopyToOpts = ?config(copy_to_opts, Config),
|
||||||
|
ToInstallDir = ?config(to_install_dir, Config),
|
||||||
|
NameVsn = proplists:get_value(name_vsn, Config),
|
||||||
|
%% Start the node for the first time. The plugin should start
|
||||||
|
%% successfully even if it's not extracted yet. Simply starting
|
||||||
|
%% the node would crash if not working properly.
|
||||||
|
CopyToNode = emqx_common_test_helpers:start_slave(CopyTo, CopyToOpts),
|
||||||
|
ct:pal("~p config:\n ~p", [
|
||||||
|
CopyToNode, erpc:call(CopyToNode, emqx_plugins, get_config, [[], #{}])
|
||||||
|
]),
|
||||||
|
ct:pal("~p install_dir:\n ~p", [
|
||||||
|
CopyToNode, erpc:call(CopyToNode, file, list_dir, [ToInstallDir])
|
||||||
|
]),
|
||||||
|
?assertMatch(
|
||||||
|
{ok, #{running_status := running, config_status := enabled}},
|
||||||
|
rpc:call(CopyToNode, emqx_plugins, describe, [NameVsn])
|
||||||
|
),
|
||||||
|
ok.
|
||||||
|
|
||||||
make_tar(Cwd, NameWithVsn) ->
|
make_tar(Cwd, NameWithVsn) ->
|
||||||
make_tar(Cwd, NameWithVsn, NameWithVsn).
|
make_tar(Cwd, NameWithVsn, NameWithVsn).
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed a bug where external plugins could not be configured via environment variables in a lone-node cluster.
|
Loading…
Reference in New Issue