From e39c093f4cdc55084d27d378d64dd2bc464dec0b Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 25 Nov 2011 15:31:55 +0100 Subject: Rename create_target.xml to create_target.xmlsrc to prepare for codeinclude --- .gitignore | 1 + system/doc/system_principles/create_target.xml | 497 ---------------------- system/doc/system_principles/create_target.xmlsrc | 496 +++++++++++++++++++++ 3 files changed, 497 insertions(+), 497 deletions(-) delete mode 100644 system/doc/system_principles/create_target.xml create mode 100644 system/doc/system_principles/create_target.xmlsrc diff --git a/.gitignore b/.gitignore index 065c499708..46a47febcb 100644 --- a/.gitignore +++ b/.gitignore @@ -322,6 +322,7 @@ JAVADOC-GENERATED /system/doc/top/PR.template /system/doc/top/erlresolvelinks.js /system/doc/programming_examples/funs.xml +/system/doc/system_principles/create_target.xml /system/doc/tutorial/c_port.xml /system/doc/tutorial/c_portdriver.xml /system/doc/tutorial/cnode.xml diff --git a/system/doc/system_principles/create_target.xml b/system/doc/system_principles/create_target.xml deleted file mode 100644 index 7d9f4681b9..0000000000 --- a/system/doc/system_principles/create_target.xml +++ /dev/null @@ -1,497 +0,0 @@ - - - - -
- - 20022009 - Ericsson AB. 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. - - - - Creating a First Target System - Peter Högfeldt - - - - - 2002-09-17 - A - create_target.xml -
- -
- Introduction -

When creating a system using Erlang/OTP, the most simple way is - to install Erlang/OTP somewhere, install the application specific - code somewhere else, and then start the Erlang runtime system, - making sure the code path includes the application specific code.

-

Often it is not desirable to use an Erlang/OTP system as is. A - developer may create new Erlang/OTP compliant applications for a - particular purpose, and several original Erlang/OTP applications - may be irrelevant for the purpose in question. Thus, there is a - need to be able to create a new system based on a given - Erlang/OTP system, where dispensable applications are removed, - and a set of new applications that are included in the new - system. Documentation and source code is irrelevant and is - therefore not included in the new system.

-

This chapter is about creating such a system, which we call a - target system.

-

In the following sections we consider creating target systems with - different requirements of functionality:

- - a basic target system that can be started by - calling the ordinary erl script, - a simple target system where also code - replacement in run-time can be performed, and - an embedded target system where there is also - support for logging output from the system to file for later - inspection, and where the system can be started automatically - at boot time. - -

We only consider the case when Erlang/OTP is running on a UNIX - system.

-

There is an example Erlang module target_system.erl that - contains functions for creating and installing a target system. - That module is used in the examples below. The source code of - the module is listed at the end of this chapter.

-
- -
- Creating a Target System -

It is assumed that you have a working Erlang/OTP system structured - according to the OTP Design Principles.

-

Step 1. First create a .rel file (see - rel(4)) that specifies the erts version - and lists all applications that should be included in the new - basic target system. An example is the following - mysystem.rel file:

- -%% mysystem.rel -{release, - {"MYSYSTEM", "FIRST"}, - {erts, "5.1"}, - [{kernel, "2.7"}, - {stdlib, "1.10"}, - {sasl, "1.9.3"}, - {pea, "1.0"}]}. -

The listed applications are not only original Erlang/OTP - applications but possibly also new applications that you have - written yourself (here examplified by the application - pea).

-

Step 2. From the directory where the mysystem.rel - file reside, start the Erlang/OTP system:

-
-os> erl -pa /home/user/target_system/myapps/pea-1.0/ebin
-

where also the path to the pea-1.0 ebin directory is - provided.

-

Step 3. Now create the target system:

-
-1> target_system:create("mysystem").
-

The target_system:create/1 function does the following:

- - Reads the mysystem.rel file, and creates a new file - plain.rel which is identical to former, except that it - only lists the kernel and stdlib applications. - From the mysystem.rel and plain.rel files - creates the files mysystem.script, - mysystem.boot, plain.script, and - plain.boot through a call to - systools:make_script/2. - -

Creates the file mysystem.tar.gz by a call to - systools:make_tar/2. That file has the following - contents:

- -erts-5.1/bin/ -releases/FIRST/start.boot -releases/mysystem.rel -lib/kernel-2.7/ -lib/stdlib-1.10/ -lib/sasl-1.9.3/ -lib/pea-1.0/ -

The file releases/FIRST/start.boot is a copy of our - mysystem.boot, and a copy of the original - mysystem.rel has been put in the releases - directory.

-
- Creates the temporary directory tmp and extracts the tar file - mysystem.tar.gz into that directory. - Deletes the erl and start files from - tmp/erts-5.1/bin. XXX Why. - Creates the directory tmp/bin. - Copies the previously creates file plain.boot to - tmp/bin/start.boot. - Copies the files epmd, run_erl, and - to_erl from the directory tmp/erts-5.1/bin to - the directory tmp/bin. - Creates the file tmp/releases/start_erl.data with the - contents "5.1 FIRST". - - Recreates the file mysystem.tar.gz from the directories - in the directory tmp, and removes tmp. -
-
- -
- Installing a Target System -

Step 4. Install the created target system in a - suitable directory.

-
-2> target_system:install("mysystem", "/usr/local/erl-target").
-

The function target_system:install/2 does the following: -

- - Extracts the tar file mysystem.tar.gz into the target - directory /usr/local/erl-target. - In the target directory reads the file releases/start_erl.data - in order to find the Erlang runtime system version ("5.1"). - Substitutes %FINAL_ROOTDIR% and %EMU% for - /usr/local/erl-target and beam, respectively, in - the files erl.src, start.src, and - start_erl.src of the target erts-5.1/bin - directory, and puts the resulting files erl, - start, and run_erl in the target bin - directory. - Finally the target releases/RELEASES file is created - from data in the releases/mysystem.rel file. - -
- -
- Starting a Target System -

Now we have a target system that can be started in various ways.

-

We start it as a basic target system by invoking

-
-os> /usr/local/erl-target/bin/erl
-

where only the kernel and stdlib applications are - started, i.e. the system is started as an ordinary development - system. There are only two files needed for all this to work: - bin/erl file (obtained from erts-5.1/bin/erl.src) - and the bin/start.boot file (a copy of plain.boot).

-

We can also start a distributed system (requires bin/epmd).

-

To start all applications specified in the original - mysystem.rel file, use the -boot flag as follows:

-
-os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start
-

We start a simple target system as above. The only difference - is that also the file releases/RELEASES is present for - code replacement in run-time to work.

-

To start an embedded target system the shell script - bin/start is used. That shell script calls - bin/run_erl, which in turn calls bin/start_erl - (roughly, start_erl is an embedded variant of - erl).

-

The shell script start is only an example. You should - edit it to suite your needs. Typically it is executed when the - UNIX system boots.

-

run_erl is a wrapper that provides logging of output from - the run-time system to file. It also provides a simple mechanism - for attaching to the Erlang shell (to_erl).

-

start_erl requires the root directory - ("/usr/local/erl-target"), the releases directory - ("/usr/local/erl-target/releases"), and the location of - the start_erl.data file. It reads the run-time system - version ("5.1") and release version ("FIRST") from - the start_erl.data file, starts the run-time system of the - version found, and provides -boot flag specifying the boot - file of the release version found - ("releases/FIRST/start.boot").

-

start_erl also assumes that there is sys.config in - release version directory ("releases/FIRST/sys.config). That - is the topic of the next section (see below).

-

The start_erl shell script should normally not be - altered by the user.

-
- -
- System Configuration Parameters -

As was pointed out above start_erl requires a - sys.config in the release version directory - ("releases/FIRST/sys.config"). If there is no such a - file, the system start will fail. Hence such a file has to - added as well.

-

-

If you have system configuration data that are neither file - location dependent nor site dependent, it may be convenient to - create the sys.config early, so that it becomes a part of - the target system tar file created by - target_system:create/1. In fact, if you create, in the - current directory, not only the mysystem.rel file, but - also a sys.config file, that latter file will be tacitly - put in the apropriate directory.

-
- -
- Differences from the Install Script -

The above install/2 procedure differs somewhat from that - of the ordinary Install shell script. In fact, create/1 - makes the release package as complete as possible, and leave to the - install/2 procedure to finish by only considering location - dependent files.

-
- -
- Listing of target_system.erl - - RelFile = RelFileName ++ ".rel", - io:fwrite("Reading file: \"~s\" ...~n", [RelFile]), - {ok, [RelSpec]} = file:consult(RelFile), - io:fwrite("Creating file: \"~s\" from \"~s\" ...~n", - ["plain.rel", 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("plain.rel", [write]), - io:fwrite(Fd, "~p.~n", [PlainRelSpec]), - file:close(Fd), - - io:fwrite("Making \"plain.script\" and \"plain.boot\" files ...~n"), - make_script("plain"), - - io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n", - [RelFileName, RelFileName]), - make_script(RelFileName), - - TarFileName = io_lib:fwrite("~s.tar.gz", [RelFileName]), - io:fwrite("Creating tar file \"~s\" ...~n", [TarFileName]), - make_tar(RelFileName), - - io:fwrite("Creating directory \"tmp\" ...~n"), - file:make_dir("tmp"), - - io:fwrite("Extracting \"~s\" into directory \"tmp\" ...~n", [TarFileName]), - extract_tar(TarFileName, "tmp"), - - TmpBinDir = filename:join(["tmp", "bin"]), - ErtsBinDir = filename:join(["tmp", "erts-" ++ ErtsVsn, "bin"]), - io:fwrite("Deleting \"erl\" and \"start\" in directory \"~s\" ...~n", - [ErtsBinDir]), - file:delete(filename:join([ErtsBinDir, "erl"])), - file:delete(filename:join([ErtsBinDir, "start"])), - - io:fwrite("Creating temporary directory \"~s\" ...~n", [TmpBinDir]), - file:make_dir(TmpBinDir), - - io:fwrite("Copying file \"plain.boot\" to \"~s\" ...~n", - [filename:join([TmpBinDir, "start.boot"])]), - copy_file("plain.boot", filename:join([TmpBinDir, "start.boot"])), - - io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" - "\"~s\" to \"~s\" ...~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(["tmp", "releases", "start_erl.data"]), - io:fwrite("Creating \"~s\" ...~n", [StartErlDataFile]), - StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), - write_file(StartErlDataFile, StartErlData), - - io:fwrite("Recreating tar file \"~s\" from contents in directory " - "\"tmp\" ...~n", [TarFileName]), - {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), - {ok, Cwd} = file:get_cwd(), - file:set_cwd("tmp"), - erl_tar:add(Tar, "bin", []), - erl_tar:add(Tar, "erts-" ++ ErtsVsn, []), - erl_tar:add(Tar, "releases", []), - erl_tar:add(Tar, "lib", []), - erl_tar:close(Tar), - file:set_cwd(Cwd), - io:fwrite("Removing directory \"tmp\" ...~n"), - remove_dir_tree("tmp"), - ok. - - -install(RelFileName, RootDir) -> - TarFile = RelFileName ++ ".tar.gz", - io:fwrite("Extracting ~s ...~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) -%% -make_script(RelFileName) -> - Opts = [no_module_tests], - systools:make_script(RelFileName, Opts). - -%% make_tar(RelFileName) -%% -make_tar(RelFileName) -> - RootDir = code:root_dir(), - systools:make_tar(RelFileName, [{erts, RootDir}]). - -%% 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, InFd} = file:open(Src, [raw, binary, read]), - {ok, OutFd} = file:open(Dest, [raw, binary, write]), - do_copy_file(InFd, OutFd), - file:close(InFd), - file:close(OutFd), - case lists:member(preserve, Opts) of - true -> - {ok, FileInfo} = file:read_file_info(Src), - file:write_file_info(Dest, FileInfo); - false -> - ok - end. - -do_copy_file(InFd, OutFd) -> - case file:read(InFd, ?BUFSIZE) of - {ok, Bin} -> - file:write(OutFd, Bin), - do_copy_file(InFd, OutFd); - eof -> - 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]), - {ok, FileInfo} = file:read_file_info(FilePath), - case FileInfo#file_info.type of - directory -> - {ok, DirFiles} = file:list_dir(FilePath), - remove_all_files(FilePath, DirFiles), - file:del_dir(FilePath); - _ -> - file:delete(FilePath) - end - end, Files). - ]]> -
-
- diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc new file mode 100644 index 0000000000..1564423e00 --- /dev/null +++ b/system/doc/system_principles/create_target.xmlsrc @@ -0,0 +1,496 @@ + + + + +
+ + 20022011 + Ericsson AB. 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. + + + + Creating a First Target System + Peter Högfeldt + + + + + 2002-09-17 + A + create_target.xml +
+ +
+ Introduction +

When creating a system using Erlang/OTP, the most simple way is + to install Erlang/OTP somewhere, install the application specific + code somewhere else, and then start the Erlang runtime system, + making sure the code path includes the application specific code.

+

Often it is not desirable to use an Erlang/OTP system as is. A + developer may create new Erlang/OTP compliant applications for a + particular purpose, and several original Erlang/OTP applications + may be irrelevant for the purpose in question. Thus, there is a + need to be able to create a new system based on a given + Erlang/OTP system, where dispensable applications are removed, + and a set of new applications that are included in the new + system. Documentation and source code is irrelevant and is + therefore not included in the new system.

+

This chapter is about creating such a system, which we call a + target system.

+

In the following sections we consider creating target systems with + different requirements of functionality:

+ + a basic target system that can be started by + calling the ordinary erl script, + a simple target system where also code + replacement in run-time can be performed, and + an embedded target system where there is also + support for logging output from the system to file for later + inspection, and where the system can be started automatically + at boot time. + +

We only consider the case when Erlang/OTP is running on a UNIX + system.

+

There is an example Erlang module target_system.erl that + contains functions for creating and installing a target system. + That module is used in the examples below. The source code of + the module is listed at the end of this chapter.

+
+ +
+ Creating a Target System +

It is assumed that you have a working Erlang/OTP system structured + according to the OTP Design Principles.

+

Step 1. First create a .rel file (see + rel(4)) that specifies the erts version + and lists all applications that should be included in the new + basic target system. An example is the following + mysystem.rel file:

+ +%% mysystem.rel +{release, + {"MYSYSTEM", "FIRST"}, + {erts, "5.1"}, + [{kernel, "2.7"}, + {stdlib, "1.10"}, + {sasl, "1.9.3"}, + {pea, "1.0"}]}. +

The listed applications are not only original Erlang/OTP + applications but possibly also new applications that you have + written yourself (here examplified by the application + pea).

+

Step 2. From the directory where the mysystem.rel + file reside, start the Erlang/OTP system:

+
+os> erl -pa /home/user/target_system/myapps/pea-1.0/ebin
+

where also the path to the pea-1.0 ebin directory is + provided.

+

Step 3. Now create the target system:

+
+1> target_system:create("mysystem").
+

The target_system:create/1 function does the following:

+ + Reads the mysystem.rel file, and creates a new file + plain.rel which is identical to former, except that it + only lists the kernel and stdlib applications. + From the mysystem.rel and plain.rel files + creates the files mysystem.script, + mysystem.boot, plain.script, and + plain.boot through a call to + systools:make_script/2. + +

Creates the file mysystem.tar.gz by a call to + systools:make_tar/2. That file has the following + contents:

+ +erts-5.1/bin/ +releases/FIRST/start.boot +releases/mysystem.rel +lib/kernel-2.7/ +lib/stdlib-1.10/ +lib/sasl-1.9.3/ +lib/pea-1.0/ +

The file releases/FIRST/start.boot is a copy of our + mysystem.boot, and a copy of the original + mysystem.rel has been put in the releases + directory.

+
+ Creates the temporary directory tmp and extracts the tar file + mysystem.tar.gz into that directory. + Deletes the erl and start files from + tmp/erts-5.1/bin. XXX Why. + Creates the directory tmp/bin. + Copies the previously creates file plain.boot to + tmp/bin/start.boot. + Copies the files epmd, run_erl, and + to_erl from the directory tmp/erts-5.1/bin to + the directory tmp/bin. + Creates the file tmp/releases/start_erl.data with the + contents "5.1 FIRST". + + Recreates the file mysystem.tar.gz from the directories + in the directory tmp, and removes tmp. +
+
+ +
+ Installing a Target System +

Step 4. Install the created target system in a + suitable directory.

+
+2> target_system:install("mysystem", "/usr/local/erl-target").
+

The function target_system:install/2 does the following: +

+ + Extracts the tar file mysystem.tar.gz into the target + directory /usr/local/erl-target. + In the target directory reads the file releases/start_erl.data + in order to find the Erlang runtime system version ("5.1"). + Substitutes %FINAL_ROOTDIR% and %EMU% for + /usr/local/erl-target and beam, respectively, in + the files erl.src, start.src, and + start_erl.src of the target erts-5.1/bin + directory, and puts the resulting files erl, + start, and run_erl in the target bin + directory. + Finally the target releases/RELEASES file is created + from data in the releases/mysystem.rel file. + +
+ +
+ Starting a Target System +

Now we have a target system that can be started in various ways.

+

We start it as a basic target system by invoking

+
+os> /usr/local/erl-target/bin/erl
+

where only the kernel and stdlib applications are + started, i.e. the system is started as an ordinary development + system. There are only two files needed for all this to work: + bin/erl file (obtained from erts-5.1/bin/erl.src) + and the bin/start.boot file (a copy of plain.boot).

+

We can also start a distributed system (requires bin/epmd).

+

To start all applications specified in the original + mysystem.rel file, use the -boot flag as follows:

+
+os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start
+

We start a simple target system as above. The only difference + is that also the file releases/RELEASES is present for + code replacement in run-time to work.

+

To start an embedded target system the shell script + bin/start is used. That shell script calls + bin/run_erl, which in turn calls bin/start_erl + (roughly, start_erl is an embedded variant of + erl).

+

The shell script start is only an example. You should + edit it to suite your needs. Typically it is executed when the + UNIX system boots.

+

run_erl is a wrapper that provides logging of output from + the run-time system to file. It also provides a simple mechanism + for attaching to the Erlang shell (to_erl).

+

start_erl requires the root directory + ("/usr/local/erl-target"), the releases directory + ("/usr/local/erl-target/releases"), and the location of + the start_erl.data file. It reads the run-time system + version ("5.1") and release version ("FIRST") from + the start_erl.data file, starts the run-time system of the + version found, and provides -boot flag specifying the boot + file of the release version found + ("releases/FIRST/start.boot").

+

start_erl also assumes that there is sys.config in + release version directory ("releases/FIRST/sys.config). That + is the topic of the next section (see below).

+

The start_erl shell script should normally not be + altered by the user.

+
+ +
+ System Configuration Parameters +

As was pointed out above start_erl requires a + sys.config in the release version directory + ("releases/FIRST/sys.config"). If there is no such a + file, the system start will fail. Hence such a file has to + added as well.

+

+

If you have system configuration data that are neither file + location dependent nor site dependent, it may be convenient to + create the sys.config early, so that it becomes a part of + the target system tar file created by + target_system:create/1. In fact, if you create, in the + current directory, not only the mysystem.rel file, but + also a sys.config file, that latter file will be tacitly + put in the apropriate directory.

+
+ +
+ Differences from the Install Script +

The above install/2 procedure differs somewhat from that + of the ordinary Install shell script. In fact, create/1 + makes the release package as complete as possible, and leave to the + install/2 procedure to finish by only considering location + dependent files.

+
+ +
+ Listing of target_system.erl + + RelFile = RelFileName ++ ".rel", + io:fwrite("Reading file: \"~s\" ...~n", [RelFile]), + {ok, [RelSpec]} = file:consult(RelFile), + io:fwrite("Creating file: \"~s\" from \"~s\" ...~n", + ["plain.rel", 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("plain.rel", [write]), + io:fwrite(Fd, "~p.~n", [PlainRelSpec]), + file:close(Fd), + + io:fwrite("Making \"plain.script\" and \"plain.boot\" files ...~n"), + make_script("plain"), + + io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n", + [RelFileName, RelFileName]), + make_script(RelFileName), + + TarFileName = io_lib:fwrite("~s.tar.gz", [RelFileName]), + io:fwrite("Creating tar file \"~s\" ...~n", [TarFileName]), + make_tar(RelFileName), + + io:fwrite("Creating directory \"tmp\" ...~n"), + file:make_dir("tmp"), + + io:fwrite("Extracting \"~s\" into directory \"tmp\" ...~n", [TarFileName]), + extract_tar(TarFileName, "tmp"), + + TmpBinDir = filename:join(["tmp", "bin"]), + ErtsBinDir = filename:join(["tmp", "erts-" ++ ErtsVsn, "bin"]), + io:fwrite("Deleting \"erl\" and \"start\" in directory \"~s\" ...~n", + [ErtsBinDir]), + file:delete(filename:join([ErtsBinDir, "erl"])), + file:delete(filename:join([ErtsBinDir, "start"])), + + io:fwrite("Creating temporary directory \"~s\" ...~n", [TmpBinDir]), + file:make_dir(TmpBinDir), + + io:fwrite("Copying file \"plain.boot\" to \"~s\" ...~n", + [filename:join([TmpBinDir, "start.boot"])]), + copy_file("plain.boot", filename:join([TmpBinDir, "start.boot"])), + + io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" + "\"~s\" to \"~s\" ...~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(["tmp", "releases", "start_erl.data"]), + io:fwrite("Creating \"~s\" ...~n", [StartErlDataFile]), + StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), + write_file(StartErlDataFile, StartErlData), + + io:fwrite("Recreating tar file \"~s\" from contents in directory " + "\"tmp\" ...~n", [TarFileName]), + {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), + {ok, Cwd} = file:get_cwd(), + file:set_cwd("tmp"), + erl_tar:add(Tar, "bin", []), + erl_tar:add(Tar, "erts-" ++ ErtsVsn, []), + erl_tar:add(Tar, "releases", []), + erl_tar:add(Tar, "lib", []), + erl_tar:close(Tar), + file:set_cwd(Cwd), + io:fwrite("Removing directory \"tmp\" ...~n"), + remove_dir_tree("tmp"), + ok. + + +install(RelFileName, RootDir) -> + TarFile = RelFileName ++ ".tar.gz", + io:fwrite("Extracting ~s ...~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) +%% +make_script(RelFileName) -> + Opts = [no_module_tests], + systools:make_script(RelFileName, Opts). + +%% make_tar(RelFileName) +%% +make_tar(RelFileName) -> + RootDir = code:root_dir(), + systools:make_tar(RelFileName, [{erts, RootDir}]). + +%% 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, InFd} = file:open(Src, [raw, binary, read]), + {ok, OutFd} = file:open(Dest, [raw, binary, write]), + do_copy_file(InFd, OutFd), + file:close(InFd), + file:close(OutFd), + case lists:member(preserve, Opts) of + true -> + {ok, FileInfo} = file:read_file_info(Src), + file:write_file_info(Dest, FileInfo); + false -> + ok + end. + +do_copy_file(InFd, OutFd) -> + case file:read(InFd, ?BUFSIZE) of + {ok, Bin} -> + file:write(OutFd, Bin), + do_copy_file(InFd, OutFd); + eof -> + 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]), + {ok, FileInfo} = file:read_file_info(FilePath), + case FileInfo#file_info.type of + directory -> + {ok, DirFiles} = file:list_dir(FilePath), + remove_all_files(FilePath, DirFiles), + file:del_dir(FilePath); + _ -> + file:delete(FilePath) + end + end, Files). + ]]> +
+
-- cgit v1.2.3 From e10079c3793da3d0f6d76adaf38422cba63bc427 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 28 Nov 2011 10:39:15 +0100 Subject: Fix minor faults in documentation of release handling Fix typos or minor faults. Move out code listing of target_system.erl, and use codeinclude statement to include this file from sasl/examples directory. --- lib/sasl/doc/src/release_handler.xml | 21 +- system/doc/design_principles/release_handling.xml | 44 +-- system/doc/design_principles/release_structure.xml | 20 +- system/doc/system_principles/create_target.xmlsrc | 295 +++------------------ 4 files changed, 84 insertions(+), 296 deletions(-) diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml index bd4a513750..e3438ede41 100644 --- a/lib/sasl/doc/src/release_handler.xml +++ b/lib/sasl/doc/src/release_handler.xml @@ -64,10 +64,10 @@ downgraded to the specified version by evaluating the instructions in relup. An installed release can be made permanent. There can only be one permanent release in - the system, and this is the release that is used if the system is - restarted. An installed release, except the permanent one, can be - removed. When a release is removed, all files that - belong to that release only are deleted.

+ the system, and this is the release that is used if the system + is restarted. An installed release, except the permanent one, + can be removed. When a release is removed, all files + that belong to that release only are deleted.

Each version of the release has a status. The status can be unpacked, current, permanent, or old. There is always one latest release which either has status @@ -107,16 +107,17 @@ old reboot_old permanent restarted. This is taken care of automatically if Erlang is started as an embedded system. Read about this in Embedded System. In this case, the system configuration file sys.config is mandatory.

-

A new release may restart the system. Which program to use is - specified by the SASL configuration parameter start_prg - which defaults to $ROOT/bin/start.

+

The installation of a new release may restart the system. Which + program to use is specified by the SASL configuration + parameter start_prg which defaults + to $ROOT/bin/start.

The emulator restart on Windows NT expects that the system is started using the erlsrv program (as a service). Furthermore the release handler expects that the service is named NodeName_Release, where NodeName is the first part of the Erlang nodename (up to, but not including - the "@") and Release is the current release of - the application. The release handler furthermore expects that a + the "@") and Release is the current version of + the release. The release handler furthermore expects that a program like start_erl.exe is specified as "machine" to erlsrv. During upgrading with restart, a new service will be registered and started. The new service will be set to @@ -484,7 +485,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). release_handler to end up in an inconsistent state.

No persistent information is updated, why these functions can be used on any Erlang node, embedded or not. Also, using these - functions does not effect which code will be loaded in case of + functions does not affect which code will be loaded in case of a reboot.

If the upgrade or downgrade fails, the application may end up in an inconsistent state.

diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml index 8ed36f3c56..4378b6599c 100644 --- a/system/doc/design_principles/release_handling.xml +++ b/system/doc/design_principles/release_handling.xml @@ -178,13 +178,13 @@ Release Handling Instructions

OTP supports a set of release handling instructions - that is used when creating .appup files. The release + that are used when creating .appup files. The release handler understands a subset of these, the low-level instructions. To make it easier for the user, there are also a number of high-level instructions, which are translated to low-level instructions by systools:make_relup.

Here, some of the most frequently used instructions are - described. The complete list of instructions is found in + described. The complete list of instructions can be found in appup(4).

First, some definitions:

@@ -239,9 +239,10 @@

update with argument supervisor is used when changing the start specification of a supervisor. See Appup Cookbook.

-

The release handler finds the processes using a module - to update by traversing the supervision tree of each running - application and checking all the child specifications:

+

When a module is to be updated, the release handler finds + which processes that are using the module by + traversing the supervision tree of each running application + and checking all the child specifications:

{Id, StartFunc, Restart, Shutdown, Type, Modules}

A process is using a module if the name is listed in @@ -265,8 +266,8 @@

The instruction loads the module and is absolutely necessary when running Erlang in embedded mode. It is not strictly required when running Erlang in interactive (default) mode, - since the code server automatically searches for and loads - unloaded modules.

+ since the code server then automatically searches for and + loads unloaded modules.

The opposite of add_module is delete_module which unloads a module:

@@ -294,7 +295,7 @@ the modules are unloaded using a number of delete_module instructions and then the application specification is unloaded from the application controller.

-

Instruction for removing an application:

+

Instruction for restarting an application:

{restart_application, Application}

Restarting an application means that the application is stopped @@ -331,17 +332,17 @@ of the emulator and the core applications. Then it shuts down the current emulator by calling init:reboot(), see init(3). All processes are terminated gracefully and - the system can then be rebooted by the heart program, using - the temporary boot file. After the reboot, the rest of the - relup instructions are executed. This is done as a part of the - boot script.

+ the system is rebooted by the heart program, using the + temporary boot file. After the reboot, the rest of the relup + instructions are executed. This is done as a part of the + temporary boot script.

An info report is written when the upgrade is completed. To programatically find out if the upgrade is complete, - call release_handler:which_releases/0 and check if the - expected release has status current.

-

The new version must be made permanent when the new emulator - is up and running. Otherwise, the old version will be used in - case of a new system reboot.

