Skip to content

Feature/load new lifecycle config#208

Draft
NicolasFussberger wants to merge 16 commits into
eclipse-score:mainfrom
etas-contrib:feature/load-new-lifecycle-config
Draft

Feature/load new lifecycle config#208
NicolasFussberger wants to merge 16 commits into
eclipse-score:mainfrom
etas-contrib:feature/load-new-lifecycle-config

Conversation

@NicolasFussberger
Copy link
Copy Markdown
Contributor

@NicolasFussberger NicolasFussberger commented May 19, 2026

  • Introduces an interface in src/launch_manager_daemon/config for loading a launch manager configuration file
  • Introduce an implementation of this interface using flatbuffer
  • Introduce unit tests for the new code

Note: The code is not actually in use yet. The python script which does the translation from the user-facing json configuration to the flatbuffer json format is not part of the PR and will be added in a follow up PR.
Furthermore, the launch manager code needs to be adapted to use the new structure.

Background:

  • In the last months we had defined a new user-facing configuration format (see src/launch_manager_daemon/config/config_schema/launch_manager.schema.json).
  • However, this new format is currently still mapped to the old configuration files (to processes / process groups). So the code is not actually reading the new configuration file

Relates To: #209

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.4.2) and connecting to it...
INFO: Invocation ID: 9f4ce11a-7031-4d5b-980e-a0acc98003bd
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (32 packages loaded, 10 targets configured)

Analyzing: target //:license-check (85 packages loaded, 10 targets configured)

Analyzing: target //:license-check (138 packages loaded, 2720 targets configured)

Analyzing: target //:license-check (147 packages loaded, 6739 targets configured)

Analyzing: target //:license-check (151 packages loaded, 8079 targets configured)

Analyzing: target //:license-check (158 packages loaded, 8128 targets configured)

Analyzing: target //:license-check (158 packages loaded, 8130 targets configured)

INFO: Analyzed target //:license-check (163 packages loaded, 10268 targets configured).
[8 / 16] [Prepa] Creating runfiles tree bazel-out/k8-opt-exec-ST-d57f47055a04/bin/external/score_tooling+/dash/tool/formatters/dash_format_converter.runfiles [for tool]
[13 / 16] JavaToolchainCompileClasses external/rules_java+/toolchains/platformclasspath_classes; 0s disk-cache, processwrapper-sandbox
[15 / 16] Building license.check.license_check.jar (); 0s disk-cache, multiplex-worker
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 20.998s, Critical Path: 2.41s
INFO: 16 processes: 12 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 16 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions
Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

Comment thread MODULE.bazel
module_name = "score_baselibs",
commit = "498a4b256c9073602140243d30c33b106e279f75",
remote = "https://github.com/eclipse-score/baselibs.git",
)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulquiring Any idea when a new baselibs release will be available containing the new flatbuffer functionality?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
}

private:
friend class Builder;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment would have been helpful to mention that this saves the need to write getters in the builder class.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed in meeting. The friend is needed to access the private constructor of the Config class.
This is in line with typical builder pattern implementation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving the Builder class to the outer scope so that it is not a nested class anymore.
Nested class is not required and may be discouraged by some SCA rules.

Done in f70d64b

Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp
{
if (ev != nullptr && ev->key() != nullptr)
{
result.emplace(ev->key()->str(), safeString(ev->value()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the key cannot be nullptr?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the flatbuffer schema I have defined it as

// A key-value pair representing an environment variable.
table EnvironmentalVariable {
  key:string (required);
  value:string (required);
}

So I think if an environment variable is there, the key and value must be available.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding asserts for values that are never expected to be nullptr.
safestring can be removed for value() because it is required in the schema

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asserts added in 99cdb9c


SwitchRunTargetAction convertRequiredSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa)
{
return convertSwitchRunTargetAction(sa).value();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value can throw.
Image

.value_or(std::string{}) as alternative?

Copy link
Copy Markdown
Contributor Author

@NicolasFussberger NicolasFussberger May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should never happen because the SwitchRunTargetRecoveryAction is defined as required in this context:

// Configuration for a Run Target representing an operational mode of the system.
table RunTarget {
 ....
  // Recovery action when a component in this Run Target fails.
  recovery_action:SwitchRunTargetAction (required);
}

However to be defensive against potential future changes on the schema, we could:

  • Add a try/catch within parseFlatbuffer and return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); in case there is any exception.
  • And/or put in an assertion
    auto opt=convertSwitchRunTargetAction(sa)
    assert(opt.has_value() && "SwitchRunTargetAction is null although it is expected to be a mandatory configuration");
    return opt.value();

What do you think?

Copy link
Copy Markdown
Contributor Author

@NicolasFussberger NicolasFussberger May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed: We shall add asserts

Done in 99cdb9c

Comment thread MODULE.bazel
module_name = "score_baselibs",
commit = "498a4b256c9073602140243d30c33b106e279f75",
remote = "https://github.com/eclipse-score/baselibs.git",
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constexpr int32_t kExpectedSchemaVersion = 1;
constexpr double kSecondsToMilliseconds = 1000.0;

uint32_t secondsToMs(double seconds)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <iostream>
#include <cstdint>
#include <string_view>
#include <cassert>

constexpr double kSecondsToMilliseconds = 1000.0;

uint32_t secondsToMs(double seconds)
{
    return static_cast<uint32_t>(seconds * kSecondsToMilliseconds);
}

int main () {
    assert(secondsToMs(0.000500) == 0);// holds is this a problem ?
    assert(secondsToMs(0.001000) == 1);
}

if this is a problem we might need to change the fbs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is not an issue.

The user is configuring all time values in seconds

Though we should reconsider whether the want to switch the configuration to ms.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to safeguard that the user does not configure anything < 1ms?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an assertion for now, to be moved to schema validation later

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assertion added in a1f2860

Assertion fails if configured seconds > 0 but is rounded down to 0ms.

Comment thread src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs
@paulquiring
Copy link
Copy Markdown
Contributor

review from my side is finished.


uint32_t secondsToMs(double seconds)
{
return static_cast<uint32_t>(seconds * kSecondsToMilliseconds);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this result in UB if seconds < 0 or > UINT32_MAX?

Schema validator should take care about negative input, but static analysis or compiler warnings may not know about this. However we don't have cap on max timeout in schema.

Maybe we can log warning if value is too small or too big and apply some boundary values

Config::Builder builder;

// initial_run_target is a required field, guaranteed non-null by the schema and verifier.
builder.setInitialRunTarget(config->initial_run_target()->str());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have mixed feelings about defensive coding, but if somebody prepares crazy config (bypassing verifier), we will crash instead of printing error message and exiting.

However if somebody is doing this, then maybe, they should not expect much support from launch manager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants