Erlang programs are organized into modules. Each module in a release must have a unique name.
Collections of modules which cooperate to solve a particular problem are organized into applications. Applications are described in an application resource file.
Collections of applications are organized into a release. Releases are described in a release resource file.
Each module in the system has a version number. An Erlang module should start with
-module(Mod). -vsn(Vsn). ...
and should be stored in a file named as Mod.erl
.
The name of the module is Mod
and the version of the
module is Vsn
. Mod
must be an atom while Vsn
can be any valid Erlang term. For example, the version can be an
integer or a string, which represents an Ericsson product number.
Also the applications have versions, but the version must be a
string. For example, the application resource file for the
application named snmp
must be stored in a file named
snmp.app
and must start:
{application, snmp, [{vsn, Va}, {modules, [{lists, V1}, {ordsets, V2} ...
Here, Va
is the version of the application (a
string). The application uses the Erlang module versions V1,
V2, ...
, where V1, V2, ...
can be any valid Erlang
terms. The only requirement is that the module version types
(integers, strings, etc.) agrees with the convention used in the
module declarations.
![]() |
In the application resource file, the name of a module must
be specified in {application, snmp, [{vsn, Va}, {modules, [lists, ordsets, ... |
Applications can be upgraded and the instructions to do this
are placed in the .appup
file for the application. For
example, for the snmp
application these instructions are
placed in the snmp.appup
file. An .appup
file contains
the following:
{Vsn, [{UpFromVsn, UpFromScript}, ...], [{DownToVsn, DownToScript}, ...] }.
Vsn
is the version of the application
UpFromVsn
is a version we can upgrade from
UpFromScript
is the script which describes the
sequence of release upgrade instructions. Refer to the section
Release Handling Instructions
DownToVsn
is a version to which we can downgrade
DownToScript
is the script which describes the
sequence of downgrade instructions.
In the case of UpFromScript
and DownFromScript
,
the scripts typically contain one line for each module in the
application.
A release resource file has a structure similar to an
application resource file. The file ReleaseFileName.rel
, which
describes the release contains the following:
{release, {Name,Vsn}, {erts, EVsn}, [{AppName, AppVsn}, {AppName, AppVsn, AppType}, {AppName, AppVsn, IncApps}, {AppName, AppVsn, AppType, IncApps} ...]}.
Name
is the name of the release (a
string). Name
needs not to be the same as ReleaseFileName
above.
Vsn
is the version of the release (a string).
{erts, EVsn}
indicates which Erlang runtime system
version EVsn
the release is intended for, for example
"4.4". EVsn
must be a string.
AppName
is the name of an application included in
the release (an atom).
AppVsn
is the version of the AppName
application (a string).
application:start(AppName, AppType)
, if the
AppType
is permanent
,
transient
or temporary
. If AppType
is
load
the application is loaded but not started, and if it is
none
the application is neither loaded or started.
IncApps
is a list of applications that are included
by an application, for example [AppName, ...]
. This
list overrides the included_applications
key in the
application resource file .app
. It must be a
subset of the list of included applications which are
specified in the .app
file.
![]() |
The list of applications must contain the |
Releases can also be upgraded and instructions for this should
be written in the relup
file (see the definition of
the relup
file). The tedious work of writing the relup
file is
automated and in most cases, the file will be automatically
generated from the .appup
files for the applications in the
release.
There are tools available to build and check release packages. These tools read the release resource file, the application resource files and upgrade files, and they generate a boot script, a release upgrade script, and also build a release package.
The following functions are in the systools
module:
make_script
generates a boot script
make_relup
generates a release upgrade script
make_tar
generates a release package .tar
file .
These functions read the .rel
release resource file from
the current directory and perform syntax and dependency checks
before the output is generated.
![]() |
The generated files are written to the current directory as well. |
Refer to the Reference Manual for more information about these functions.
A release should be divided into the following directories:
$ROOTDIR/lib/App1-AVsn1/ebin /priv /App2-AVsn2/ebin /priv ... /AppN-AVsnN/ebin /priv /erts-EVsn/bin /releases/Vsn /bin
The release resource file includes one AppN-AVsnN
directory per application. AppN
is the name and
AVsnN
is the version of the application.
ebin
directory contains the Erlang object code
and the application resource file.
priv
directory contains any application private
data. Specifically, port programs should be located in the
priv
directory. The priv
directory of an application
is found by a call to code:priv_dir(AppName)
.
releases/Vsn
directory. Vsn
is the release
version found in the release resource file.
erts-EVsn/bin
directory.
releases
directory should also contain the
ReleaseFileName.rel
files, and new release packages are
installed here.
bin
directory contains the top level Erlang
executable program erl
.
Applications are not required to be located under the
$ROOTDIR/lib
directory. Accordingly, several installation
directories may exist which contain different parts of a
system. For example, the previous example could be extended as
follows:
$SECOND_ROOT/.../SApp1-SAVsn1/ebin /priv /SApp2-SAVsn2/ebin /priv ... /SAppN-SAVsnN/ebin /priv $THIRD_ROOT/TApp1-TAVsn1/ebin /priv /TApp2-TAVsn2/ebin /priv ... /TAppN-TAVsnN/ebin /priv
The $SECOND_ROOT
and $THIRD_ROOT
are introduced
as variables
in the call to the
systools:make_script/2
function.
If a complete system consists of some disk-less and/or
read-only client nodes, a clients
directory should be
added to the $ROOTDIR
directory. By a read-only node we
mean a node with a read-only file system.
The clients
directory should have one sub-directory
per supported client node. The name of each client directory
should be the name of the corresponding client node. As a
minimum, each client directory should contain the bin
and
releases
sub-directories. These directories are used to
store information about installed releases and to appoint the
current release to the client. Accordingly, the $ROOTDIR
directory contains the following:
$ROOTDIR/... /clients/ClientName1/bin /releases/Vsn /ClientName2/bin /releases/Vsn ... /ClientNameN/bin /releases/Vsn
This structure should be used if all clients are running the
same type of Erlang machine. If there are clients running
different types of Erlang machines, or on different operating
systems, the clients
directory could be divided into one
sub-directory per type of Erlang machine. Alternatively, you
can set up one ROOTDIR
per type of machine. For each
type, some of the directories specified for the ROOTDIR
directory should be included:
$ROOTDIR/... /clients/Type1/lib /erts-EVsn /bin /ClientName1/bin /releases/Vsn /ClientName2/bin /releases/Vsn ... /ClientNameN/bin /releases/Vsn ... /TypeN/lib /erts-EVsn /bin ...
With this structure, the root directory for clients of
Type1
is $ROOTDIR/clients/Type1
.
Suppose we have a system called "test", which consists of the
three applications: snmp
, kernel
and
stdlib
. The snmp
application is described in the
application resource file snmp.app
as follows:
{application, snmp, [{vsn, "10"}, {modules, [{snmp_table, 2}, {snmp_map, 3}, {snmp_stuff,5}]}, {applications, [stdlib, kernel]}, {mod, {snmp_stuff, [12,34]}} ]}.
![]() |
The resource file shown contains only a sub-set of the information available in the actual resource files. Refer to the Design Principles chapter, section Applications for a more detailed description of the contents of an application resource file. |
In the example shown, version "10" of snmp
uses version
2 of snmp_table
, version 3 of snmp_map
an so on. It
requires that stdlib
and kernel
are started before
this application is started. It is started by evaluating the
function snmp_stuff:start(normal,
[12,34])
. snmp_stuff
is the SNMP application call-back module
for the application complying with the behavior application
.
![]() |
We have used integer version numbers written as strings for the application version. In our further discussion we will simplify things by using integer version numbers. We will also assume that version N+1 is the successor of version N of a system component. |
The application resource file stdlib.app
for
stdlib
version "6" contains the following:
{application, stdlib, [{vsn, "6"}, {modules, [{lists,2}, {dict,4}, {ordsets, 7}]}, {applications, []}, ]}.
![]() |
|
Finally, the kernel.app
file of the kernel
application version "2" contains the following:
{application, kernel, [{vsn, "2"}, {modules, [{net_kernel, 3}, {auth, 3}, {rcp, 5}]}, {applications, [stdlib]}, {mod, {net_kernel,[]}} ]}.
We can now in the test1.rel
file define release "5" of
the "test" release in terms of these applications:
{release, {"test", "5"}, {erts, "4.4"}, [{kernel, "2"}, {stdlib, "6"}, {snmp, "10"} ]}.
![]() |
This means that release "5" of the "test" system is built
from |
In the example shown, we have defined enough to be able to generate a system. We now have to generate a start script off-line which will be used when the system is loaded. We evaluate:
systools:make_script("test1")
where test1
refers to the test1.rel
file.
This command reads the test1.rel
file and checks that
all applications required for the release can be found and that
all the modules which are required can be located and have the
correct version numbers.
All required application resource files and all required
Erlang files must be located somewhere within the current code
path, {path, Path}
.
If there were no errors, a start script called
test1.script
and a boot file called test1.boot
are created. The latter is a binary version of the former, and
is used when starting the system (e.g. by issuing the command
erl -boot test1
).
Suppose now that we make a change to snmp
which
results in new versions of the modules snmp_map
and
snmp_stuff
. This is specified as follows in a new
version of snmp.app
:
{application, snmp, [{vsn,"11"}, {modules, [{snmp_table, 2}, {snmp_map, 4}, {snmp_stuff,6}]}, {applications, [stdlib, kernel]}, {mod, {snmp_stuff, [12,34]}} ]}.
![]() |
We have changed the two modules |
We can now define a new release of the system in the file
test2.rel
as follows:
{release, {"test","6"}, {erts, "4.4"}, [{kernel, "2"}, {stdlib, "6"}, {snmp, "11"} ]}.
As before we generate the test2.script
and test2.boot
file by calling
systools:make_script("test2").
So far we have version "5" and "6" of the "test" release
defined in the test1.rel
and test2.rel
files,
and the generated script and boot files test1.script
,
test1.boot
, test2.script
, and test2.boot
.
In our example two versions of the "test" release only differ
in the contents of the snmp
application. In order to
be able to update from version "5" to version "6" of the
"test" release, we have to provide a specification of the
upgrade of the snmp
application in the form of an
application upgrade file snmp.appup
.
The contents of the snmp.appup
file is as follows:
{"11", [{"10", [{update, snmp_map, soft, soft_purge, soft_purge, []}, {update, snmp_stuff, soft, soft_purge, soft_purge, []}]}], [{"10", [{update, snmp_map, soft, soft_purge, soft_purge, []}, {update, snmp_stuff, soft, soft_purge, soft_purge, []}]}] }.
The snmp
application is upgraded by changing code for
the snmp_map
and snmp_stuff
modules. It is downgraded
by changing code for the same two modules.
Since only the snmp
application was changed between
version "5" and version "6" of the "test" release, no
.appup
files are needed for the other applications.
In order to finish the specification of the upgrade of the
complete "test" release, a release upgrade file, relup
,
has to be created (relup
is not a file suffix; the
complete name of the file is relup
). The relup
file is created by evaluating:
systools:make_relup("test2", ["test1"], ["test1"]).
Here the first argument is name of the .rel
file we
upgrade to or downgrade from. The second and third arguments
are lists of .rel
files, specifying releases to upgrade
from, and downgrade to, respectively.
A relup
file contains low-level code change instructions
for the whole release, based on all application .appup
files.
Next, we want to generate a release package which can be
installed in the target system. After evaluating
make_script/1
and make_relup/3
as described above,
we do it by evaluating
systools:make_tar("test2").
A release package file, named test2.tar.gz
is generated.
The release package file may be installed
in a target system by using the
release_handler.
In this example, the release package file will contain all
applications of version "6" of the "test" release, and also
a releases
directory with the following contents:
$ROOTDIR/releases/test2.rel /6/relup /start.boot
where start.boot
is a copy of the original
test2.boot
.