diff options
author | Siri Hansen <[email protected]> | 2012-08-27 14:29:13 +0200 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2012-08-27 14:29:13 +0200 |
commit | 5d2e66f48c9be7e67e38977d8f88f737f60dfc54 (patch) | |
tree | 127ff6e1b6bc5649d75a1faef2f2c3083ee4a417 | |
parent | 46dea84b7af49d5a4d20fce06b5c10bdccbe19d5 (diff) | |
parent | eba1ece8d123cab16b357ea43a8dfc75a959ae0a (diff) | |
download | otp-5d2e66f48c9be7e67e38977d8f88f737f60dfc54.tar.gz otp-5d2e66f48c9be7e67e38977d8f88f737f60dfc54.tar.bz2 otp-5d2e66f48c9be7e67e38977d8f88f737f60dfc54.zip |
Merge branch 'siri/reltool/slim_release/OTP-9743' into maint
* siri/reltool/slim_release/OTP-9743:
[reltool] Add documentation for option 'excl_lib'
[reltool] Add option {excl_lib,otp_root}
-rw-r--r-- | lib/reltool/doc/src/reltool.xml | 48 | ||||
-rw-r--r-- | lib/reltool/src/reltool.hrl | 3 | ||||
-rw-r--r-- | lib/reltool/src/reltool_server.erl | 2 | ||||
-rw-r--r-- | lib/reltool/src/reltool_target.erl | 72 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE.erl | 67 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE_data/Makefile.src | 11 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app | 7 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl | 49 | ||||
-rw-r--r-- | lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl | 37 |
9 files changed, 265 insertions, 31 deletions
diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index 9a4e2d130e..9b43640d83 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -221,6 +221,52 @@ system.</p> </item> + <tag><c>excl_lib</c></tag> + <item> + <warning><p>This option is experimental.</p></warning> + <p>If the <c>excl_lib</c> option is set to <c>otp_root</c> + then reltool will not copy anything from the Erlang/OTP + installation ($OTP_ROOT) into the target structure. The goal + is to create a "slim" release which can be used together with + an existing Erlang/OTP installation. The target structure will + therefore only contain a <c>lib</c> directory with the + applications that were found outside of $OTP_ROOT (typically + your own applications), and a <c>releases</c> directory with + the generated <c>.rel,</c> <c>.script</c> and <c>.boot</c> + files.</p> + + <p>When starting this release, three things must be specified:</p> + <taglist> + <tag><b>Which <c>releases</c> directory to use</b></tag> + <item>Tell the release handler to use the <c>releases</c> + directory in our target structure instead of + <c>$OTP_ROOT/releases</c>. This is done by setting the SASL + environment variable <c>releases_dir</c>, either from the + command line (<c>-sasl releases_dir + <target-dir>/releases</c>) or in + <c>sys.config</c>.</item> + + <tag><b>Which boot file to use</b></tag> + <item>The default boot file is <c>$OTP_ROOT/bin/start</c>, + but in this case we need to specify a boot file from our + target structure, typically + <c><target-dir>/releases/<vsn>/<RelName></c>. This + is done with the <c>-boot</c> command line option to + <c>erl</c></item> + + <tag><b>The location of our applications</b></tag> + <item>The generated .script (and .boot) file uses the + environment variable <c>$RELTOOL_EXT_LIB</c> as prefix for + the paths to all applications. The <c>-boot_var</c> option + to <c>erl</c> can be used for specifying the value of this + variable, typically <c>-boot_var RELTOOL_EXT_LIB + <target-dir>/lib</c>.</item> + </taglist> + + <p>Example:</p> + <p><code>erl -sasl releases_dir \"mytarget/releases\" -boot mytarget/releases/1.0/myrel -boot_var RELTOOL_EXT_LIB mytarget/lib</code></p> + </item> + <tag><c>incl_sys_filters</c></tag> <item> <p>This parameter normally contains a list of regular @@ -452,6 +498,7 @@ app() = {vsn, app_vsn()} | {incl_cond, incl_cond()} | {debug_info, debug_info()} | {app_file, app_file()} + | {excl_lib, excl_lib()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} @@ -477,6 +524,7 @@ escript() = {incl_cond, incl_cond()} escript_file() = file() excl_app_filters() = regexps() excl_archive_filters() = regexps() +excl_lib() = otp_root excl_sys_filters() = regexps() file() = string() incl_app() = app_name() diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl index 26dcd82447..f0d8b38519 100644 --- a/lib/reltool/src/reltool.hrl +++ b/lib/reltool/src/reltool.hrl @@ -79,6 +79,7 @@ | {debug_info, debug_info()} | {app_file, app_file()} | {profile, profile()} + | {excl_lib, excl_lib()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} @@ -123,6 +124,7 @@ -type incl_defaults() :: boolean(). -type incl_derived() :: boolean(). -type status() :: missing | ok. +-type excl_lib() :: otp_root. -record(common, { @@ -233,6 +235,7 @@ rels :: [#rel{}], emu_name :: emu_name(), profile :: profile(), + excl_lib :: excl_lib(), incl_sys_filters :: [#regexp{}], excl_sys_filters :: [#regexp{}], incl_app_filters :: [#regexp{}], diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 034a42e1e2..3d1d7e54bf 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -1408,6 +1408,8 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals]) -> ExclApp, Sys#sys.excl_app_filters), embedded_app_type = AppType}; + excl_lib when Val =:= otp_root -> + Sys#sys{excl_lib=Val}; incl_sys_filters -> Sys#sys{incl_sys_filters = dec_re(Key, Val, Sys#sys.incl_sys_filters)}; diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index e3a7b02143..c39ed0ecd5 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -687,6 +687,8 @@ strip_name_ebin(Dir, Name, Vsn) -> case lists:reverse(Dir) of ["ebin", Name | D] -> {ok, lists:reverse(D)}; ["ebin", FullName | D] -> {ok, lists:reverse(D)}; + [Name | D] -> {ok, lists:reverse(D)}; + [FullName | D] -> {ok, lists:reverse(D)}; _ -> false end. @@ -733,8 +735,20 @@ do_spec_rel_files(#rel{name = RelName} = Rel, Sys) -> BootFile = RelName ++ ".boot", MergedApps = merge_apps(Rel, Sys), GenRel = do_gen_rel(Rel, Sys, MergedApps), + Variables = + case Sys#sys.excl_lib of + otp_root -> + %% All applications that are fetched from somewhere + %% other than $OTP_ROOT/lib will get $RELTOOL_EXT_LIB + %% as path prefix in the .script file. + [{"RELTOOL_EXT_LIB",LibDir} || LibDir <- Sys#sys.lib_dirs] ++ + [{"RELTOOL_EXT_LIB",filename:dirname(AppLibDir)} || + #app{active_dir=AppLibDir,use_selected_vsn=dir} + <- MergedApps]; + _ -> + [] + end, PathFlag = true, - Variables = [], {ok, Script} = do_gen_script(Rel, Sys, MergedApps, PathFlag, Variables), {ok, BootBin} = gen_boot(Script), Date = date(), @@ -771,29 +785,34 @@ gen_spec(Sys) -> end. do_gen_spec(#sys{root_dir = RootDir, + excl_lib = ExclLib, incl_sys_filters = InclRegexps, excl_sys_filters = ExclRegexps, relocatable = Relocatable, apps = Apps} = Sys) -> - {create_dir, _, SysFiles} = spec_dir(RootDir), - {ExclRegexps2, SysFiles2} = - strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps), RelFiles = spec_rel_files(Sys), - {InclRegexps2, BinFiles} = - spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps), + {SysFiles, InclRegexps2, ExclRegexps2, Mandatory} = + case ExclLib of + otp_root -> + {[],InclRegexps,ExclRegexps,["lib"]}; + _ -> + {create_dir, _, SF} = spec_dir(RootDir), + {ER2, SF2} = strip_sys_files(Relocatable, SF, Apps, ExclRegexps), + {IR2, BinFiles} = + spec_bin_files(Sys, SF, SF2, RelFiles, InclRegexps), + SF3 = [{create_dir, "bin", BinFiles}] ++ SF2, + {SF3,IR2,ER2,["bin","erts","lib"]} + end, LibFiles = spec_lib_files(Sys), {BootVsn, StartFile} = spec_start_file(Sys), - SysFiles3 = - [ - {create_dir, "releases", + SysFiles2 = + [{create_dir, "releases", [StartFile, - {create_dir,BootVsn, RelFiles}]}, - {create_dir, "bin", BinFiles} - ] ++ SysFiles2, - SysFiles4 = filter_spec(SysFiles3, InclRegexps2, ExclRegexps2), - SysFiles5 = SysFiles4 ++ [{create_dir, "lib", LibFiles}], - check_sys(["bin", "erts", "lib"], SysFiles5), - SysFiles5. + {create_dir,BootVsn, RelFiles}]}] ++ SysFiles, + SysFiles3 = filter_spec(SysFiles2, InclRegexps2, ExclRegexps2), + SysFiles4 = SysFiles3 ++ [{create_dir, "lib", LibFiles}], + check_sys(Mandatory, SysFiles4), + SysFiles4. strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) -> ExclRegexps2 = @@ -967,22 +986,35 @@ safe_lookup_spec(Prefix, Specs) -> %% Specify applications %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec_lib_files(#sys{apps = Apps} = Sys) -> +spec_lib_files(#sys{root_dir = RootDir, + apps = Apps, + excl_lib = ExclLib} = Sys) -> Filter = fun(#app{is_escript = IsEscript, is_included = IsIncl, - is_pre_included = IsPre, name = Name}) -> + is_pre_included = IsPre, name = Name, + active_dir = ActiveDir}) -> if Name =:= ?MISSING_APP_NAME -> false; IsEscript =/= false -> false; IsIncl; IsPre -> - true; + case ExclLib of + otp_root -> + not lists:prefix(RootDir,ActiveDir); + _ -> + true + end; true -> false end end, SelectedApps = lists:filter(Filter, Apps), - check_apps([kernel, stdlib], SelectedApps), + case ExclLib of + otp_root -> + ok; + _ -> + check_apps([kernel, stdlib], SelectedApps) + end, lists:flatten([spec_app(App, Sys) || App <- SelectedApps]). check_apps([Mandatory | Names], Apps) -> diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index 8a98dc36cf..f29f6049a5 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -67,6 +67,7 @@ all() -> create_standalone_app_clash, create_multiple_standalone, create_old_target, + create_slim, eval_target_spec, otp_9135, otp_9229_dupl_mod_exclude_app, @@ -985,6 +986,56 @@ create_old_target(_Config) -> ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate target system + +create_slim(Config) -> + %% Configure the server + RelName = "slim", + RelVsn = "1.0", + + DataDir = ?config(data_dir,Config), + LibDir = filename:join(DataDir,"slim"), + + Sys = + {sys, + [ + {root_dir, code:root_dir()}, + {lib_dirs, []}, + {boot_rel, RelName}, + {rel, RelName, RelVsn, [sasl, stdlib, kernel, a]}, + {app, sasl, [{incl_cond, include}]}, + {app, a, [{incl_cond, include}, + {lib_dir,filename:join(LibDir,"a-1.0")}]}, + {excl_lib,otp_root} + ]}, + + %% Generate target file + TargetDir = filename:absname(filename:join([?WORK_DIR, "target_slim"])), + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), + ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), + + TargetLibDir = filename:join(TargetDir,"lib"), + TargetRelDir = filename:join(TargetDir,"releases"), + TargetRelVsnDir = filename:join(TargetRelDir,RelVsn), + + {ok,["a-1.0.ez"]} = file:list_dir(TargetLibDir), + + RootDir = code:root_dir(), + Erl = filename:join([RootDir, "bin", "erl"]), + Args = "-boot_var RELTOOL_EXT_LIB " ++ TargetLibDir ++ + " -boot " ++ filename:join(TargetRelVsnDir,RelName) ++ + " -sasl releases_dir \\\"" ++ TargetRelDir ++ "\\\"", + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl, Args)), + ?msym(RootDir, rpc:call(Node, code, root_dir, [])), + ?msym([{RelName,RelVsn,_,permanent}], + rpc:call(Node,release_handler,which_releases,[])), + ?msym(ok, stop_node(Node)), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate target system with eval_target_spec/3 eval_target_spec(_Config) -> @@ -2226,8 +2277,10 @@ mod_path(Node,Mod) -> %% Node handling start_node(Name, ErlPath) -> + start_node(Name, ErlPath, []). +start_node(Name, ErlPath, Args) -> FullName = full_node_name(Name), - CmdLine = mk_node_cmdline(Name, ErlPath), + CmdLine = mk_node_cmdline(Name, ErlPath, Args), io:format("Starting node ~p: ~s~n", [FullName, CmdLine]), case open_port({spawn, CmdLine}, []) of Port when is_port(Port) -> @@ -2246,14 +2299,7 @@ stop_node(Node) -> spawn(Node, fun () -> halt() end), receive {nodedown, Node} -> ok end. -mk_node_cmdline(Name) -> - Prog = case catch init:get_argument(progname) of - {ok,[[P]]} -> P; - _ -> exit(no_progname_argument_found) - end, - mk_node_cmdline(Name, Prog). - -mk_node_cmdline(Name, Prog) -> +mk_node_cmdline(Name, Prog, Args) -> Static = "-detached -noinput", Pa = filename:dirname(code:which(?MODULE)), NameSw = case net_kernel:longnames() of @@ -2268,7 +2314,8 @@ mk_node_cmdline(Name, Prog) -> ++ NameSw ++ " " ++ NameStr ++ " " ++ "-pa " ++ Pa ++ " " ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr ++ " " - ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()). + ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()) + ++ " " ++ Args. full_node_name(PreName) -> HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end, diff --git a/lib/reltool/test/reltool_server_SUITE_data/Makefile.src b/lib/reltool/test/reltool_server_SUITE_data/Makefile.src index 21410ceaa9..02846f42b6 100644 --- a/lib/reltool/test/reltool_server_SUITE_data/Makefile.src +++ b/lib/reltool/test/reltool_server_SUITE_data/Makefile.src @@ -22,7 +22,11 @@ SEL_VSN= \ use_selected_vsn/b-3.0/ebin/b.@EMULATOR@ \ use_selected_vsn/lib2/b-2.0/ebin/b.@EMULATOR@ -all: $(OTP9229) $(DEPENDENCIES) $(ESCRIPT) $(SEL_VSN) +SLIM= \ + slim/a-1.0/ebin/a_sup.@EMULATOR@ \ + slim/a-1.0/ebin/a.@EMULATOR@ + +all: $(OTP9229) $(DEPENDENCIES) $(ESCRIPT) $(SEL_VSN) $(SLIM) otp_9229/x-1.0/ebin/x.@EMULATOR@: otp_9229/x-1.0/src/x.erl erlc $(EFLAGS) -ootp_9229/x-1.0/ebin otp_9229/x-1.0/src/x.erl @@ -55,3 +59,8 @@ use_selected_vsn/b-3.0/ebin/b.@EMULATOR@: use_selected_vsn/b-3.0/src/b.erl erlc $(EFLAGS) -ouse_selected_vsn/b-3.0/ebin use_selected_vsn/b-3.0/src/b.erl use_selected_vsn/lib2/b-2.0/ebin/b.@EMULATOR@: use_selected_vsn/lib2/b-2.0/src/b.erl erlc $(EFLAGS) -ouse_selected_vsn/lib2/b-2.0/ebin use_selected_vsn/lib2/b-2.0/src/b.erl + +slim/a-1.0/ebin/a_sup.@EMULATOR@: slim/a-1.0/src/a_sup.erl + erlc $(EFLAGS) -oslim/a-1.0/ebin slim/a-1.0/src/a_sup.erl +slim/a-1.0/ebin/a.@EMULATOR@: slim/a-1.0/src/a.erl + erlc $(EFLAGS) -oslim/a-1.0/ebin slim/a-1.0/src/a.erl diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app new file mode 100644 index 0000000000..3160e00da7 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/ebin/a.app @@ -0,0 +1,7 @@ +{application, a, + [{description, "A CXC 138 11"}, + {vsn, "1.0"}, + {modules, [a, a_sup]}, + {registered, [a_sup]}, + {applications, [kernel, stdlib]}, + {mod, {a_sup, []}}]}. diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl new file mode 100644 index 0000000000..bb500bed69 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a.erl @@ -0,0 +1,49 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a). + + +-behaviour(gen_server). + +-vsn(1). + +%% External exports +-export([start_link/0, a/0]). +%% Internal exports +-export([init/1, handle_call/3, handle_info/2, terminate/2]). + +start_link() -> gen_server:start_link({local, aa}, a, [], []). + +a() -> gen_server:call(aa, a). + +%%----------------------------------------------------------------- +%% Callback functions from gen_server +%%----------------------------------------------------------------- +init([]) -> + process_flag(trap_exit, true), + {ok, state}. + +handle_call(a, _From, State) -> + X = application:get_all_env(a), + {reply, X, State}. + +handle_info(_, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. diff --git a/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl new file mode 100644 index 0000000000..a141c1767b --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE_data/slim/a-1.0/src/a_sup.erl @@ -0,0 +1,37 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a_sup). + + +-behaviour(supervisor). + +%% External exports +-export([start/2]). + +%% Internal exports +-export([init/1]). + +start(_, _) -> + supervisor:start_link({local, a_sup}, a_sup, []). + +init([]) -> + SupFlags = {one_for_one, 4, 3600}, + Config = {a, + {a, start_link, []}, + permanent, 2000, worker, [a]}, + {ok, {SupFlags, [Config]}}. |