From 1a715c8708a3029cf559498ab2adc65197c2a3ae Mon Sep 17 00:00:00 2001 From: Georgy Sychev Date: Thu, 17 Feb 2022 22:49:48 +0300 Subject: [PATCH] feat(emqx_dashboard): subsciption to update password emqx_dashboard restarted in ekka hook Closes #3155 --- CHANGES-4.3.md | 1 + .../src/emqx_rule_engine.appup.src | 12 +- .../src/emqx_dashboard_admin.erl | 83 ++++---- .../test/emqx_dashboard_SUITE.erl | 149 ++++++++++++- src/emqx.appup.src | 200 ++++++------------ src/emqx.erl | 14 +- 6 files changed, 273 insertions(+), 186 deletions(-) diff --git a/CHANGES-4.3.md b/CHANGES-4.3.md index bb33daaba..77617a60c 100644 --- a/CHANGES-4.3.md +++ b/CHANGES-4.3.md @@ -25,6 +25,7 @@ File format: * Prohibit empty topics in strict mode * Make sure ehttpc delete useless pool always succeed. * Update mongodb driver to fix potential process leak. +* Dashboard admin password persists after leaving/joining the cluster ## v4.3.13 diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src index e151086be..f47cff1f9 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src @@ -4,12 +4,12 @@ [{"4.3.8", [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_events,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}]}, {"4.3.7", [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, @@ -101,12 +101,12 @@ [{"4.3.8", [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_events,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, - {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}]}, {"4.3.7", [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, diff --git a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl index 420380f88..505c468cd 100644 --- a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl +++ b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl @@ -21,7 +21,6 @@ -behaviour(gen_server). -include("emqx_dashboard.hrl"). --include_lib("emqx/include/logger.hrl"). -boot_mnesia({mnesia, [boot]}). -copy_mnesia({mnesia, [copy]}). @@ -146,9 +145,9 @@ update_pwd(Username, Fun) -> Trans = fun() -> User = case lookup_user(Username) of - [Admin] -> Admin; - [] -> - mnesia:abort(<<"Username Not Found">>) + [Admin] -> Admin; + [] -> + mnesia:abort(<<"Username Not Found">>) end, mnesia:write(Fun(User)) end, @@ -156,7 +155,14 @@ update_pwd(Username, Fun) -> -spec(lookup_user(binary()) -> [mqtt_admin()]). -lookup_user(Username) when is_binary(Username) -> mnesia:dirty_read(mqtt_admin, Username). +lookup_user(Username) when is_binary(Username) -> + case binenv(default_user_username) of + Username -> + Password = hashed_default_passwd(), + [#mqtt_admin{username=Username, password=Password, tags= <<"administrator">>}]; + _ -> + mnesia:dirty_read(mqtt_admin, Username) + end. -spec(all_users() -> [#mqtt_admin{}]). all_users() -> ets:tab2list(mqtt_admin). @@ -187,7 +193,8 @@ check(Username, Password) -> init([]) -> %% Add default admin user - _ = add_default_user(binenv(default_user_username), binenv(default_user_passwd)), + {ok, _} = mnesia:subscribe({table, mqtt_admin, simple}), + add_default_user_hashed(binenv(default_user_username), hashed_default_passwd()), {ok, state}. handle_call(_Req, _From, State) -> @@ -196,6 +203,17 @@ handle_call(_Req, _From, State) -> handle_cast(_Msg, State) -> {noreply, State}. +handle_info({mnesia_table_event, {write, Admin, _}}, State) -> + #mqtt_admin{username=Username, password=HashedPassword} = Admin, + case binenv(default_user_username) of + Username -> + application:set_env(emqx_dashboard, default_user_passwd_hashed, HashedPassword); + + _ -> + ignore + end, + {noreply, State}; + handle_info(_Msg, State) -> {noreply, State}. @@ -222,37 +240,26 @@ salt() -> <>. binenv(Key) -> - iolist_to_binary(application:get_env(emqx_dashboard, Key, "")). + iolist_to_binary(application:get_env(emqx_dashboard, Key, <<>>)). -add_default_user(Username, Password) when ?EMPTY_KEY(Username) orelse ?EMPTY_KEY(Password) -> - ignore; +add_default_user_hashed(Username, HashedPassword) -> + case mnesia:dirty_read(mqtt_admin, Username) of + [] -> + Admin = #mqtt_admin{username=Username, password=HashedPassword, tags= <<"administrator">>}, + return(mnesia:transaction(fun add_user_/1, [Admin])); + _ -> ok + end. -add_default_user(Username, Password) -> - case lookup_user(Username) of - [] -> add_user(Username, Password, <<"administrator">>); - _ -> - case check(Username, Password) of - ok -> - ?LOG(warning, - "[Dashboard] The initial default password for dashboard 'admin' user in emqx_dashboard.conf\n" - "For safety, it should be changed as soon as possible.\n" - "Please use the './bin/emqx_ctl admins' CLI to change it.\n" - "Then remove `dashboard.default_user.login/password` from emqx_dashboard.conf" - ); - {error, _} -> - %% We can't force add default, - %% otherwise passwords that have been updated via HTTP API will be reset after reboot. - ?LOG(warning, - "[Dashboard] dashboard.default_user.password in the plugins/emqx_dashboard.conf\n" - "does not match the password in the database(mnesia).\n" - "1. If you have already changed the password via the HTTP API or `./bin/emqx_ctl admins`," - "this warning has no effect.\n" - "You should remove the `dashboard.default_user.login/password` from emqx_dashboard.conf " - "to resolve this warning.\n" - "2. If you just want to update the password by manually changing the configuration file,\n" - "you need to delete the old user and password using `emqx_ctl admins del ~s` first\n" - "the new password in emqx_dashboard.conf can take effect after reboot.", - []) - end - end, - ok. +hashed_default_passwd() -> + case binenv(default_user_passwd_hashed) of + Empty0 when ?EMPTY_KEY(Empty0) -> + case binenv(default_user_passwd) of + Empty when ?EMPTY_KEY(Empty) -> + undefined; + Password -> + Hashed = hash(Password), + application:set_env(emqx_dashboard, default_user_passwd_hashed, Hashed), + Hashed + end; + HashedPassword -> HashedPassword + end. diff --git a/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl b/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl index 5099d4449..28d80ae7d 100644 --- a/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl +++ b/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl @@ -29,6 +29,8 @@ -include_lib("emqx/include/emqx.hrl"). +-include("emqx_dashboard.hrl"). + -define(CONTENT_TYPE, "application/x-www-form-urlencoded"). -define(HOST, "http://127.0.0.1:18083/"). @@ -40,21 +42,23 @@ -define(OVERVIEWS, ['alarms/activated', 'alarms/deactivated', banned, brokers, stats, metrics, listeners, clients, subscriptions, routes, plugins]). all() -> - [{group, overview}, + [ + {group, overview}, {group, admins}, {group, rest}, {group, cli} ]. groups() -> - [{overview, [sequence], [t_overview]}, - {admins, [sequence], [t_admins_add_delete]}, - {rest, [sequence], [t_rest_api, t_auth_exhaustive_attack]}, + [ + {overview, [sequence], [t_overview]}, + {admins, [sequence], [t_admins_add_delete, t_admins_persist_default_password, t_default_password_persists_after_leaving_cluster]}, + {rest, [sequence], [t_rest_api]}, {cli, [sequence], [t_cli]} ]. init_per_suite(Config) -> - emqx_ct_helpers:start_apps([emqx_modules, emqx_management, emqx_dashboard]), + ok = emqx_ct_helpers:start_apps([emqx_modules, emqx_management, emqx_dashboard]), Config. end_per_suite(_Config) -> @@ -84,9 +88,93 @@ t_admins_add_delete(_) -> ?assertNotEqual(true, request_dashboard(get, api_path("brokers"), auth_header_("username", "pwd"))). +t_admins_persist_default_password(_) -> + emqx_dashboard_admin:change_password(<<"admin">>, <<"new_password">>), + ct:sleep(100), + [#mqtt_admin{password=Password, tags= <<"administrator">>}] = emqx_dashboard_admin:lookup_user(<<"admin">>), + + %% To ensure that state persists even if the process dies + application:stop(emqx_dashboard), + application:start(emqx_dashboard), + + ct:sleep(100), + + %% It get's restarted by the app automatically + [#mqtt_admin{password=PasswordAfterRestart}] = emqx_dashboard_admin:lookup_user(<<"admin">>), + ?assertEqual(Password, PasswordAfterRestart), + emqx_dashboard_admin:change_password(<<"admin">>, <<"public">>). + +debug(Label, Slave) -> + ct:print( + "[~p]~nusers local ~p~nusers remote: ~p~nenv local: ~p~nenv remote: ~p", + [ + Label, + ets:tab2list(mqtt_admin), + rpc:call(Slave, ets, tab2list, [mqtt_admin]), + application:get_all_env(emqx_dashboard), + rpc:call(Slave, application, get_all_env, [emqx_dashboard]) + ]). + + +t_default_password_persists_after_leaving_cluster(_) -> + [#mqtt_admin{password=InitialPassword}] = emqx_dashboard_admin:lookup_user(<<"admin">>), + + ct:print("Cluster status: ~p", [ekka_cluster:info()]), + ct:print("Table nodes: ~p", [mnesia:table_info(mqtt_admin, active_replicas)]), + + Slave = start_slave('test1', [emqx_modules, emqx_management, emqx_dashboard]), + + %% To make sure that subscription is not lost during reconnection + rpc:call(Slave, ekka, leave, []), + ct:sleep(100), %% To ensure that leave gets processed + rpc:call(Slave, ekka, join, [node()]), + ct:sleep(100), %% To ensure that join gets processed + + ct:print("Cluster status: ~p", [ekka_cluster:info()]), + ct:print("Table nodes: ~p", [mnesia:table_info(mqtt_admin, active_replicas)]), + + ct:print("Apps: ~p", [ + rpc:call(Slave, application, which_applications, []) + ]), + + debug(0, Slave), + + emqx_dashboard_admin:change_password(<<"admin">>, <<"new_password">>), + ct:sleep(100), %% To ensure that event gets processed + + debug(1, Slave), + + [#mqtt_admin{password=Password}] = rpc:call(Slave, emqx_dashboard_admin, lookup_user, [<<"admin">>]), + ?assertNotEqual(InitialPassword, Password), + + rpc:call(Slave, ekka, leave, []), + + debug(2, Slave), + + rpc:call(Slave, application, stop, [emqx_dashboard]), + + debug(3, Slave), + + rpc:call(Slave, application, start, [emqx_dashboard]), + + debug(4, Slave), + + ?assertEqual( + ok, + rpc:call(Slave, emqx_dashboard_admin, check, [<<"admin">>, <<"new_password">>])), + + ?assertMatch( + {error, _}, + rpc:call(Slave, emqx_dashboard_admin, check, [<<"admin">>, <<"password">>])), + + {ok, _} = stop_slave(Slave, [emqx_dashboard, emqx_management, emqx_modules]), + + emqx_dashboard_admin:change_password(<<"admin">>, <<"public">>). + t_rest_api(_Config) -> {ok, Res0} = http_get("users"), Users = get_http_data(Res0), + ct:pal("~p", [emqx_dashboard_admin:all_users()]), ?assert(lists:member(#{<<"username">> => <<"admin">>, <<"tags">> => <<"administrator">>}, Users)), @@ -170,3 +258,54 @@ api_path(Path) -> json(Data) -> {ok, Jsx} = emqx_json:safe_decode(Data, [return_maps]), Jsx. + +start_slave(Name, Apps) -> + {ok, Node} = ct_slave:start(list_to_atom(atom_to_list(Name) ++ "@" ++ host()), + [{kill_if_fail, true}, + {monitor_master, true}, + {init_timeout, 10000}, + {startup_timeout, 10000}, + {erl_flags, ebin_path()}]), + + pong = net_adm:ping(Node), + setup_node(Node, Apps), + Node. + +stop_slave(Node, Apps) -> + [ok = Res || Res <- rpc:call(Node, emqx_ct_helpers, stop_apps, [Apps])], + rpc:call(Node, ekka, leave, []), + ct_slave:stop(Node). + +host() -> + [_, Host] = string:tokens(atom_to_list(node()), "@"), Host. + +ebin_path() -> + string:join(["-pa" | lists:filter(fun is_lib/1, code:get_path())], " "). + +is_lib(Path) -> + string:prefix(Path, code:lib_dir()) =:= nomatch. + +setup_node(Node, Apps) -> + EnvHandler = + fun(emqx) -> + application:set_env(emqx, listeners, []), + application:set_env(gen_rpc, port_discovery, manual), + ok; + (emqx_management) -> + application:set_env(emqx_management, listeners, []), + ok; + (emqx_dashboard) -> + application:set_env(emqx_dashboard, listeners, []), + ok; + (_) -> + ok + end, + + [ok = rpc:call(Node, application, load, [App]) || App <- [gen_rpc, emqx | Apps]], + ok = rpc:call(Node, emqx_ct_helpers, start_apps, [Apps, EnvHandler]), + + rpc:call(Node, ekka, join, [node()]), + rpc:call(Node, application, stop, [emqx_dashboard]), + rpc:call(Node, application, start, [emqx_dashboard]), + + ok. diff --git a/src/emqx.appup.src b/src/emqx.appup.src index 8825da442..17a0e92e9 100644 --- a/src/emqx.appup.src +++ b/src/emqx.appup.src @@ -3,13 +3,12 @@ {VSN, [{"4.3.14", [{load_module,emqx_frame,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_hooks,brutal_purge,soft_purge,[]}, + {load_module,emqx,brutal_purge,soft_purge,[]}]}, {"4.3.13", - [{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, - {load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, + {load_module,emqx,brutal_purge,soft_purge,[]}, + {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_frame,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, @@ -21,12 +20,9 @@ {load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, - {load_module,emqx_connection,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}]}, {"4.3.12", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_frame,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -48,12 +44,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.11", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -77,12 +70,9 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_http_lib,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.10", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -106,12 +96,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_connection,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.9", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -139,12 +126,9 @@ {load_module,emqx_os_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.8", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -172,12 +156,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.7", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -206,12 +187,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.6", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -240,12 +218,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.5", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -275,11 +250,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.4", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -310,11 +283,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.3", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -346,11 +317,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.2", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -382,11 +351,9 @@ {load_module,emqx_os_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.1", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]}, @@ -421,11 +388,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.0", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]}, @@ -463,18 +428,16 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], [{"4.3.14", [{load_module,emqx_frame,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_hooks,brutal_purge,soft_purge,[]}, + {load_module,emqx,brutal_purge,soft_purge,[]}]}, {"4.3.13", - [{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, - {load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, + {load_module,emqx,brutal_purge,soft_purge,[]}, + {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_frame,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, @@ -486,12 +449,9 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, - {load_module,emqx_connection,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}]}, {"4.3.12", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_frame,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, @@ -512,12 +472,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.11", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -540,12 +497,9 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_http_lib,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.10", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -568,12 +522,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_connection,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.9", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -600,12 +551,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.8", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -632,12 +580,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.7", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -665,12 +610,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.6", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -698,12 +640,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.5", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -732,11 +671,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.4", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -766,11 +703,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.3", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -801,11 +736,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.2", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, @@ -836,11 +769,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.1", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]}, @@ -874,11 +805,9 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {"4.3.0", - [{load_module,emqx_flapping,brutal_purge,soft_purge,[]}, - {load_module,emqx_listeners,brutal_purge,soft_purge,[]}, + [{load_module,emqx_hooks,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]}, @@ -914,6 +843,5 @@ {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, - {load_module,emqx_limiter,brutal_purge,soft_purge,[]}, - {load_module,emqx_hooks,brutal_purge,soft_purge,[]}]}, + {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}]}. diff --git a/src/emqx.erl b/src/emqx.erl index 5c90cf953..7fb3c734f 100644 --- a/src/emqx.erl +++ b/src/emqx.erl @@ -234,7 +234,19 @@ shutdown(Reason) -> ). reboot() -> - lists:foreach(fun application:start/1 , default_started_applications()). + case is_application_running(emqx_dashboard) of + true -> + application:stop(emqx_dashboard), %% dashboard must be started after mnesia + lists:foreach(fun application:start/1 , default_started_applications()), + application:start(emqx_dashboard); + + false -> + lists:foreach(fun application:start/1 , default_started_applications()) + end. + +is_application_running(App) -> + StartedApps = proplists:get_value(started, application:info()), + proplists:is_defined(App, StartedApps). -ifdef(EMQX_ENTERPRISE). default_started_applications() ->