Skip to content

Conversation

@logonoff
Copy link
Member

@logonoff logonoff commented Feb 10, 2026

Before this update, clicking View raw logs when a resource log is very long would cause the console to hang while it logs the logs. With this release, a modal now appears which shows the current log download progress, which also allows cancellation of the download.

Screencast.From.2026-02-11.16-47-20.mp4

@openshift-ci-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Feb 10, 2026
@openshift-ci-robot
Copy link
Contributor

@logonoff: This pull request references Jira Issue OCPBUGS-76283, which is invalid:

  • expected the bug to target the "4.22.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Before this update, clicking View raw logs when a resource log is very long would cause the console to hang while it logs the logs. With this release, a modal now appears which shows the current log download progress, which also allows cancellation of the download.

Screencast.From.2026-02-10.09-23-56.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.

@logonoff
Copy link
Member Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Feb 10, 2026
@openshift-ci-robot
Copy link
Contributor

@logonoff: This pull request references Jira Issue OCPBUGS-76283, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @yapei

Details

In response to this:

/jira refresh

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 component/core Related to console core functionality component/shared Related to console-shared approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated labels Feb 10, 2026
@logonoff logonoff changed the title OCPBUGS-76283: Show modal when downloading OCPBUGS-76283: Show modal when downloading pod logs Feb 10, 2026
@logonoff logonoff force-pushed the OCPBUGS-76283-log-ux branch from e090472 to 4d4fd67 Compare February 10, 2026 17:42
@openshift-ci-robot
Copy link
Contributor

@logonoff: This pull request references Jira Issue OCPBUGS-76283, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @yapei

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Before this update, clicking View raw logs when a resource log is very long would cause the console to hang while it logs the logs. With this release, a modal now appears which shows the current log download progress, which also allows cancellation of the download.

Screencast.From.2026-02-10.09-23-56.mp4

Summary by CodeRabbit

  • New Features
  • Download progress modal now available that displays real-time download progress, gracefully handles connection errors with helpful messages, supports user-initiated cancellation, and manages file operations automatically.
  • "View raw log" feature introduced enabling users to download raw logs with live progress tracking, automatic file opening when complete, and manual backup download options.

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.

@logonoff logonoff force-pushed the OCPBUGS-76283-log-ux branch from 4d4fd67 to 8962a0c Compare February 10, 2026 17:47
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

This change introduces a new FetchProgressModal component for handling streaming data downloads with progress tracking and error handling. The component accepts a fetch URL, title, and callback function to process downloaded data.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses the main change: introducing a modal for downloading pod logs with progress tracking to prevent console hangs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@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

🤖 Fix all issues with AI agents
In
`@frontend/packages/console-shared/src/components/modals/FetchProgressModal.tsx`:
- Around line 73-125: The fetchData function must validate the Response before
streaming: after awaiting coFetch(urlRef.current, ...) check response.ok and
that response.body exists; if response.ok is false or response.body is
null/undefined, set an appropriate error via setErrorMessage (use
response.status/text or t('Could not fetch data')), setEndState('failed'),
setIsDownloading(false) and return early to avoid calling
response.body.getReader(); this guard should live just after the coFetch call in
fetchData to prevent treating error responses as successful streams.

In `@frontend/public/components/utils/resource-log.tsx`:
- Around line 716-723: handleFetchedLogData currently passes detect() result
straight to TextDecoder which can be null or an unsupported label; update the
function to validate and normalize the encoding: call detect(new
Uint8Array(arrayBuffer)), if it returns null or an unsupported label map it to
'utf-8' (or another TextDecoder-supported label), then wrap the new
TextDecoder(...).decode(...) and the Blob/URL creation in a try-catch to handle
decode errors (logging or showing a user error) and ensure URL.revokeObjectURL
is used after open; references: handleFetchedLogData, detect, TextDecoder,
URL.createObjectURL.
🧹 Nitpick comments (1)
frontend/packages/console-shared/src/components/modals/__tests__/FetchProgressModal.spec.tsx (1)

72-103: Add an assertion that the data callback fires on success.

