diff options
author | Siri Hansen <[email protected]> | 2012-09-17 12:27:05 +0200 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2012-09-17 12:27:05 +0200 |
commit | 04c6b9a40f782099ece28dbde39c35f25dd2e37b (patch) | |
tree | f580dc9c18dbb948d771cbda65c1da57a9170a52 | |
parent | 6a40b71e364fd0ac7f68bebfdd51c80f9f66730a (diff) | |
download | otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.tar.gz otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.tar.bz2 otp-04c6b9a40f782099ece28dbde39c35f25dd2e37b.zip |
[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.
-rw-r--r-- | lib/reltool/src/reltool_target.erl | 54 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE.erl | 21 |
2 files changed, 61 insertions, 14 deletions
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 @@ -509,6 +511,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}] %% Purpose: Sort applications according to dependencies among 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)), |