Skip to content

[fournos_launcher] Allow deploying clusterless jobs - #123

Merged
kpouget merged 12 commits into
openshift-psap:mainfrom
kpouget:fournos
Jul 16, 2026
Merged

[fournos_launcher] Allow deploying clusterless jobs#123
kpouget merged 12 commits into
openshift-psap:mainfrom
kpouget:fournos

Conversation

@kpouget

@kpouget kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

goes along with openshift-psap/fournos#99

Summary by CodeRabbit

  • New Features
    • Added a CI launcher command entry point and a forge-launcher Tekton pipeline to run launcher tasks and always export artifacts (also expanded workflow pipeline resources).
    • Added FOURNOS /clusterless and /fournos directives, including validation and environment-based namespace targeting.
  • Bug Fixes
    • Improved forge step kubeconfig handling with an optional secret parameter, safer conditional kubeconfig export, and clusterless fallback when kubeconfig is missing.
    • Updated orchestration validation and submit/submit-and-wait to support clusterless mode without a cluster while rejecting clusterless+exclusive conflicts.

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign albertoperdomo2 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kpouget, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 04145a16-ce2b-4134-af14-044f8a1c1da3

📥 Commits

Reviewing files that changed from the base of the PR and between 736bead and db89654.

📒 Files selected for processing (13)
  • fournos/gitops/base/workflows/kustomization.yaml
  • fournos/gitops/base/workflows/pipeline-launcher.yaml
  • fournos/gitops/base/workflows/pipeline-prepare-test.yaml
  • fournos/gitops/base/workflows/task-forge-step.yaml
  • projects/fournos_launcher/CHANGELOG-orchestration.md
  • projects/fournos_launcher/CHANGELOG-toolbox.md
  • projects/fournos_launcher/orchestration/cli.py
  • projects/fournos_launcher/orchestration/config.yaml
  • projects/fournos_launcher/orchestration/pr_args.py
  • projects/fournos_launcher/orchestration/submit.py
  • projects/fournos_launcher/toolbox/submit_and_wait/main.py
  • projects/fournos_launcher/toolbox/submit_and_wait/templates/job.yaml.j2
  • projects/skeleton/orchestration/ci.py
📝 Walkthrough

Walkthrough

The PR adds clusterless and Fournos environment directives, permits submission without a cluster, introduces a launcher command and Tekton pipeline, and makes kubeconfig setup conditional when the secret is unavailable.

Changes

Clusterless launcher workflow

Layer / File(s) Summary
Clusterless configuration and validation
projects/fournos_launcher/orchestration/config.yaml, projects/fournos_launcher/orchestration/pr_args.py, projects/fournos_launcher/orchestration/submit.py
Adds clusterless configuration, /clusterless and /fournos directive handlers, conflict validation, and submission parameter propagation.
Clusterless submission interface
projects/fournos_launcher/orchestration/cli.py, projects/fournos_launcher/toolbox/submit_and_wait/main.py, projects/fournos_launcher/toolbox/submit_and_wait/templates/job.yaml.j2
Propagates clusterless mode through CLI and submission APIs, validates cluster and exclusive settings, and renders either clusterless or cluster-backed job configuration.
Launcher command and Tekton pipeline
projects/skeleton/orchestration/ci.py, fournos/gitops/base/workflows/pipeline-launcher.yaml, fournos/gitops/base/workflows/kustomization.yaml, fournos/gitops/base/workflows/pipeline-prepare-test.yaml
Adds the launcher CLI command, registers workflow manifests, sequences launcher tasks, and updates the prepare-test dependency chain.
Conditional kubeconfig setup
fournos/gitops/base/workflows/task-forge-step.yaml
Uses a placeholder parameter and optional secret volume to select between normal kubeconfig and clusterless execution.
Workflow changelog updates
projects/fournos_launcher/CHANGELOG-orchestration.md, projects/fournos_launcher/CHANGELOG-toolbox.md
Documents the clusterless directives, validation, optional cluster selection, and conditional job rendering.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI as Fournos submit CLI
  participant Submit as submit_job
  participant Tekton as forge-launcher Pipeline
  participant Forge as forge-step Task
  CLI->>Submit: Provide clusterless or Fournos configuration
  Submit->>Tekton: Start launcher pipeline
  Tekton->>Forge: Run preflight and launcher tasks
  Forge->>Forge: Select kubeconfig or clusterless mode
  Tekton->>Forge: Export artifacts in finally
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enabling clusterless job deployment.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
fournos/gitops/base/workflows/task-forge-step.yaml (1)

16-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Placeholder string duplicated between param default and script logic.

The value "fournos-clusterless-placeholder" appears as the param default here and is hardcoded again in the script at lines 81 and 87. If one is updated without the other, the conditional logic silently breaks. Consider adding a comment cross-referencing the locations, or deriving the comparison from a single env var.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fournos/gitops/base/workflows/task-forge-step.yaml` around lines 16 - 17, The
kubeconfig placeholder is duplicated between the parameter default and script
logic. Update the workflow’s kubeconfig handling to derive the comparisons from
the parameter/environment value or otherwise centralize the placeholder,
ensuring the default and checks cannot diverge; anchor the change around the
kubeconfig parameter and the script’s placeholder checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@fournos/gitops/base/workflows/task-forge-step.yaml`:
- Around line 16-17: The kubeconfig placeholder is duplicated between the
parameter default and script logic. Update the workflow’s kubeconfig handling to
derive the comparisons from the parameter/environment value or otherwise
centralize the placeholder, ensuring the default and checks cannot diverge;
anchor the change around the kubeconfig parameter and the script’s placeholder
checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d09354f8-7089-40b9-8a99-611496cb8534

📥 Commits

Reviewing files that changed from the base of the PR and between b19e99f and d090f38.

📒 Files selected for processing (2)
  • fournos/gitops/base/workflows/task-forge-step.yaml
  • projects/skeleton/orchestration/ci.py

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 0 seconds

01 Launcher 0 seconds

🔄 02 Export-Artifacts

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: /cluster (cluster.name) must be set - cannot submit job without target cluster

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: cluster_name is required

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: cluster_name is required unless clusterless mode is enabled

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: cluster_name is required unless clusterless mode is enabled

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
projects/fournos_launcher/toolbox/submit_and_wait/main.py (1)

49-66: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider relaxing the cluster_name type hint for clusterless mode.

cluster_name: str is a required positional parameter with no default, but in clusterless mode the caller (e.g., submit.py) may pass None when cluster.name is absent from config. The type hint should reflect this: str | None = None or str = "".

♻️ Suggested type hint update
 def run(
-    cluster_name: str,
+    cluster_name: str | None = None,
     project: str,
     *,
     args: list = None,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/fournos_launcher/toolbox/submit_and_wait/main.py` around lines 49 -
66, The run function’s cluster_name annotation requires a string even though
clusterless callers may provide no cluster name. Update run’s cluster_name
parameter to accept None and default appropriately, preserving existing behavior
for configured cluster names and clusterless execution.
projects/fournos_launcher/orchestration/cli.py (1)

60-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Eliminate redundant get_config("fournos.job.clusterless") call.

clusterless_mode is fetched at line 60 inside the else block and then unconditionally re-fetched at line 68. When the else branch is taken, this produces a duplicate get_config call (including duplicate log output). Hoist the fetch above the validation so it's only called once.

♻️ Proposed refactor
     if cluster:
         config.project.set_config("cluster.name", cluster)
     else:
         cluster = config.project.get_config("cluster.name")
-        clusterless_mode = config.project.get_config("fournos.job.clusterless")
 
-        if not cluster and not clusterless_mode:
+    clusterless_mode = config.project.get_config("fournos.job.clusterless")
+
+    if not cluster and not clusterless_mode:
         raise ValueError(
             "--cluster or cluster.name is mandatory (unless clusterless mode is enabled)"
         )
 
-    # Validate clusterless and exclusive modes are not both enabled
-    clusterless_mode = config.project.get_config("fournos.job.clusterless")
     exclusive_mode = config.project.get_config("fournos.job.exclusive")
     if clusterless_mode and exclusive_mode:
         raise ValueError(
             "Clusterless mode and exclusive mode cannot both be enabled - use /clusterless (sets exclusive=false) or /exclusive false"
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/fournos_launcher/orchestration/cli.py` around lines 60 - 78, Hoist
the clusterless_mode assignment before the cluster/clusterless validation in the
surrounding CLI function, then reuse that variable for both the
mandatory-cluster check and the clusterless/exclusive conflict check. Remove the
inner else-block fetch and the later duplicate get_config call, preserving the
existing validation and logging behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@projects/fournos_launcher/orchestration/cli.py`:
- Around line 60-78: Hoist the clusterless_mode assignment before the
cluster/clusterless validation in the surrounding CLI function, then reuse that
variable for both the mandatory-cluster check and the clusterless/exclusive
conflict check. Remove the inner else-block fetch and the later duplicate
get_config call, preserving the existing validation and logging behavior.

In `@projects/fournos_launcher/toolbox/submit_and_wait/main.py`:
- Around line 49-66: The run function’s cluster_name annotation requires a
string even though clusterless callers may provide no cluster name. Update run’s
cluster_name parameter to accept None and default appropriately, preserving
existing behavior for configured cluster names and clusterless execution.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62dfd778-ebe6-431d-b18e-bcac3cb3ab54

📥 Commits

Reviewing files that changed from the base of the PR and between b08fc73 and f247582.

📒 Files selected for processing (6)
  • projects/fournos_launcher/orchestration/cli.py
  • projects/fournos_launcher/orchestration/config.yaml
  • projects/fournos_launcher/orchestration/pr_args.py
  • projects/fournos_launcher/orchestration/submit.py
  • projects/fournos_launcher/toolbox/submit_and_wait/main.py
  • projects/fournos_launcher/toolbox/submit_and_wait/templates/job.yaml.j2
🚧 Files skipped from review as they are similar to previous changes (3)
  • projects/fournos_launcher/orchestration/config.yaml
  • projects/fournos_launcher/orchestration/submit.py
  • projects/fournos_launcher/orchestration/pr_args.py

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: cluster_name is required unless clusterless mode is enabled

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 0 seconds 🔴

Error: ValueError: cluster_name is required unless clusterless mode is enabled

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 15 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-skeleton-20260713-124550' failed: Failed to fetch Pipeline 'forge-launcher': Not Found

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget kpouget changed the title fournos: gitops: base/workflows/task-forge-step: update for clusterless jobs [fournos_launcher] Allow deploying clusterless jobs Jul 13, 2026
@kpouget

kpouget commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 0 seconds

01 Launcher 0 seconds

🔄 02 Export-Artifacts

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of skeleton succeeded after 1 minute, 13 seconds 🟢
/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of skeleton succeeded after 1 minute, 42 seconds 🟢
/test fournos skeleton
/pipeline forge-launcher
/fournos wip
/cluster psap-mgmt

@kpouget

kpouget commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 0 seconds

01 Launcher 0 seconds

🔄 02 Export-Artifacts

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of skeleton succeeded after 1 minute, 25 seconds 🟢
/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/cluster psap-mgmt
/pipeline forge-launcher

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of skeleton failed after 5 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-skeleton-20260715-112305' failed: Failed to fetch Pipeline 'forge-launcher': Not Found

/test fournos skeleton
/cluster psap-mgmt
/pipeline forge-launcher

@kpouget

kpouget commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/cluster psap-mgmt
/pipeline forge-test-only

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 0 seconds

01 Test 12 seconds

🔄 02 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of skeleton succeeded after 1 minute, 48 seconds 🟢
/test fournos skeleton
/cluster psap-mgmt
/pipeline forge-test-only

@kpouget

kpouget commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 0 seconds

01 Launcher 0 seconds

🔄 02 Export-Artifacts

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of skeleton succeeded after 3 minutes, 7 seconds 🟢
/test fournos skeleton
/clusterless
/pipeline forge-launcher
/fournos wip

@kpouget

kpouget commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

tests passed in the WIP namespace, merging this 👍🏻

@kpouget
kpouget enabled auto-merge July 16, 2026 12:46
@kpouget
kpouget merged commit 441ea2d into openshift-psap:main Jul 16, 2026
5 checks passed
@kpouget
kpouget deleted the fournos branch July 16, 2026 12:48
@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of skeleton 🟢

Execution Engine Configuration

forge:
  args: []
  configOverrides: {}
  project: skeleton

Artifact Links

Test Logs

00 Preflight 1 second

Vault Extra File Psap-Forge-Notifications Slack-Webhook-Url

Extra vault file detected: psap-forge-notifications/slack-webhook-url

This file exists in the vault but is not defined in the vault specification. This is not an error but should be reviewed for security purposes.

01 Launcher 0 seconds

Vault Extra File Psap-Forge-Notifications Slack-Webhook-Url

Extra vault file detected: psap-forge-notifications/slack-webhook-url

This file exists in the vault but is not defined in the vault specification. This is not an error but should be reviewed for security purposes.

🔄 02 Export-Artifacts

Vault Extra File Psap-Forge-Notifications Slack-Webhook-Url

Extra vault file detected: psap-forge-notifications/slack-webhook-url

This file exists in the vault but is not defined in the vault specification. This is not an error but should be reviewed for security purposes.

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.

1 participant