fix(relup): inject relup only for the current rel vsn

This commit is contained in:
Shawn 2022-02-27 09:28:35 +08:00
parent 692d1e2a33
commit 2365d1e983
2 changed files with 48 additions and 37 deletions

View File

@ -128,31 +128,34 @@ prod_compile_opts() ->
prod_overrides() ->
[{add, [ {erl_opts, [deterministic]}]}].
relup_deps(Profile) ->
{post_hooks, [{"(linux|darwin|solaris|freebsd|netbsd|openbsd)", release,
"scripts/inject-relup.escript " ++ filename:join(["_build", Profile, "rel", "emqx"])}]}.
relup_deps(Profile, Vsn) ->
InjectCmd = "scripts/inject-relup.escript " ++ filename:join(["_build", Profile, "rel", "emqx", "releases", Vsn]),
{post_hooks,
[ {"(linux|darwin|solaris|freebsd|netbsd|openbsd)", relup, InjectCmd}
]
}.
profiles() ->
Vsn = get_vsn(),
[ {'emqx', [ {erl_opts, prod_compile_opts()}
, {relx, relx(Vsn, cloud, bin)}
, {overrides, prod_overrides()}
, relup_deps('emqx')
, relup_deps('emqx', Vsn)
]}
, {'emqx-pkg', [ {erl_opts, prod_compile_opts()}
, {relx, relx(Vsn, cloud, pkg)}
, {overrides, prod_overrides()}
, relup_deps('emqx-pkg')
, relup_deps('emqx-pkg', Vsn)
]}
, {'emqx-edge', [ {erl_opts, prod_compile_opts()}
, {relx, relx(Vsn, edge, bin)}
, {overrides, prod_overrides()}
, relup_deps('emqx-edge')
, relup_deps('emqx-edge', Vsn)
]}
, {'emqx-edge-pkg', [ {erl_opts, prod_compile_opts()}
, {relx, relx(Vsn, edge, pkg)}
, {overrides, prod_overrides()}
, relup_deps('emqx-edge-pkg')
, relup_deps('emqx-edge-pkg', Vsn)
]}
, {check, [ {erl_opts, common_compile_opts()}
]}

View File

@ -8,51 +8,59 @@
-define(INFO(FORMAT, ARGS), io:format(user, "[inject-relup] " ++ FORMAT ++"~n", ARGS)).
usage() ->
"Usage: " ++ escript:script_name() ++ " <path-to-release-dir>".
"Usage: " ++ escript:script_name() ++ " <path-to-relup-file-or-dir>".
main([Dir]) ->
case filelib:is_dir(Dir) of
true ->
ok = inject(Dir);
main([DirOrFile]) ->
case filelib:is_dir(DirOrFile) of
true -> ok = inject_dir(DirOrFile);
false ->
?ERROR("not a valid dir: ~p", [Dir]),
erlang:halt(1)
case filelib:is_regular(DirOrFile) of
true -> inject_file(DirOrFile);
false ->
?ERROR("not a valid file: ~p", [DirOrFile]),
erlang:halt(1)
end
end;
main(_Args) ->
?ERROR("~s", [usage()]),
erlang:halt(1).
inject(Dir) ->
RelupFiles = filelib:wildcard(filename:join([Dir, "releases", "*", "relup"])),
lists:foreach(fun(File) ->
case file:consult(File) of
{ok, [{CurrRelVsn, UpVsnRUs, DnVsnRUs}]} ->
?INFO("injecting instructions to: ~p", [File]),
UpdatedContent = [{CurrRelVsn, inject_relup_instrs(CurrRelVsn, UpVsnRUs),
inject_relup_instrs(CurrRelVsn, DnVsnRUs)}],
file:write_file("/tmp/" ++ filename:basename(File), term_to_text(UpdatedContent));
{ok, _BadFormat} ->
?ERROR("bad formatted relup file: ~p", [File]);
{error, Reason} ->
?ERROR("read relup file ~p failed: ~p", [File, Reason])
end
end, RelupFiles).
inject_dir(Dir) ->
RelupFiles = filelib:wildcard(filename:join([Dir, "**", "relup"])),
lists:foreach(fun inject_file/1, RelupFiles).
inject_relup_instrs(CurrRelVsn, RUs) ->
[{Vsn, Desc, append_emqx_relup_instrs(CurrRelVsn, Vsn, Instrs)} || {Vsn, Desc, Instrs} <- RUs].
inject_file(File) ->
case file:script(File) of
{ok, {CurrRelVsn, UpVsnRUs, DnVsnRUs}} ->
?INFO("injecting instructions to: ~p", [File]),
UpdatedContent = {CurrRelVsn, inject_relup_instrs(up, CurrRelVsn, UpVsnRUs),
inject_relup_instrs(down, CurrRelVsn, DnVsnRUs)},
ok = file:write_file(File, term_to_text(UpdatedContent));
{ok, _BadFormat} ->
?ERROR("bad formatted relup file: ~p", [File]);
{error, Reason} ->
?ERROR("read relup file ~p failed: ~p", [File, Reason])
end.
inject_relup_instrs(Type, CurrRelVsn, RUs) ->
[{Vsn, Desc, append_emqx_relup_instrs(Type, CurrRelVsn, Vsn, Instrs)} || {Vsn, Desc, Instrs} <- RUs].
%% The `{apply, emqx_relup, post_release_upgrade, []}` will be appended to the end of
%% the instruction lists.
append_emqx_relup_instrs(CurrRelVsn, Vsn, Instrs) ->
append_emqx_relup_instrs(Type, CurrRelVsn, Vsn, Instrs) ->
CallbackFun = relup_callback_func(Type),
case lists:reverse(Instrs) of
[{apply, {emqx_relup, post_release_upgrade, _}} | _] ->
[{apply, {emqx_relup, CallbackFun, _}} | _] ->
Instrs;
RInstrs ->
lists:reverse([instr_post_release_upgrade(CurrRelVsn, Vsn) | RInstrs])
lists:reverse([ {load_object_code, {emqx, CurrRelVsn, [emqx_relup]}}
, {load, {emqx_relup, brutal_purge, soft_purge}}
, {apply, {emqx_relup, CallbackFun, [CurrRelVsn, Vsn]}}
| RInstrs])
end.
instr_post_release_upgrade(CurrRelVsn, Vsn) ->
{apply, {emqx_relup, post_release_upgrade, [CurrRelVsn, Vsn]}}.
relup_callback_func(up) -> post_release_upgrade;
relup_callback_func(down) -> post_release_downgrade.
term_to_text(Term) ->
io_lib:format("~p.", [Term]).
io_lib:format("~p.", [Term]).