aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reltool/src/reltool_server.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reltool/src/reltool_server.erl')
-rw-r--r--lib/reltool/src/reltool_server.erl304
1 files changed, 180 insertions, 124 deletions
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 6a3122f879..a1e9c0193b 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -442,12 +442,13 @@ analyse(#state{common = C,
MissingApp = default_app(?MISSING_APP, "missing"),
ets:insert(C#common.app_tab, MissingApp),
- RelApps = apps_in_rels(Rels),
- {Apps2, Status2} =
+ {RevRelApps, Status2} = apps_in_rels(Rels, Apps, Status),
+ RelApps2 = lists:reverse(RevRelApps),
+ {Apps2, Status3} =
lists:mapfoldl(fun(App, Acc) ->
- app_init_is_included(C, Sys, App, RelApps, Acc)
+ app_init_is_included(C, Sys, App, RelApps2, Acc)
end,
- Status,
+ Status2,
Apps),
Apps3 =
case app_propagate_is_included(C, Sys, Apps2, []) of
@@ -467,17 +468,51 @@ analyse(#state{common = C,
%% io:format("Missing app: ~p\n",
%% [lists:keysearch(?MISSING_APP, #app.name, Apps4)]),
Sys2 = Sys#sys{apps = Apps4},
- case verify_config(Sys2, Status2) of
- {ok, _Warnings} = Status3 ->
- {S#state{sys = Sys2}, Status3};
- {error, _} = Status3 ->
- {S, Status3}
+
+ case verify_config(RelApps2, Sys2, Status3) of
+ {ok, _Warnings} = Status4 ->
+ {S#state{sys = Sys2}, Status4};
+ {error, _} = Status4 ->
+ {S, Status4}
end.
-apps_in_rels(Rels) ->
- [{RelName, AppName} || #rel{name = RelName, rel_apps = RelApps} <- Rels,
- RA <- RelApps,
- AppName <- [RA#rel_app.name | RA#rel_app.incl_apps]].
+apps_in_rels(Rels, Apps, Status) ->
+ lists:foldl(fun(Rel, {RelApps, S}) ->
+ {MoreRelApps, S2} = apps_in_rel(Rel, Apps, S),
+ {MoreRelApps ++ RelApps, S2}
+ end,
+ {[], Status},
+ Rels).
+
+apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps, Status) ->
+ Mandatory = [{RelName, kernel}, {RelName, stdlib}],
+ Other = [{RelName, AppName} ||
+ RA <- RelApps,
+ AppName <- [RA#rel_app.name | RA#rel_app.incl_apps],
+ not lists:keymember(AppName, 2, Mandatory)],
+ more_apps_in_rels(Mandatory ++ Other, Apps, [], Status).
+
+more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc, Status) ->
+ case lists:member(RA, Acc) of
+ true ->
+ more_apps_in_rels(RelApps, Apps, Acc, Status);
+ false ->
+ case lists:keysearch(AppName, #app.name, Apps) of
+ {value, #app{info = #app_info{applications = InfoApps}}} ->
+ Extra = [{RelName, N} || N <- InfoApps],
+ {Acc2, Status2} =
+ more_apps_in_rels(Extra, Apps, [RA | Acc], Status),
+ more_apps_in_rels(RelApps, Apps, Acc2, Status2);
+ false ->
+ Text = lists:concat(["Release ", RelName,
+ " uses non existing application ",
+ AppName]),
+ Status2 = reltool_utils:return_first_error(Status, Text),
+ more_apps_in_rels(RelApps, Apps, Acc, Status2)
+ end
+ end;
+more_apps_in_rels([], _Apps, Acc, Status) ->
+ {Acc, Status}.
app_init_is_included(C,
Sys,
@@ -706,8 +741,6 @@ mod_propagate_is_used_by(_C, []) ->
read_apps(C, Sys, [#app{mods = Mods, is_included = IsIncl} = A | Apps], Acc) ->
{Mods2, IsIncl2} = read_apps(C, Sys, A, Mods, [], IsIncl),
- %% reltool_utils:print(A#app.name, stdlib, "Mods2: ~p\n",
- %% [[M#mod.status || M <- Mods2]]),
Status =
case lists:keysearch(missing, #mod.status, Mods2) of
{value, _} -> missing;
@@ -770,9 +803,7 @@ filter_app(A) ->
Mods = [M#mod{is_app_mod = undefined,
is_ebin_mod = undefined,
uses_mods = undefined,
- exists = false,
- is_pre_included = undefined,
- is_included = undefined} ||
+ exists = false} ||
M <- A#app.mods,
M#mod.incl_cond =/= undefined],
if
@@ -781,8 +812,7 @@ filter_app(A) ->
label = undefined,
info = undefined,
mods = [],
- uses_mods = undefined,
- is_included = undefined}};
+ uses_mods = undefined}};
Mods =:= [],
A#app.mod_cond =:= undefined,
A#app.incl_cond =:= undefined,
@@ -812,8 +842,7 @@ filter_app(A) ->
label = undefined,
info = undefined,
mods = Mods,
- uses_mods = undefined,
- is_included = undefined}}
+ uses_mods = undefined}}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -850,16 +879,16 @@ refresh_app(#app{name = AppName,
end,
%% Add non-existing modules
+ AppInfoMods = AppInfo#app_info.modules,
AppModNames =
case AppInfo#app_info.mod of
{StartModName, _} ->
- case lists:member(StartModName,
- AppInfo#app_info.modules) of
- true -> AppInfo#app_info.modules;
- false -> [StartModName | AppInfo#app_info.modules]
+ case lists:member(StartModName, AppInfoMods) of
+ true -> AppInfoMods;
+ false -> [StartModName | AppInfoMods]
end;
undefined ->
- AppInfo#app_info.modules
+ AppInfoMods
end,
MissingMods = add_missing_mods(AppName, EbinMods, AppModNames),
@@ -1206,11 +1235,14 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
{Sys#sys{root_dir = Val}, Status};
lib_dirs when is_list(Val) ->
{Sys#sys{lib_dirs = Val}, Status};
- mod_cond when Val =:= all; Val =:= app;
- Val =:= ebin; Val =:= derived;
+ mod_cond when Val =:= all;
+ Val =:= app;
+ Val =:= ebin;
+ Val =:= derived;
Val =:= none ->
{Sys#sys{mod_cond = Val}, Status};
- incl_cond when Val =:= include; Val =:= exclude;
+ incl_cond when Val =:= include;
+ Val =:= exclude;
Val =:= derived ->
{Sys#sys{incl_cond = Val}, Status};
boot_rel when is_list(Val) ->
@@ -1220,78 +1252,96 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
profile when Val =:= development ->
Val = ?DEFAULT_PROFILE, % assert,
{Sys#sys{profile = Val,
- incl_sys_filters = dec_re(incl_sys_filters,
- ?DEFAULT_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = dec_re(excl_sys_filters,
- ?DEFAULT_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = dec_re(incl_app_filters,
- ?DEFAULT_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = dec_re(excl_app_filters,
- ?DEFAULT_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ dec_re(incl_sys_filters,
+ ?DEFAULT_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ dec_re(excl_sys_filters,
+ ?DEFAULT_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ dec_re(incl_app_filters,
+ ?DEFAULT_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ dec_re(excl_app_filters,
+ ?DEFAULT_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= embedded ->
{Sys#sys{profile = Val,
- incl_sys_filters = dec_re(incl_sys_filters,
- ?EMBEDDED_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = dec_re(excl_sys_filters,
- ?EMBEDDED_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = dec_re(incl_app_filters,
- ?EMBEDDED_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = dec_re(excl_app_filters,
- ?EMBEDDED_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ dec_re(incl_sys_filters,
+ ?EMBEDDED_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ dec_re(excl_sys_filters,
+ ?EMBEDDED_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ dec_re(incl_app_filters,
+ ?EMBEDDED_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ dec_re(excl_app_filters,
+ ?EMBEDDED_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= standalone ->
{Sys#sys{profile = Val,
- incl_sys_filters = dec_re(incl_sys_filters,
- ?STANDALONE_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = dec_re(excl_sys_filters,
- ?STANDALONE_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = dec_re(incl_app_filters,
- ?STANDALONE_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = dec_re(excl_app_filters,
- ?STANDALONE_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ dec_re(incl_sys_filters,
+ ?STANDALONE_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ dec_re(excl_sys_filters,
+ ?STANDALONE_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ dec_re(incl_app_filters,
+ ?STANDALONE_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ dec_re(excl_app_filters,
+ ?STANDALONE_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
incl_sys_filters ->
- {Sys#sys{incl_sys_filters = dec_re(Key,
- Val,
- Sys#sys.incl_sys_filters)},
+ {Sys#sys{incl_sys_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.incl_sys_filters)},
Status};
excl_sys_filters ->
- {Sys#sys{excl_sys_filters = dec_re(Key,
- Val,
- Sys#sys.excl_sys_filters)},
+ {Sys#sys{excl_sys_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.excl_sys_filters)},
Status};
incl_app_filters ->
- {Sys#sys{incl_app_filters = dec_re(Key,
- Val,
- Sys#sys.incl_app_filters)},
+ {Sys#sys{incl_app_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.incl_app_filters)},
Status};
excl_app_filters ->
- {Sys#sys{excl_app_filters = dec_re(Key,
- Val,
- Sys#sys.excl_app_filters)},
+ {Sys#sys{excl_app_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.excl_app_filters)},
Status};
incl_archive_filters ->
- {Sys#sys{incl_archive_filters = dec_re(Key,
- Val,
- Sys#sys.incl_archive_filters)},
+ {Sys#sys{incl_archive_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.incl_archive_filters)},
Status};
excl_archive_filters ->
- {Sys#sys{excl_archive_filters = dec_re(Key,
- Val,
- Sys#sys.excl_archive_filters)},
+ {Sys#sys{excl_archive_filters =
+ dec_re(Key,
+ Val,
+ Sys#sys.excl_archive_filters)},
Status};
archive_opts when is_list(Val) ->
{Sys#sys{archive_opts = Val}, Status};
@@ -1300,7 +1350,8 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
app_type when Val =:= permanent;
Val =:= transient;
Val =:= temporary;
- Val =:= load; Val =:= none ->
+ Val =:= load;
+ Val =:= none ->
{Sys#sys{app_type = Val}, Status};
app_file when Val =:= keep; Val =:= strip, Val =:= all ->
{Sys#sys{app_file = Val}, Status};
@@ -1341,24 +1392,28 @@ decode(#app{} = App, [{Key, Val} | KeyVals], Status) ->
Val =:= none ->
{App#app{app_type = Val}, Status};
incl_app_filters ->
- {App#app{incl_app_filters = dec_re(Key,
- Val,
- App#app.incl_app_filters)},
+ {App#app{incl_app_filters =
+ dec_re(Key,
+ Val,
+ App#app.incl_app_filters)},
Status};
excl_app_filters ->
- {App#app{excl_app_filters = dec_re(Key,
- Val,
- App#app.excl_app_filters)},
+ {App#app{excl_app_filters =
+ dec_re(Key,
+ Val,
+ App#app.excl_app_filters)},
Status};
incl_archive_filters ->
- {App#app{incl_archive_filters = dec_re(Key,
- Val,
- App#app.incl_archive_filters)},
+ {App#app{incl_archive_filters =
+ dec_re(Key,
+ Val,
+ App#app.incl_archive_filters)},
Status};
excl_archive_filters ->
- {App#app{excl_archive_filters = dec_re(Key,
- Val,
- App#app.excl_archive_filters)},
+ {App#app{excl_archive_filters =
+ dec_re(Key,
+ Val,
+ App#app.excl_archive_filters)},
Status};
archive_opts when is_list(Val) ->
{App#app{archive_opts = Val}, Status};
@@ -1463,24 +1518,41 @@ merge_config(OldSys, NewSys, Force, Status) ->
apps = PatchedApps},
{NewSys2, Status5}.
-verify_config(Sys, Status) ->
- case lists:keymember(Sys#sys.boot_rel, #rel.name, Sys#sys.rels) of
+verify_config(RelApps, #sys{boot_rel = BootRel, rels = Rels, apps = Apps}, Status) ->
+ case lists:keymember(BootRel, #rel.name, Rels) of
true ->
- lists:foldl(fun(Rel, Acc)-> check_rel(Rel, Sys, Acc) end,
- Status,
- Sys#sys.rels);
+ Status2 = lists:foldl(fun(RA, Acc) ->
+ check_app(RA, Apps, Acc) end,
+ Status,
+ RelApps),
+ lists:foldl(fun(#rel{name = RelName}, Acc)->
+ check_rel(RelName, RelApps, Acc)
+ end,
+ Status2,
+ Rels);
false ->
- Text = lists:concat(["Release ", Sys#sys.boot_rel,
+ Text = lists:concat(["Release ", BootRel,
" is mandatory (used as boot_rel)"]),
reltool_utils:return_first_error(Status, Text)
end.
-check_rel(#rel{name = RelName, rel_apps = RelApps},
- #sys{apps = Apps},
- Status) ->
+check_app({RelName, AppName}, Apps, Status) ->
+ case lists:keysearch(AppName, #app.name, Apps) of
+ {value, App} when App#app.is_pre_included ->
+ Status;
+ {value, App} when App#app.is_included ->
+ Status;
+ _ ->
+ Text = lists:concat(["Release ", RelName,
+ " uses non included application ",
+ AppName]),
+ reltool_utils:return_first_error(Status, Text)
+ end.
+
+check_rel(RelName, RelApps, Status) ->
EnsureApp =
fun(AppName, Acc) ->
- case lists:keymember(AppName, #rel_app.name, RelApps) of
+ case lists:member({RelName, AppName}, RelApps) of
true ->
Acc;
false ->
@@ -1492,23 +1564,7 @@ check_rel(#rel{name = RelName, rel_apps = RelApps},
end
end,
Mandatory = [kernel, stdlib],
- Status2 = lists:foldl(EnsureApp, Status, Mandatory),
- CheckRelApp =
- fun(#rel_app{name = AppName}, Acc) ->
- case lists:keysearch(AppName, #app.name, Apps) of
- {value, App} when App#app.is_pre_included ->
- Acc;
- {value, App} when App#app.is_included ->
- Acc;
- _ ->
- Text = lists:concat(["Release ", RelName,
- " uses non included application ",
- AppName]),
-
- reltool_utils:return_first_error(Acc, Text)
- end
- end,
- lists:foldl(CheckRelApp, Status2, RelApps).
+ lists:foldl(EnsureApp, Status, Mandatory).
patch_erts_version(RootDir, Apps, Status) ->
AppName = erts,