Skip to content

Improve reliability and error diagnostics of upgrade monitoring - #77

Open
wirwolf wants to merge 3 commits into
masterfrom
claude/vigilant-fermi-cwe394
Open

wirwolf wants to merge 3 commits into
masterfrom
claude/vigilant-fermi-cwe394

Conversation

@wirwolf

@wirwolf wirwolf commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR enhances the reliability and debuggability of the UpgradeModule's Kubernetes monitoring logic by fixing race conditions, improving error handling, and including stderr in error messages.

Key Changes

  • Fixed race condition in job initialization: Moved initial Job UID snapshot from the first interval tick to before helm upgrade starts. This prevents newly created Jobs from being incorrectly treated as pre-existing when the first monitoring tick lands after helm creates the Job.

  • Added in-flight request tracking: Introduced inFlight flags in both kubectlWatchPodsLogsAndEvents() and watchJobStatus() to prevent concurrent kubectl calls from overlapping, ensuring clean state management.

  • Improved error handling in log watching: Wrapped the auxiliary pod log watching in try-catch-finally to prevent transient kubectl/API failures from escaping as unhandled rejections, which would crash the app and kill the running helm upgrade.

  • Enhanced stderr capture and error messages:

    • Modified interpretChildProcessExit() to accept and include stderr in error messages
    • Updated stdout/stderr collection to preserve full output without splitting on newlines
    • Changed process event listener from 'exit' to 'close' to ensure stdout is fully drained before processing
  • Improved logging levels: Changed several Logger.fatal() calls to Logger.warn() for transient failures (JSON parsing, API connectivity) since these are recoverable conditions, not fatal errors.

  • Extracted common logic: Added parseJobList() helper method to centralize Job list parsing logic.

  • Removed obsolete state: Removed the isFirstPoll boolean flag which is no longer needed with the new initialization approach.

Notable Implementation Details

  • The initial Job UID snapshot is now captured synchronously before the monitoring interval starts, eliminating the race condition window
  • Error handling distinguishes between auxiliary operations (log watching) that should not crash the app and critical operations (job status polling) that should report errors
  • The switch from 'exit' to 'close' event ensures complete stdout/stderr capture, which is critical for JSON parsing

https://claude.ai/code/session_01JzncmhbXTJUsBEsqys93Ht

The pods poller in kubectlWatchPodsLogsAndEvents did not catch a rejected
kubectl call. A single transient API error (e.g. connection reset) became an
unhandled rejection -> SIGTERM -> helm killed mid-upgrade, leaving the release
stuck in pending-upgrade.

- catch kubectl errors in the pods poller and log them as warnings
- wait for 'close' instead of 'exit' so stdout is fully drained before
  JSON.parse (fixes spurious "Can not parse JSON output")
- keep stdout newlines, capture stderr and include it in the error message
- handle spawn 'error' events
- skip a poll tick while the previous kubectl call is still running
- snapshot existing Job UIDs before helm starts; previously the snapshot
  was taken on the first non-empty poll, which could include the Job just
  created by this upgrade and hide its failure

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzncmhbXTJUsBEsqys93Ht
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T10:48:12.987158Z e5a6388 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5a6388a04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Modules/UpgradeModule.ts Resolved
Comment thread src/Modules/UpgradeModule.ts Resolved
If the initial "existing jobs" kubectl call failed, the watcher continued
with an empty baseline and could treat a stale failed Job from a previous
release as current, sending SIGTERM to an unrelated upgrade.

- retry the baseline up to 5 times before helm starts
- if it is still missing, make no failure decision until a successful poll
  establishes it (those Jobs are treated as pre-existing)
- accept only a real list response (items array) as a baseline

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzncmhbXTJUsBEsqys93Ht
The pre-upgrade Job snapshot runs before helm is started, and kubectl's
default --request-timeout is 0 (never). A stalled API request could leave
helm uninvoked and the release lock held indefinitely.

- pass --request-timeout 10s to one-shot polls (job/pods), before
  KUBECTL_CMD_ARGS so a user-supplied value still wins
- SIGKILL a one-shot kubectl process after 30s as a hard bound for cases
  the request timeout does not cover (e.g. hung exec credential plugin)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzncmhbXTJUsBEsqys93Ht
@wirwolf wirwolf self-assigned this Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants