From 04c6b9a40f782099ece28dbde39c35f25dd2e37b Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 17 Sep 2012 12:27:05 +0200 Subject: [reltool] Keep order from rel spec when sorting used and included applications The rel specification now dictates the order in which included and used applications are loaded/started by the boot file. If the applications are not specified in the rel spec, then the order from the .app file is used. This was a bug earlier reported on systools, and is now also implemented in reltool. Example: If a .app file specified {applications,[x,y]} {included_applications,[b,c]} And the reltool.config has {rel, "myrel", "1.0", [a,y,x,c,b]} Then the boot file will load/start y before x and c before b. Earlier x would always be started before y and b always before c due to the order in the .app file. --- lib/reltool/src/reltool_target.erl | 54 ++++++++++++++++++++++++++++++- lib/reltool/test/reltool_server_SUITE.erl | 21 +++++------- 2 files changed, 61 insertions(+), 14 deletions(-) (limited to 'lib/reltool') diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index a47da75c63..6cb7ba0163 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -333,7 +333,9 @@ merge_apps(#rel{name = RelName, A#app.name =/= ?MISSING_APP_NAME, not lists:keymember(A#app.name, #app.name, MergedApps2)], MergedApps3 = do_merge_apps(RelName, Embedded, Apps, EmbAppType, MergedApps2), - sort_apps(lists:reverse(MergedApps3)). + RevMerged = lists:reverse(MergedApps3), + MergedSortedUsedAndIncs = sort_used_and_incl_apps(RevMerged,RevMerged), + sort_apps(MergedSortedUsedAndIncs). do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -508,6 +510,56 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> [], SplitMods). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% sort_used_and_incl_apps(Apps, OrderedApps) -> Apps +%% Apps = [#app{}] +%% OrderedApps = [#app{}] +%% +%% OTP-4121, OTP-9984 +%% (Tickets are written for systools, but needs to be implemented here +%% as well.) +%% Make sure that used and included applications are given in the same +%% order as in the release resource file (.rel). Otherwise load and +%% start instructions in the boot script, and consequently release +%% upgrade instructions in relup, may end up in the wrong order. + +sort_used_and_incl_apps([#app{info=Info} = App|Apps], OrderedApps) -> + Incls2 = + case Info#app_info.incl_apps of + Incls when length(Incls)>1 -> + sort_appl_list(Incls, OrderedApps); + Incls -> + Incls + end, + Uses2 = + case Info#app_info.applications of + Uses when length(Uses)>1 -> + sort_appl_list(Uses, OrderedApps); + Uses -> + Uses + end, + App2 = App#app{info=Info#app_info{incl_apps=Incls2, applications=Uses2}}, + [App2|sort_used_and_incl_apps(Apps, OrderedApps)]; +sort_used_and_incl_apps([], _OrderedApps) -> + []. + +sort_appl_list(List, Order) -> + IndexedList = find_pos(List, Order), + SortedIndexedList = lists:keysort(1, IndexedList), + lists:map(fun({_Index,Name}) -> Name end, SortedIndexedList). + +find_pos([Name|Incs], OrderedApps) -> + [find_pos(1, Name, OrderedApps)|find_pos(Incs, OrderedApps)]; +find_pos([], _OrderedApps) -> + []. + +find_pos(N, Name, [#app{name=Name}|_OrderedApps]) -> + {N, Name}; +find_pos(N, Name, [_OtherAppl|OrderedApps]) -> + find_pos(N+1, Name, OrderedApps). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function: sort_apps(Apps) -> {ok, Apps'} | throw({error, Error}) %% Types: Apps = {{Name, Vsn}, #application}] diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index 2cf4e5b916..8cff86d2a0 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -299,7 +299,6 @@ create_release(_Config) -> %% started before the including application. %% Circular dependencies shall also be detected and cause error. -create_release_sort(_Config) -> {skip, "Two bugs related to sorting"}; create_release_sort(Config) -> DataDir = ?config(data_dir,Config), %% Configure the server @@ -375,7 +374,6 @@ create_release_sort(Config) -> {mnesia, _}]}}, reltool:get_rel([{config, Sys}], RelName3)), - %%! BUG: same as OTP-4121, but for reltool???? Or revert tools and mnesia ?msym({ok, {release, {RelName4, RelVsn}, {erts, _}, [{kernel, _}, @@ -426,7 +424,6 @@ create_release_sort(Config) -> {z,_,[]}]}}, reltool:get_rel([{config, Sys}], RelName9)), - %%! BUG: same as OTP-9984, but for reltool???? Or revert inets and sasl? ?msym({ok,{release,{RelName10,RelVsn}, {erts,_}, [{kernel,_}, @@ -665,11 +662,10 @@ create_script_sort(Config) -> {ok, Script3} = ?msym({ok, _}, reltool:get_script(Pid, RelName3)), ?m(equal, diff_script(SystoolsScript3, Script3)), - %% BUG, same as OTP-4121, but for reltool - %% ?msym({ok,_,_}, systools_make_script(FullName4,ZPath)), - %% {ok, [SystoolsScript4]} = ?msym({ok,[_]}, file:consult(FullName4++".script")), - %% {ok, Script4} = ?msym({ok, _}, reltool:get_script(Pid, RelName4)), - %% ?m(equal, diff_script(SystoolsScript4, Script4)), + ?msym({ok,_,_}, systools_make_script(FullName4,ZPath)), + {ok, [SystoolsScript4]} = ?msym({ok,[_]}, file:consult(FullName4++".script")), + {ok, Script4} = ?msym({ok, _}, reltool:get_script(Pid, RelName4)), + ?m(equal, diff_script(SystoolsScript4, Script4)), ?msym({error,_,[{error_reading,{sasl,{override_include,_}}}]}, systools_make_script(FullName5,ZPath)), @@ -698,11 +694,10 @@ create_script_sort(Config) -> {ok, Script9} = ?msym({ok, _}, reltool:get_script(Pid, RelName9)), ?m(equal, diff_script(SystoolsScript9, Script9)), - %% BUG, same as OTP-9984, but for reltool - %% ?msym({ok,_,_}, systools_make_script(FullName10,ZPath)), - %% {ok, [SystoolsScript10]} = ?msym({ok,[_]}, file:consult(FullName10++".script")), - %% {ok, Script10} = ?msym({ok, _}, reltool:get_script(Pid, RelName10)), - %% ?m(equal, diff_script(SystoolsScript10, Script10)), + ?msym({ok,_,_}, systools_make_script(FullName10,ZPath)), + {ok, [SystoolsScript10]} = ?msym({ok,[_]}, file:consult(FullName10++".script")), + {ok, Script10} = ?msym({ok, _}, reltool:get_script(Pid, RelName10)), + ?m(equal, diff_script(SystoolsScript10, Script10)), %% Stop server ?m(ok, reltool:stop(Pid)), -- cgit v1.2.3