+ call release_handler:which_releases(current) and check + if it returns the expected (i.e. the new) release.

+

The new release version must be made permanent when the new + emulator is up and running. Otherwise, the old version will be + used in case of a new system reboot.

On UNIX, the release handler tells the heart program which command to use to reboot the system. Note that the environment variable HEART_COMMAND, normally used by the heart @@ -362,8 +363,8 @@ a relup script, and it shall always be placed at the end. If the relup is generated by systools:make_relup/3,4 this is automatically ensured.

-

When the release handler encounters the instruction, it shuts down - the emulator by calling init:reboot(), see +

When the release handler encounters the instruction, it shuts + down the emulator by calling init:reboot(), see init(3). All processes are terminated gracefully and the system can then be rebooted by the heart program using the new release version. No more upgrade instruction will be @@ -581,8 +582,8 @@ release_handler:remove_release(Vsn) => ok [].

2) Start the system as a simple target system. Note that in reality, it should be started as an embedded system. However, - using erl with the correct boot script and .config - file is enough for illustration purposes:

+ using erl with the correct boot script and config file is + enough for illustration purposes:

 % cd $ROOT
 % bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys
@@ -617,6 +618,7 @@ lib/ch_app-2/ebin/ch3.beam
 releases/B/start.boot
 releases/B/relup
 releases/B/sys.config
+releases/B/ch_rel-2.rel
 releases/ch_rel-2.rel
     

4) Copy the release package ch_rel-2.tar.gz to the $ROOT/releases directory.

diff --git a/system/doc/design_principles/release_structure.xml b/system/doc/design_principles/release_structure.xml index 2e1daa611a..8aea0e1a10 100644 --- a/system/doc/design_principles/release_structure.xml +++ b/system/doc/design_principles/release_structure.xml @@ -4,7 +4,7 @@
- 20032009 + 20032011 Ericsson AB. All Rights Reserved. @@ -61,12 +61,14 @@ {ApplicationN, AppVsnN}]}.

