3.13. global directives
these directives can be used anywhere in your config file. they are not affected by the active section.
In addition to the directives below, the parser also supports line-level
conditional prefixes of the form ifdef SOME_DEFINE: key: value and
ifndef SOME_DEFINE: key: value. Those are documented further below in
conditional config lines: ifdef and ifndef.
Historically these directive spellings are not fully uniform: the various
include directives are written without a trailing :, while
push_name_prefix:, add_message_definition_dir:, and
add_process_default_template: are written with one.
3.13.1. include
syntax:
INCLUDE_DIRECTIVE := "include" + FILENAME + "\n"
example:
include my_subsystem.inc.lnc
this directive can be used to read ln-config-directives from another file. it is useful to split up larger configs across multiple files. also parts of your config might be provided by some other project that provides such an include file.
the included file will be read exactly the same way the main config file is read, with the only exception that names-prefixes pushed in an include file will automatically be pop’ed at the end of that file.
3.13.2. optional_include
syntax:
OPT_INCLUDE_DIRECTIVE := "optional_include" + FILENAME + "\n"
example:
optional_include my_subsystem_for_%(host).inc.lnc
same as the above include directive, but it’s not considered as an error if the specified file does not exist.
this is useful to conditionally include many directives only if some condition is matched - this can be
achieved by using %()-defines in that FILENAME.
3.13.3. include_glob & optional_include_glob
syntax:
INCLUDE_GLOB_DIRECTIVE := "include_glob" + PATTERN + "\n"
OPT_INCLUDE_GLOB_DIRECTIVE := "optional_include_glob" + PATTERN + "\n"
example:
include_glob cissygen/**/*.inc.lnc
this directive can search for multiple include files and include them in the same way as the above include directive would do it. this is useful if you want to include many, possibly generated files where you don’t want to explicitely spell the exact-filename.
patterns are matches with python’s fnmatch.fnmatch()-function with the addition that ** can match any
sub-directory.
3.13.4. pipe_include
syntax:
PIPE_INCLUDE_DIRECTIVE := "pipe_include" + COMMANDLINE + "\n"
example:
pipe_include python generate_ln_config.py
this directive will execute the specified COMMANDLINE while the current config file is parsed. the
standard-output from that command will be interpreted as if it would be contents of an include file, in
exactly the same way as above with the include-directive.
this can be used to procedurally generate processes, defines or any other config-directives.
3.13.5. requires_version
syntax:
REQUIRES_VERSION_DIRECTIVE := "requires_version" + VERSION + "\n"
example:
requires_version 3.5.0
This directive aborts config loading unless the running ln_manager
version is at least the specified version.
Use this when a configuration depends on parser or manager behavior that is not available in older installations. The check is performed while reading the config file, before the rest of the file is processed further.
3.13.6. push_name_prefix
syntax:
push_name_prefix: <PREFIX>
all objects (processes, groups, states) which are defined after this directive will get their name prefixed
with <PREFIX>/ (note the additional /).
example:
# ...
push_name_prefix: MyPrefix
process proc1
# ...
process proc2
# ...
push_name_prefix: SubSection
process proc3
# ...
pop_name_prefix
process proc4
# ...
will create 4 processes with these names:
MyPrefix/proc1
MyPrefix/proc2
MyPrefix/SubSection/proc3
MyPrefix/proc4
this is mainly useful when having the instance-flag enable_auto_groups set to true (see
its description for more information).
3.13.7. pop_name_prefix
syntax:
pop_name_prefix
will remove the last pushed name prefix.
3.13.8. warning
this directive can be used to output warnings to ln-managers log while reading the configuration. this can be useful for debugging: e.g. to print out the value of a define at a certain point within the configuration:
syntax:
WARNING_DIRECTIVE := "warning: " + MESSAGE + "\n"
MESSAGE := EVALUATED_STRING
example:
defines
SOME_SETTING: value42
warning: value of SOME_SETTING: %(SOME_SETTING)
the MESSAGE will be prefixed with the current configration file’s name and the line-number within that
file.
example log-output could look like this:
2021-11-16 10:54:32.97 warning SystemConfiguratio path/to/my/config.lnc:10: value of SOME_SETTING: value42
3.13.9. conditional config lines: ifdef and ifndef
These are not separate sections. Instead, they are prefixes that
conditionally enable or skip one normal key: value config line.
You can think of them as a very small, line-based preprocessor, similar in
spirit to C’s #ifdef and #ifndef.
syntax:
IFDEF_LINE := "ifdef " + DEFINE_NAME + ": " + KEY + ": " + VALUE + "\n"
IFNDEF_LINE := "ifndef " + DEFINE_NAME + ": " + KEY + ": " + VALUE + "\n"
example:
defines
ENABLE_DEBUG_OUTPUT: 1
process demo
ifdef ENABLE_DEBUG_OUTPUT: add environment: DEBUG_OUTPUT=1
ifndef LOG_LEVEL: add environment: LOG_LEVEL=info
In the example above:
ifdef ENABLE_DEBUG_OUTPUT: ...is applied becauseENABLE_DEBUG_OUTPUTexists and is non-empty.ifndef LOG_LEVEL: ...is applied becauseLOG_LEVELis not defined.
The parser behaves as if the inner line had been written directly at that position:
add environment: DEBUG_OUTPUT=1
add environment: LOG_LEVEL=info
Important behavior and limitations:
ifdefchecks whether the named define currently exists and has a non-empty value.ifndefis the inverse: it applies the line only when the define is missing or currently set to the empty string.The define name after
ifdef/ifndefis taken literally. It is not string-evaluated, so writeifdef SOME_DEFINE: ..., notifdef %(SOME_DEFINE): ....Only one normal
key: valueline can be guarded. The text after the condition must itself be one complete config line.It works for normal section entries such as
add environment: ...,environment: ...orflags: ....It also works for single-line directives and entries such as
include ...,optional_include ...,include_glob ...,pipe_include ...,add_message_definition_dir: ...,add_process_default_template: ...,undef: ...,push_name_prefix: ...,pop_name_prefix,warning: ...,requires_version ..., and entries in sections such ashosts,node_mapandcustom_start_tools.It can also guard section-header lines such as
process fooorstate bar, but this still affects only that one line.Because these conditionals are line-scoped, they are not a block syntax. Guarding a section header does not automatically guard the following section body. If you need to conditionally include a larger block, use
include/pipe_includetogether withifdef/ifndefor restructure the config so each guarded item is a complete single line.Multi-line values starting with
[are still parsed as a single logical value. If the condition is false, the whole multi-line value is skipped.
This is especially useful for optional process properties, environment entries, or per-project additions that should only be active when a define has been provided earlier in the configuration.
3.13.10. undef
syntax:
UNDEF_LINE := "undef: " + DEFINE_NAME + "\n"
example:
defines
ENABLE_LOGGING: 1
process demo
ifdef ENABLE_LOGGING: add environment: ENABLE_LOGGING=1
undef: ENABLE_LOGGING
ifdef ENABLE_LOGGING: add environment: THIS_LINE_WILL_NOT_BE_USED=1
undef removes a define from the current set of active defines.
Behavior details:
removing a define that does not exist is silently ignored
the define name is taken literally and is not string-evaluated
this is often useful together with
ifdef/ifndefwhen a define should only affect part of a configuration file
3.13.11. add_message_definition_dir
syntax:
ADD_MESSAGE_DEFINITION_DIR := "add_message_definition_dir: " + DIRECTORY + "\n"
example:
add_message_definition_dir: %(CURDIR)/msg_defs
This directive adds another directory to ln_manager’s message-definition search path.
The directory is appended to the end of the list of configured
message-definition search paths, in the same order in which
add_message_definition_dir directives appear in the config file. See also
Message Definitions for the detailed lookup rules.
This is important because ln_manager must be able to find all message definitions that are used at runtime, for example:
topic message definitions used by configured processes and running clients
service message definitions
The value is usually the directory that contains the top-level namespace
folders of your message definitions. If a message definition is named
my_project/some_type, ln_manager will look for a file with that relative
path below each known message-definition directory.
Typical usage is to add a project-local message-definition directory near the top of the config file, before any processes or states that depend on those types are defined.
3.13.12. add_process_default_template
syntax:
ADD_PROCESS_DEFAULT_TEMPLATE := "add_process_default_template: " + TEMPLATE_USE + "\n"
example:
add_process_default_template: shell with home("my_home", "echo hello")
This directive registers a default use_template specification that is
applied automatically to matching processes later in the configuration.
Behavior details:
the directive is global and may appear anywhere in the config
it affects processes defined after it is read
the current push_name_prefix stack is stored with the directive, so the default template only applies to processes below that prefix
process-local
use_templateentries are still possible in addition to these defaultsprocesses can disable such automatically applied defaults with the
no_default_templatesflag
This is useful when many processes in one part of the config should all inherit
the same template without repeating use_template: ... in every process
section.