diff --git a/scripts/inject-relup.escript b/scripts/inject-relup.escript index 93fe34a90..32c944246 100755 --- a/scripts/inject-relup.escript +++ b/scripts/inject-relup.escript @@ -49,20 +49,20 @@ inject_relup_instrs(Type, RUs) -> %% The `{apply, emqx_relup, post_release_upgrade, []}` will be appended to the end of %% the instruction lists. append_emqx_relup_instrs(up, FromRelVsn, Instrs0) -> - Extra = #{}, %% we may need some extended args - filter_and_check_instrs(up, Instrs0) ++ + {{UpExtra, _}, Instrs1} = filter_and_check_instrs(up, Instrs0), + Instrs1 ++ [ {load, {emqx_app, brutal_purge, soft_purge}} , {load, {emqx_relup, brutal_purge, soft_purge}} - , {apply, {emqx_relup, post_release_upgrade, [FromRelVsn, Extra]}} + , {apply, {emqx_relup, post_release_upgrade, [FromRelVsn, UpExtra]}} ]; append_emqx_relup_instrs(down, ToRelVsn, Instrs0) -> - Extra = #{}, %% we may need some extended args + {{_, DnExtra}, Instrs1} = filter_and_check_instrs(down, Instrs0) %% NOTE: When downgrading, we apply emqx_relup:post_release_downgrade/2 before reloading %% or removing the emqx_relup module. - Instrs1 = filter_and_check_instrs(down, Instrs0) ++ + Instrs1 ++ [ {load, {emqx_app, brutal_purge, soft_purge}} - , {apply, {emqx_relup, post_release_downgrade, [ToRelVsn, Extra]}} + , {apply, {emqx_relup, post_release_downgrade, [ToRelVsn, DnExtra]}} ], %% emqx_relup does not exist before release "4.4.2" LoadInsts = @@ -75,37 +75,49 @@ append_emqx_relup_instrs(down, ToRelVsn, Instrs0) -> Instrs1 ++ LoadInsts. filter_and_check_instrs(Type, Instrs) -> - case take_emqx_vsn_and_modules(Instrs) of - {EmqxAppVsn, EmqxMods, RemainInstrs} when EmqxAppVsn =/= not_found, EmqxMods =/= [] -> + case filter_fetch_emqx_mods_and_extra(Instrs) of + {_, _, [], _} -> + ?ERROR("cannot find any 'load_object_code' instructions for app emqx", []), + error({instruction_not_found, load_object_code}); + {UpExtra, DnExtra, EmqxMods, RemainInstrs} -> assert_mandatory_modules(Type, EmqxMods), - [{load_object_code, {emqx, EmqxAppVsn, EmqxMods}} | RemainInstrs]; - {_, _, _} -> - ?ERROR("cannot found 'load_module' instructions for app emqx", []), - error({instruction_not_found, load_object_code}) + {{UpExtra, DnExtra}, RemainInstrs} end. -take_emqx_vsn_and_modules(Instrs) -> - lists:foldl(fun - ({load_object_code, {emqx, AppVsn, Mods}}, {_EmqxAppVsn, EmqxMods, RemainInstrs}) -> - {AppVsn, EmqxMods ++ Mods, RemainInstrs}; - ({load, {Mod, _, _}}, {EmqxAppVsn, EmqxMods, RemainInstrs}) - when Mod =:= emqx_relup; Mod =:= emqx_app -> - {EmqxAppVsn, EmqxMods, RemainInstrs}; - ({remove, {emqx_relup, _, _}}, {EmqxAppVsn, EmqxMods, RemainInstrs}) -> - {EmqxAppVsn, EmqxMods, RemainInstrs}; - ({apply, {emqx_relup, _, _}}, {EmqxAppVsn, EmqxMods, RemainInstrs}) -> - {EmqxAppVsn, EmqxMods, RemainInstrs}; - (Instr, {EmqxAppVsn, EmqxMods, RemainInstrs}) -> - {EmqxAppVsn, EmqxMods, RemainInstrs ++ [Instr]} - end, {not_found, [], []}, Instrs). +filter_fetch_emqx_mods_and_extra(Instrs) -> + lists:foldl(fun do_filter_and_get/2, {UpExtra, DnExtra, [], []}, Instrs). + +%% collect modules for emqx app +do_filter_and_get({load_object_code, {emqx, _AppVsn, Mods}} = Instr, + {UpExtra, DnExtra, EmqxMods, RemainInstrs}) -> + {UpExtra, DnExtra, EmqxMods ++ Mods, RemainInstrs ++ [Instr]}; +%% remove 'load' instrs +do_filter_and_get({load, {Mod, _, _}}, {UpExtra, DnExtra, EmqxMods, RemainInstrs}) + when Mod =:= emqx_relup; Mod =:= emqx_app -> + {UpExtra, DnExtra, EmqxMods, RemainInstrs}; +%% remove 'remove' instrs +do_filter_and_get({remove, {emqx_relup, _, _}}, {UpExtra, DnExtra, EmqxMods, RemainInstrs}) -> + {UpExtra, DnExtra, EmqxMods, RemainInstrs}; +%% remove 'apply' instrs for upgrade, and collect the 'Extra' parameter +do_filter_and_get({apply, {emqx_relup, post_release_upgrade, [_, UpExtra0]}}, + {_, DnExtra, EmqxMods, RemainInstrs}) -> + {UpExtra0, DnExtra, EmqxMods, RemainInstrs}; +%% remove 'apply' instrs for downgrade, and collect the 'Extra' parameter +do_filter_and_get({apply, {emqx_relup, post_release_downgrade, [_, DnExtra0]}}, + {UpExtra, _, EmqxMods, RemainInstrs}) -> + {UpExtra, DnExtra0, EmqxMods, RemainInstrs}; +%% keep all other instrs unchanged +do_filter_and_get(Instr, {UpExtra, DnExtra, EmqxMods, RemainInstrs}) -> + {UpExtra, DnExtra, EmqxMods, RemainInstrs ++ [Instr]}. + assert_mandatory_modules(up, Mods) -> assert(lists:member(emqx_relup, Mods) andalso lists:member(emqx_app, Mods), - "cannot found 'load_module' instructions for emqx_app and emqx_rel: ~p", [Mods]); + "cannot find any 'load_object_code' instructions for emqx_app and emqx_rel: ~p", [Mods]); assert_mandatory_modules(down, Mods) -> assert(lists:member(emqx_app, Mods), - "cannot found 'load_module' instructions for emqx_app", []). + "cannot find any 'load_object_code' instructions for emqx_app", []). assert(true, _, _) -> ok; diff --git a/src/emqx_relup.erl b/src/emqx_relup.erl index dc443947a..fcc90d088 100644 --- a/src/emqx_relup.erl +++ b/src/emqx_relup.erl @@ -17,7 +17,7 @@ -module(emqx_relup). %% NOTE: DO NOT remove this `-include`. -%% We use this to forece this module to upgraded every release. +%% We use this to force this module to be upgraded every release. -include("emqx_release.hrl"). -export([ post_release_upgrade/2 @@ -27,13 +27,13 @@ -define(INFO(FORMAT), io:format("[emqx_relup] " ++ FORMAT ++ "~n")). -define(INFO(FORMAT, ARGS), io:format("[emqx_relup] " ++ FORMAT ++ "~n", ARGS)). -%% what to do after upgraded from a old release vsn. +%% What to do after upgraded from an old release vsn. post_release_upgrade(FromRelVsn, _) -> {_, CurrRelVsn} = ?EMQX_RELEASE, ?INFO("emqx has been upgraded to from ~s to ~s!", [FromRelVsn, CurrRelVsn]), reload_components(). -%% what to do after downgraded to a old release vsn. +%% What to do after downgraded to an old release vsn. post_release_downgrade(ToRelVsn, _) -> {_, CurrRelVsn} = ?EMQX_RELEASE, ?INFO("emqx has been downgraded to from ~s to ~s!", [CurrRelVsn, ToRelVsn]),