The file must be named Rel.rel, where Rel is a unique name.

-

Name, Vsn and Evsn are strings.

+

Name, Vsn and EVsn are strings.

Each Application (atom) and AppVsn (string) is the name and version of an application included in the release. - Note the the minimal release based on Erlang/OTP consists of + Note that the minimal release based on Erlang/OTP consists of the kernel and stdlib applications, so these applications must be included in the list.

+

If the release is to be upgraded, it must also include + the sasl application.

Example: We want to make a release of ch_app from the Applications @@ -173,6 +175,7 @@ lib/ch_app-1/ebin/ch_app.beam lib/ch_app-1/ebin/ch_sup.beam lib/ch_app-1/ebin/ch3.beam releases/A/start.boot +releases/A/ch_rel-1.rel releases/ch_rel-1.rel

Note that a new boot script was generated, without the local option set, before the release package was made. @@ -180,6 +183,17 @@ releases/ch_rel-1.rel under lib. Also, we do not know where the release package will be installed, so we do not want any hardcoded absolute paths in the boot script here.

+

The release resource file mysystem.rel is duplicated in + the tar file. Originally, this file was only stored in + the releases directory in order to make it possible for + the release_handler to extract this file + separately. After unpacking the tar file, release_handler + would automatically copy the file + to releases/FIRST. However, sometimes the tar file is + unpacked without involving the release_handler (e.g. when + unpacking the first target system) and therefore the file is now + instead duplicated in the tar file so no manual copying is + necessary.

If a relup file and/or a system configuration file called sys.config is found, these files are included in the release package as well. See diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc index 1564423e00..bc2a76db47 100644 --- a/system/doc/system_principles/create_target.xmlsrc +++ b/system/doc/system_principles/create_target.xmlsrc @@ -44,9 +44,9 @@ may be irrelevant for the purpose in question. Thus, there is a need to be able to create a new system based on a given Erlang/OTP system, where dispensable applications are removed, - and a set of new applications that are included in the new - system. Documentation and source code is irrelevant and is - therefore not included in the new system.

+ and a set of new applications are included. Documentation and + source code is irrelevant and is therefore not included in the + new system.

This chapter is about creating such a system, which we call a target system.

In the following sections we consider creating target systems with @@ -63,10 +63,11 @@

We only consider the case when Erlang/OTP is running on a UNIX system.

-

There is an example Erlang module target_system.erl that - contains functions for creating and installing a target system. - That module is used in the examples below. The source code of - the module is listed at the end of this chapter.

+

In the sasl application there is an example Erlang + module target_system.erl that contains functions for + creating and installing a target system. This module is used in + the examples below, and the source code of the module is listed + at the end of this chapter.

@@ -117,28 +118,41 @@ os> erl -pa /home/user/target_system/myapps/pea-1.0/ebin erts-5.1/bin/ releases/FIRST/start.boot +releases/FIRST/mysystem.rel releases/mysystem.rel lib/kernel-2.7/ lib/stdlib-1.10/ lib/sasl-1.9.3/ lib/pea-1.0/

The file releases/FIRST/start.boot is a copy of our - mysystem.boot, and a copy of the original - mysystem.rel has been put in the releases - directory.

+ mysystem.boot

+

The release resource file mysystem.rel is duplicated + in the tar file. Originally, this file was only stored in + the releases directory in order to make it possible + for the release_handler to extract this file + separately. After unpacking the tar + file, release_handler would automatically copy the + file to releases/FIRST. However, sometimes the tar + file is unpacked without involving + the release_handler (e.g. when unpacking the first + target system) and therefore the file is now instead + duplicated in the tar file so no manual copying is + necessary.

Creates the temporary directory tmp and extracts the tar file mysystem.tar.gz into that directory. Deletes the erl and start files from - tmp/erts-5.1/bin. XXX Why. + tmp/erts-5.1/bin. These files will be created again from + source when installing the release. Creates the directory tmp/bin. - Copies the previously creates file plain.boot to + Copies the previously created file plain.boot to tmp/bin/start.boot. Copies the files epmd, run_erl, and to_erl from the directory tmp/erts-5.1/bin to the directory tmp/bin. - Creates the file tmp/releases/start_erl.data with the - contents "5.1 FIRST". + Creates the file tmp/releases/start_erl.data with + the contents "5.1 FIRST". This file is to be passed as data + file to the start_erl script. Recreates the file mysystem.tar.gz from the directories in the directory tmp, and removes tmp. @@ -210,7 +224,7 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI file of the release version found ("releases/FIRST/start.boot").

start_erl also assumes that there is sys.config in - release version directory ("releases/FIRST/sys.config). That + release version directory ("releases/FIRST/sys.config"). That is the topic of the next section (see below).

The start_erl shell script should normally not be altered by the user.

@@ -222,7 +236,7 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI sys.config in the release version directory ("releases/FIRST/sys.config"). If there is no such a file, the system start will fail. Hence such a file has to - added as well.

+ be added as well.

If you have system configuration data that are neither file location dependent nor site dependent, it may be convenient to @@ -245,252 +259,9 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI

Listing of target_system.erl - This module can also be found in the examples directory + of the sasl application.

+ -%% Note: RelFileName below is the *stem* without trailing .rel, -%% .script etc. -%% - -%% create(RelFileName) -%% -create(RelFileName) -> - RelFile = RelFileName ++ ".rel", - io:fwrite("Reading file: \"~s\" ...~n", [RelFile]), - {ok, [RelSpec]} = file:consult(RelFile), - io:fwrite("Creating file: \"~s\" from \"~s\" ...~n", - ["plain.rel", 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("plain.rel", [write]), - io:fwrite(Fd, "~p.~n", [PlainRelSpec]), - file:close(Fd), - - io:fwrite("Making \"plain.script\" and \"plain.boot\" files ...~n"), - make_script("plain"), - - io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n", - [RelFileName, RelFileName]), - make_script(RelFileName), - - TarFileName = io_lib:fwrite("~s.tar.gz", [RelFileName]), - io:fwrite("Creating tar file \"~s\" ...~n", [TarFileName]), - make_tar(RelFileName), - - io:fwrite("Creating directory \"tmp\" ...~n"), - file:make_dir("tmp"), - - io:fwrite("Extracting \"~s\" into directory \"tmp\" ...~n", [TarFileName]), - extract_tar(TarFileName, "tmp"), - - TmpBinDir = filename:join(["tmp", "bin"]), - ErtsBinDir = filename:join(["tmp", "erts-" ++ ErtsVsn, "bin"]), - io:fwrite("Deleting \"erl\" and \"start\" in directory \"~s\" ...~n", - [ErtsBinDir]), - file:delete(filename:join([ErtsBinDir, "erl"])), - file:delete(filename:join([ErtsBinDir, "start"])), - - io:fwrite("Creating temporary directory \"~s\" ...~n", [TmpBinDir]), - file:make_dir(TmpBinDir), - - io:fwrite("Copying file \"plain.boot\" to \"~s\" ...~n", - [filename:join([TmpBinDir, "start.boot"])]), - copy_file("plain.boot", filename:join([TmpBinDir, "start.boot"])), - - io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" - "\"~s\" to \"~s\" ...~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(["tmp", "releases", "start_erl.data"]), - io:fwrite("Creating \"~s\" ...~n", [StartErlDataFile]), - StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), - write_file(StartErlDataFile, StartErlData), - - io:fwrite("Recreating tar file \"~s\" from contents in directory " - "\"tmp\" ...~n", [TarFileName]), - {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), - {ok, Cwd} = file:get_cwd(), - file:set_cwd("tmp"), - erl_tar:add(Tar, "bin", []), - erl_tar:add(Tar, "erts-" ++ ErtsVsn, []), - erl_tar:add(Tar, "releases", []), - erl_tar:add(Tar, "lib", []), - erl_tar:close(Tar), - file:set_cwd(Cwd), - io:fwrite("Removing directory \"tmp\" ...~n"), - remove_dir_tree("tmp"), - ok. - - -install(RelFileName, RootDir) -> - TarFile = RelFileName ++ ".tar.gz", - io:fwrite("Extracting ~s ...~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) -%% -make_script(RelFileName) -> - Opts = [no_module_tests], - systools:make_script(RelFileName, Opts). - -%% make_tar(RelFileName) -%% -make_tar(RelFileName) -> - RootDir = code:root_dir(), - systools:make_tar(RelFileName, [{erts, RootDir}]). - -%% 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, InFd} = file:open(Src, [raw, binary, read]), - {ok, OutFd} = file:open(Dest, [raw, binary, write]), - do_copy_file(InFd, OutFd), - file:close(InFd), - file:close(OutFd), - case lists:member(preserve, Opts) of - true -> - {ok, FileInfo} = file:read_file_info(Src), - file:write_file_info(Dest, FileInfo); - false -> - ok - end. - -do_copy_file(InFd, OutFd) -> - case file:read(InFd, ?BUFSIZE) of - {ok, Bin} -> - file:write(OutFd, Bin), - do_copy_file(InFd, OutFd); - eof -> - 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]), - {ok, FileInfo} = file:read_file_info(FilePath), - case FileInfo#file_info.type of - directory -> - {ok, DirFiles} = file:list_dir(FilePath), - remove_all_files(FilePath, DirFiles), - file:del_dir(FilePath); - _ -> - file:delete(FilePath) - end - end, Files). - ]]>
-- cgit v1.2.3 From 2243001806a00b8ed37873fd0eb416d34a990833 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 2 Dec 2011 15:36:38 +0100 Subject: Add all valid report types in documentation of rb:list --- lib/sasl/doc/src/rb.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml index f35ceb5777..3da825878e 100644 --- a/lib/sasl/doc/src/rb.xml +++ b/lib/sasl/doc/src/rb.xml @@ -4,7 +4,7 @@
- 19962010 + 19962011 Ericsson AB. All Rights Reserved. @@ -123,7 +123,9 @@ List all reports Type = type() - type() = crash_report | supervisor_report | error | progress + type() = error | error_report | info_msg | info_report | + warning_msg | warning_report | crash_report | + supervisor_report | progress

This function lists all reports loaded in the -- cgit v1.2.3