Skip to content

Conversation

Fortune-Ndlovu
Copy link
Member

@Fortune-Ndlovu Fortune-Ndlovu commented Mar 20, 2025

Description

This PR introduces a new convention for user-specific config overrides using a structured directory layout inside the existing configs/ folder. These override files are .gitignore'd and will automatically be loaded by the system at runtime.

New directory structure

configs/
├── app-config/
│   ├── app-config.yaml                  # Default (tracked)
│   └── app-config.local.yaml            # User override (git-ignored)
├── dynamic-plugins/
│   ├── dynamic-plugins.yaml             # Default (tracked)
│   └── dynamic-plugins.override.yaml    # User override (git-ignored)
├── extra-files/                         # Optional additional files
│   ├── github-app-credentials.example.yaml
│   ├── github-app-credentials.local.yaml
│   └── (any other user file)

Entrypoint updates

  • fixes.sh (install-dynamic-plugins container):

    • Detects and symlinks dynamic-plugins.override.yaml as the active config, falling back to the default otherwise.
  • wait-for-plugins.sh (rhdh container):

    • Checks for app-config.local.yaml and appends it to the list of configs passed to the node packages/backend startup command.

Git ignores

Updated .gitignore to:

  • Exclude all *.local.yaml and override files
  • Exclude all files in extra-files/, except the github-app-credentials.example.yaml

Result

Users can now:

  • Add local config overrides without touching version-controlled files.
  • Pull upstream changes without merge issues.
  • Use *.local.yaml and override files that are auto-loaded at runtime.

Which issue(s) does this PR fix or relate to

PR acceptance criteria

  • Tests
  • Documentation

How to test changes / Special notes to the reviewer

…onflicts

- Added  and  as sample configuration files.
- Removed  and  from the repository.
- Updated  to exclude user-specific config files.
- Modified  to allow missing config files and fall back to sample files if necessary.
- Updated README with instructions on copying sample config files.

Signed-off-by: Fortune-Ndlovu <[email protected]>
@rm3l
Copy link
Member

rm3l commented Mar 20, 2025

/cc @rm3l @kadel @benwilcock

@openshift-ci openshift-ci bot requested review from benwilcock, kadel and rm3l March 20, 2025 17:04
@rm3l
Copy link
Member

rm3l commented Mar 21, 2025

This PR introduces a user-friendly approach to managing configuration files in RHDH Local, ensuring users can modify their setup without conflicting with repository updates.

Key Changes:

  • Added configs/app-config.local.yaml.sample and configs/dynamic-plugins.yaml.sample as template configuration files.

  • Removed configs/app-config.local.yaml and configs/dynamic-plugins.yaml from the repository to avoid merge conflicts.

  • Updated .gitignore to ignore user-created config files (app-config.local.yaml, dynamic-plugins.yaml).

  • Modified compose.yaml:

    • Ensures missing config files don’t break the setup by falling back to sample files.
    • Simplified volume mounts for install-dynamic-plugins.
  • Updated the README:

    • Instructs users to copy sample files before making custom modifications.
    • Clarifies that the system will default to sample configurations if the user skips this step.

As I was concerned that this would not work OOTB without copying the app-config.yaml.sample and dynamic-plugins.yaml.sample files, I was thinking of another approach that could probably help here.

Since we control the entrypoint scripts used by both the install-dynamic-plugins and rhdh containers, and that we are mounting the whole configs folder in both containers, I think maybe we can tweak these scripts such that they allow us to support this "user configs" case.

I mean, with a new configs folder structure like this (making sure to git-ignore any *.local.yaml files):

configs/
├── app-config/
│   ├── app-config.local.yaml (git-ignored)
│   └── app-config.yaml
├── dynamic-plugins/
│   ├── dynamic-plugins.override.yaml (git-ignored)
│   └── dynamic-plugins.yaml
└── extra-files/ (git-ignore everything here except github-app-credentials.example.yaml)
    ├── github-app-credentials.example.yaml
    └── github-app-credentials.local.yaml (git-ignored)
    └── any-other-user-file (git-ignored)

We could do the following:

  1. change the fixes.sh script (entrypoint of the install-dynamic-plugins container) to check for the presence of the configs/dynamic-plugins/dynamic-plugins.override.yaml file and create a symlink , like so:
if [ -f "configs/dynamic-plugins/dynamic-plugins.override.yaml" ]; then
    echo "Using dynamic-plugins.override.yaml file"
    ln -sf /opt/app-root/src/configs/dynamic-plugins/dynamic-plugins.override.yaml /opt/app-root/src/dynamic-plugins.yaml
else
    ln -sf /opt/app-root/src/configs/dynamic-plugins/dynamic-plugins.yaml /opt/app-root/src/dynamic-plugins.yaml
fi
  1. change the wait-for-plugins.sh script (entrypoint of the rhdh container) to check for the presence of the configs/app-config/app-config.local.yaml file and append it to the node process args, like so:
USER_APP_CONFIG="configs/app-config/app-config.local.yaml"
extraCliArgs=""
if [ -f "$USER_APP_CONFIG" ]; then
    extraCliArgs="--config $USER_APP_CONFIG"
fi

node packages/backend --no-node-snapshot \
    --config app-config.yaml \
    --config app-config.example.yaml \
    --config app-config.example.production.yaml \
    --config $DYNAMIC_PLUGINS_CONFIG \
    --config configs/app-config/app-config.yaml $extraCliArgs

This way, users would just need to create their configs/dynamic-plugins/dynamic-plugins.override.yaml file and/or configs/app-config/app-config.local.yaml and/or any configs/extra-files/* file and it would work automagically.

Just like when working with a local Backstage, this would allow users to append their app-config.local.yaml to the Node process and Backstage would handle the merging of the various app-config files.

Thoughts? @kadel @benwilcock @Fortune-Ndlovu

@Fortune-Ndlovu
Copy link
Member Author

Thanks, Armel for the great suggestion, I’ve now implemented this approach!

Refactored configs/ into a structured layout:

  • configs/app-config/app-config.yaml (default)
  • configs/app-config/app-config.local.yaml (user override, git-ignored)
  • configs/dynamic-plugins/dynamic-plugins.yaml (default)
  • configs/dynamic-plugins/dynamic-plugins.override.yaml (user override, git-ignored)
  • configs/extra-files/ for any additional user config (like GitHub credentials)

Updated fixes.sh and wait-for-plugins.sh to:

  • Automatically load user override configs if present
  • Fall back to defaults if not

Removed the need to manually copy .sample files — the system now works out-of-the-box.

Updated .gitignore, compose.yaml, test.yml, and the README.md accordingly.

@Fortune-Ndlovu
Copy link
Member Author

CI unhappy

curl: (7) Failed to connect to localhost port 7007
Max retries reached. Exiting.

The HTTP 200 check step timed out after 30 retries meaning:
The container is running, but Backstage never started
Or the container crashed early
Or something in the new wait-for-plugins.sh or config logic broke app startup 👀

my-name added 6 commits March 31, 2025 14:33
…he image. AND made the default app-onfig file from this repo to be last

Signed-off-by: my-name <my-email>
…milar to the rhdh repo. Also Ignore dynamic-plugins.override.yaml and extra-files/* BUT Keep legacy files (e.g., dynamic-plugins.yaml, github-app-credentials.example.yaml) ignored for backward compatibility.

Signed-off-by: my-name <my-email>
…mic-plugins.override.yaml file instead. So dynamic-plugins.local.yaml is not needed.

Signed-off-by: my-name <my-email>
…l' but also copy it to 'configs/github-app-credentials.example.yaml' for backward compatibility and made sure that 'configs/github-app-credentials.example.yaml' is git-ignored. MOREOVER Keep 'configs/dynamic-plugins/dynamic-plugins.yaml' but also copy it to 'configs/dynamic-plugins.yaml', for backward compatibility and made sure that configs/dynamic-plugins.yaml is git-ignored. MOREOVER keep 'configs/app-config/app-config.yaml' and copy it to configs/app-config.local.yaml, for backward compatibility?

Just make sure that configs/app-config.local.yaml is git-ignored.

Signed-off-by: my-name <my-email>
…sting users nor create any Git conflicts.

Signed-off-by: my-name <my-email>
… break existing users nor create any Git conflicts.

Signed-off-by: my-name <my-email>
@Fortune-Ndlovu
Copy link
Member Author

/cc @rm3l @kadel @benwilcock for review please!

my-name added 2 commits April 15, 2025 10:56
…c-plugins.yaml can be loaded if present as well.

Signed-off-by: my-name <my-email>
…expand the string into proper CLI flags instead of passing it as one long argument.

Signed-off-by: my-name <my-email>
@Fortune-Ndlovu Fortune-Ndlovu requested a review from kadel April 16, 2025 13:53
Copy link
Member

@kadel kadel left a comment

Choose a reason for hiding this comment

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

missing example files

Signed-off-by: my-name <my-email>
@Fortune-Ndlovu
Copy link
Member Author

Fortune-Ndlovu commented Apr 16, 2025

@kadel, do we need example files? I feel like adding additional files may add additional complexity for new users

@Fortune-Ndlovu Fortune-Ndlovu requested a review from kadel April 16, 2025 14:50
Copy link
Member

@rm3l rm3l left a comment

Choose a reason for hiding this comment

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

do we need example files? I feel like adding additional files may add additional complexity for new users

I agree it could be helpful to have a few example files.
So I'd suggest adding a configs/app-config/app-config.local.example.yaml with a GH integration referencing the configs/extra-files/github-app-credentials.example.yaml file, along with a configs/dynamic-plugins/dynamic-plugins.override.example.yaml file.

@kadel
Copy link
Member

kadel commented Apr 22, 2025

@kadel, do we need example files? I feel like adding additional files may add additional complexity for new users

I'm convinced about the opposite. Almost every user will need dynamic-plugins.override.yaml and app-config.local.yaml and without an example that they can easily copy to bootstrap their custom configs we are making it first run a lot more complex.

We are already using the pattern of the example, configs that user's copies with default.env and github-app-credentials.example.yaml. We should do the same with dynamic plugins config and app-config as well.

…e the copy if they wish.

Signed-off-by: my-name <my-email>
@Fortune-Ndlovu Fortune-Ndlovu force-pushed the user-config-sample-files branch from 2376639 to 3576b66 Compare April 24, 2025 11:11
@Fortune-Ndlovu Fortune-Ndlovu requested a review from rm3l April 24, 2025 14:59
@Fortune-Ndlovu Fortune-Ndlovu requested a review from rm3l April 24, 2025 22:29
@Fortune-Ndlovu
Copy link
Member Author

cc/ @kadel @rm3l, final review needed please :)

…amic-plugins.override.yaml

Signed-off-by: my-name <my-email>
Copy link
Member

@rm3l rm3l left a comment

Choose a reason for hiding this comment

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

LGTM with the review comments addressed. I've also checked that the approach here remains backward-compatible.

/lgtm

@openshift-ci openshift-ci bot added the lgtm label Apr 25, 2025
@rm3l rm3l merged commit 5a53cd5 into redhat-developer:main Apr 25, 2025
7 checks passed
rm3l added a commit to rm3l/rhdh-local that referenced this pull request Apr 25, 2025
@rm3l rm3l mentioned this pull request Apr 25, 2025
2 tasks
rm3l added a commit that referenced this pull request Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants