Skip to content

fix: move kubeconfig and podman injection to backend to prevent browser cancellation#1475

Open
olexii4 wants to merge 1 commit intomainfrom
CHE-23694
Open

fix: move kubeconfig and podman injection to backend to prevent browser cancellation#1475
olexii4 wants to merge 1 commit intomainfrom
CHE-23694

Conversation

@olexii4
Copy link
Contributor

@olexii4 olexii4 commented Mar 10, 2026

What does this PR do?

This PR fixes a race condition where injectKubeConfig and podmanLogin API requests are cancelled by the browser when the Dashboard navigates to the IDE URL (eclipse-che/che#23694).

When a workspace transitions to RUNNING status, the Dashboard frontend simultaneously fires background API calls (injectKubeConfig, podmanLogin) and navigates the browser to the IDE URL. When the Dashboard runs in a single browser tab, the browser cancels all pending HTTP requests upon navigation, causing the kubeconfig and podman credentials to never be injected into workspace containers.

The fix moves the injection trigger from the frontend WebSocket handler to the backend PATCH route, where it runs server-side and is not affected by browser navigation.

The Race Condition (before this fix)

WebSocket: Workspace RUNNING
           │
     ┌─────┴──────┐
     ▼             ▼
handleWSMsg    Redux store update
     │             │
     ▼             ▼
injectKubeConfig   OpenWorkspace.runStep()
podmanLogin        → detects isRunning
(HTTP POST)        → checks endpoint
     │             │
     │             ▼
     │         window.location.replace(ideUrl)
     │             │
     ▼             ▼
 ❌ CANCELLED   ✓ Browser navigates to IDE

Key Changes:

  1. PostStartInjector service — New server-side service that watches a specific DevWorkspace via the Kubernetes Watch API after it is started and injects kubeconfig + podman credentials once it reaches the Running phase. Contains:
    • watchAndInject static method — Starts a per-workspace Kubernetes watch keyed by namespace/name
    • Duplicate subscription guard — Prevents multiple watchers for the same workspace
    • Auto-cleanup on: successful injection, Failed phase, 60-second timeout, or watch error
  2. devworkspaces.ts PATCH route update — When the PATCH request sets spec.started: true, the route triggers PostStartInjector.watchAndInject() to begin monitoring the workspace server-side
  3. getKubeConfig helper — New helper that returns a KubeConfig configured with the user's token, needed by the Kubernetes Watch API
  4. getDevWorkspaceClient mock update — Added podmanApi mock and getKubeConfig mock for test coverage
  5. devworkspaces.spec.ts test update — Added PostStartInjector mock to backend route tests
  6. handleWebSocketMessage.ts update — Removed the injectKubeConfig/podmanLogin block and related imports from the frontend WebSocket message handler
  7. handleWebSocketMessage.spec.ts test update — Removed tests that verified the (now-removed) frontend injection behavior

Behavior:

Scenario Patch payload Backend action
Workspace start (spec.started: true) [{op: "replace", path: "/spec/started", value: true}] PostStartInjector creates a Kubernetes watch, waits for Running, injects kubeconfig + podman login
Workspace reaches Running injectKubeConfig and podmanLogin called server-side, watcher unsubscribes
Workspace enters Failed phase Watcher unsubscribes, no injection attempted
Workspace does not reach Running within 60s Watcher times out and unsubscribes
Multiple rapid start requests for the same workspace Only one watcher is created (deduplication by namespace/name key)
Non-start PATCH (e.g., annotation update) [{op: "replace", path: "/metadata/annotations", ...}] No watcher created, standard PATCH behavior

Note: The frontend no longer triggers injectKubeConfig or podmanLogin. All injection is handled server-side by the backend process, which is long-lived and unaffected by browser navigation.

Screenshot/screencast of this PR

N/A — backend-only behavioral change, no UI modifications.

What issues does this PR fix or reference?

fixes eclipse-che/che#23694

Is it tested? How?

Deploy Eclipse Che with the image from this PR.

Test KubeConfig and Podman Injection (single tab):

  1. Deploy Eclipse Che with the Dashboard image from this PR
  2. Open the Eclipse Che Dashboard in a browser: {che-server}/dashboard/
  3. Close all other browser tabs — ensure the dashboard is running in the only open tab
  4. Open browser DevTools → Network tab (filter by "XHR" or "Fetch" for clarity)
  5. Navigate to a factory URL by changing the browser address to:
    {che-server}/dashboard/#https://registry.devfile.io/devfiles/nodejs-mongodb/1.0.0
    
  6. Observe the workspace creation and starting process
  7. When the workspace transitions to RUNNING, the browser should navigate to the IDE without cancelling any requests

Verify:

  • No kubeconfig or podmanlogin POST requests appear in the browser Network tab (they now happen server-side)
  • kubectl get pods works inside the workspace terminal (kubeconfig was injected)
  • podman login to the OpenShift internal registry succeeds (podman credentials were injected)
  • Backend logs show PostStartInjector messages confirming successful injection:
    PostStartInjector: <namespace>/<workspace> is Running, injecting kubeconfig and podman login
    

Test timeout / failure scenarios:

  1. Start a workspace that is known to fail (e.g., invalid devfile)
  2. Check backend logs — PostStartInjector should log abort on Failed phase
  3. If a workspace takes longer than 60 seconds, the watcher should timeout and log a warning

Release Notes

fix: injectKubeConfig and podmanLogin now execute server-side when a workspace starts, preventing request cancellation when the browser navigates to the IDE URL (eclipse-che/che#23694)

Docs PR

N/A

@che-bot
Copy link
Contributor

che-bot commented Mar 10, 2026

Click here to review and test in web IDE: Contribute

@openshift-ci
Copy link

openshift-ci bot commented Mar 10, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: olexii4

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

@github-actions
Copy link

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1475

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1475", name: che-dashboard}]}}]"

@olexii4 olexii4 changed the title Che 23694 fix: move kubeconfig and podman injection to backend to prevent browser cancellation Mar 10, 2026
@olexii4 olexii4 requested a review from svor March 10, 2026 15:07
@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.39%. Comparing base (fcf9bd9) to head (3bbc8b1).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1475      +/-   ##
==========================================
+ Coverage   93.35%   93.39%   +0.03%     
==========================================
  Files         562      563       +1     
  Lines       54290    54431     +141     
  Branches     4114     4130      +16     
==========================================
+ Hits        50681    50834     +153     
+ Misses       3565     3553      -12     
  Partials       44       44              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1475

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1475", name: che-dashboard}]}}]"

The frontend WebSocket handler fired injectKubeConfig and podmanLogin
HTTP requests when a workspace reached Running status. Because the
browser simultaneously navigates to the IDE URL, those requests were
cancelled when the Dashboard ran in a single tab.

Move the injection trigger to the backend PATCH route: when a patch
sets spec.started=true, a PostStartInjector watches the DevWorkspace
via the Kubernetes Watch API and calls injectKubeConfig/podmanLogin
server-side once the workspace reaches Running. The watcher auto-
cleans up on success, Failed phase, or a 60-second timeout, and
prevents duplicate subscriptions per workspace.

Fixes eclipse-che/che#23694

Assisted-by: Cursor
Signed-off-by: Oleksii Orel <oorel@redhat.com>
@github-actions
Copy link

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1475

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1475", name: che-dashboard}]}}]"

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.

[UD] PodmanLogin and InjectKubeConfig Requests Fail When Dashboard Runs in a Single Tab

2 participants