From 799db76d8ad070f11118b0914aeabef9320ea9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Wed, 28 Jan 2026 15:27:15 +0100 Subject: [PATCH 1/6] Initial configuration draft --- .../docs/concepts/configuration.md | 229 ++++++++++++++++++ .../docs/images/example_graph.png | Bin 0 -> 43431 bytes 2 files changed, 229 insertions(+) create mode 100644 src/launch_manager_daemon/docs/concepts/configuration.md create mode 100644 src/launch_manager_daemon/docs/images/example_graph.png diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md new file mode 100644 index 00000000..95b134d8 --- /dev/null +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -0,0 +1,229 @@ +# Launch Manager Daemon Configuration Concept + +## Version + +The version of the configuration schema should be included in every configuration file. +When loading the configuration file at runtime, the launch_manager will check that it matches the supported schema version. + +## Usage of Defaults + +We should have a mechanism to define default values to avoid repetition of common properties. + +### Proposal for first version: Default component and default sandbox definition + +In the `defaults` section of file, the user can define default values for component and sandbox properties. +All keys have the identical names as used for the configuration of a concrete component / sandbox. + +```json +"defaults_": { + "sandbox": { + "startup_timeout": 0.5, + "shutdown_timeout": 0.5, + "uid" : 1000, + "gid" : 1000, + "supplementary_group_ids": [500, 600, 700], + "environmental_variables": { + "LD_LIBRARY_PATH": "/opt/lib", + "EMPTY_ENV_VAR": "" + }, + "process_arguments": [], + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": "0" + ... + }, + "component": { + "is_native_application": false, + "is_supervised": true, + "is_self_terminating": false, + "is_state_manager": false, + "depends_on": [] + }, + "run_target": { + "transition_timeout": 2 + } +} +``` + +Any setting not defined as part of a component or sandbox definition will automatically use the default value. +Overwriting Behavior: +* Primitive values (like `uid`) simply get overwritten if configured +* Dictionaries (like `environmental_variables`) get merged. Keys can be overwritten by configuring the same keys. +* Lists (like `supplementary_group_ids`) get overwritten. In the future we may add further properties like `supplementary_group_ids_extend` to add to the default list instead of overwriting - if this use case gets necessary. + +### Proposal for future extension: Defining different component and sandbox templates + +As per our discussion there may be a use case to have different kinds of components and different kinds of sandboxes with their own defaults. +The approach above can be extended in this direction, by defining multiple sandboxes and multiple components in the "defaults" section. +Component and sandbox definition could then refer to one of the predefined alternatives. + +## Dependencies between components + +Each dependency is configured as a json object, as we foresee that further properties might be added to the dependency in the future (i.e. support for kinds of dependencies). + +Initially (when mapping the new configuration to the existing software), the component states are identical to the process state: +* `Running`: The process finished initialization (or is a self-terminating processes) +* `Terminated`: The process terminated + +```json +"components": { + "test_app2": { + "depends_on": { + "test_app4": { + "required_state": "Running", + } + } + } +} +``` + +## Assignment to RunTargets + +For every dependency, the required state of the component is implicitly "Running". + +```json +"run_targets": { + "run_target_01": { + "description": "Example description of a Run Target number 01.", + "includes": ["test_app1"] + } + ... +} +``` + +## Timeout Values + +All timeout values will be in seconds. + +## Configuration Example + +![Example Graph](../images/example_graph.png) + +```json +{ + "schema_version": 1, + "defaults": { + "sandbox": { + "startup_timeout": 0.5, + "shutdown_timeout": 0.5, + "uid" : 1000, + "gid" : 1000, + "supplementary_group_ids": [500, 600, 700], + "security_policy": "", + "environmental_variables": { + "LD_LIBRARY_PATH": "/opt/lib", + "GLOBAL_ENV_VAR": "abc", + "EMPTY_GLOBAL_ENV_VAR": "" + }, + "process_arguments": [], + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": "0", + "working_directory": "/tmp", + "resource_limits": {} + }, + "component": { + "is_native_application": false, + "is_supervised": true, + "is_self_terminating": false, + "is_state_manager": false, + "depends_on": [] + } + }, + "components": { + "setup_filesystem_sh": { + "is_native_application": true, + "is_supervised": false, + "is_self_terminating": true, + "sandbox": { + "executable_path" : "/bin/sh", + "process_arguments": ["-c", "/opt/scripts/setup_filesystem.sh"], + } + }, + "dlt-daemon": { + "is_native_application": true, + "is_supervised": false, + "depends_on": { + "setup_filesystem_sh": { + "required_state": "Terminated" + } + }, + "sandbox": { + "executable_path" : "/opt/apps/dlt-daemon/dltd", + } + }, + "someip-daemon": { + "sandbox": { + "executable_path" : "/opt/apps/someip/someipd", + } + }, + "test_app1": { + "depends_on": { + "dlt-daemon": { + "required_state": "Running" + }, + "someip-daemon": { + "required_state": "Running" + } + }, + "sandbox": { + "executable_path" : "/opt/apps/test_app1/test_app1", + } + }, + "state_manager": { + "is_state_manager": true, + "depends_on": { + "setup_filesystem_sh": { + "required_state": "Terminated" + } + }, + "sandbox": { + "executable_path" : "/opt/apps/state_manager/sm", + } + } + }, + "run_targets": { + "Minimal": { + "description": "Minimal functionality of the system", + "includes": ["state_manager"] + }, + "Full": { + "description": "Everything running", + "includes": ["Minimal", "test_app1"] + }, + "Off": { + "description": "Nothing is running" + } + }, + "initial_run_target": "Minimal", + "health_monitoring" : { + "evaluation_cycle_ms": 500 + }, + "watchdogs": { + "simple_watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout_ms": 2000, + "deactivate_on_shutdown": true, + "require_magic_close": false + } + } +} +``` + +## Open Topics + +### RecoveryAction + +In the initial version (mapping to the config to the existing software) the only supported RecoveryAction will be to switch to a predefined recovery RunTarget in case of any error. + +How to define the SwitchRunTarget RecoveryAction without entangling the component definition with the RunTarget definition? + +### Execution dependencies: Component State vs. Process State + +For the initial version, it will be easiest to have component state identical to process state as this is already supported by the existing code. + +### How to configure the initial RunTarget + +Should we reserve a name for the initial RunTarget or make this configurable (see `initial_run_target`)? + +### Defining json schema + +After agreement on the rough structure, we will define a json schema depicting all possible configuration options. \ No newline at end of file diff --git a/src/launch_manager_daemon/docs/images/example_graph.png b/src/launch_manager_daemon/docs/images/example_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..ddb3c45b9d9b4639b2b535358bd627cbe7280b2b GIT binary patch literal 43431 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