The success test validates UI and state, but not that the fetched payload is delivered to the callback—this is core behavior and worth locking down.

Suggested test enhancement
     await waitFor(() => {
       expect(setIsDownloading).toHaveBeenCalledWith(false);
     });
+    await waitFor(() => {
+      expect(mockCallback).toHaveBeenCalledWith(expect.any(ArrayBuffer));
+    });
 
     rerender(
       <FetchProgressModal

Comment on lines 73 to 138
const fetchData = useCallback(async () => {
setBytesDownloaded(0);
abortControllerRef.current = new AbortController();

try {
const response = await coFetch(urlRef.current, {
signal: abortControllerRef.current.signal,
});

const reader = response.body.getReader();
const chunks: Uint8Array[] = [];
let received = 0;

try {
// Stream reading requires an indefinite loop that exits when done is true
// eslint-disable-next-line no-constant-condition
while (true) {
// Sequential reads are required; each chunk depends on the previous read completing
// eslint-disable-next-line no-await-in-loop
const { done, value } = await reader.read();
if (done) break;

chunks.push(value);
received += value.length;
setBytesDownloaded(received);
}

const arrayBuffer = new Uint8Array(received);
let position = 0;
for (const chunk of chunks) {
arrayBuffer.set(chunk, position);
position += chunk.length;
}

callbackRef.current(arrayBuffer.buffer);
setEndState('complete');
} finally {
reader.releaseLock();
}
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') {
setErrorMessage(t('Download canceled'));
// Download was cancelled, do nothing
return;
}
// eslint-disable-next-line no-console
console.error('Failed to fetch:', error);
setErrorMessage(error?.message || t('Could not fetch data'));
} finally {
abortControllerRef.current = null;
setIsDownloading(false);
setEndState((prev) => (prev === 'complete' ? 'complete' : 'failed'));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Search for coFetch implementation
fd -type f -name '*.ts' -o -name '*.tsx' | xargs rg -l 'export.*coFetch|function coFetch' | head -20

Repository: openshift/console

Length of output: 404


🏁 Script executed:

# Also search in common directories
fd -type f \( -name '*fetch*.ts' -o -name '*fetch*.tsx' \) | head -20

Repository: openshift/console

Length of output: 231


🏁 Script executed:

# Search for coFetch definition more broadly
rg 'const coFetch|export.*coFetch' -A 5 | head -100

Repository: openshift/console

Length of output: 3008


🏁 Script executed:

# Find the co-fetch implementation
fd -name 'co-fetch*' -type f

Repository: openshift/console

Length of output: 291


🏁 Script executed:

# Search in console/internal
find . -path '*console/internal*' -name '*fetch*' -type f | grep -v node_modules | head -20

Repository: openshift/console

Length of output: 43


🏁 Script executed:

# Find where coFetch is defined
rg 'export.*const coFetch|export function coFetch' -A 20

Repository: openshift/console

Length of output: 43


🏁 Script executed:

# Find co-fetch file more carefully
find . -name 'co-fetch.ts' -o -name 'co-fetch.tsx' 2>/dev/null | head -5

Repository: openshift/console

Length of output: 90


🏁 Script executed:

# Check the FetchProgressModal import
head -50 frontend/packages/console-shared/src/components/modals/FetchProgressModal.tsx | grep -A 2 -B 2 'coFetch\|import'

Repository: openshift/console

Length of output: 528


🏁 Script executed:

# Search for coFetch in internal directory
rg 'coFetch' frontend/ --type ts --type tsx -l | head -20

Repository: openshift/console

Length of output: 88


🏁 Script executed:

# Read the coFetch implementation
cat ./frontend/public/co-fetch.ts

Repository: openshift/console

Length of output: 4841


🏁 Script executed:

# Check test cases for FetchProgressModal
cat frontend/packages/console-shared/src/components/modals/__tests__/FetchProgressModal.spec.tsx

Repository: openshift/console

Length of output: 8063


🏁 Script executed:

# Search for coFetch implementations in SDK or elsewhere
rg 'export.*consoleFetch|export.*coFetch' -A 10 | head -80

Repository: openshift/console

Length of output: 7271


🏁 Script executed:

# Get the full console-fetch.ts implementation
cat frontend/packages/console-dynamic-plugin-sdk/src/utils/fetch/console-fetch.ts

Repository: openshift/console

Length of output: 6752


🏁 Script executed:

# Check getUtilsConfig to see what appFetch is
rg 'appFetch' -A 5 -B 5 | head -100

Repository: openshift/console

Length of output: 10212


🏁 Script executed:

# Look for configSetup and getUtilsConfig
find . -name '*configSetup*' -o -name '*config*' | grep -E '(utils|setup)' | head -10

Repository: openshift/console

Length of output: 400


🏁 Script executed:

# Search for appFetch implementation in the main console app
rg 'appFetch.*=' -A 10 | head -150

Repository: openshift/console

Length of output: 2157


🏁 Script executed:

# Look for where coFetch is initialized or configured
rg 'coFetch|appFetch' frontend/public --type ts -A 3 -B 3 | head -100

Repository: openshift/console

Length of output: 6490


Add validation for response status and body before streaming.

coFetch returns the raw Response without validating status codes. If the server returns non-2xx or a response without body, the component will either render "success" for an error payload or throw a low-signal TypeError when calling getReader().

Add this guard after the coFetch call:

Required fix
  const response = await coFetch(urlRef.current, {
    signal: abortControllerRef.current.signal,
  });
+  if (!response.ok || !response.body) {
+    throw new Error(t('Could not fetch data'));
+  }

  const reader = response.body.getReader();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fetchData = useCallback(async () => {
setBytesDownloaded(0);
abortControllerRef.current = new AbortController();
try {
const response = await coFetch(urlRef.current, {
signal: abortControllerRef.current.signal,
});
const reader = response.body.getReader();
const chunks: Uint8Array[] = [];
let received = 0;
try {
// Stream reading requires an indefinite loop that exits when done is true
// eslint-disable-next-line no-constant-condition
while (true) {
// Sequential reads are required; each chunk depends on the previous read completing
// eslint-disable-next-line no-await-in-loop
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
received += value.length;
setBytesDownloaded(received);
}
const arrayBuffer = new Uint8Array(received);
let position = 0;
for (const chunk of chunks) {
arrayBuffer.set(chunk, position);
position += chunk.length;
}
callbackRef.current(arrayBuffer.buffer);
setEndState('complete');
} finally {
reader.releaseLock();
}
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') {
setErrorMessage(t('Download canceled'));
// Download was cancelled, do nothing
return;
}
// eslint-disable-next-line no-console
console.error('Failed to fetch:', error);
setErrorMessage(error?.message || t('Could not fetch data'));
} finally {
abortControllerRef.current = null;
setIsDownloading(false);
setEndState((prev) => (prev === 'complete' ? 'complete' : 'failed'));
}
const fetchData = useCallback(async () => {
setBytesDownloaded(0);
abortControllerRef.current = new AbortController();
try {
const response = await coFetch(urlRef.current, {
signal: abortControllerRef.current.signal,
});
if (!response.ok || !response.body) {
throw new Error(t('Could not fetch data'));
}
const reader = response.body.getReader();
const chunks: Uint8Array[] = [];
let received = 0;
try {
// Stream reading requires an indefinite loop that exits when done is true
// eslint-disable-next-line no-constant-condition
while (true) {
// Sequential reads are required; each chunk depends on the previous read completing
// eslint-disable-next-line no-await-in-loop
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
received += value.length;
setBytesDownloaded(received);
}
const arrayBuffer = new Uint8Array(received);
let position = 0;
for (const chunk of chunks) {
arrayBuffer.set(chunk, position);
position += chunk.length;
}
callbackRef.current(arrayBuffer.buffer);
setEndState('complete');
} finally {
reader.releaseLock();
}
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') {
setErrorMessage(t('Download canceled'));
// Download was cancelled, do nothing
return;
}
// eslint-disable-next-line no-console
console.error('Failed to fetch:', error);
setErrorMessage(error?.message || t('Could not fetch data'));
} finally {
abortControllerRef.current = null;
setIsDownloading(false);
setEndState((prev) => (prev === 'complete' ? 'complete' : 'failed'));
}
🤖 Prompt for AI Agents
In
`@frontend/packages/console-shared/src/components/modals/FetchProgressModal.tsx`
around lines 73 - 125, The fetchData function must validate the Response before
streaming: after awaiting coFetch(urlRef.current, ...) check response.ok and
that response.body exists; if response.ok is false or response.body is
null/undefined, set an appropriate error via setErrorMessage (use
response.status/text or t('Could not fetch data')), setEndState('failed'),
setIsDownloading(false) and return early to avoid calling
response.body.getReader(); this guard should live just after the coFetch call in
fetchData to prevent treating error responses as successful streams.

Comment on lines +716 to +723
/** callback for FetchProgressModal to process fetched log data */
const handleFetchedLogData = useCallback((arrayBuffer: ArrayBuffer) => {
const encoding = detect(new Uint8Array(arrayBuffer));
const text = new TextDecoder(encoding).decode(arrayBuffer);
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

chardet detect() return value null unsupported encoding javascript

💡 Result:

  • In the chardet (runk/node-chardet) npm package, detect() is typed to return string | null—so null is an expected result when the library can’t make a confident guess from the bytes you provided. [1]
  • Make sure you’re passing the original bytes (Buffer/Uint8Array), not a JS string (strings are already UTF‑16 in memory, which makes “detecting the original encoding” meaningless and can lead to bad/ambiguous results). [2]
  • chardet supports only a fixed set of encodings (UTF-8/16/32, ISO-2022-, Shift_JIS, Big5, EUC-, GB18030, ISO-8859-, windows-125, KOI8-R, etc.). If the real data is outside these, detection may be unreliable and can yield null or a “best effort” guess. [2]

Why you then see “unsupported encoding” in JavaScript/Node

Even if chardet.detect() returns a string, that encoding label may not be supported by Buffer.toString() / TextDecoder (Node only supports a small set like utf8, utf16le, latin1, etc.). So doing this often fails:

const enc = chardet.detect(buf);      // e.g. "windows-1252" or "UTF-16 LE"
const text = buf.toString(enc);       // throws: unknown/unsupported encoding

What to do

  1. Handle null and/or use analyse() to inspect confidence and apply a threshold. [2]
  2. Normalize encoding names for Node built-ins (example: "UTF-16 LE""utf16le").
  3. For encodings like windows-1252, decode with a library such as iconv-lite (since Node’s Buffer won’t decode it directly).

Sources:
[1] chardet API docs showing detect: (buffer: Uint8Array) => string | null https://www.jsdocs.io/package/chardet (v2.1.1)
[2] chardet README (bytes-only input note + supported encodings list) https://npm.io/package/chardet


🏁 Script executed:

cat frontend/public/components/utils/resource-log.tsx | head -750 | tail -50

Repository: openshift/console

Length of output: 1838


🏁 Script executed:

rg "detect\|chardet" frontend/public/components/utils/resource-log.tsx -B 3 -A 3

Repository: openshift/console

Length of output: 43


🏁 Script executed:

rg "from.*detect\|import.*detect" frontend/public/components/utils/resource-log.tsx

Repository: openshift/console

Length of output: 43


🏁 Script executed:

head -100 frontend/public/components/utils/resource-log.tsx | rg "import|detect"

Repository: openshift/console

Length of output: 1818


🏁 Script executed:

sed -n '1,50p' frontend/public/components/utils/resource-log.tsx

Repository: openshift/console

Length of output: 1034


🏁 Script executed:

rg "handleFetchedLogData" frontend/public/components/utils/resource-log.tsx -B 5 -A 15

Repository: openshift/console

Length of output: 1427


Guard against null returns and unsupported encoding labels from chardet.detect().

The detect() function returns string | null, and even when it returns a string, that encoding label may not be supported by TextDecoder (chardet supports ~30 encodings; TextDecoder supports a subset). Currently there's no null check or error handling, so TextDecoder will throw and the user's download is incorrectly marked as failed. Add a null guard, normalize to a supported label (e.g., UTF-8), and wrap in try-catch:

Safer decode with fallback
-  const encoding = detect(new Uint8Array(arrayBuffer));
-  const text = new TextDecoder(encoding).decode(arrayBuffer);
+  const detected = detect(new Uint8Array(arrayBuffer));
+  const encoding = typeof detected === 'string' ? detected : 'utf-8';
+  let text: string;
+  try {
+    text = new TextDecoder(encoding).decode(arrayBuffer);
+  } catch {
+    text = new TextDecoder('utf-8').decode(arrayBuffer);
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** callback for FetchProgressModal to process fetched log data */
const handleFetchedLogData = useCallback((arrayBuffer: ArrayBuffer) => {
const encoding = detect(new Uint8Array(arrayBuffer));
const text = new TextDecoder(encoding).decode(arrayBuffer);
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
}, []);
/** callback for FetchProgressModal to process fetched log data */
const handleFetchedLogData = useCallback((arrayBuffer: ArrayBuffer) => {
const detected = detect(new Uint8Array(arrayBuffer));
const encoding = typeof detected === 'string' ? detected : 'utf-8';
let text: string;
try {
text = new TextDecoder(encoding).decode(arrayBuffer);
} catch {
text = new TextDecoder('utf-8').decode(arrayBuffer);
}
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
}, []);
🤖 Prompt for AI Agents
In `@frontend/public/components/utils/resource-log.tsx` around lines 716 - 723,
handleFetchedLogData currently passes detect() result straight to TextDecoder
which can be null or an unsupported label; update the function to validate and
normalize the encoding: call detect(new Uint8Array(arrayBuffer)), if it returns
null or an unsupported label map it to 'utf-8' (or another TextDecoder-supported
label), then wrap the new TextDecoder(...).decode(...) and the Blob/URL creation
in a try-catch to handle decode errors (logging or showing a user error) and
ensure URL.revokeObjectURL is used after open; references: handleFetchedLogData,
detect, TextDecoder, URL.createObjectURL.

@logonoff logonoff force-pushed the OCPBUGS-76283-log-ux branch from 8962a0c to 588c24b Compare February 10, 2026 17:54
Copy link
Member

@TheRealJon TheRealJon left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Feb 10, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 10, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: logonoff, TheRealJon

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

The pull request process is described 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

@logonoff
Copy link
Member Author

/assign @yapei

@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Feb 11, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 11, 2026

New changes are detected. LGTM label has been removed.

@yapei
Copy link
Contributor

yapei commented Feb 12, 2026

/assign @XiyunZhao

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 12, 2026
@logonoff logonoff force-pushed the OCPBUGS-76283-log-ux branch from cf46905 to 62374bb Compare February 12, 2026 01:49
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 12, 2026
@logonoff logonoff force-pushed the OCPBUGS-76283-log-ux branch from 62374bb to 790d653 Compare February 12, 2026 03:47
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 12, 2026

@logonoff: all tests passed!

Full PR test history. Your PR dashboard.

Details

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 kubernetes-sigs/prow repository. I understand the commands that are listed here.

@XiyunZhao
Copy link
Contributor

XiyunZhao commented Feb 12, 2026

Hi @logonoff, I encountered a potential edge case while verifying this PR
If a pod continuously generates extremely large logs, clicking “Open the raw file in another window” or “Download” results in the new window or download request remaining in a perpetual “preparing” or “resuming” state. It appears to hang indefinitely, and the user is forced to manually cancel the operation
This seems to create another form of UI freeze or unresponsive behavior
How should this scenario be handled? Is there an expected limitation or safeguard for extremely large or continuously streaming logs?

Here is the script I used

apiVersion: v1
kind: Pod
metadata:
  name: huge-log-spammer
spec:
  restartPolicy: Always
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: spammer
    image: registry.k8s.io/busybox
    command:
      - sh
      - -c
      - |
        while true; do
          head -c 20000 /dev/zero | tr '\0' 'A'
          echo ""
        done
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. component/core Related to console core functionality component/shared Related to console-shared jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants