[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

Every module in the system has a version number. An Erlang module should start:

-module(Mod).
-vsn(Vsn).
...
    

This module should be stored in a file named 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.

Applications also 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.

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. The .appup file looks as follows:

{Vsn,
    [{UpFromVsn, UpFromScript}, ...],
    [{DownToVsn, DownToScript}, ...]
}.
    

In the case of UpFrom Script 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 ReleaseName.rel which describes the ReleaseName release looks as follows:

{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 has been automated and in most cases the file can 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 and upgrade files and they generate a boot script, a release upgrade script, and build a release package.

The following functions exists in the systools module:

These functions read the .rel release resource file from the current directory and performs 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.

There is no requirement for applications 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 variables are introduced to the system through the systools module.

3.3.1 Diskless and/or Read-Only Clients

If a complete system consists of some diskless and/or read-only client nodes, a clients directory should be added to the $ROOTDIR directory. With 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 looks as follows:

$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. Altlernatively, 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 first application can be described in an application resource file 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 Erlang Development Environment User Guide, Chapter 3: Design Principles, section Applications for a more detailed description of the content in 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 application callback module for the 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.

stdlib version "6" looks as follows:

{application, stdlib,
 [{vsn, "6"},
  {modules,
   [{lists,2},
    {dict,4},
    {ordsets, 7}]},
  {applications,
   []},
 ]}.
    

Note!

stdlib is a "code only" application and has no callback module.

Finally, kernel version "2" looks as follows:

{application, kernel,
 [{vsn, "2"},
  {modules,
   [{net_kernel, 3},
    {auth, 3},
    {rcp, 5}]},
  {applications,
   [stdlib]},
  {mod,
   {net_kernel,[]}}]}.
    

We can now 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("test")
      

This command 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. This is easy because each module only belongs to one application.

If there were no errors, a start script called test.script and a boot file called test.boot are created. The script first loads all the modules to be used and then starts and loads all the applications in the order given in the release description file. This file may be re-ordered if other dependencies were found among the applications.

All required application resource files and all required Erlang files must be located somewhere within the current code path.

If this succeeds, then the command erl -boot test can be issued. This command actually starts the system.

3.4.2 Changing an Application

Suppose now that we make a change to snmp which results in new versions of snmp_map and snmp_stuff. This can be described as follows:

{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 as follows:

{release,
 {"test","6"},
 {erts, "4.4"},
 [{kernel, "2"},
  {stdlib, "6"},
  {snmp, "11"}
 ]}.
      

The .appup file for the snmp application should be:

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

In this file, we state that the snmp application can be upgraded by changing code on the snmp_map and snmp_stuff modules. We also state that the snmp application can be downgraded by changing the same two modules.

We can now compile a new script file named test2 as before:

systools:make_script("test2")
      

A relup file is generated by evaluating:

systools:make_relup("test2", ["test"], ["test"]).
      

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 this by evaluating

systools:make_tar("test2").
      

This creates a release package file, named test2.tar.gz. This release package file may be installed in a target system by using the release_handler.


Copyright © 1991-98 Ericsson Telecom AB