%lu 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 Date: Thu, 29 Jan 2026 11:11:29 +0000 Subject: [PATCH 2/6] Renaming sandbox into deployment_config and adding some justification --- .../docs/concepts/configuration.md | 64 +++++++++++++------ 1 file changed, 46 insertions(+), 18 deletions(-) mode change 100644 => 100755 src/launch_manager_daemon/docs/concepts/configuration.md diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md old mode 100644 new mode 100755 index 95b134d8..0e30f2dd --- a/src/launch_manager_daemon/docs/concepts/configuration.md +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -5,18 +5,46 @@ The version of the configuration schema should be included in every configuration file. When loading the configuration file at runtime, the launch_manager will check that it matches the supported schema version. +## Component vs deployment configuration + +A component (also referred to as a software component) is an independent software unit - such as an application or a software container - that can be developed separately and subsequently deployed into a target system (for example machine). Components are usually combined into a functioning system during the deployment, or integration, phase. +Because a single component may be deployed into multiple systems, the deployment configuration is intentionally separated from the component description. In summary: +* The **deployment configuration** defines information specific to a particular system setup. +* The **component description** defines the fundamental characteristics of the software component, which are typically determined during that component’s development phase. + +For illustration, please refer to the following example. + +```json +"components": { + "setup_filesystem_sh": { + "is_native_application": true, + "is_supervised": false, + "is_self_terminating": true, + "deployment_config": { + "executable_path" : "/opt/scripts/setup_filesystem.sh", + "process_arguments": ["-a", "-b"], + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": "0", + "uid" : 1000, + "gid" : 1000, + "supplementary_group_ids": [500, 600, 700], + } + } +} +``` + ## Usage of Defaults We should have a mechanism to define default values to avoid repetition of common properties. -### Proposal for first version: Default component and default sandbox definition +### Proposal for first version: Default component and default deployment_config definition -In the `defaults` section of file, the user can define default values for component and sandbox properties. -All keys have the identical names as used for the configuration of a concrete component / sandbox. +In the `defaults` section of file, the user can define default values for component and deployment_config properties. +All keys have the identical names as used for the configuration of a concrete component / deployment_config. ```json "defaults_": { - "sandbox": { + "deployment_config": { "startup_timeout": 0.5, "shutdown_timeout": 0.5, "uid" : 1000, @@ -44,17 +72,17 @@ All keys have the identical names as used for the configuration of a concrete co } ``` -Any setting not defined as part of a component or sandbox definition will automatically use the default value. +Any setting not defined as part of a component or deployment_config definition will automatically use the default value. Overwriting Behavior: * Primitive values (like `uid`) simply get overwritten if configured * Dictionaries (like `environmental_variables`) get merged. Keys can be overwritten by configuring the same keys. * Lists (like `supplementary_group_ids`) get overwritten. In the future we may add further properties like `supplementary_group_ids_extend` to add to the default list instead of overwriting - if this use case gets necessary. -### Proposal for future extension: Defining different component and sandbox templates +### Proposal for future extension: Defining different component and deployment_config templates -As per our discussion there may be a use case to have different kinds of components and different kinds of sandboxes with their own defaults. -The approach above can be extended in this direction, by defining multiple sandboxes and multiple components in the "defaults" section. -Component and sandbox definition could then refer to one of the predefined alternatives. +As per our discussion there may be a use case to have different kinds of components and different kinds of deployment configurations with their own defaults. +The approach above can be extended in this direction, by defining multiple deployment configurations and multiple components in the "defaults" section. +Component and deployment config definition could then refer to one of the predefined alternatives. ## Dependencies between components @@ -92,7 +120,7 @@ For every dependency, the required state of the component is implicitly "Running ## Timeout Values -All timeout values will be in seconds. +All time periods will be configured in seconds. If a smaller time period is needed, then a fraction numbers should be used. For example we should use `0.001` for one millisecond timeout value. ## Configuration Example @@ -102,7 +130,7 @@ All timeout values will be in seconds. { "schema_version": 1, "defaults": { - "sandbox": { + "deployment_config": { "startup_timeout": 0.5, "shutdown_timeout": 0.5, "uid" : 1000, @@ -133,9 +161,9 @@ All timeout values will be in seconds. "is_native_application": true, "is_supervised": false, "is_self_terminating": true, - "sandbox": { - "executable_path" : "/bin/sh", - "process_arguments": ["-c", "/opt/scripts/setup_filesystem.sh"], + "deployment_config": { + "executable_path" : "/opt/scripts/setup_filesystem.sh", + "process_arguments": ["-a", "-b"], } }, "dlt-daemon": { @@ -146,12 +174,12 @@ All timeout values will be in seconds. "required_state": "Terminated" } }, - "sandbox": { + "deployment_config": { "executable_path" : "/opt/apps/dlt-daemon/dltd", } }, "someip-daemon": { - "sandbox": { + "deployment_config": { "executable_path" : "/opt/apps/someip/someipd", } }, @@ -164,7 +192,7 @@ All timeout values will be in seconds. "required_state": "Running" } }, - "sandbox": { + "deployment_config": { "executable_path" : "/opt/apps/test_app1/test_app1", } }, @@ -175,7 +203,7 @@ All timeout values will be in seconds. "required_state": "Terminated" } }, - "sandbox": { + "deployment_config": { "executable_path" : "/opt/apps/state_manager/sm", } } From 4c4610a1e8f81e2a90d31659cb9e9ef9681bea63 Mon Sep 17 00:00:00 2001 From: SimonKozik <244535158+SimonKozik@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:26:05 +0000 Subject: [PATCH 3/6] Adding transition_timeout to example config --- .../docs/concepts/configuration.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md index 0e30f2dd..837c724e 100755 --- a/src/launch_manager_daemon/docs/concepts/configuration.md +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -27,7 +27,7 @@ For illustration, please refer to the following example. "scheduling_priority": "0", "uid" : 1000, "gid" : 1000, - "supplementary_group_ids": [500, 600, 700], + "supplementary_group_ids": [500, 600, 700] } } } @@ -154,6 +154,9 @@ All time periods will be configured in seconds. If a smaller time period is need "is_self_terminating": false, "is_state_manager": false, "depends_on": [] + }, + "run_target": { + "transition_timeout": 2 } }, "components": { @@ -215,7 +218,8 @@ All time periods will be configured in seconds. If a smaller time period is need }, "Full": { "description": "Everything running", - "includes": ["Minimal", "test_app1"] + "includes": ["Minimal", "test_app1"], + "transition_timeout": 5 }, "Off": { "description": "Nothing is running" @@ -254,4 +258,4 @@ Should we reserve a name for the initial RunTarget or make this configurable (se ### Defining json schema -After agreement on the rough structure, we will define a json schema depicting all possible configuration options. \ No newline at end of file +After agreement on the rough structure, we will define a json schema depicting all possible configuration options. From cafab09508bdcda2c3e4e056eeca9c9fe3b405ec Mon Sep 17 00:00:00 2001 From: SimonKozik <244535158+SimonKozik@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:15:25 +0000 Subject: [PATCH 4/6] Adding description of supported configuration elements --- .../docs/concepts/configuration.md | 120 +++++++++++++----- 1 file changed, 85 insertions(+), 35 deletions(-) diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md index 837c724e..1ad62b04 100755 --- a/src/launch_manager_daemon/docs/concepts/configuration.md +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -8,18 +8,20 @@ When loading the configuration file at runtime, the launch_manager will check th ## Component vs deployment configuration A component (also referred to as a software component) is an independent software unit - such as an application or a software container - that can be developed separately and subsequently deployed into a target system (for example machine). Components are usually combined into a functioning system during the deployment, or integration, phase. -Because a single component may be deployed into multiple systems, the deployment configuration is intentionally separated from the component description. In summary: +Because a single component may be deployed into multiple systems, the deployment configuration is intentionally separated from the component properties. In summary: * The **deployment configuration** defines information specific to a particular system setup. -* The **component description** defines the fundamental characteristics of the software component, which are typically determined during that component’s development phase. +* The **component properties** describe the fundamental characteristics of the software component, which are typically determined during that component’s development phase. For illustration, please refer to the following example. ```json "components": { "setup_filesystem_sh": { - "is_native_application": true, - "is_supervised": false, - "is_self_terminating": true, + "component_properties": { + "is_native_application": true, + "is_supervised": false, + "is_self_terminating": true + }, "deployment_config": { "executable_path" : "/opt/scripts/setup_filesystem.sh", "process_arguments": ["-a", "-b"], @@ -59,7 +61,7 @@ All keys have the identical names as used for the configuration of a concrete co "scheduling_priority": "0" ... }, - "component": { + "component_properties": { "is_native_application": false, "is_supervised": true, "is_self_terminating": false, @@ -95,15 +97,44 @@ Initially (when mapping the new configuration to the existing software), the com ```json "components": { "test_app2": { - "depends_on": { - "test_app4": { - "required_state": "Running", + "component_properties": { + "depends_on": { + "test_app4": { + "required_state": "Running" + } } } } } ``` +## Supported component properties + +Currently following component properties are supported: +* `is_native_application`: Property describing if component is using S-CORE platform functionality (true / false). +* `is_supervised`: Property describing if component sends alive notifications to Launch Manager (true / false). +* `is_self_terminating`: Property describing if component intends to terminate on its own after startup. Please note that daemons usually stay running and waits for termination request from Launch Manager (true / false). +* `is_state_manager`: Property describing if component needs access to the API that changes current Run Target (true / false). +* `depends_on`: List of components on which this component depends. + +## Supported deployment configuration elements + +Currently following configuration elements are supported: +* `startup_timeout`: Period of time in which, `running` notification should be reported from the component to the Launch Manager. This timeout is measured from the moment the child process is created, till notification is received by LM. +* `shutdown_timeout`: Period of time in which component should terminate, after receiving SIGTERM signal from Launch Manager. This timeout is measured from the moment LM sends SIGTERM, till Operating System (OS) notifies LM that child process finished execution. +* `uid`: POSIX User ID assigned to this component. +* `gid`: POSIX Group ID assigned to this component. +* `supplementary_group_ids`: List of supplementary group IDs, that are assigned to this component. +* `security_policy`: Name of the security policy assigned to this component. +* `environmental_variables`: List of environmental variables that should be passed to this component. +* `process_arguments`: List of arguments, also know as command line arguments, that should be passed to this component. +* `scheduling_policy`: Scheduling policy that should be applied to the first thread of this component. +* `scheduling_priority`: Scheduling priority that should be applied to the first thread of this component. +* `working_directory`: Working directory that should be set for this component. +* `restarts_during_startup`: If component does not send `running` notification in time, see `startup_timeout` configuration for more details, Launch Manager will consider this a startup failure. This setting specify how many more times LM should try to start this component, before giving up and considering Run Target transition to fail. If `restarts_during_startup` is set to 0 (zero), no restart attempts will be performed and Run Target transition will fail immediately. +* `resource_limits`: Resource limitations that should be applied to this component. + * `memory_usage`: Maximum memory (in bytes) that can be consumed by this component during runtime. + ## Assignment to RunTargets For every dependency, the required state of the component is implicitly "Running". @@ -148,7 +179,7 @@ All time periods will be configured in seconds. If a smaller time period is need "working_directory": "/tmp", "resource_limits": {} }, - "component": { + "component_properties": { "is_native_application": false, "is_supervised": true, "is_self_terminating": false, @@ -161,64 +192,83 @@ All time periods will be configured in seconds. If a smaller time period is need }, "components": { "setup_filesystem_sh": { - "is_native_application": true, - "is_supervised": false, - "is_self_terminating": true, + "component_properties": { + "is_native_application": true, + "is_supervised": false, + "is_self_terminating": true + }, "deployment_config": { "executable_path" : "/opt/scripts/setup_filesystem.sh", - "process_arguments": ["-a", "-b"], + "process_arguments": ["-a", "-b"] } }, "dlt-daemon": { - "is_native_application": true, - "is_supervised": false, - "depends_on": { - "setup_filesystem_sh": { - "required_state": "Terminated" + "component_properties": { + "is_native_application": true, + "is_supervised": false, + "depends_on": { + "setup_filesystem_sh": { + "required_state": "Terminated" + } } }, "deployment_config": { - "executable_path" : "/opt/apps/dlt-daemon/dltd", + "executable_path" : "/opt/apps/dlt-daemon/dltd" } }, "someip-daemon": { "deployment_config": { - "executable_path" : "/opt/apps/someip/someipd", + "executable_path" : "/opt/apps/someip/someipd" } }, "test_app1": { - "depends_on": { - "dlt-daemon": { - "required_state": "Running" - }, - "someip-daemon": { - "required_state": "Running" + "component_properties": { + "depends_on": { + "dlt-daemon": { + "required_state": "Running" + }, + "someip-daemon": { + "required_state": "Running" + } } }, "deployment_config": { - "executable_path" : "/opt/apps/test_app1/test_app1", + "executable_path" : "/opt/apps/test_app1/test_app1" } }, "state_manager": { - "is_state_manager": true, - "depends_on": { - "setup_filesystem_sh": { - "required_state": "Terminated" + "component_properties": { + "is_state_manager": true, + "depends_on": { + "setup_filesystem_sh": { + "required_state": "Terminated" + } } }, "deployment_config": { - "executable_path" : "/opt/apps/state_manager/sm", + "executable_path" : "/opt/apps/state_manager/sm" } } }, "run_targets": { "Minimal": { "description": "Minimal functionality of the system", - "includes": ["state_manager"] + "includes": [ + { + "component": "state_manager" + } + ] }, "Full": { "description": "Everything running", - "includes": ["Minimal", "test_app1"], + "includes": [ + { + "run_target": "Minimal" + }, + { + "component": "test_app1" + } + ], "transition_timeout": 5 }, "Off": { From 1c14a8440affc6211971705d4d6aa98bdd1bb19f Mon Sep 17 00:00:00 2001 From: SimonKozik <244535158+SimonKozik@users.noreply.github.com> Date: Tue, 3 Feb 2026 15:36:14 +0000 Subject: [PATCH 5/6] Applying review comments, some cosmetic changes --- .../docs/concepts/configuration.md | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md index 1ad62b04..55e81cf0 100755 --- a/src/launch_manager_daemon/docs/concepts/configuration.md +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -20,6 +20,12 @@ For illustration, please refer to the following example. "component_properties": { "is_native_application": true, "is_supervised": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + }, "is_self_terminating": true }, "deployment_config": { @@ -45,7 +51,7 @@ In the `defaults` section of file, the user can define default values for compon All keys have the identical names as used for the configuration of a concrete component / deployment_config. ```json -"defaults_": { +"defaults": { "deployment_config": { "startup_timeout": 0.5, "shutdown_timeout": 0.5, @@ -58,12 +64,18 @@ All keys have the identical names as used for the configuration of a concrete co }, "process_arguments": [], "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": "0" + "scheduling_priority": "0", ... }, "component_properties": { "is_native_application": false, "is_supervised": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + }, "is_self_terminating": false, "is_state_manager": false, "depends_on": [] @@ -113,6 +125,11 @@ Initially (when mapping the new configuration to the existing software), the com Currently following component properties are supported: * `is_native_application`: Property describing if component is using S-CORE platform functionality (true / false). * `is_supervised`: Property describing if component sends alive notifications to Launch Manager (true / false). +* `alive_supervision`: Description of alive monitoring, that should be applied to this component. + * `reporting_cycle`: Property describing the duration of time period, used for evaluation of alive supervision. + * `failed_cycles_tolerance`: Property describing number of reporting cycles (see `reporting_cycle`) that could fail in a row, before recovery action will be triggered. + * `min_indications`: Property describing minimal number of checkpoints, that shall be reported in a given `reporting_cycle`. + * `max_indications`: Property describing maximal number of checkpoints, that can be reported in a given `reporting_cycle`. * `is_self_terminating`: Property describing if component intends to terminate on its own after startup. Please note that daemons usually stay running and waits for termination request from Launch Manager (true / false). * `is_state_manager`: Property describing if component needs access to the API that changes current Run Target (true / false). * `depends_on`: List of components on which this component depends. @@ -143,7 +160,9 @@ For every dependency, the required state of the component is implicitly "Running "run_targets": { "run_target_01": { "description": "Example description of a Run Target number 01.", - "includes": ["test_app1"] + "includes": { + "components": ["test_app1"] + } } ... } @@ -182,6 +201,12 @@ All time periods will be configured in seconds. If a smaller time period is need "component_properties": { "is_native_application": false, "is_supervised": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + }, "is_self_terminating": false, "is_state_manager": false, "depends_on": [] @@ -253,38 +278,32 @@ All time periods will be configured in seconds. If a smaller time period is need "run_targets": { "Minimal": { "description": "Minimal functionality of the system", - "includes": [ - { - "component": "state_manager" - } - ] + "includes": { + "components": ["state_manager"] + } }, "Full": { "description": "Everything running", - "includes": [ - { - "run_target": "Minimal" - }, - { - "component": "test_app1" - } - ], + "includes": { + "components": ["test_app1"], + "run_targets": ["Minimal"] + }, "transition_timeout": 5 }, "Off": { "description": "Nothing is running" - } + }, + "initial_run_target": "Minimal" }, - "initial_run_target": "Minimal", "health_monitoring" : { - "evaluation_cycle_ms": 500 - }, - "watchdogs": { - "simple_watchdog": { - "device_file_path": "/dev/watchdog", - "max_timeout_ms": 2000, - "deactivate_on_shutdown": true, - "require_magic_close": false + "evaluation_cycle": 0.5, + "watchdogs": { + "simple_watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout": 2, + "deactivate_on_shutdown": true, + "require_magic_close": false + } } } } From 7821fb29856501370337887e7bed2a9d40f86f88 Mon Sep 17 00:00:00 2001 From: SimonKozik <244535158+SimonKozik@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:06:26 +0000 Subject: [PATCH 6/6] Changes discussed during [lifecycle and health] meeting on 04 Feb 2026 --- .../docs/concepts/configuration.md | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/launch_manager_daemon/docs/concepts/configuration.md b/src/launch_manager_daemon/docs/concepts/configuration.md index 55e81cf0..3cff0ba8 100755 --- a/src/launch_manager_daemon/docs/concepts/configuration.md +++ b/src/launch_manager_daemon/docs/concepts/configuration.md @@ -29,7 +29,7 @@ For illustration, please refer to the following example. "is_self_terminating": true }, "deployment_config": { - "executable_path" : "/opt/scripts/setup_filesystem.sh", + "bin_dir" : "/opt/scripts", "process_arguments": ["-a", "-b"], "scheduling_policy": "SCHED_OTHER", "scheduling_priority": "0", @@ -53,6 +53,7 @@ All keys have the identical names as used for the configuration of a concrete co ```json "defaults": { "deployment_config": { + "bin_dir" : "/opt", "startup_timeout": 0.5, "shutdown_timeout": 0.5, "uid" : 1000, @@ -62,7 +63,6 @@ All keys have the identical names as used for the configuration of a concrete co "LD_LIBRARY_PATH": "/opt/lib", "EMPTY_ENV_VAR": "" }, - "process_arguments": [], "scheduling_policy": "SCHED_OTHER", "scheduling_priority": "0", ... @@ -78,7 +78,8 @@ All keys have the identical names as used for the configuration of a concrete co }, "is_self_terminating": false, "is_state_manager": false, - "depends_on": [] + "depends_on": [], + "process_arguments": [], }, "run_target": { "transition_timeout": 2 @@ -123,6 +124,9 @@ Initially (when mapping the new configuration to the existing software), the com ## Supported component properties Currently following component properties are supported: +* `binary_name`: Relative path, describing location of the executable file inside `bin_dir` folder. Full path to the executable will be equal to `{bin_dir}/{binary_name}`. Valid examples of `binary_name` include, but are not limited to: + * `test_app1` + * `bin/test_app1` * `is_native_application`: Property describing if component is using S-CORE platform functionality (true / false). * `is_supervised`: Property describing if component sends alive notifications to Launch Manager (true / false). * `alive_supervision`: Description of alive monitoring, that should be applied to this component. @@ -133,6 +137,7 @@ Currently following component properties are supported: * `is_self_terminating`: Property describing if component intends to terminate on its own after startup. Please note that daemons usually stay running and waits for termination request from Launch Manager (true / false). * `is_state_manager`: Property describing if component needs access to the API that changes current Run Target (true / false). * `depends_on`: List of components on which this component depends. +* `process_arguments`: List of arguments, also know as command line arguments, that should be passed to this component. ## Supported deployment configuration elements @@ -144,9 +149,9 @@ Currently following configuration elements are supported: * `supplementary_group_ids`: List of supplementary group IDs, that are assigned to this component. * `security_policy`: Name of the security policy assigned to this component. * `environmental_variables`: List of environmental variables that should be passed to this component. -* `process_arguments`: List of arguments, also know as command line arguments, that should be passed to this component. * `scheduling_policy`: Scheduling policy that should be applied to the first thread of this component. * `scheduling_priority`: Scheduling priority that should be applied to the first thread of this component. +* `bin_dir`: Path to a folder where component has bin installed. * `working_directory`: Working directory that should be set for this component. * `restarts_during_startup`: If component does not send `running` notification in time, see `startup_timeout` configuration for more details, Launch Manager will consider this a startup failure. This setting specify how many more times LM should try to start this component, before giving up and considering Run Target transition to fail. If `restarts_during_startup` is set to 0 (zero), no restart attempts will be performed and Run Target transition will fail immediately. * `resource_limits`: Resource limitations that should be applied to this component. @@ -192,13 +197,15 @@ All time periods will be configured in seconds. If a smaller time period is need "GLOBAL_ENV_VAR": "abc", "EMPTY_GLOBAL_ENV_VAR": "" }, - "process_arguments": [], "scheduling_policy": "SCHED_OTHER", "scheduling_priority": "0", + "bin_dir": "/opt", "working_directory": "/tmp", + "restarts_during_startup": 2, "resource_limits": {} }, "component_properties": { + "binary_name": "", "is_native_application": false, "is_supervised": true, "alive_supervision": { @@ -209,7 +216,8 @@ All time periods will be configured in seconds. If a smaller time period is need }, "is_self_terminating": false, "is_state_manager": false, - "depends_on": [] + "depends_on": [], + "process_arguments": [] }, "run_target": { "transition_timeout": 2 @@ -218,17 +226,19 @@ All time periods will be configured in seconds. If a smaller time period is need "components": { "setup_filesystem_sh": { "component_properties": { + "binary_name": "bin/setup_filesystem.sh", "is_native_application": true, "is_supervised": false, - "is_self_terminating": true + "is_self_terminating": true, + "process_arguments": ["-a", "-b"] }, "deployment_config": { - "executable_path" : "/opt/scripts/setup_filesystem.sh", - "process_arguments": ["-a", "-b"] + "bin_dir": "/opt/scripts" } }, "dlt-daemon": { "component_properties": { + "binary_name": "dltd", "is_native_application": true, "is_supervised": false, "depends_on": { @@ -238,16 +248,20 @@ All time periods will be configured in seconds. If a smaller time period is need } }, "deployment_config": { - "executable_path" : "/opt/apps/dlt-daemon/dltd" + "bin_dir" : "/opt/apps/dlt-daemon" } }, "someip-daemon": { + "component_properties": { + "binary_name": "someipd" + }, "deployment_config": { - "executable_path" : "/opt/apps/someip/someipd" + "bin_dir" : "/opt/apps/someip" } }, "test_app1": { "component_properties": { + "binary_name": "test_app1", "depends_on": { "dlt-daemon": { "required_state": "Running" @@ -258,11 +272,12 @@ All time periods will be configured in seconds. If a smaller time period is need } }, "deployment_config": { - "executable_path" : "/opt/apps/test_app1/test_app1" + "bin_dir" : "/opt/apps/test_app1" } }, "state_manager": { "component_properties": { + "binary_name": "sm", "is_state_manager": true, "depends_on": { "setup_filesystem_sh": { @@ -271,7 +286,7 @@ All time periods will be configured in seconds. If a smaller time period is need } }, "deployment_config": { - "executable_path" : "/opt/apps/state_manager/sm" + "bin_dir" : "/opt/apps/state_manager" } } },