|
|
@@ -16,6 +16,7 @@
|
|
|
-module(emqx_machine_boot).
|
|
|
|
|
|
-include_lib("emqx/include/logger.hrl").
|
|
|
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
|
|
|
|
|
-export([post_boot/0]).
|
|
|
-export([stop_apps/0, ensure_apps_started/0]).
|
|
|
@@ -24,7 +25,6 @@
|
|
|
-export([stop_port_apps/0]).
|
|
|
|
|
|
-dialyzer({no_match, [basic_reboot_apps/0]}).
|
|
|
--dialyzer({no_match, [basic_reboot_apps_edition/1]}).
|
|
|
|
|
|
-ifdef(TEST).
|
|
|
-export([sorted_reboot_apps/1, reboot_apps/0]).
|
|
|
@@ -94,7 +94,8 @@ stop_one_app(App) ->
|
|
|
|
|
|
ensure_apps_started() ->
|
|
|
?SLOG(notice, #{msg => "(re)starting_emqx_apps"}),
|
|
|
- lists:foreach(fun start_one_app/1, sorted_reboot_apps()).
|
|
|
+ lists:foreach(fun start_one_app/1, sorted_reboot_apps()),
|
|
|
+ ?tp(emqx_machine_boot_apps_started, #{}).
|
|
|
|
|
|
start_one_app(App) ->
|
|
|
?SLOG(debug, #{msg => "starting_app", app => App}),
|
|
|
@@ -128,44 +129,39 @@ reboot_apps() ->
|
|
|
BaseRebootApps ++ ConfigApps.
|
|
|
|
|
|
basic_reboot_apps() ->
|
|
|
- ?BASIC_REBOOT_APPS ++
|
|
|
- [
|
|
|
- emqx_prometheus,
|
|
|
- emqx_modules,
|
|
|
- emqx_dashboard,
|
|
|
- emqx_connector,
|
|
|
- emqx_gateway,
|
|
|
- emqx_resource,
|
|
|
- emqx_rule_engine,
|
|
|
- emqx_bridge,
|
|
|
- emqx_management,
|
|
|
- emqx_retainer,
|
|
|
- emqx_exhook,
|
|
|
- emqx_authn,
|
|
|
- emqx_authz,
|
|
|
- emqx_slow_subs,
|
|
|
- emqx_auto_subscribe,
|
|
|
- emqx_plugins,
|
|
|
- emqx_psk
|
|
|
- ] ++ basic_reboot_apps_edition(emqx_release:edition()).
|
|
|
-
|
|
|
-basic_reboot_apps_edition(ce) ->
|
|
|
- [emqx_telemetry];
|
|
|
-basic_reboot_apps_edition(ee) ->
|
|
|
- [
|
|
|
- emqx_license,
|
|
|
- emqx_s3,
|
|
|
- emqx_ft,
|
|
|
- emqx_eviction_agent,
|
|
|
- emqx_node_rebalance,
|
|
|
- emqx_schema_registry
|
|
|
- ];
|
|
|
-%% unexcepted edition, should not happen
|
|
|
-basic_reboot_apps_edition(_) ->
|
|
|
- [].
|
|
|
+ PrivDir = code:priv_dir(emqx_machine),
|
|
|
+ RebootListPath = filename:join([PrivDir, "reboot_lists.eterm"]),
|
|
|
+ {ok, [
|
|
|
+ #{
|
|
|
+ common_business_apps := CommonBusinessApps,
|
|
|
+ ee_business_apps := EEBusinessApps,
|
|
|
+ ce_business_apps := CEBusinessApps
|
|
|
+ }
|
|
|
+ ]} = file:consult(RebootListPath),
|
|
|
+ EditionSpecificApps =
|
|
|
+ case emqx_release:edition() of
|
|
|
+ ee -> EEBusinessApps;
|
|
|
+ ce -> CEBusinessApps;
|
|
|
+ _ -> []
|
|
|
+ end,
|
|
|
+ BusinessApps = CommonBusinessApps ++ EditionSpecificApps,
|
|
|
+ ?BASIC_REBOOT_APPS ++ (BusinessApps -- excluded_apps()).
|
|
|
+
|
|
|
+excluded_apps() ->
|
|
|
+ OptionalApps = [bcrypt, jq, observer],
|
|
|
+ [system_monitor, observer_cli] ++
|
|
|
+ [App || App <- OptionalApps, not is_app(App)].
|
|
|
+
|
|
|
+is_app(Name) ->
|
|
|
+ case application:load(Name) of
|
|
|
+ ok -> true;
|
|
|
+ {error, {already_loaded, _}} -> true;
|
|
|
+ _ -> false
|
|
|
+ end.
|
|
|
|
|
|
sorted_reboot_apps() ->
|
|
|
- Apps = [{App, app_deps(App)} || App <- reboot_apps()],
|
|
|
+ Apps0 = [{App, app_deps(App)} || App <- reboot_apps()],
|
|
|
+ Apps = inject_bridge_deps(Apps0),
|
|
|
sorted_reboot_apps(Apps).
|
|
|
|
|
|
app_deps(App) ->
|
|
|
@@ -174,6 +170,25 @@ app_deps(App) ->
|
|
|
{ok, List} -> lists:filter(fun(A) -> lists:member(A, reboot_apps()) end, List)
|
|
|
end.
|
|
|
|
|
|
+%% `emqx_bridge' is special in that it needs all the bridges apps to
|
|
|
+%% be started before it, so that, when it loads the bridges from
|
|
|
+%% configuration, the bridge app and its dependencies need to be up.
|
|
|
+inject_bridge_deps(RebootAppDeps) ->
|
|
|
+ BridgeApps = [
|
|
|
+ App
|
|
|
+ || {App, _Deps} <- RebootAppDeps,
|
|
|
+ lists:prefix("emqx_bridge_", atom_to_list(App))
|
|
|
+ ],
|
|
|
+ lists:map(
|
|
|
+ fun
|
|
|
+ ({emqx_bridge, Deps0}) when is_list(Deps0) ->
|
|
|
+ {emqx_bridge, Deps0 ++ BridgeApps};
|
|
|
+ (App) ->
|
|
|
+ App
|
|
|
+ end,
|
|
|
+ RebootAppDeps
|
|
|
+ ).
|
|
|
+
|
|
|
sorted_reboot_apps(Apps) ->
|
|
|
G = digraph:new(),
|
|
|
try
|