diff options
Diffstat (limited to 'lib/sasl/examples/src/target_system.erl')
-rw-r--r-- | lib/sasl/examples/src/target_system.erl | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/lib/sasl/examples/src/target_system.erl b/lib/sasl/examples/src/target_system.erl new file mode 100644 index 0000000000..0e1e0b2324 --- /dev/null +++ b/lib/sasl/examples/src/target_system.erl @@ -0,0 +1,259 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% 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 online 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. +%% +%% %CopyrightEnd% +%% +-module(target_system). +-export([create/1, create/2, install/2]). + +%% Note: RelFileName below is the *stem* without trailing .rel, +%% .script etc. +%% + +%% create(RelFileName) +%% +create(RelFileName) -> + create(RelFileName,[]). + +create(RelFileName,SystoolsOpts) -> + RelFile = RelFileName ++ ".rel", + Dir = filename:dirname(RelFileName), + PlainRelFileName = filename:join(Dir,"plain"), + PlainRelFile = PlainRelFileName ++ ".rel", + io:fwrite("Reading file: ~p ...~n", [RelFile]), + {ok, [RelSpec]} = file:consult(RelFile), + io:fwrite("Creating file: ~p from ~p ...~n", + [PlainRelFile, RelFile]), + {release, + {RelName, RelVsn}, + {erts, ErtsVsn}, + AppVsns} = RelSpec, + PlainRelSpec = {release, + {RelName, RelVsn}, + {erts, ErtsVsn}, + lists:filter(fun({kernel, _}) -> + true; + ({stdlib, _}) -> + true; + (_) -> + false + end, AppVsns) + }, + {ok, Fd} = file:open(PlainRelFile, [write]), + io:fwrite(Fd, "~p.~n", [PlainRelSpec]), + file:close(Fd), + + io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n", + [PlainRelFileName,PlainRelFileName]), + make_script(PlainRelFileName,SystoolsOpts), + + io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n", + [RelFileName, RelFileName]), + make_script(RelFileName,SystoolsOpts), + + TarFileName = filename:join(Dir,RelFileName ++ ".tar.gz"), + io:fwrite("Creating tar file ~p ...~n", [TarFileName]), + make_tar(RelFileName,SystoolsOpts), + + TmpDir = filename:join(Dir,"tmp"), + io:fwrite("Creating directory ~p ...~n",[TmpDir]), + file:make_dir(TmpDir), + + io:fwrite("Extracting ~p into directory ~p ...~n", [TarFileName,TmpDir]), + extract_tar(TarFileName, TmpDir), + + TmpBinDir = filename:join([TmpDir, "bin"]), + ErtsBinDir = filename:join([TmpDir, "erts-" ++ ErtsVsn, "bin"]), + io:fwrite("Deleting \"erl\" and \"start\" in directory ~p ...~n", + [ErtsBinDir]), + file:delete(filename:join([ErtsBinDir, "erl"])), + file:delete(filename:join([ErtsBinDir, "start"])), + + io:fwrite("Creating temporary directory ~p ...~n", [TmpBinDir]), + file:make_dir(TmpBinDir), + + io:fwrite("Copying file \"~s.boot\" to ~p ...~n", + [PlainRelFileName, filename:join([TmpBinDir, "start.boot"])]), + copy_file(PlainRelFileName++".boot",filename:join([TmpBinDir, "start.boot"])), + + io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" + "~p to ~p ...~n", + [ErtsBinDir, TmpBinDir]), + copy_file(filename:join([ErtsBinDir, "epmd"]), + filename:join([TmpBinDir, "epmd"]), [preserve]), + copy_file(filename:join([ErtsBinDir, "run_erl"]), + filename:join([TmpBinDir, "run_erl"]), [preserve]), + copy_file(filename:join([ErtsBinDir, "to_erl"]), + filename:join([TmpBinDir, "to_erl"]), [preserve]), + + StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]), + io:fwrite("Creating ~p ...~n", [StartErlDataFile]), + StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), + write_file(StartErlDataFile, StartErlData), + + io:fwrite("Recreating tar file ~p from contents in directory ~p ...~n", + [TarFileName,TmpDir]), + {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), + %% {ok, Cwd} = file:get_cwd(), + %% file:set_cwd("tmp"), + ErtsDir = "erts-"++ErtsVsn, + erl_tar:add(Tar, filename:join(TmpDir,"bin"), "bin", []), + erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []), + erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []), + erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []), + erl_tar:close(Tar), + %% file:set_cwd(Cwd), + io:fwrite("Removing directory ~p ...~n",[TmpDir]), + remove_dir_tree(TmpDir), + ok. + + +install(RelFileName, RootDir) -> + TarFile = RelFileName ++ ".tar.gz", + io:fwrite("Extracting ~p ...~n", [TarFile]), + extract_tar(TarFile, RootDir), + StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]), + {ok, StartErlData} = read_txt_file(StartErlDataFile), + [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"), + ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]), + BinDir = filename:join([RootDir, "bin"]), + io:fwrite("Substituting in erl.src, start.src and start_erl.src to\n" + "form erl, start and start_erl ...\n"), + subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, + [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], + [preserve]), + io:fwrite("Creating the RELEASES file ...\n"), + create_RELEASES(RootDir, + filename:join([RootDir, "releases", RelFileName])). + +%% LOCALS + +%% make_script(RelFileName,Opts) +%% +make_script(RelFileName,Opts) -> + systools:make_script(RelFileName, [no_module_tests, + {outdir,filename:dirname(RelFileName)} + |Opts]). + +%% make_tar(RelFileName,Opts) +%% +make_tar(RelFileName,Opts) -> + RootDir = code:root_dir(), + systools:make_tar(RelFileName, [{erts, RootDir}, + {outdir,filename:dirname(RelFileName)} + |Opts]). + +%% extract_tar(TarFile, DestDir) +%% +extract_tar(TarFile, DestDir) -> + erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]). + +create_RELEASES(DestDir, RelFileName) -> + release_handler:create_RELEASES(DestDir, RelFileName ++ ".rel"). + +subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> + lists:foreach(fun(Script) -> + subst_src_script(Script, SrcDir, DestDir, + Vars, Opts) + end, Scripts). + +subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> + subst_file(filename:join([SrcDir, Script ++ ".src"]), + filename:join([DestDir, Script]), + Vars, Opts). + +subst_file(Src, Dest, Vars, Opts) -> + {ok, Conts} = read_txt_file(Src), + NConts = subst(Conts, Vars), + write_file(Dest, NConts), + case lists:member(preserve, Opts) of + true -> + {ok, FileInfo} = file:read_file_info(Src), + file:write_file_info(Dest, FileInfo); + false -> + ok + end. + +%% subst(Str, Vars) +%% Vars = [{Var, Val}] +%% Var = Val = string() +%% Substitute all occurrences of %Var% for Val in Str, using the list +%% of variables in Vars. +%% +subst(Str, Vars) -> + subst(Str, Vars, []). + +subst([$%, C| Rest], Vars, Result) when $A =< C, C =< $Z -> + subst_var([C| Rest], Vars, Result, []); +subst([$%, C| Rest], Vars, Result) when $a =< C, C =< $z -> + subst_var([C| Rest], Vars, Result, []); +subst([$%, C| Rest], Vars, Result) when C == $_ -> + subst_var([C| Rest], Vars, Result, []); +subst([C| Rest], Vars, Result) -> + subst(Rest, Vars, [C| Result]); +subst([], _Vars, Result) -> + lists:reverse(Result). + +subst_var([$%| Rest], Vars, Result, VarAcc) -> + Key = lists:reverse(VarAcc), + case lists:keysearch(Key, 1, Vars) of + {value, {Key, Value}} -> + subst(Rest, Vars, lists:reverse(Value, Result)); + false -> + subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]]) + end; +subst_var([C| Rest], Vars, Result, VarAcc) -> + subst_var(Rest, Vars, Result, [C| VarAcc]); +subst_var([], Vars, Result, VarAcc) -> + subst([], Vars, [VarAcc ++ [$%| Result]]). + +copy_file(Src, Dest) -> + copy_file(Src, Dest, []). + +copy_file(Src, Dest, Opts) -> + {ok,_} = file:copy(Src, Dest), + case lists:member(preserve, Opts) of + true -> + {ok, FileInfo} = file:read_file_info(Src), + file:write_file_info(Dest, FileInfo); + false -> + ok + end. + +write_file(FName, Conts) -> + {ok, Fd} = file:open(FName, [write]), + file:write(Fd, Conts), + file:close(Fd). + +read_txt_file(File) -> + {ok, Bin} = file:read_file(File), + {ok, binary_to_list(Bin)}. + +remove_dir_tree(Dir) -> + remove_all_files(".", [Dir]). + +remove_all_files(Dir, Files) -> + lists:foreach(fun(File) -> + FilePath = filename:join([Dir, File]), + case filelib:is_dir(FilePath) of + true -> + {ok, DirFiles} = file:list_dir(FilePath), + remove_all_files(FilePath, DirFiles), + file:del_dir(FilePath); + _ -> + file:delete(FilePath) + end + end, Files). |