Provided by: erlang-manpages_16.b.3-dfsg-1ubuntu2_all bug

NAME

       release_handler - Unpacking and Installation of Release Packages

DESCRIPTION

       The  release  handler  is a process belonging to the SASL application which is responsible
       for release handling, that is, unpacking, installation, and removal of release packages.

       An introduction to release handling and a usage example can be found in Design Principles.

       A release package is a compressed tar file containing code for  a  certain  version  of  a
       release, created by calling systools:make_tar/1,2. The release package should be placed in
       the $ROOT/releases directory of the previous version of the release  where  $ROOT  is  the
       installation  root directory, code:root_dir(). Another releases directory can be specified
       using the SASL configuration  parameter  releases_dir,  or  the  OS  environment  variable
       RELDIR.  The  release handler must have write access to this directory in order to install
       the new release. The persistent state of the release handler is stored  there  in  a  file
       called RELEASES.

       A  release  package  should  always  contain the release resource file Name.rel and a boot
       script Name.boot. It may contain a release upgrade file relup and a  system  configuration
       file  sys.config. The .rel file contains information about the release: its name, version,
       and which ERTS and application versions it uses. The relup file contains scripts  for  how
       to upgrade to, or downgrade from, this version of the release.

       The  release package can be unpacked, which extracts the files. An unpacked release can be
       installed. The currently used version of the release is then upgraded or 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.

       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  permanent  (normal
       case), or current (installed, but not yet made permanent). The following table illustrates
       the meaning of the status values:

       Status     Action                NextStatus
       -------------------------------------------
         -        unpack                unpacked
       unpacked   install               current
                  remove                  -
       current    make_permanent        permanent
                  install other         old
                  remove                  -
       permanent  make other permanent  old
                  install               permanent
       old        reboot_old            permanent
                  install               current
                  remove                  -

       The release handler process is a locally registered process on each node. When  a  release
       is installed in a distributed system, the release handler on each node must be called. The
       release installation may be synchronized between nodes. From an operator view, it  may  be
       unsatisfactory  to  specify  each  node.  The aim is to install one release package in the
       system, no matter how many nodes there are. If this is the case, it  is  recommended  that
       software management functions are written which take care of this problem. Such a function
       may have knowledge of the system architecture, so it can contact each  individual  release
       handler to install the package.

       For  release  handling  to work properly, the runtime system needs to have knowledge about
       which release it is currently running. It must also be able to change (in run-time)  which
       boot  script and system configuration file should be used if the system is 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.

       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 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 automatic and the old service removed as soon as the new release is
       made permanent.

       The  release  handler at a node which runs on a diskless machine, or with a read-only file
       system, must be configured accordingly using the following sasl  configuration  parameters
       (see sasl(7) for details):

         masters:
           This  node  uses  a  number  of  master  nodes  in  order  to  store and fetch release
           information. All master nodes must be up and running whenever release  information  is
           written by this node.

         client_directory:
           The client_directory in the directory structure of the master nodes must be specified.

         static_emulator:
           This  parameter specifies if the Erlang emulator is statically installed at the client
           node. A node with a static emulator  cannot  dynamically  switch  to  a  new  emulator
           because the executable files are statically written into memory.

       It is also possible to use the release handler to unpack and install release packages when
       not running Erlang as an embedded system, but in this case the user must somehow make sure
       that  correct  boot  scripts  and  configuration  files are used if the system needs to be
       restarted.

       There are additional functions for using another file structure than the structure defined
       in OTP. These functions can be used to test a release upgrade locally.

EXPORTS

       check_install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}
       check_install_release(Vsn,Opts) -> {ok, OtherVsn, Descr} | {error, Reason}

              Types:

                 Vsn = OtherVsn = string()
                 Opts = [Opt]
                 Opt = purge
                 Descr = term()
                 Reason = term()

              Checks  if  the  specified version Vsn of the release can be installed. The release
              must not have status current. Issues  warnings  if  relup  or  sys.config  are  not
              present.  If  relup  is  present,  its  contents  are checked and {error,Reason} is
              returned if an error is found. Also  checks  that  all  required  applications  are
              present and that all new code can be loaded, or {error,Reason} is returned.

              This  function  evaluates all instructions that occur before the point_of_no_return
              instruction in the release upgrade script.

              Returns the same as install_release/1. Descr defaults to "" if  no  relup  file  is
              found.

              If  the  option purge is given, all old code that can be soft purged will be purged
              after all other checks are successfully completed. This can be useful in  order  to
              reduce the time needed by install_release.

       create_RELEASES(Root, RelDir, RelFile, AppDirs) -> ok | {error, Reason}

              Types:

                 Root = RelDir = RelFile = string()
                 AppDirs = [{App, Vsn, Dir}]
                  App = atom()
                  Vsn = Dir = string()
                 Reason = term()

              Creates  an initial RELEASES file to be used by the release handler. This file must
              exist in order to install new releases.

              Root is the root of the installation ($ROOT) as described above. RelDir is the  the
              directory  where  the  RELEASES  file  should be created (normally $ROOT/releases).
              RelFile is the name of the .rel file that describes the initial release,  including
              the extension .rel.

              AppDirs  can  be  used  to  specify  from  where  the  modules  for  the  specified
              applications should be loaded. App is the  name  of  an  application,  Vsn  is  the
              version,  and  Dir  is  the  name  of  the  directory where App-Vsn is located. The
              corresponding modules should be located under Dir/App-Vsn/ebin. The directories for
              applications not specified in AppDirs are assumed to be located in $ROOT/lib.

       install_file(Vsn, File) -> ok | {error, Reason}

              Types:

                 Vsn = File = string()
                 Reason = term()

              Installs  a  release  dependent  file in the release structure. A release dependent
              file is a file that must be  in  the  release  structure  when  a  new  release  is
              installed: start.boot, relup and sys.config.

              The  function  can  be  called,  for example, when these files are generated at the
              target. It should be called after set_unpacked/2 has been called.

       install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}
       install_release(Vsn, [Opt]) -> {ok, OtherVsn, Descr} | {continue_after_restart,  OtherVsn,
       Descr} | {error, Reason}

              Types:

                 Vsn = OtherVsn = string()
                 Opt = {error_action, Action} | {code_change_timeout, Timeout}
                  | {suspend_timeout, Timeout} | {update_paths, Bool}
                  Action = restart | reboot
                  Timeout = default | infinity | int()>0
                  Bool = boolean()
                 Descr = term()
                 Reason  =  {illegal_option, Opt} | {already_installed, Vsn} | {change_appl_data,
                 term()} | {missing_base_app,  OtherVsn,  App}  |  {could_not_create_hybrid_boot,
                 term()} | term()
                 App = atom()

              Installs the specified version Vsn of the release. Looks first for a relup file for
              Vsn and a script {UpFromVsn,Descr1,Instructions1} in this file for  upgrading  from
              the  current  version.  If  not  found, the function looks for a relup file for the
              current  version  and  a  script  {Vsn,Descr2,Instructions2}  in  this   file   for
              downgrading to Vsn.

              If  a  script  is  found,  the  first  thing  that happens is that the applications
              specifications are updated according to the .app files and sys.config belonging  to
              the release version Vsn.

              After  the  application  specifications  have been updated, the instructions in the
              script are evaluated and the function returns  {ok,OtherVsn,Descr}  if  successful.
              OtherVsn  and  Descr  are the version (UpFromVsn or Vsn) and description (Descr1 or
              Descr2) as specified in the script.

              If {continue_after_restart,OtherVsn,Descr} is returned, it means that the  emulator
              will be restarted before the upgrade instructions are executed. This will happen if
              the emulator or any of the applications kernel, stdlib or sasl are updated. The new
              version of the emulator and these core applications will execute after the restart,
              but for all other applications the old versions will be  started  and  the  upgrade
              will be performed as normal by executing the upgrade instructions.

              If a recoverable error occurs, the function returns {error,Reason} and the original
              application specifications are restored. If a  non-recoverable  error  occurs,  the
              system is restarted.

              The option error_action defines if the node should be restarted (init:restart()) or
              rebooted (init:reboot()) in case of an error during the  installation.  Default  is
              restart.

              The   option   code_change_timeout   defines   the   timeout   for   all  calls  to
              sys:change_code. If no value is specified or default is given,  the  default  value
              defined in sys is used.

              The  option suspend_timeout defines the timeout for all calls to sys:suspend. If no
              value is specified, the values defined by the Timeout parameter of the  upgrade  or
              suspend  instructions  are used. If default is specified, the default value defined
              in sys is used.

              The option {update_paths,Bool} indicates if all application code  paths  should  be
              updated  (Bool==true),  or  if  only code paths for modified applications should be
              updated (Bool==false, default). This option only has effect for  other  application
              directories  than  the  default $ROOT/lib/App-Vsn, that is, application directories
              provided in the AppDirs argument in a call to create_RELEASES/4 or set_unpacked/2.

              Example: In the current version CurVsn of a release, the application  directory  of
              myapp  is $ROOT/lib/myapp-1.0. A new version NewVsn is unpacked outside the release
              handler, and the release handler is informed about this with a call to:

              release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
              => {ok,NewVsn}

              If  NewVsn  is  installed   with   the   option   {update_paths,true},   afterwards
              code:lib_dir(myapp) will return /home/user/myapp-1.0.

          Note:
              Installing  a new release might be quite time consuming if there are many processes
              in the system. The reason is that each process must be checked  for  references  to
              old  code  before  a  module  can  be  purged.  This  check  might  lead to garbage
              collections and copying of data.

              If you wish to speed up  the  execution  of  install_release,  then  you  may  call
              check_install_release  first,  using  the option purge. This will do the same check
              for old code, and then purge all modules  that  can  be  soft  purged.  The  purged
              modules will then no longer have any old code, and install_release will not need to
              do the checks.

              Obviously, this will not reduce the overall time for the upgrade, but it will allow
              checks  and  purge  to  be  executed  in  the background before the real upgrade is
              started.

          Note:
              When upgrading the emulator from a version older than OTP R15,  there  will  be  an
              attempt to load new application beam code into the old emulator. In some cases, the
              new beam format can not be read by the old emulator, and so the code  loading  will
              fail  and  terminate  the  complete  upgrade.  To  overcome  this  problem, the new
              application code should be compiled with the old emulator.  See  Design  Principles
              for more information about emulator upgrade from pre OTP R15 versions.

       make_permanent(Vsn) -> ok | {error, Reason}

              Types:

                 Vsn = string()
                 Reason = {bad_status, Status} | term()

              Makes the specified version Vsn of the release permanent.

       remove_release(Vsn) -> ok | {error, Reason}

              Types:

                 Vsn = string()
                 Reason = {permanent, Vsn} | client_node | term()

              Removes  a  release  and  its  files  from  the system. The release must not be the
              permanent release. Removes only the files and directories not  in  use  by  another
              release.

       reboot_old_release(Vsn) -> ok | {error, Reason}

              Types:

                 Vsn = string()
                 Reason = {bad_status, Status} | term()

              Reboots  the  system  by  making the old release permanent, and calls init:reboot()
              directly. The release must have status old.

       set_removed(Vsn) -> ok | {error, Reason}

              Types:

                 Vsn = string()
                 Reason = {permanent, Vsn} | term()

              Makes it possible to handle removal of releases outside the release handler.  Tells
              the release handler that the release is removed from the system. This function does
              not delete any files.

       set_unpacked(RelFile, AppDirs) -> {ok, Vsn} | {error, Reason}

              Types:

                 RelFile = string()
                 AppDirs = [{App, Vsn, Dir}]
                  App = atom()
                  Vsn = Dir = string()
                 Reason = term()

              Makes it possible to handle unpacking of  releases  outside  the  release  handler.
              Tells  the  release handler that the release is unpacked. Vsn is extracted from the
              release resource file RelFile.

              AppDirs  can  be  used  to  specify  from  where  the  modules  for  the  specified
              applications  should  be  loaded.  App  is  the  name of an application, Vsn is the
              version, and Dir is the name  of  the  directory  where  App-Vsn  is  located.  The
              corresponding modules should be located under Dir/App-Vsn/ebin. The directories for
              applications not specified in AppDirs are assumed to be located in $ROOT/lib.

       unpack_release(Name) -> {ok, Vsn} | {error, Reason}

              Types:

                 Name = Vsn = string()
                 Reason = client_node | term()

              Unpacks a release package Name.tar.gz located in the releases directory.

              Performs some checks on the package - for example checks that all  mandatory  files
              are present - and extracts its contents.

       which_releases() -> [{Name, Vsn, Apps, Status}]

              Types:

                 Name = Vsn = string()
                 Apps = ["App-Vsn"]
                 Status = unpacked | current | permanent | old

              Returns all releases known to the release handler.

       which_releases(Status) -> [{Name, Vsn, Apps, Status}]

              Types:

                 Name = Vsn = string()
                 Apps = ["App-Vsn"]
                 Status = unpacked | current | permanent | old

              Returns all releases known to the release handler of a specific status.

APPLICATION UPGRADE/DOWNGRADE

       The  following  functions can be used to test upgrade and downgrade of single applications
       (instead of upgrading/downgrading an entire release). A script corresponding to  relup  is
       created on-the-fly, based on the .appup file for the application, and evaluated exactly in
       the same way as release_handler does.

   Warning:
       These functions are primarily intended for simplified testing of .appup  files.  They  are
       not run within the context of the release_handler process. They must therefore not be used
       together with calls to install_release/1,2, as this will cause 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 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.

EXPORTS

       upgrade_app(App, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}

              Types:

                 App = atom()
                 Dir = string()
                 Unpurged = [Module]
                  Module = atom()
                 Reason = term()

              Upgrades  an  application  App from the current version to a new version located in
              Dir according to the .appup script.

              App is the name of the application, which must be started. Dir is the  new  library
              directory  of  App,  the corresponding modules as well as the .app and .appup files
              should be located under Dir/ebin.

              The function looks in the .appup file and tries to find an upgrade script from  the
              current version of the application using upgrade_script/2. This script is evaluated
              using eval_appup_script/4, exactly in the same way as install_release/1,2 does.

              Returns {ok, Unpurged} if evaluating the script is successful, where Unpurged is  a
              list of unpurged modules, or restart_emulator if this instruction is encountered in
              the script, or {error, Reason} if an error occurred when finding or evaluating  the
              script.

              If  the restart_new_emulator instruction is found in the script, upgrade_app/2 will
              return {error,restart_new_emulator}. The reason for this is that  this  instruction
              requires  that  a  new  version  of  the emulator is started before the rest of the
              upgrade  instructions  can  be  executed,  and   this   can   only   be   done   by
              install_release/1,2.

       downgrade_app(App, Dir) ->
       downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}

              Types:

                 App = atom()
                 Dir = OldVsn = string()
                 Unpurged = [Module]
                  Module = atom()
                 Reason = term()

              Downgrades an application App from the current version to a previous version OldVsn
              located in Dir according to the .appup script.

              App is the name of the application, which must be started. OldVsn is  the  previous
              version of the application and can be omitted if Dir is of the format "App-OldVsn".
              Dir is the library directory of this previous version  of  App,  the  corresponding
              modules  as  well as the old .app file should be located under Dir/ebin. The .appup
              file should be located in the ebin directory of the current  library  directory  of
              the application (code:lib_dir(App)).

              The  function looks in the .appup file and tries to find an downgrade script to the
              previous version of  the  application  using  downgrade_script/3.  This  script  is
              evaluated using eval_appup_script/4, exactly in the same way as install_release/1,2
              does.

              Returns {ok, Unpurged} if evaluating the script is successful, where Unpurged is  a
              list of unpurged modules, or restart_emulator if this instruction is encountered in
              the script, or {error, Reason} if an error occurred when finding or evaluating  the
              script.

       upgrade_script(App, Dir) -> {ok, NewVsn, Script}

              Types:

                 App = atom()
                 Dir = string()
                 NewVsn = string()
                 Script = Instructions -- see appup(5)

              Tries  to  find an application upgrade script for App from the current version to a
              new version located in Dir.

              The  upgrade  script  can  then  be  evaluated  using  eval_appup_script/4.  It  is
              recommended  to  use upgrade_app/2 instead, but this function is useful in order to
              inspect the contents of the script.

              App is the name of the application, which must be started. Dir is the  new  library
              directory  of  App,  the corresponding modules as well as the .app and .appup files
              should be located under Dir/ebin.

              The function looks in the .appup file and tries to find an upgrade script from  the
              current  version of the application. High-level instructions are translated to low-
              level instructions and the instructions are sorted  in  the  same  manner  as  when
              generating a relup script.

              Returns  {ok,  NewVsn,  Script}  if successful, where NewVsn is the new application
              version.

              Failure: If a script cannot be found, the function fails with an appropriate  error
              reason.

       downgrade_script(App, OldVsn, Dir) -> {ok, Script}

              Types:

                 App = atom()
                 OldVsn = Dir = string()
                 Script = Instructions -- see appup(5)

              Tries to find an application downgrade script for App from the current version to a
              previous version OldVsn located in Dir.

              The downgrade script  can  then  be  evaluated  using  eval_appup_script/4.  It  is
              recommended  to use downgrade_app/2,3 instead, but this function is useful in order
              to inspect the contents of the script.

              App is the name of the application, which must be  started.  Dir  is  the  previous
              library  directory  of  App, the corresponding modules as well as the old .app file
              should be located under Dir/ebin. The .appup file should be  located  in  the  ebin
              directory of the current library directory of the application (code:lib_dir(App)).

              The  function  looks  in the .appup file and tries to find an downgrade script from
              the current version of the application. High-level instructions are  translated  to
              low-level  instructions  and the instructions are sorted in the same manner as when
              generating a relup script.

              Returns {ok, Script} if successful.

              Failure: If a script cannot be found, the function fails with an appropriate  error
              reason.

       eval_appup_script(App,  ToVsn,  ToDir,  Script)  ->  {ok,  Unpurged}  | restart_emulator |
       {error, Reason}

              Types:

                 App = atom()
                 ToVsn = ToDir = string()
                 Script -- see upgrade_script/2, downgrade_script/3
                 Unpurged = [Module]
                  Module = atom()
                 Reason = term()

              Evaluates an application upgrade  or  downgrade  script  Script,  the  result  from
              calling  upgrade_script/2  or  downgrade_script/3,  exactly  in  the  same  way  as
              install_release/1,2 does.

              App is the name of the application, which must be started. ToVsn is the version  to
              be  upgraded/downgraded to, and ToDir is the library directory of this version. The
              corresponding modules as well as the .app and .appup files should be located  under
              Dir/ebin.

              Returns  {ok, Unpurged} if evaluating the script is successful, where Unpurged is a
              list of unpurged modules, or restart_emulator if this instruction is encountered in
              the script, or {error, Reason} if an error occurred when evaluating the script.

              If the restart_new_emulator instruction is found in the script, eval_appup_script/4
              will  return  {error,restart_new_emulator}.  The  reason  for  this  is  that  this
              instruction  requires that a new version of the emulator is started before the rest
              of the upgrade instructions  can  be  executed,  and  this  can  only  be  done  by
              install_release/1,2.

