diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index c4f77b9a0..4a15597f0 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -157,9 +157,6 @@ roots(low) -> , {"quota", sc(ref("quota"), #{})} - , {"plugins", %% TODO: move to emqx_conf_schema - sc(ref("plugins"), - #{})} , {"stats", sc(ref("stats"), #{})} @@ -797,13 +794,6 @@ fields("deflate_opts") -> } ]; -fields("plugins") -> - [ {"expand_plugins_dir", - sc(string(), - #{}) - } - ]; - fields("broker") -> [ {"sys_msg_interval", sc(hoconsc:union([disabled, duration()]), diff --git a/apps/emqx_conf/src/emqx_conf_schema.erl b/apps/emqx_conf/src/emqx_conf_schema.erl index 9f03d1e7f..3136bf557 100644 --- a/apps/emqx_conf/src/emqx_conf_schema.erl +++ b/apps/emqx_conf/src/emqx_conf_schema.erl @@ -50,6 +50,7 @@ , emqx_authz_schema , emqx_auto_subscribe_schema , emqx_modules_schema + , emqx_plugins_schema , emqx_dashboard_schema , emqx_gateway_schema , emqx_prometheus_schema diff --git a/apps/emqx_plugins/etc/emqx_plugins.conf b/apps/emqx_plugins/etc/emqx_plugins.conf new file mode 100644 index 000000000..35f02a9f8 --- /dev/null +++ b/apps/emqx_plugins/etc/emqx_plugins.conf @@ -0,0 +1,7 @@ +plugins { + prebuilt { + } + external { + } + install_dir = "plugins" +} diff --git a/apps/emqx_plugins/src/emqx_plugins.app.src b/apps/emqx_plugins/src/emqx_plugins.app.src new file mode 100644 index 000000000..a772f219f --- /dev/null +++ b/apps/emqx_plugins/src/emqx_plugins.app.src @@ -0,0 +1,9 @@ +%% -*- mode: erlang -*- +{application, emqx_plugins, + [{description, "EMQ X Plugin Management"}, + {vsn, "0.1.0"}, + {modules, []}, + {mod, {emqx_plugins_app,[]}}, + {applications, [kernel,stdlib,emqx]}, + {env, []} + ]}. diff --git a/apps/emqx_plugins/src/emqx_plugins.appup.src b/apps/emqx_plugins/src/emqx_plugins.appup.src new file mode 100644 index 000000000..f9474dd33 --- /dev/null +++ b/apps/emqx_plugins/src/emqx_plugins.appup.src @@ -0,0 +1,8 @@ +%% -*- mode: erlang -*- +{"0.1.0", + [ {<<".*">>, []} + ], + [ + {<<".*">>, []} + ] +}. diff --git a/apps/emqx/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl similarity index 98% rename from apps/emqx/src/emqx_plugins.erl rename to apps/emqx_plugins/src/emqx_plugins.erl index c28ead717..003ca7ec3 100644 --- a/apps/emqx/src/emqx_plugins.erl +++ b/apps/emqx_plugins/src/emqx_plugins.erl @@ -16,9 +16,8 @@ -module(emqx_plugins). --include("emqx.hrl"). --include("logger.hrl"). - +-include_lib("emqx/include/emqx.hrl"). +-include_lib("emqx/include/logger.hrl"). -export([ load/0 , load/1 @@ -41,7 +40,7 @@ %% @doc Load all plugins when the broker started. -spec(load() -> ok | ignore | {error, term()}). load() -> - ok = load_ext_plugins(emqx:get_config([plugins, expand_plugins_dir], undefined)). + ok = load_ext_plugins(emqx:get_config([plugins, install_dir], undefined)). %% @doc Load a Plugin -spec(load(atom()) -> ok | {error, term()}). diff --git a/apps/emqx_plugins/src/emqx_plugins_app.erl b/apps/emqx_plugins/src/emqx_plugins_app.erl new file mode 100644 index 000000000..c04fbb445 --- /dev/null +++ b/apps/emqx_plugins/src/emqx_plugins_app.erl @@ -0,0 +1,30 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_plugins_app). + +-behaviour(application). + +-export([ start/2 + , stop/1 + ]). + +start(_Type, _Args) -> + {ok, Sup} = emqx_plugins_sup:start_link(), + {ok, Sup}. + +stop(_State) -> + ok. diff --git a/apps/emqx_plugins/src/emqx_plugins_schema.erl b/apps/emqx_plugins/src/emqx_plugins_schema.erl new file mode 100644 index 000000000..7b7b3c15e --- /dev/null +++ b/apps/emqx_plugins/src/emqx_plugins_schema.erl @@ -0,0 +1,94 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_plugins_schema). + +-behaviour(hocon_schema). + +-export([ roots/0 + , fields/1 + ]). + +-include_lib("typerefl/include/types.hrl"). + +roots() -> ["plugins"]. + +fields("plugins") -> + #{fields => fields(), + desc => """ +Manage EMQ X plugins. +
+Plugins can be pre-built as a part of EMQ X package, +or installed as a standalone package to the specific directory. +The standalone-installed plugins are referred to as 'external' plugins. +""" + }. + +fields() -> + [ {prebuilt, fun prebuilt/1} + , {external, fun external/1} + , {install_dir, fun install_dir/1} + ]. + +prebuilt(type) -> hoconsc:map("name", boolean()); +prebuilt(nullable) -> true; +prebuilt(T) when T=/= desc -> undefined; +prebuilt(desc) -> """ +A map() from plugin name to a boolean (true | false) flag to indicate +whether or not to enable the prebuilt plugin. +
+Most of the prebuilt plugins from 4.x are converted into features since 5.0. +""" ++ prebuilt_plugins() ++ +""" +
+Enabled plugins are loaded (started) as a part of EMQ X node's boot sequence. +Plugins can be loaded on the fly, and enabled from dashbaord UI and/or CLI. +
+Example config: {emqx_foo_bar: true, emqx_bazz: false} +""". + +external(type) -> hoconsc:map("name", string()); +external(nullable) -> true; +external(T) when T =/= desc -> undefined; +external(desc) -> +""" +A map from plugin name to a version number string for enabled ones. +To disable an external plugin, set the value to 'false'. +
+Enabled plugins are loaded (started) as a part of EMQ X node's boot sequence. +Plugins can be loaded on the fly, and enabled from dashbaord UI and/or CLI. +
+Example config: {emqx_extplug1: \"0.1.0\", emqx_extplug2: false} +""". + +install_dir(type) -> string(); +install_dir(nullable) -> true; +install_dir(default) -> "plugins"; %% runner's root dir +install_dir(T) when T =/= desc -> undefined; +install_dir(desc) -> """ +In which directory are the external plugins installed. +The plugin beam files and configuration files should reside in +the sub-directory named as emqx_foo_bar-0.1.0. +""". + +%% TODO: when we have some prebuilt plugins, change this function to: +%% """ +%% The names should be one of +%% - name1 +%% - name2 +%% """ +prebuilt_plugins() -> + "So far, we do not have any prebuilt plugins". diff --git a/apps/emqx_plugins/src/emqx_plugins_sup.erl b/apps/emqx_plugins/src/emqx_plugins_sup.erl new file mode 100644 index 000000000..c1e26752e --- /dev/null +++ b/apps/emqx_plugins/src/emqx_plugins_sup.erl @@ -0,0 +1,30 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_plugins_sup). + +-behaviour(supervisor). + +-export([start_link/0]). + +-export([init/1]). + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +init([]) -> + Children = [], + {ok, {{one_for_one, 10, 10}, Children}}. diff --git a/apps/emqx/test/emqx_plugins_SUITE.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl similarity index 97% rename from apps/emqx/test/emqx_plugins_SUITE.erl rename to apps/emqx_plugins/test/emqx_plugins_SUITE.erl index 3aba5a997..2281f09dc 100644 --- a/apps/emqx/test/emqx_plugins_SUITE.erl +++ b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl @@ -42,7 +42,7 @@ init_per_suite(Config) -> emqx_common_test_helpers:boot_modules([]), emqx_common_test_helpers:start_apps([]), - emqx_config:put([plugins, expand_plugins_dir], DataPath), + emqx_config:put([plugins, install_dir], DataPath), ?assertEqual(ok, emqx_plugins:load()), Config. @@ -57,7 +57,7 @@ t_load(_) -> ?assertEqual({error, not_started}, emqx_plugins:unload(emqx_mini_plugin)), ?assertEqual({error, not_started}, emqx_plugins:unload(emqx_hocon_plugin)), - emqx_config:put([plugins, expand_plugins_dir], undefined). + emqx_config:put([plugins, install_dir], undefined). t_load_ext_plugin(_) -> ?assertError({plugin_app_file_not_found, _}, diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/Makefile b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/Makefile similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/Makefile rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/Makefile diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/etc/emqx_hocon_plugin.conf b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/etc/emqx_hocon_plugin.conf similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/etc/emqx_hocon_plugin.conf rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/etc/emqx_hocon_plugin.conf diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin.app.src b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin.app.src similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin.app.src rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin.app.src diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_app.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_app.erl similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_app.erl rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_app.erl diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/Makefile b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/Makefile similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/Makefile rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/Makefile diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/etc/emqx_mini_plugin.conf b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/etc/emqx_mini_plugin.conf similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/etc/emqx_mini_plugin.conf rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/etc/emqx_mini_plugin.conf diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/priv/emqx_mini_plugin.schema b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/priv/emqx_mini_plugin.schema similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/priv/emqx_mini_plugin.schema rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/priv/emqx_mini_plugin.schema diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin.app.src b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin.app.src similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin.app.src rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin.app.src diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin_app.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin_app.erl similarity index 100% rename from apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin_app.erl rename to apps/emqx_plugins/test/emqx_plugins_SUITE_data/emqx_mini_plugin/src/emqx_mini_plugin_app.erl diff --git a/rebar.config.erl b/rebar.config.erl index 2beabd147..f63fedd84 100644 --- a/rebar.config.erl +++ b/rebar.config.erl @@ -305,6 +305,7 @@ relx_apps(ReleaseType, Edition) -> , emqx_statsd , emqx_prometheus , emqx_psk + , emqx_plugins ] ++ [quicer || is_quicer_supported()] %++ [emqx_license || is_enterprise(Edition)]