Skip to content

Conversation

@rszwajko
Copy link
Member

@rszwajko rszwajko commented Nov 28, 2025

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Summary by CodeRabbit

  • New Features

    • Added HTTP and HTTPS constants to the public API for consistent protocol handling.
  • Bug Fixes

    • Improved VNC console disconnect flow to detect abnormal disconnects and perform an HTTP verification before cleanup.
    • Replaced a placeholder session check with real detection logic to determine if a VNC session is already in use.

✏️ Tip: You can customize this high-level summary in your review settings.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Nov 28, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Retrieve websocket error from the response.

🎥 Demo

TODO

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 28, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

📝 Walkthrough

Walkthrough

Adds HTTP/HTTPS constants, implements abnormal VNC disconnect detection (WS close code 1006) with an HTTP validation fallback to determine if a VNC session is in use, and replaces a no-op session check with a real isSessionAlreadyInUse(error: Error): boolean implementation.

Changes

Cohort / File(s) Summary
Protocol Constants
src/utils/components/Consoles/components/utils/ConsoleConsts.ts
Added two exported string constants: HTTP = 'http' and HTTPS = 'https'.
VNC Disconnect Handling
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
Added buildUrl helper and use for initial WS URL; introduced abnormalDisconnect detection for close code 1006; on abnormal disconnect, perform an HTTP fetch (consoleFetchText) to verify session use before cleanup; adjusted noVNC socket close handling to propagate abnormal disconnect detection.
Session In-Use Detection
src/utils/components/Consoles/components/vnc-console/utils/util.ts
Replaced no-op with export const isSessionAlreadyInUse(error: Error): boolean that checks error.message against a new internal VNC_IN_USE_ERROR_TEXT constant.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review propagation and reset of the abnormalDisconnect flag and interactions with existing cleanup paths.
  • Verify buildUrl produces correct ws/wss and http/https variants for encrypted vs. unencrypted flows.
  • Confirm consoleFetchText is invoked with the correct protocol and URL and that its result handling covers error cases.
  • Validate the exact VNC_IN_USE_ERROR_TEXT matches backend responses (avoid brittle string matching).

Suggested labels

lgtm

Suggested reviewers

  • galkremer1
  • metalice
  • Pedro-S-Abreu

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly identifies the main change as part 2 of a feature for VNC connections using the preserveSession flag, with a specific Jira reference.
Description check ✅ Passed The PR description includes a detailed explanation of the changes, references to related PRs and issues, reference URLs, a demo video, and is properly formatted with the provided template sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ceb0ba and 64c7412.

📒 Files selected for processing (3)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1 hunks)
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3 hunks)
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file with no nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components as the default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Extract as much logic as possible from components into custom hooks or utility files to improve testability and avoid bloated components.
Use default exports for all components.
Keep component files under 150 lines whenever possible.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders.
Lazy load components with React.lazy and Suspense for performance optimization.
Always specify dependencies in useEffect hooks to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic (e.g., API calls, data transformation, form handling).
Define constants in utility files with uppercase and underscore-separated naming (e.g., API_URL).
Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized (e.g., use fetchUserData instead of getData).
Keep functions short and focused on one action. Apply Red → Green → Refactor: write a failing solution, implement a working solution, then refactor for readability and performance.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using the any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions rather than relying on TypeScript to infer them from the implementation.
Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.
Keep global/store state minimal and straightforward. Obtain approval in the PR before adding new values to prevent bloating.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx,js,jsx}: Avoid comments whenever possible; write self-explanatory code. Use comments sparingly for unusual values or decisions to explain the rationale.
Avoid circular dependencies. Use index files cautiously to prevent situations that lead to circular imports.
Use Husky to run linters before commits and lint-staged to make it configurable. Do not skip linting.
Use Cypress or Playwright for end-to-end (E2E) testing to ensure comprehensive UI coverage.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use ESLint (with React and TypeScript plugins) and Prettier for consistent formatting and linting.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
**/*.ts

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use .ts file extension for non-component files containing logic or utilities.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
🧠 Learnings (2)
📚 Learning: 2025-11-28T11:04:05.062Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-11-28T11:04:05.062Z
Learning: Applies to **/*.{ts,tsx} : Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.

Applied to files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
📚 Learning: 2025-11-28T11:04:05.062Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-11-28T11:04:05.062Z
Learning: Applies to **/*.{ts,tsx} : Define constants in utility files with uppercase and underscore-separated naming (e.g., `API_URL`).

Applied to files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
🧬 Code graph analysis (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (4)
src/utils/components/Consoles/utils/utils.ts (1)
  • isConnectionEncrypted (1-1)
src/utils/components/Consoles/utils/constants.ts (2)
  • SECURE (1-1)
  • INSECURE (2-2)
src/utils/components/Consoles/components/utils/ConsoleConsts.ts (4)
  • WSS (18-18)
  • WS (17-17)
  • HTTPS (20-20)
  • HTTP (19-19)
src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)
  • isSessionAlreadyInUse (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: i18n
  • GitHub Check: build
  • GitHub Check: unit-test
🔇 Additional comments (4)
src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1)

17-20: HTTP/HTTPS constants are consistent with existing protocol helpers

Adding HTTP/HTTPS alongside WS/WSS follows the constant-naming guideline and centralizes protocol strings, which will help avoid magic values in consumers.

src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)

13-17: Session-in-use detection helper is straightforward and avoids magic strings

Factoring the backend error text into VNC_IN_USE_ERROR_TEXT and implementing isSessionAlreadyInUse as a small, typed helper makes the behavior clear and easy to update if the message ever changes. The use of optional chaining keeps it safe against unexpected error shapes.

src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (2)

5-5: Typed buildUrl helper simplifies URL construction and clarifies preserveSession usage

The new buildUrl consolidates URL construction for both WebSocket and HTTP flows and correctly types preserveSession as a boolean, matching how connect(preserveSession = true) is called. Centralizing protocol and port handling (with HTTP/HTTPS/WS/WSS and INSECURE/SECURE) removes string duplication and improves maintainability.

Also applies to: 9-9, 42-55


94-100: Verify error object structure for session-in-use detection

The session tracking and disconnect handling logic is sound, but the reliability of isSessionAlreadyInUse(error) depends on whether the error object rejected by consoleFetchText on non-2xx responses exposes the backend message in error.message. Confirm with the dynamic plugin SDK documentation or source code that the error object structure reliably contains the response body text so that matching against VNC_IN_USE_ERROR_TEXT will work as intended. If error.message contains a generic HTTP error string instead, the string matching will fail and require fallback detection logic (e.g., checking HTTP status codes directly).


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 and usage tips.

@openshift-ci openshift-ci bot added the approved This issue is something we want to fix label Nov 28, 2025
@rszwajko rszwajko changed the title CNV-69165: Use preserveSession flag for VNC connections - part 1 CNV-69165: Use preserveSession flag for VNC connections - part 2 Nov 28, 2025
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Nov 28, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Retrieve websocket error from the response.

🎥 Demo

TODO

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@rszwajko rszwajko force-pushed the preserveSessionVncErrorHandling branch from a5804d6 to c823143 Compare December 1, 2025 11:03
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 1, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 1, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Summary by CodeRabbit

  • Bug Fixes
  • Improved VNC console disconnect handling by adding verification to determine if a VNC session is still in use after abnormal disconnections, enabling better error recovery and session state management.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (2)

42-43: Add explicit type annotations to buildUrl.

Per coding guidelines, functions should have explicit return types and avoid implicit any types. The parameter object lacks type definition.

Apply this diff:

-const buildUrl = ({ hostname, path, port, preserveSession, protocol }): string =>
+type BuildUrlParams = {
+  hostname: string;
+  path: string;
+  port: string;
+  preserveSession: boolean;
+  protocol: string;
+};
+
+const buildUrl = ({ hostname, path, port, preserveSession, protocol }: BuildUrlParams): string =>
   `${protocol}://${hostname}:${port}${path}?preserveSession=${Boolean(preserveSession).toString()}`;

170-184: Add dependency array to useEffect.

Per coding guidelines, always specify dependencies in useEffect hooks. The current implementation runs on every render, relying on the rfbRef.current guard. This should use an empty array [] to run only once on mount.

Apply this diff:

   useEffect(() => {
     if (!rfbRef.current) {
       connect();
       setVncState((prev) => ({
         actions: {
           // keep the methods bound during connect()
           ...prev.actions,
           // add stable methods (semi-constant)
           connect,
           disconnect,
         },
       }));
     }
     return () => disconnect();
-  });
+  }, []);

Note: If connect and disconnect are intentionally meant to be updated on re-renders, include them in the dependency array: [connect, disconnect].

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9dc26e3 and c823143.

📒 Files selected for processing (3)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1 hunks)
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3 hunks)
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.ts

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use .ts file extension for non-component files containing logic or utilities.

Files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic (e.g., API calls, data transformation, form handling).
Define constants in utility files with uppercase and underscore-separated naming (e.g., API_URL).
Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized (e.g., use fetchUserData instead of getData).
Keep functions short and focused on one action. Apply Red → Green → Refactor: write a failing solution, implement a working solution, then refactor for readability and performance.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using the any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions rather than relying on TypeScript to infer them from the implementation.
Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.
Keep global/store state minimal and straightforward. Obtain approval in the PR before adding new values to prevent bloating.

Files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx,js,jsx}: Avoid comments whenever possible; write self-explanatory code. Use comments sparingly for unusual values or decisions to explain the rationale.
Avoid circular dependencies. Use index files cautiously to prevent situations that lead to circular imports.
Use Husky to run linters before commits and lint-staged to make it configurable. Do not skip linting.
Use Cypress or Playwright for end-to-end (E2E) testing to ensure comprehensive UI coverage.

Files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use ESLint (with React and TypeScript plugins) and Prettier for consistent formatting and linting.

Files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file with no nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components as the default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Extract as much logic as possible from components into custom hooks or utility files to improve testability and avoid bloated components.
Use default exports for all components.
Keep component files under 150 lines whenever possible.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders.
Lazy load components with React.lazy and Suspense for performance optimization.
Always specify dependencies in useEffect hooks to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
🧠 Learnings (2)
📚 Learning: 2025-11-28T11:04:05.062Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-11-28T11:04:05.062Z
Learning: Applies to **/*.{ts,tsx} : Define constants in utility files with uppercase and underscore-separated naming (e.g., `API_URL`).

Applied to files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
📚 Learning: 2025-11-28T11:04:05.062Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-11-28T11:04:05.062Z
Learning: Applies to **/*.{ts,tsx} : Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.

Applied to files:

  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
🧬 Code graph analysis (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3)
src/utils/components/Consoles/utils/utils.ts (1)
  • isConnectionEncrypted (1-1)
src/utils/components/Consoles/utils/constants.ts (2)
  • SECURE (1-1)
  • INSECURE (2-2)
src/utils/components/Consoles/components/utils/ConsoleConsts.ts (4)
  • WSS (18-18)
  • WS (17-17)
  • HTTPS (20-20)
  • HTTP (19-19)
🔇 Additional comments (4)
src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1)

19-20: LGTM!

The HTTP and HTTPS constants follow the uppercase naming convention and are logically grouped with the existing WS/WSS protocol constants. Based on learnings, this aligns with the coding standard for defining constants in utility files.

src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)

13-17: LGTM with minor observation.

The implementation correctly checks for the VNC-in-use error message. The optional chaining on error?.message? is appropriate for null-safety.

Note: The ?. on includes (i.e., includes?.()) is technically unnecessary since String.prototype.includes is always a function when message is a string. However, this doesn't affect correctness.

src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (2)

102-107: LGTM - proper event coordination.

The disconnect listener correctly checks abnormalDisconnect to avoid duplicate cleanup when the abnormal path handles cleanup separately via the HTTP check flow.


124-134: LGTM - HTTP validation flow for abnormal disconnects.

The logic correctly uses an HTTP request to differentiate between a true disconnect and a "VNC session in use" scenario. The flow handles both success (not in use) and failure (check error message) cases appropriately.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 1, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Summary by CodeRabbit

  • New Features

  • Added HTTP and HTTPS constants to the public API for consistent protocol handling.

  • Bug Fixes

  • Improved VNC console disconnect handling to detect abnormal disconnects and verify whether a VNC session is still in use before cleanup.

  • Replaced a no-op session check with real detection logic to better determine in-use session state and improve reconnection behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)

13-17: Improve typing and simplify isSessionAlreadyInUse implementation

Right now the function is typed as (error: Error) but is called from a catch where the value is often unknown and you’re defensively using optional chaining. It’s safer and clearer to accept unknown and narrow to Error explicitly, which also avoids relying on optional chaining here.

Suggested change:

-const VNC_IN_USE_ERROR_TEXT = 'Active VNC connection. Request denied.';
-
-export const isSessionAlreadyInUse = (error: Error): boolean => {
-  return error?.message?.includes?.(VNC_IN_USE_ERROR_TEXT) ?? false;
-};
+const VNC_IN_USE_ERROR_TEXT = 'Active VNC connection. Request denied.';
+
+export const isSessionAlreadyInUse = (error: unknown): boolean =>
+  error instanceof Error && error.message.includes(VNC_IN_USE_ERROR_TEXT);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c823143 and b6aaa6f.

📒 Files selected for processing (3)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1 hunks)
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3 hunks)
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file with no nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components as the default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Extract as much logic as possible from components into custom hooks or utility files to improve testability and avoid bloated components.
Use default exports for all components.
Keep component files under 150 lines whenever possible.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders.
Lazy load components with React.lazy and Suspense for performance optimization.
Always specify dependencies in useEffect hooks to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic (e.g., API calls, data transformation, form handling).
Define constants in utility files with uppercase and underscore-separated naming (e.g., API_URL).
Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized (e.g., use fetchUserData instead of getData).
Keep functions short and focused on one action. Apply Red → Green → Refactor: write a failing solution, implement a working solution, then refactor for readability and performance.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using the any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions rather than relying on TypeScript to infer them from the implementation.
Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.
Keep global/store state minimal and straightforward. Obtain approval in the PR before adding new values to prevent bloating.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx,js,jsx}: Avoid comments whenever possible; write self-explanatory code. Use comments sparingly for unusual values or decisions to explain the rationale.
Avoid circular dependencies. Use index files cautiously to prevent situations that lead to circular imports.
Use Husky to run linters before commits and lint-staged to make it configurable. Do not skip linting.
Use Cypress or Playwright for end-to-end (E2E) testing to ensure comprehensive UI coverage.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use ESLint (with React and TypeScript plugins) and Prettier for consistent formatting and linting.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
**/*.ts

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use .ts file extension for non-component files containing logic or utilities.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
🧠 Learnings (1)
📚 Learning: 2025-11-28T11:04:05.062Z
Learnt from: CR
Repo: kubevirt-ui/kubevirt-plugin PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-11-28T11:04:05.062Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Avoid comments whenever possible; write self-explanatory code. Use comments sparingly for unusual values or decisions to explain the rationale.