TYPICAL ERROR REASONS

         * {bad_masters, Masters} - The master nodes Masters are not alive.

         * {bad_rel_file, File} - Specified .rel file File can not be read, or does not contain a
           single term.

         * {bad_rel_data, Data} - Specified .rel file  does  not  contain  a  recognized  release
           specification, but another term Data.

         * {bad_relup_file, File} - Specified relup file Relup contains bad data.

         * {cannot_extract_file,  Name,  Reason}  -  Problems  when  extracting  from a tar file,
           erl_tar:extract/2 returned {error, {Name, Reason}}.

         * {existing_release, Vsn} - Specified release version Vsn is already in use.

         * {Master, Reason, When} - Some operation, indicated by the term  When,  failed  on  the
           master node Master with the specified error reason Reason.

         * {no_matching_relup, Vsn, CurrentVsn} - Cannot find a script for up/downgrading between
           CurrentVsn and Vsn.

         * {no_such_directory, Path} - The directory Path does not exist.

         * {no_such_file, Path} - The path Path (file or directory) does not exist.

         * {no_such_file, {Master, Path}} - The path Path (file or directory) does not  exist  at
           the master node Master.

         * {no_such_release, Vsn} - The specified version Vsn of the release does not exist.

         * {not_a_directory, Path} - Path exists, but is not a directory.

         * {Posix,  File}  - Some file operation failed for File. Posix is an atom named from the
           Posix error codes, such as enoent, eacces or eisdir. See file(3erl).

         * Posix - Some file operation failed, as above.

SEE ALSO

       OTP Design Principles, config(5), relup(5), rel(5), script(5), sys(3erl), systools(3erl)