systools(3)
π systools(3) β Erlang Module Definition π
okay so this is literally the release-handling toolkit of Erlang, and it is giving main character energy. π We're in part 1, bestie β more is coming, so no sign-off yet. π
β¨ NAME β¨
systools β A Set of Release Handling Tools
πΈ DESCRIPTION πΈ
This module contains functions to generate boot scripts (.boot, .script), a release upgrade file (relup), and release packages. π¦
π See Also π
app(4), appup(4), erl(1), rel(4), release_handler, relup(4), script(4)
π₯ FUNCTIONS π₯
π
make_relup(Name, UpFrom, DownTo, [Opt]) -> Result π
make_relup(Name, UpFrom, DownTo, [Opt]) -> Result
when
Name :: string(),
UpFrom :: [Name | {Name, Descr}],
DownTo :: [Name | {Name, Descr}],
Descr :: term(),
Opt ::
{path, [Dir]} |
restart_emulator | silent | noexec |
{outdir, Dir} |
warnings_as_errors,
Dir :: string(),
Result ::
ok | error |
{ok, Relup :: term(), Module, Warnings} |
{error, Module, Error},
Module :: atom(),
Warnings :: term(),
Error :: term().
Slay, so what does make_relup actually do? It generates a release upgrade file relup containing instructions for upgrading from or downgrading to one or more previous releases. β¨
The instructions are used by release_handler when installing a new version of a release in runtime. It's giving runtime glow-up/downgrade instructions, no cap.
By default, the relup file is located in the current working directory. If option {outdir,Dir} is specified, the relup file is located in directory Dir instead.
The release resource file Name.rel is compared with all release resource files Name2.rel, specified in UpFrom and DownTo. For each such pair, the following is deducted:
- Which applications to be deleted, that is, applications listed in
Name.relbut not inName2.rel - Which applications to be added, that is, applications listed in
Name2.relbut not inName.rel - Which applications to be upgraded/downgraded, that is, applications listed in both
Name.relandName2.relbut with different versions - If the emulator needs to be restarted after upgrading or downgrading, that is, if the ERTS version differs between
Name.relandName2.rel
Instructions for this are added to the relup file in the above order. Instructions for upgrading or downgrading between application versions are fetched from the relevant application upgrade files App.appup, sorted in the same order as when generating a boot script, see make_script/1,2. High-level instructions are translated into low-level instructions and the result is printed to the relup file.
The optional Descr parameter is included "as is" in the relup file, see relup(4). Defaults to the empty list.
All the files are searched for in the code path. It is assumed that the .app and .appup files for an application are located in the same directory.
If option {path,[Dir]} is specified, this path is appended to the current path. Wildcard * is expanded to all matching directories, for example, lib/*/ebin.
If option restart_emulator is specified, a low-level instruction to restart the emulator is appended to the relup file. This ensures that a complete reboot of the system is done when the system is upgraded or downgraded.
If an upgrade includes a change from an emulator earlier than OTP R15 to OTP R15 or later, the warning pre_R15_emulator_upgrade is issued. For more information about this, see Design Principles in System Documentation.
By default, errors and warnings are printed to tty and the function returns ok or error. If option silent is specified, the function instead either returns {ok,Relup,Module,Warnings}, where Relup is the release upgrade file, or {error,Module,Error}. Warnings and errors can be converted to strings by calling Module:format_warning(Warnings) or Module:format_error(Error).
If option noexec is specified, the function returns the same values as for silent but no relup file is created.
If option warnings_as_errors is specified, warnings are treated as errors.
π make_script(Name, [Opt]) -> Result π
make_script(Name, [Opt]) -> Result
when
Name :: string(),
Opt ::
src_tests |
{path, [Dir]} |
local |
{variables, [Var]} |
exref |
{exref, [App]} |
silent |
{outdir, Dir} |
no_dot_erlang | no_warn_sasl |
warnings_as_errors |
{script_name, Name},
Dir :: string(),
Var :: {VarName, Prefix},
VarName :: string(),
Prefix :: string(),
App :: atom(),
Result ::
ok | error |
{ok, Module, Warnings} |
{error, Module, Error},
Module :: atom(),
Warnings :: term(),
Error :: term().
This one is the boot-script bestie. Generates a boot script Name.script and its binary version, the boot file Name.boot, unless the {script_name, ScriptName} option is given, in which case the names are ScriptName.script and ScriptName.boot. π
The boot file specifies which code to be loaded and which applications to be started when the Erlang runtime system is started. See script(4).
The release resource file Name.rel is read to determine which applications are included in the release. Then the relevant application resource files App.app are read to determine which modules to be loaded, and if and how the applications are to be started. (Keys modules and mod, see app(4).
By default, the boot script and boot file are located in the same directory as Name.rel. That is, in the current working directory unless Name contains a path. If option {outdir,Dir} is specified, they are located in Dir instead.
The correctness of each application is checked as follows:
- The version of an application specified in the
.relfile is to be the same as the version specified in the.appfile. - There are to be no undefined applications, that is, dependencies to applications that are not included in the release. (Key
applicationsin the.appfile). - There are to be no circular dependencies among the applications.
- There are to be no duplicated modules, that is, modules with the same name but belonging to different applications.
- If option
src_testsis specified, a warning is issued if the source code for a module is missing or is newer than the object code.
The applications are sorted according to the dependencies between the applications. Where there are no dependencies, the order in the .rel file is kept.
β οΈ The function fails if the mandatory applicationsKernelandSTDLIBare not included in the.relfile and have start typepermanent(which is default).
If SASL is not included as an application in the .rel file, a warning is issued because such a release cannot be used in an upgrade. To turn off this warning, add option no_warn_sasl.
All files are searched for in the current path. It is assumed that the .app and .beam files for an application are located in the same directory. The .erl files are also assumed to be located in this directory, unless it is an ebin directory in which case they can be located in the corresponding src directory.
If option {path,[Dir]} is specified, this path is appended to the current path. A directory in the path can be specified with a wildcard *, this is expanded to all matching directories. Example: "lib/*/ebin".
In the generated boot script all application directories are structured as App-Vsn/ebin. They are assumed to be located in $ROOT/lib, where $ROOT is the root directory of the installed release. If option local is specified, the actual directories where the applications were found are used instead. This is a useful way to test a generated boot script locally.
Option variables can be used to specify an installation directory other than $ROOT/lib for some of the applications. If a variable {VarName,Prefix} is specified and an application is found in a directory Prefix/Rest/App[-Vsn]/ebin, this application gets the path VarName/Rest/App-Vsn/ebin in the boot script. If an application is found in a directory Prefix/Rest, the path is VarName/Rest/App-Vsn/ebin. When starting Erlang, all variables VarName are given values using command-line flag boot_var.
Example: If option {variables,[{"TEST","lib"}]} is specified and myapp.app is found in lib/myapp/ebin, the path to this application in the boot script is "$TEST/myapp-1/ebin". If myapp.app is found in lib/test, the path is $TEST/test/myapp-1/ebin.
The checks performed before the boot script is generated can be extended with some cross reference checks by specifying option exref. These checks are performed with the Xref tool. All applications, or the applications specified with {exref,[App]}, are checked by Xref and warnings are issued for calls to undefined functions.
By default, errors and warnings are printed to tty and the function returns ok or error. If option silent is specified, the function instead returns {ok,Module,Warnings} or {error,Module,Error}. Warnings and errors can be converted to strings by calling Module:format_warning(Warnings) or Module:format_error(Error).
If option warnings_as_errors is specified, warnings are treated as errors.
no_dot_erlangβ if you pass this one, the boot-time instruction to load the.erlangfile just... doesn't get baked in. Gone. Skipped. β¨
π«Ά make_tar/2 β the one that wraps your whole release in a cute little tarball
make_tar(Name, Opts) -> Result
when
Name :: string(),
Opts :: [Opt],
Opt ::
{dirs, [IncDir]} |
{path, [Dir]} |
{variables, [Var]} |
{var_tar, VarTar} |
{erts, Dir} |
erts_all | src_tests | exref |
{exref, [App]} |
silent |
{outdir, Dir} |
no_warn_sasl | warnings_as_errors |
{extra_files, ExtraFiles},
Dir :: file:filename_all(),
IncDir :: src | include | atom(),
Var :: {VarName, PreFix},
VarName :: string(),
PreFix :: string(),
VarTar :: include | ownfile | omit,
App :: atom(),
Result ::
ok | error |
{ok, Module :: module(), Warnings :: term()} |
{error, Module :: module(), Error :: term()},
ExtraFiles ::
[{file:filename_all(), NameInArchive}],
NameInArchive :: string().
Okay bestie, this is the glow-up function: it creates a release package file called Name.tar.gz. π
Heads up fr fr: this file must be uncompressed and unpacked on the target system using release_handler before the new release can be installed. No shortcuts, no "I'll do it later". Periodt.
So how does it know what to pack? It reads the release resource file Name.rel to figure out which applications are in the release. Then it reads the relevant application resource files App.app to figure out the version and modules of each application (that's the vsn and modules keys, see app(4)). iykyk. π
By default, the release package file lands in the same directory as Name.rel. Since that's the current working directory unless Name contains a path β yep, cwd by default. But if you specify option {outdir,Dir}, it lives in Dir instead. Main character relocation energy. β¨
If SASL is not included as an application in the .rel file, a warning gets issued, because a release like that cannot be used in an upgrade. π To turn that warning off, add option no_warn_sasl. If you want it quiet, you know what to do.
By default, the release package contains the directories lib/App-Vsn/ebin and lib/App-Vsn/priv for each included application. Want more directories in there? Specify option dirs, for example {dirs,[src,examples]}. Easy. Obsessed.
All these files are searched for in the current path. And if you specify option {path,[Dir]}, that path gets appended to the current path. The wildcard * expands to all matching directories, like:
lib/*/ebin
So "lib/*/ebin" is valid and it just slurps up every matching directory. Slay. π
And if you hand it {extra_files, ExtraFiles}, then those ExtraFiles get added to the tarball after everything else to be included has been added. Last in, no queue-jumping. π«Ά
Option variables lets you specify an installation directory other than lib for some of the applications. If variable {VarName,Prefix} is specified and an application is found in directory Prefix/Rest/App[-Vsn]/ebin, then that application is packed into a separate VarName.tar.gz file as Rest/App-Vsn/ebin. π§
Example time β say you specify {variables,[{"TEST","lib"}]} and myapp.app is located in lib/myapp-1/ebin. Then application myapp is included in TEST.tar.gz:
% tar tf TEST.tar
myapp-1/ebin/myapp.app
Iconic behaviour honestly. π
Option {var_tar,VarTar} can be used to specify if and where a separate package is to be stored. VarTar is one of these three:
includeβ each separate (variable) package is included in the mainReleaseName.tar.gzfile. This is the default. πownfileβ each separate (variable) package is generated as a separate file in the same directory as theReleaseName.tar.gzfile. Doing its own thing, separate but equal.omitβ no separate (variable) packages are generated at all. Applications that are found underneath a variable directory are ignored. Ghosted. π
A directory releases is also included in the release package, containing Name.rel and a subdirectory RelVsn. RelVsn is the release version as specified in Name.rel. πΈ
And releases/RelVsn contains the boot script Name.boot renamed to start.boot and, if found, the files relup and sys.config or sys.config.src. These files get searched for in the same directory as Name.rel, in the current working directory, and in any directories specified using option path. Lowkey important detail: in the case of sys.config, it is not included if sys.config.src is found. Don't ask, that's just the rule. π
If the release package is supposed to contain a new Erlang runtime system, the erts-ErtsVsn/bin directory of the specified runtime system {erts,Dir} gets copied to erts-ErtsVsn/bin. Note that some erts executables are not copied by default β if you want to include all executables you can give the erts_all option. π₯
All checks with function make_script are performed before the release package is created. And yep β options src_tests and exref are also valid here. Same squad, different function.
The return value and the handling of errors and warnings are the same as described for make_script. So if you read that bit, you already know, bestie. π«Ά
π script2boot/1 β the lil transformer
script2boot(File) -> ok | error when File :: string().
This function transforms the File.script boot script into a binary term, which is stored in the File.boot file. β¨
Why, you ask? Because the Erlang runtime system requires that the contents of the script used to boot the system is a binary Erlang term. It simply will not accept anything else. So this is not optional, it's giving necessity. π
And a cute little note: a boot script generated using make_script is already transformed to the binary form. So like, you don't need to do it again. No cap. π
That's the whole vibe check, bestie β this page is from the fine folks at Ericsson AB, and it ships with sasl version 4.4 as systools(3). Go forth and build your releases, you absolute icon. π¦πβ¨
π¦ where this page comes from
- nixos 26.05: erlang 29.1.2
- nixpkgs unstable: erlang 29.1.2
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms