refactor(appup): always generate appup from script

This commit is contained in:
Zaiming (Stone) Shi 2022-03-07 19:43:55 +01:00
parent 9fbc211fd0
commit d8e29f19cb
5 changed files with 271 additions and 230 deletions

View File

@ -1,6 +1,10 @@
%% -*- mode: erlang -*- %% -*- mode: erlang -*-
%% Unless you know what you are doing, DO NOT edit manually!!
{VSN, {VSN,
[{<<"4.3.[0-3]">>, [{"4.3.5",
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}]},
{<<"4\\.3\\.[0-3]">>,
[{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]}, [{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
{add_module,emqx_acl_mnesia_db}, {add_module,emqx_acl_mnesia_db},
@ -12,17 +16,17 @@
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
{load_module,emqx_acl_mnesia_api,brutal_purge,soft_purge,[]}, {load_module,emqx_acl_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]}, {load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
{<<"4.3.4">>, {"4.3.4",
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]}, [{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]},
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]}, {load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
{<<"4.3.5">>, {<<".*">>,[]}],
[{"4.3.5",
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]}, [{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}]}, {load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}]},
{<<".*">>,[]}], {<<"4\\.3\\.[0-3]">>,
[{<<"4.3.[0-3]">>,
[{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]}, [{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
{apply,{emqx_acl_mnesia_migrator,stop_supervised,[]}}, {apply,{emqx_acl_mnesia_migrator,stop_supervised,[]}},
@ -34,13 +38,10 @@
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
{delete_module,emqx_acl_mnesia_migrator}, {delete_module,emqx_acl_mnesia_migrator},
{delete_module,emqx_acl_mnesia_db}]}, {delete_module,emqx_acl_mnesia_db}]},
{<<"4.3.4">>, {"4.3.4",
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]}, [{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]}, {load_module,emqx_auth_mnesia_cli,brutal_purge,soft_purge,[]},
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]}, {load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]}, {load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
{<<"4.3.5">>,
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]}]},
{<<".*">>,[]}]}. {<<".*">>,[]}]}.

View File

@ -2,10 +2,10 @@
{"4.3.4", {"4.3.4",
[ [
{<<"4.3.3">>, [ {"4.3.3", [
{load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []} {load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []}
]}, ]},
{<<"4.3.[1-2]">>, [ {<<"4\\.3\\.[1-2]">>, [
{load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []}, {load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []},
{load_module, emqx_bridge_mqtt_actions, brutal_purge, soft_purge, []} {load_module, emqx_bridge_mqtt_actions, brutal_purge, soft_purge, []}
]}, ]},
@ -17,10 +17,10 @@
{<<".*">>, []} {<<".*">>, []}
], ],
[ [
{<<"4.3.3">>, [ {"4.3.3", [
{load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []} {load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []}
]}, ]},
{<<"4.3.[1-2]">>, [ {<<"4\\.3\\.[1-2]">>, [
{load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []}, {load_module, emqx_bridge_mqtt, brutal_purge, soft_purge, []},
{load_module, emqx_bridge_mqtt_actions, brutal_purge, soft_purge, []} {load_module, emqx_bridge_mqtt_actions, brutal_purge, soft_purge, []}
]}, ]},
@ -31,4 +31,4 @@
]}, ]},
{<<".*">>, []} {<<".*">>, []}
] ]
}. }.

View File

@ -8,7 +8,7 @@
set -euo pipefail set -euo pipefail
usage() { usage() {
echo "$0 PROFILE PREV_VERSION" echo "$0 PROFILE"
} }
# ensure dir # ensure dir
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/.." cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
@ -34,11 +34,43 @@ case "$PROFILE" in
;; ;;
esac esac
PREV_VERSION="$(git describe --tag --match "${TAG_PREFIX}*" | grep -oE "${TAG_PREFIX}4\.[0-9]+\.[0-9]+")" PREV_TAG="$(git describe --tag --match "${TAG_PREFIX}*" | grep -oE "${TAG_PREFIX}4\.[0-9]+\.[0-9]+")"
PREV_VERSION="${PREV_VERSION#[e|v]}" PREV_VERSION="${PREV_TAG#[e|v]}"
shift 1 shift 1
ESCRIPT_ARGS="$*" ESCRIPT_ARGS=()
while [ "$#" -gt 0 ]; do
case $1 in
-h|--help)
help
exit 0
;;
--skip-build)
SKIP_BUILD='yes'
shift
;;
--check)
# hijack the --check option
IS_CHECK='yes'
shift
;;
*)
ESCRIPT_ARGS+=( "$1" )
shift
;;
esac
done
if [ "$TAG_PREFIX" = 'v' ]; then
SRC_DIRS="{apps,src,lib-ce}"
else
SRC_DIRS="{apps,src,lib-ee}"
fi
## make sure we build here in bash and always pass --skip-build to escript
if [ "${SKIP_BUILD:-}" != 'yes' ]; then
make "${PROFILE}"
fi
SYSTEM="${SYSTEM:-$(./scripts/get-distro.sh)}" SYSTEM="${SYSTEM:-$(./scripts/get-distro.sh)}"
if [ -z "${ARCH:-}" ]; then if [ -z "${ARCH:-}" ]; then
@ -59,18 +91,30 @@ fi
PACKAGE_NAME="${PROFILE}-${SYSTEM}-${PREV_VERSION}-${ARCH}.zip" PACKAGE_NAME="${PROFILE}-${SYSTEM}-${PREV_VERSION}-${ARCH}.zip"
DOWNLOAD_URL="https://www.emqx.com/downloads/${DIR}/v${PREV_VERSION}/${PACKAGE_NAME}" DOWNLOAD_URL="https://www.emqx.com/downloads/${DIR}/v${PREV_VERSION}/${PACKAGE_NAME}"
if [ ! -f EMQX_ENTERPRISE ]; then PREV_DIR_BASE="/tmp/emqx-appup-base"
SRC_REPO='emqx.git' mkdir -p "${PREV_DIR_BASE}"
SRC_DIRS='{src,apps,lib-ce}/**' pushd "${PREV_DIR_BASE}"
else if [ ! -f "${PACKAGE_NAME}" ]; then
SRC_REPO='emqx-enterprise.git' echo "Download: ${PACKAGE_NAME}"
SRC_DIRS='{src,apps,lib-ee}/**' curl -f -L -o "${PACKAGE_NAME}" "${DOWNLOAD_URL}"
fi fi
# shellcheck disable=SC2086 if [ ! -d "${PREV_TAG}" ]; then
unzip -q -n -d "${PREV_TAG}" "${PACKAGE_NAME}"
fi
popd
./scripts/update_appup.escript \ ./scripts/update_appup.escript \
--make-command "make ${PROFILE}-rel" \ --src-dirs "${SRC_DIRS}/**" \
--binary-rel-url "$DOWNLOAD_URL" \ --release-dir "_build/${PROFILE}/lib" \
--repo "$SRC_REPO" \ --prev-release-dir "${PREV_DIR_BASE}/${PREV_TAG}/emqx/lib" \
--release-dir "_build/${PROFILE}/rel/emqx/lib" \ --skip-build \
--src-dirs "${SRC_DIRS}" \ "${ESCRIPT_ARGS[@]}" "$PREV_VERSION"
$ESCRIPT_ARGS "$PREV_VERSION"
if [ "${IS_CHECK:-}" = 'yes' ]; then
diffs="$(git diff --name-only | grep -E '\.appup\.src' || true)"
if [ "$diffs" != '' ]; then
git --no-pager diff
echo "$0 ---check produced git diff"
exit 1
fi
fi

View File

@ -25,15 +25,14 @@ Usage:
Options: Options:
--check Don't update the appfile, just check that they are complete --check Don't update the appfile, just check that they are complete
--repo Upsteam git repo URL --repo Upsteam git repo URL
--remote Get upstream repo URL from the specified git remote --remote Get upstream repo URL from the specified git remote
--skip-build Don't rebuild the releases. May produce wrong results --skip-build Don't rebuild the releases. May produce wrong results
--make-command A command used to assemble the release --make-command A command used to assemble the release
--release-dir Release directory --prev-release-dir Previous version's release dir (if already built/extracted)
--src-dirs Directories where source code is found. Defaults to '{src,apps,lib-*}/**/' --release-dir Release directory
--binary-rel-url Binary release URL pattern. --src-dirs Directories where source code is found. Defaults to '{src,apps,lib-*}/**/'
E.g. https://www.emqx.com/downloads/broker/v4.3.12/emqx-centos7-4.3.12-amd64.zip
". ".
-record(app, -record(app,
@ -48,7 +47,7 @@ default_options() ->
, check => false , check => false
, prev_tag => undefined , prev_tag => undefined
, src_dirs => "{src,apps,lib-*}/**/" , src_dirs => "{src,apps,lib-*}/**/"
, binary_rel_url => undefined , prev_beams_dir => undefined
}. }.
%% App-specific actions that should be added unconditionally to any update/downgrade: %% App-specific actions that should be added unconditionally to any update/downgrade:
@ -56,7 +55,7 @@ app_specific_actions(_) ->
[]. [].
ignored_apps() -> ignored_apps() ->
[emqx_dashboard, emqx_management] ++ otp_standard_apps(). [gpb, emqx_dashboard, emqx_management] ++ otp_standard_apps().
main(Args) -> main(Args) ->
#{prev_tag := Baseline} = Options = parse_args(Args, default_options()), #{prev_tag := Baseline} = Options = parse_args(Args, default_options()),
@ -68,7 +67,7 @@ parse_args([PrevTag = [A|_]], State) when A =/= $- ->
parse_args(["--check"|Rest], State) -> parse_args(["--check"|Rest], State) ->
parse_args(Rest, State#{check => true}); parse_args(Rest, State#{check => true});
parse_args(["--skip-build"|Rest], State) -> parse_args(["--skip-build"|Rest], State) ->
parse_args(Rest, State#{make_command => "true"}); parse_args(Rest, State#{make_command => undefined});
parse_args(["--repo", Repo|Rest], State) -> parse_args(["--repo", Repo|Rest], State) ->
parse_args(Rest, State#{clone_url => Repo}); parse_args(Rest, State#{clone_url => Repo});
parse_args(["--remote", Remote|Rest], State) -> parse_args(["--remote", Remote|Rest], State) ->
@ -77,15 +76,16 @@ parse_args(["--make-command", Command|Rest], State) ->
parse_args(Rest, State#{make_command => Command}); parse_args(Rest, State#{make_command => Command});
parse_args(["--release-dir", Dir|Rest], State) -> parse_args(["--release-dir", Dir|Rest], State) ->
parse_args(Rest, State#{beams_dir => Dir}); parse_args(Rest, State#{beams_dir => Dir});
parse_args(["--prev-release-dir", Dir|Rest], State) ->
parse_args(Rest, State#{prev_beams_dir => Dir});
parse_args(["--src-dirs", Pattern|Rest], State) -> parse_args(["--src-dirs", Pattern|Rest], State) ->
parse_args(Rest, State#{src_dirs => Pattern}); parse_args(Rest, State#{src_dirs => Pattern});
parse_args(["--binary-rel-url", URL|Rest], State) ->
parse_args(Rest, State#{binary_rel_url => {ok, URL}});
parse_args(_, _) -> parse_args(_, _) ->
fail(usage()). fail(usage()).
main(Options, Baseline) -> main(Options, Baseline) ->
{CurrRelDir, PrevRelDir} = prepare(Baseline, Options), {CurrRelDir, PrevRelDir} = prepare(Baseline, Options),
putopt(prev_beams_dir, PrevRelDir),
log("~n===================================~n" log("~n===================================~n"
"Processing changes..." "Processing changes..."
"~n===================================~n"), "~n===================================~n"),
@ -93,38 +93,9 @@ main(Options, Baseline) ->
PrevAppsIdx = index_apps(PrevRelDir), PrevAppsIdx = index_apps(PrevRelDir),
%% log("Curr: ~p~nPrev: ~p~n", [CurrAppsIdx, PrevAppsIdx]), %% log("Curr: ~p~nPrev: ~p~n", [CurrAppsIdx, PrevAppsIdx]),
AppupChanges = find_appup_actions(CurrAppsIdx, PrevAppsIdx), AppupChanges = find_appup_actions(CurrAppsIdx, PrevAppsIdx),
case getopt(check) of ok = update_appups(AppupChanges),
true -> ok = check_appup_files(),
case AppupChanges of ok = warn_and_exit(is_valid()).
[] ->
ok;
_ ->
Diffs =
lists:filtermap(
fun({App, {Upgrade, Downgrade, OldUpgrade, OldDowngrade}}) ->
case parse_appup_diffs(Upgrade, OldUpgrade,
Downgrade, OldDowngrade) of
ok ->
false;
{diffs, Diffs} ->
{true, {App, Diffs}}
end
end,
AppupChanges),
case Diffs =:= [] of
true ->
ok;
false ->
set_invalid(),
log("ERROR: The appup files are incomplete. Missing changes:~n ~p",
[Diffs])
end
end;
false ->
update_appups(AppupChanges)
end,
check_appup_files(),
warn_and_exit(is_valid()).
warn_and_exit(true) -> warn_and_exit(true) ->
log(" log("
@ -136,50 +107,34 @@ warn_and_exit(false) ->
log("~nERROR: Incomplete appups found. Please inspect the output for more details.~n"), log("~nERROR: Incomplete appups found. Please inspect the output for more details.~n"),
halt(1). halt(1).
prepare(Baseline, Options = #{make_command := MakeCommand, beams_dir := BeamDir, binary_rel_url := BinRel}) -> prepare(Baseline, Options = #{make_command := MakeCommand, beams_dir := BeamDir}) ->
log("~n===================================~n" log("~n===================================~n"
"Baseline: ~s" "Baseline: ~s"
"~n===================================~n", [Baseline]), "~n===================================~n", [Baseline]),
log("Building the current version...~n"), log("Building the current version...~n"),
bash(MakeCommand), ok = bash(MakeCommand),
log("Downloading and building the previous release...~n"),
PrevRelDir = PrevRelDir =
case BinRel of case maps:get(prev_beams_dir, Options, undefined) of
undefined -> undefined ->
log("Building the previous release...~n"),
{ok, PrevRootDir} = build_prev_release(Baseline, Options), {ok, PrevRootDir} = build_prev_release(Baseline, Options),
filename:join(PrevRootDir, BeamDir); filename:join(PrevRootDir, BeamDir);
{ok, _URL} -> Dir ->
{ok, PrevRootDir} = download_prev_release(Baseline, Options), %% already built
PrevRootDir Dir
end, end,
{BeamDir, PrevRelDir}. {BeamDir, PrevRelDir}.
build_prev_release(Baseline, #{clone_url := Repo, make_command := MakeCommand}) -> build_prev_release(Baseline, #{clone_url := Repo, make_command := MakeCommand}) ->
BaseDir = "/tmp/emqx-baseline/", BaseDir = "/tmp/emqx-appup-base/",
Dir = filename:basename(Repo, ".git") ++ [$-|Baseline], Dir = filename:basename(Repo, ".git") ++ [$-|Baseline],
%% TODO: shallow clone
Script = "mkdir -p ${BASEDIR} && Script = "mkdir -p ${BASEDIR} &&
cd ${BASEDIR} && cd ${BASEDIR} &&
{ [ -d ${DIR} ] || git clone --branch ${TAG} ${REPO} ${DIR}; } && { [ -d ${DIR} ] || git clone --depth 1 --branch ${TAG} ${REPO} ${DIR}; } &&
cd ${DIR} &&" ++ MakeCommand, cd ${DIR} &&" ++ MakeCommand,
Env = [{"REPO", Repo}, {"TAG", Baseline}, {"BASEDIR", BaseDir}, {"DIR", Dir}], Env = [{"REPO", Repo}, {"TAG", Baseline}, {"BASEDIR", BaseDir}, {"DIR", Dir}],
bash(Script, Env), ok = bash(Script, Env),
{ok, filename:join(BaseDir, Dir)}. {ok, filename:join([BaseDir, Dir, "_build/*/lib"])}.
download_prev_release(Tag, #{binary_rel_url := {ok, URL0}, clone_url := Repo}) ->
URL = string:replace(URL0, "%TAG%", Tag, all),
BaseDir = "/tmp/emqx-baseline-bin/",
Dir = filename:basename(Repo, ".git") ++ [$-|Tag],
Filename = filename:join(BaseDir, Dir),
Script = "mkdir -p ${OUTFILE} &&
if [ ! -f \"${OUTFILE}.zip\" ]; then \
echo \"Download: ${OUTFILE}\" && \
curl -f -L -o \"${OUTFILE}.zip\" \"${URL}\"; \
fi &&
unzip -q -n -d ${OUTFILE} ${OUTFILE}.zip",
Env = [{"TAG", Tag}, {"OUTFILE", Filename}, {"URL", URL}],
bash(Script, Env),
{ok, Filename}.
find_upstream_repo(Remote) -> find_upstream_repo(Remote) ->
string:trim(os:cmd("git remote get-url " ++ Remote)). string:trim(os:cmd("git remote get-url " ++ Remote)).
@ -208,16 +163,16 @@ find_appup_actions(_App, AppIdx, AppIdx) ->
find_appup_actions(App, find_appup_actions(App,
CurrAppIdx = #app{version = CurrVersion}, CurrAppIdx = #app{version = CurrVersion},
PrevAppIdx = #app{version = PrevVersion}) -> PrevAppIdx = #app{version = PrevVersion}) ->
{OldUpgrade0, OldDowngrade0} = find_old_appup_actions(App, PrevVersion), {OldUpgrade0, OldDowngrade0} = find_base_appup_actions(App, PrevVersion),
OldUpgrade = ensure_all_patch_versions(App, CurrVersion, OldUpgrade0), OldUpgrade = ensure_all_patch_versions(App, CurrVersion, OldUpgrade0),
OldDowngrade = ensure_all_patch_versions(App, CurrVersion, OldDowngrade0), OldDowngrade = ensure_all_patch_versions(App, CurrVersion, OldDowngrade0),
Upgrade = merge_update_actions(App, diff_app(up, App, CurrAppIdx, PrevAppIdx), OldUpgrade), UpDiff = diff_app(up, App, CurrAppIdx, PrevAppIdx),
Downgrade = merge_update_actions(App, diff_app(down, App, PrevAppIdx, CurrAppIdx), OldDowngrade), DownDiff = diff_app(down, App, PrevAppIdx, CurrAppIdx),
if OldUpgrade =:= Upgrade andalso OldDowngrade =:= Downgrade -> Upgrade = merge_update_actions(App, UpDiff, OldUpgrade),
%% The appup file has been already updated: Downgrade = merge_update_actions(App, DownDiff, OldDowngrade),
[]; case OldUpgrade =:= Upgrade andalso OldDowngrade =:= Downgrade of
true -> true -> [];
[{App, {Upgrade, Downgrade, OldUpgrade, OldDowngrade}}] false -> [{App, {Upgrade, Downgrade, OldUpgrade, OldDowngrade}}]
end. end.
%% To avoid missing one patch version when upgrading, we try to %% To avoid missing one patch version when upgrading, we try to
@ -268,7 +223,7 @@ diff_appup_instructions(ComputedChanges, PresentChanges) ->
[], [],
ComputedChanges). ComputedChanges).
%% For external dependencies, checks if any missing diffs are present %% checks if any missing diffs are present
%% and groups them by `up' and `down' types. %% and groups them by `up' and `down' types.
parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) -> parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) ->
DiffUp = diff_appup_instructions(Upgrade, OldUpgrade), DiffUp = diff_appup_instructions(Upgrade, OldUpgrade),
@ -278,7 +233,6 @@ parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) ->
%% no diff for external dependency; ignore %% no diff for external dependency; ignore
ok; ok;
_ -> _ ->
set_invalid(),
Diffs = #{ up => DiffUp Diffs = #{ up => DiffUp
, down => DiffDown , down => DiffDown
}, },
@ -292,27 +246,17 @@ parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) ->
find_matching_version(VsnOrRegex, PresentChanges) -> find_matching_version(VsnOrRegex, PresentChanges) ->
proplists:get_value(VsnOrRegex, PresentChanges). proplists:get_value(VsnOrRegex, PresentChanges).
find_old_appup_actions(App, PrevVersion) -> find_base_appup_actions(App, PrevVersion) ->
{Upgrade0, Downgrade0} = {Upgrade, Downgrade} =
case locate(ebin_current, App, ".appup") of case locate_appup(App) of
{ok, AppupFile} -> {ok, AppupSrcFile} ->
log("Found the previous appup file: ~s~n", [AppupFile]), log("INFO: Using ~s as a source of previous update actions~n", [AppupSrcFile]),
{_, U, D} = read_appup(AppupFile), read_appup(AppupSrcFile);
{U, D};
undefined -> undefined ->
%% Fallback to the app.src file, in case the log("INFO: no appup base found for ~p~n", [App]),
%% application doesn't have a release (useful for the {[], []}
%% apps that live outside the EMQX monorepo):
case locate(src, App, ".appup.src") of
{ok, AppupSrcFile} ->
log("Using ~s as a source of previous update actions~n", [AppupSrcFile]),
{_, U, D} = read_appup(AppupSrcFile),
{U, D};
undefined ->
{[], []}
end
end, end,
{ensure_version(PrevVersion, Upgrade0), ensure_version(PrevVersion, Downgrade0)}. {ensure_version(PrevVersion, Upgrade), ensure_version(PrevVersion, Downgrade)}.
merge_update_actions(App, Changes, Vsns) -> merge_update_actions(App, Changes, Vsns) ->
lists:map(fun(Ret = {<<".*">>, _}) -> lists:map(fun(Ret = {<<".*">>, _}) ->
@ -391,7 +335,8 @@ ensure_version(Version, OldInstructions) ->
contains_version(Needle, Haystack) when is_list(Needle) -> contains_version(Needle, Haystack) when is_list(Needle) ->
lists:any( lists:any(
fun(Regex) when is_binary(Regex) -> fun(<<"*">>) -> true; %% TODO: delete after we pass esockd 5.8.4
(Regex) when is_binary(Regex) ->
case re:run(Needle, Regex) of case re:run(Needle, Regex) of
{match, _} -> {match, _} ->
true; true;
@ -434,11 +379,19 @@ vsn_number_to_string({Major, Minor, Patch}) ->
read_appup(File) -> read_appup(File) ->
%% NOTE: appup file is a script, it may contain variables or functions. %% NOTE: appup file is a script, it may contain variables or functions.
case do_read_appup(File) of
{ok, {U, D}} -> {U, D};
{error, Reason} -> fail("Failed to parse appup file ~p~n~p", [File, Reason])
end.
do_read_appup(File) ->
case file:script(File, [{'VSN', "VSN"}]) of case file:script(File, [{'VSN', "VSN"}]) of
{ok, Terms} -> {ok, {_, U, D}} ->
Terms; {ok, {U, D}};
Error -> {ok, Other} ->
fail("Failed to parse appup file ~s: ~p", [File, Error]) {error, {bad_appup_format, Other}};
{error, Reason} ->
{error, Reason}
end. end.
check_appup_files() -> check_appup_files() ->
@ -453,52 +406,77 @@ update_appups(Changes) ->
Changes). Changes).
do_update_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade) -> do_update_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade) ->
case locate(src, App, ".appup.src") of case locate_current_src(App, ".appup.src") of
{ok, AppupFile} -> {ok, AppupFile} ->
case contains_contents(AppupFile, Upgrade, Downgrade) of case contains_contents(AppupFile, Upgrade, Downgrade) of
true -> true ->
ok; ok;
false -> false ->
render_appfile(AppupFile, Upgrade, Downgrade) render_appup(App, AppupFile, Upgrade, Downgrade)
end; end;
undefined -> undefined ->
case create_stub(App) of maybe_create_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade)
{ok, AppupFile} -> end.
render_appfile(AppupFile, Upgrade, Downgrade);
false -> maybe_create_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade) ->
case parse_appup_diffs(Upgrade, OldUpgrade, case create_stub(App) of
Downgrade, OldDowngrade) of {ok, AppupFile} ->
ok -> render_appup(App, AppupFile, Upgrade, Downgrade);
%% no diff for external dependency; ignore external ->
ok; %% for external appup, the best we can do is to validate it
{diffs, Diffs} -> _ = check_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade),
set_invalid(), ok
log("ERROR: Appup file for the external dependency '~p' is not complete.~n Missing changes: ~100p~n", [App, Diffs]), end.
log("NOTE: Some changes above might be already covered by regexes.~n")
end check_appup(App, Upgrade, Downgrade, OldUpgrade, OldDowngrade) ->
end case parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) of
ok ->
%% no diff for external dependency; ignore
ok;
{diffs, Diffs} ->
set_invalid(),
log("ERROR: Appup file for '~p' is not complete.~n"
"Missing:~100p~n", [App, Diffs]),
notok
end. end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Appup file creation %% Appup file creation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
render_appfile(File, Upgrade, Downgrade) -> render_appup(App, File, Up, Down) ->
IOList = io_lib:format("%% -*- mode: erlang -*-\n{VSN,~n ~p,~n ~p}.~n", [Upgrade, Downgrade]), IsCheck = getopt(check),
case do_read_appup(File) of
{ok, {U, D}} when U =:= Up andalso D =:= Down ->
ok;
{ok, {OldU, OldD}} when IsCheck ->
check_appup(App, Up, Down, OldU, OldD);
{ok, {_, _}} ->
do_render_appup(File, Up, Down);
{error, enoent} when IsCheck ->
%% failed to read old file, exit
log("ERROR: ~s is missing", [File]),
set_invalid()
end.
do_render_appup(File, Up, Down) ->
IOList = io_lib:format("%% -*- mode: erlang -*-~n"
"%% Unless you know what you are doing, DO NOT edit manually!!~n"
"{VSN,~n ~p,~n ~p}.~n", [Up, Down]),
ok = file:write_file(File, IOList). ok = file:write_file(File, IOList).
create_stub(App) -> create_stub(App) ->
Ext = ".app.src", Ext = ".app.src",
case locate(src, App, Ext) of case locate_current_src(App, Ext) of
{ok, AppSrc} -> {ok, AppSrc} ->
DirName = filename:dirname(AppSrc), DirName = filename:dirname(AppSrc),
AppupFile = filename:basename(AppSrc, Ext) ++ ".appup.src", AppupFile = filename:basename(AppSrc, Ext) ++ ".appup.src",
Default = {<<".*">>, []}, Default = {<<".*">>, []},
AppupFileFullpath = filename:join(DirName, AppupFile), AppupFileFullpath = filename:join(DirName, AppupFile),
render_appfile(AppupFileFullpath, [Default], [Default]), render_appup(App, AppupFileFullpath, [Default], [Default]),
{ok, AppupFileFullpath}; {ok, AppupFileFullpath};
undefined -> undefined ->
false external
end. end.
%% we check whether the destination file already has the contents we %% we check whether the destination file already has the contents we
@ -517,6 +495,7 @@ contains_contents(File, Upgrade, Downgrade) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index_apps(ReleaseDir) -> index_apps(ReleaseDir) ->
log("INFO: indexing apps in ~s~n", [ReleaseDir]),
Apps0 = maps:from_list([index_app(filename:join(ReleaseDir, AppFile)) || Apps0 = maps:from_list([index_app(filename:join(ReleaseDir, AppFile)) ||
AppFile <- filelib:wildcard("**/ebin/*.app", ReleaseDir)]), AppFile <- filelib:wildcard("**/ebin/*.app", ReleaseDir)]),
maps:without(ignored_apps(), Apps0). maps:without(ignored_apps(), Apps0).
@ -531,7 +510,6 @@ index_app(AppFile) ->
, modules = Modules , modules = Modules
}}. }}.
diff_app(_, gpb, _, _) -> ok; %% gpb is not a runtime app
diff_app(UpOrDown, App, diff_app(UpOrDown, App,
#app{version = NewVersion, modules = NewModules}, #app{version = NewVersion, modules = NewModules},
#app{version = OldVersion, modules = OldModules}) -> #app{version = OldVersion, modules = OldModules}) ->
@ -568,6 +546,7 @@ diff_app(UpOrDown, App,
end; end;
false -> false ->
log("INFO: Application '~p' has been updated: ~p --[~p]--> ~p~n", [App, OldVersion, UpOrDown, NewVersion]), log("INFO: Application '~p' has been updated: ~p --[~p]--> ~p~n", [App, OldVersion, UpOrDown, NewVersion]),
log("INFO: changes [~p]: ~p~n", [UpOrDown, Changes]),
ok ok
end, end,
{New, Changed, Deleted}. {New, Changed, Deleted}.
@ -588,7 +567,7 @@ hashsums(EbinDir) ->
is_app_external(App) -> is_app_external(App) ->
Ext = ".app.src", Ext = ".app.src",
case locate(src, App, Ext) of case locate_current_src(App, Ext) of
{ok, _} -> {ok, _} ->
false; false;
undefined -> undefined ->
@ -604,8 +583,16 @@ init_globals(Options) ->
ets:insert(globals, {valid, true}), ets:insert(globals, {valid, true}),
ets:insert(globals, {options, Options}). ets:insert(globals, {options, Options}).
putopt(Option, Value) ->
ets:insert(globals, {{option, Option}, Value}).
getopt(Option) -> getopt(Option) ->
maps:get(Option, ets:lookup_element(globals, options, 2)). case ets:lookup(globals, {option, Option}) of
[] ->
maps:get(Option, ets:lookup_element(globals, options, 2));
[{_, V}] ->
V
end.
%% Set a global flag that something about the appfiles is invalid %% Set a global flag that something about the appfiles is invalid
set_invalid() -> set_invalid() ->
@ -618,20 +605,28 @@ is_valid() ->
%% Utility functions %% Utility functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Locate a file in a specified application locate_appup(App) ->
locate(ebin_current, App, Suffix) -> case locate_current_rel(App, ".appup.src") of
ReleaseDir = getopt(beams_dir), {ok, File} ->
AppStr = atom_to_list(App),
case filelib:wildcard(ReleaseDir ++ "/**/ebin/" ++ AppStr ++ Suffix) of
[File] ->
{ok, File}; {ok, File};
[] -> undefined ->
undefined %% fallback to .appup
end; locate_current_rel(App, ".appup")
locate(src, App, Suffix) -> end.
AppStr = atom_to_list(App),
locate_current_rel(App, Suffix) ->
CurDir = getopt(beams_dir),
do_locate(filename:join([CurDir, "**"]), App, Suffix).
%% Locate a file in a specified application
locate_current_src(App, Suffix) ->
SrcDirs = getopt(src_dirs), SrcDirs = getopt(src_dirs),
case find_app(SrcDirs ++ AppStr ++ Suffix) of do_locate(SrcDirs, App, Suffix).
do_locate(Dir, App, Suffix) ->
AppStr = atom_to_list(App),
Pattern = filename:join(Dir, AppStr ++ Suffix),
case find_app(Pattern) of
[File] -> [File] ->
{ok, File}; {ok, File};
[] -> [] ->
@ -641,17 +636,17 @@ locate(src, App, Suffix) ->
end. end.
find_app(Pattern) -> find_app(Pattern) ->
%% exclude _build dir inside apps lists:filter(fun(D) -> re:run(D, "apps/.*/_build") =:= nomatch end,
lists:filter(fun(S) -> string:find(S, "/_build/") =:= nomatch end,
filelib:wildcard(Pattern)). filelib:wildcard(Pattern)).
bash(undefined) -> ok;
bash(Script) -> bash(Script) ->
bash(Script, []). bash(Script, []).
bash(Script, Env) -> bash(Script, Env) ->
log("+ ~s~n+ Env: ~p~n", [Script, Env]), log("+ ~s~n+ Env: ~p~n", [Script, Env]),
case cmd("bash", #{args => ["-c", Script], env => Env}) of case cmd("bash", #{args => ["-c", Script], env => Env}) of
0 -> true; 0 -> ok;
_ -> fail("Failed to run command: ~s", [Script]) _ -> fail("Failed to run command: ~s", [Script])
end. end.

View File

@ -1,31 +1,32 @@
%% -*- mode: erlang -*- %% -*- mode: erlang -*-
%% Unless you know what you are doing, DO NOT edit manually!!
{VSN, {VSN,
[{"4.3.13", [{"4.3.13",
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, [{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,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,[]}]},
{"4.3.12", {"4.3.12",
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, [{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,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,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
{load_module,emqx_alarm,brutal_purge,soft_purge,[]}, {load_module,emqx_alarm,brutal_purge,soft_purge,[]},
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
@ -35,9 +36,10 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.11", {"4.3.11",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
@ -45,7 +47,6 @@
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]}, {load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -59,16 +60,16 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.10", {"4.3.10",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -83,9 +84,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.9", {"4.3.9",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
@ -111,9 +112,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.8", {"4.3.8",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
@ -139,9 +140,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.7", {"4.3.7",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
@ -170,8 +171,8 @@
{"4.3.6", {"4.3.6",
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, [{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -199,9 +200,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.5", {"4.3.5",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -230,9 +231,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.4", {"4.3.4",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -262,9 +263,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.3", {"4.3.3",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -295,9 +296,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.2", {"4.3.2",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -327,9 +328,9 @@
{load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]},
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.1", {"4.3.1",
[{load_module,emqx_banned,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,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -363,9 +364,9 @@
{load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]},
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.0", {"4.3.0",
[{load_module,emqx_banned,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,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}}, {apply,{emqx_metrics,assign_acl_stats_from_ets_to_counter,[]}},
@ -404,27 +405,27 @@
{<<".*">>,[]}], {<<".*">>,[]}],
[{"4.3.13", [{"4.3.13",
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, [{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
{load_module,emqx_app,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_app,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}]},
{"4.3.12", {"4.3.12",
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, [{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,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,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
@ -436,14 +437,14 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.11", {"4.3.11",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_connection,brutal_purge,soft_purge,[]}, {load_module,emqx_connection,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
@ -459,13 +460,13 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.10", {"4.3.10",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]},
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
{load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]},
{load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]},
{load_module,emqx_session,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]},
@ -482,9 +483,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.9", {"4.3.9",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
@ -509,9 +510,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.8", {"4.3.8",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
@ -536,9 +537,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.7", {"4.3.7",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_ctl,brutal_purge,soft_purge,[]}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
@ -565,9 +566,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.6", {"4.3.6",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -594,9 +595,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.5", {"4.3.5",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -624,9 +625,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.4", {"4.3.4",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -655,9 +656,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.3", {"4.3.3",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -687,9 +688,9 @@
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.2", {"4.3.2",
[{load_module,emqx_plugins,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,[]}, {load_module,emqx_banned,brutal_purge,soft_purge,[]},
{load_module,emqx_sys,brutal_purge,soft_purge,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -718,9 +719,9 @@
{load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]},
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.1", {"4.3.1",
[{load_module,emqx_banned,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,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
@ -753,9 +754,9 @@
{load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]},
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
{"4.3.0", {"4.3.0",
[{load_module,emqx_banned,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,[]}, {load_module,emqx_sys,brutal_purge,soft_purge,[]},
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_vm_mon,brutal_purge,soft_purge,[]},
{load_module,emqx_vm,brutal_purge,soft_purge,[]}, {load_module,emqx_vm,brutal_purge,soft_purge,[]},
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]}, {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},