[Erlang Systems]

3 The Release Structure

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.

3.1 Naming of Modules, Applications and Releases

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},
      {orddsets, 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.

Note!

In the application resource file, the name of a module must be specified in modules, but the version number is not a mandatory requirement. Hence the following is also valid contents for an application resource file:

{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}, ...]
}.
    

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} ...]}.
    

Note!

The list of applications must contain the kernel and the stdlib applications.

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.

3.2 Release Tools

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:

These functions read the .rel release resource file from the current directory and perform syntax and dependency checks before the output is generated.

Note!

The generated files are written to the current directory as well.

Refer to the Reference Manual for more information about these functions.

3.3 Release Directories

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.

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.

3.3.1 Disk-less and/or Read-Only Clients

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.

3.4 Example

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]}}
 ]}.
    

Note!

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.

Note!

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,
   []},
 ]}.
    

Note!

stdlib is a "code only" application and has no call-back module.

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"}
 ]}.
    

Note!

This means that release "5" of the "test" system is built from kernel version "2", stdlib version "6". The release requires the Erlang runtime system "4.4".

3.4.1 Making the Start Script

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).

3.4.2 Changing an Application

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]}}
 ]}.
      

Note!

We have changed the two modules snmp_map and snmp_stuff. Everything else remains the same.

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.

3.4.3 Making a Release Package

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.


Copyright © 1991-2000 Ericsson Utvecklings AB