Applied to files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
🧬 Code graph analysis (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (4)
src/utils/components/Consoles/utils/utils.ts (1)
  • isConnectionEncrypted (1-1)
src/utils/components/Consoles/utils/constants.ts (2)
  • SECURE (1-1)
  • INSECURE (2-2)
src/utils/components/Consoles/components/utils/ConsoleConsts.ts (4)
  • WSS (18-18)
  • WS (17-17)
  • HTTPS (20-20)
  • HTTP (19-19)
src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)
  • isSessionAlreadyInUse (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build
  • GitHub Check: i18n
  • GitHub Check: unit-test

@rszwajko rszwajko marked this pull request as draft December 1, 2025 11:36
@rszwajko rszwajko force-pushed the preserveSessionVncErrorHandling branch from b6aaa6f to 3ceb0ba Compare December 1, 2025 12:32
@rszwajko rszwajko marked this pull request as ready for review December 1, 2025 12:33
@openshift-ci openshift-ci bot requested a review from lkladnit December 1, 2025 12:33
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 1, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Summary by CodeRabbit

  • New Features

  • Added HTTP and HTTPS constants to the public API for consistent protocol handling.

  • Bug Fixes

  • Improved VNC console disconnect handling to detect abnormal disconnects and perform an HTTP verification before cleanup.

  • Replaced a no-op session check with real detection logic to determine if a VNC session is already in use.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (1)

185-199: Add dependency array to useEffect to prevent running on every render.

The effect currently has no dependency array, which causes it to run after every render and the cleanup (disconnect()) to run before every re-render. This is inefficient and violates the coding guidelines: "Always specify dependencies in useEffect hooks to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required."

Since the comment states "auto-connect only on first load" and the logic is guarded by if (!rfbRef.current), the intent is mount/unmount-only behavior.

Apply this diff to fix the dependency array:

   useEffect(() => {
     if (!rfbRef.current) {
       connect();
       setVncState((prev) => ({
         actions: {
           ...prev.actions,
           connect,
           disconnect,
         },
       }));
     }
     return () => disconnect();
-  });
+  }, [connect, disconnect, setVncState]);

Note: Since connect, disconnect, and setVncState are all memoized with useCallback, they should be stable and this dependency array will effectively run once on mount (plus cleanup on unmount).

As per coding guidelines: explicit dependencies in useEffect hooks.

♻️ Duplicate comments (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (1)

42-55: Fix buildUrl typing for preserveSession parameter.

The preserveSession parameter is typed as string (line 52) but all call sites (lines 108, 144) pass a boolean value from the connect function's boolean parameter (line 94: preserveSession = true). This type mismatch will fail strict TypeScript compilation and obscures intent.

Apply this diff to fix the type signature:

 const buildUrl = ({
   hostname,
   path,
   port,
   preserveSession,
   protocol,
 }: {
   hostname: string;
   path: string;
   port: string;
-  preserveSession: string;
+  preserveSession: boolean;
   protocol: string;
 }): string =>
-  `${protocol}://${hostname}:${port}${path}?preserveSession=${Boolean(preserveSession).toString()}`;
+  `${protocol}://${hostname}:${port}${path}?preserveSession=${preserveSession.toString()}`;
🧹 Nitpick comments (1)
src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)

13-13: Consider exporting VNC_IN_USE_ERROR_TEXT for testability.

The constant is currently not exported, which limits the ability to write tests that verify the exact error message being checked. Exporting it would improve testability without changing runtime behavior.

Apply this diff if you want to export the constant:

-const VNC_IN_USE_ERROR_TEXT = 'Active VNC connection. Request denied.';
+export const VNC_IN_USE_ERROR_TEXT = 'Active VNC connection. Request denied.';
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6aaa6f and 3ceb0ba.

📒 Files selected for processing (3)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts (1 hunks)
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3 hunks)
  • src/utils/components/Consoles/components/vnc-console/utils/util.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/components/Consoles/components/utils/ConsoleConsts.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.ts

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use .ts file extension for non-component files containing logic or utilities.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx}: Hooks should contain only logic and side effects, not return JSX. Keep JSX in components while using hooks for extracting reusable or unit-testable logic (e.g., API calls, data transformation, form handling).
Define constants in utility files with uppercase and underscore-separated naming (e.g., API_URL).
Use descriptive names for variables, functions, and components. Avoid abbreviations unless widely recognized (e.g., use fetchUserData instead of getData).
Keep functions short and focused on one action. Apply Red → Green → Refactor: write a failing solution, implement a working solution, then refactor for readability and performance.
Prefer using type instead of interface for defining the shapes of objects or functions in TypeScript.
Avoid using the any type in TypeScript as it compromises type safety. Use unknown instead and narrow the type as needed.
Always explicitly define return types for functions rather than relying on TypeScript to infer them from the implementation.
Avoid hardcoded values (magic numbers) and define them as constants for easy adjustments and readability.
Keep global/store state minimal and straightforward. Obtain approval in the PR before adding new values to prevent bloating.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{ts,tsx,js,jsx}: Avoid comments whenever possible; write self-explanatory code. Use comments sparingly for unusual values or decisions to explain the rationale.
Avoid circular dependencies. Use index files cautiously to prevent situations that lead to circular imports.
Use Husky to run linters before commits and lint-staged to make it configurable. Do not skip linting.
Use Cypress or Playwright for end-to-end (E2E) testing to ensure comprehensive UI coverage.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.{ts,tsx,js,jsx,scss}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Use ESLint (with React and TypeScript plugins) and Prettier for consistent formatting and linting.

Files:

  • src/utils/components/Consoles/components/vnc-console/utils/util.ts
  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
**/*.tsx

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.tsx: Use .tsx file extension for all React components. One component per file with no nested components.
Use PascalCase for all component names (e.g., HeaderTop.tsx).
Use functional components as the default. Use class components only for specific lifecycle methods unavailable in functional components (e.g., componentDidCatch).
Extract as much logic as possible from components into custom hooks or utility files to improve testability and avoid bloated components.
Use default exports for all components.
Keep component files under 150 lines whenever possible.
Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders.
Lazy load components with React.lazy and Suspense for performance optimization.
Always specify dependencies in useEffect hooks to avoid unnecessary re-renders or missed updates. Pass an empty array [] to run the effect only once if no dependencies are required.

Files:

  • src/utils/components/Consoles/components/vnc-console/VncConsole.tsx
🧬 Code graph analysis (1)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (3)
src/utils/components/Consoles/utils/utils.ts (1)
  • isConnectionEncrypted (1-1)
src/utils/components/Consoles/utils/constants.ts (2)
  • SECURE (1-1)
  • INSECURE (2-2)
src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)
  • isSessionAlreadyInUse (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-test
  • GitHub Check: build
🔇 Additional comments (3)
src/utils/components/Consoles/components/vnc-console/VncConsole.tsx (2)

93-120: LGTM: Session tracking and disconnect flow are correct.

The session tracking logic (isMySession()) and conditional disconnect handling (!abnormalDisconnect) work together correctly to prevent race conditions between concurrent connection attempts and to distinguish between normal and abnormal disconnects.


122-150: LGTM: Abnormal disconnect detection and HTTP fallback are correctly implemented.

The noVNC private property workaround is well-documented, the abnormal disconnect detection (code 1006) is correct, and the HTTP fallback properly guards against session conflicts with isMySession() checks in both success and error paths.

src/utils/components/Consoles/components/vnc-console/utils/util.ts (1)

15-17: LGTM: Implementation is correct and defensive.

The function correctly uses safe optional chaining to prevent runtime errors and explicitly returns a boolean. The logic correctly identifies the VNC-in-use error by checking for the specific error message text.

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski <[email protected]>
@rszwajko rszwajko force-pushed the preserveSessionVncErrorHandling branch from 3ceb0ba to 64c7412 Compare December 1, 2025 12:39
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Dec 1, 2025

@rszwajko: This pull request references CNV-69165 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

📝 Description

Follow up to #3085

Detect VNC-in-use error state

noVNC provides no direct access the error code returned by
socket.on("close") callback. As a workaround the original callback is
replaced by a custom proxy.

The backend returns the message introduced in #15267 for HTTP requests.
For the websocket requests we receive error 1006 (abnormal disconnect).
As a workaround an additional dedicated HTTP request is triggered to
retrieve the error.

Reference-Url: kubevirt/kubevirt#15267
Reference-Url: https://github.com/kubevirt/kubevirt/blob/46aa1b24982cd6fcfd37c950825c8d3acd3dbaf3/pkg/virt-handler/rest/console.go#L163
Reference-Url: https://github.com/novnc/noVNC/blob/d44f7e04fc456844836c7c5ac911d0f4e8dd06e6/core/rfb.js#L662
Reference-Url: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4
Signed-off-by: Radoslaw Szwajkowski [email protected]

🎥 Demo

Screencast.From.2025-12-01.11-50-40.mp4

Summary by CodeRabbit

  • New Features

  • Added HTTP and HTTPS constants to the public API for consistent protocol handling.

  • Bug Fixes

  • Improved VNC console disconnect flow to detect abnormal disconnects and perform an HTTP verification before cleanup.

  • Replaced a placeholder session check with real detection logic to determine if a VNC session is already in use.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot added the lgtm Passed code review, ready for merge label Dec 2, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 2, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rszwajko, upalatucci

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

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [rszwajko,upalatucci]

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

@upalatucci
Copy link
Member

/retest

@openshift-merge-bot openshift-merge-bot bot merged commit d5b9cbb into kubevirt-ui:main Dec 2, 2025
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved This issue is something we want to fix jira/valid-reference lgtm Passed code review, ready for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants