Skip to content

feat(cozyreport): collect Flux/cert-manager/host context + summary.txt - #2553

Merged
myasnikovdaniil merged 2 commits into
mainfrom
daniil/split-cozyreport
May 4, 2026
Merged

feat(cozyreport): collect Flux/cert-manager/host context + summary.txt#2553
myasnikovdaniil merged 2 commits into
mainfrom
daniil/split-cozyreport

Conversation

@myasnikovdaniil

@myasnikovdaniil myasnikovdaniil commented May 2, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Makes cozyreport.tgz actually useful when triaging an E2E failure deeper than a single pod log. Adds:

  • Flux controller logs (helm-controller, source-controller, notification-controller, kustomize-controller, last 2000 lines each)
  • Flux source resources (HelmRepository, OCIRepository, GitRepository, ExternalArtifact)
  • Decoded Helm storage secrets for non-Ready HRs (base64 -d | base64 -d | gzip -d)
  • Cluster events (all + warning-only filtered file)
  • cert-manager Certificate / CertificateRequest / Order / Challenge resources + cert-manager logs
  • cozystack-operator deployment logs (current + previous)
  • Application / ApplicationDefinition / Tenant resources
  • Sandbox host context per node: df, free, ps, dmesg, talosctl logs/dmesg/kubelet/containerd

New executable hack/cozyreport-summary.sh writes a summary.txt at the archive root listing what is broken right now — the first thing to read when downloading the artifact from a CI failure.

Surfaced from #2500.

Release note

NONE

Summary by CodeRabbit

  • New Features
    • Added a timestamped diagnostic summary report that highlights failing resources and key cluster issues.
    • Expanded diagnostic collection: controller logs (current+previous), Flux source status, cert-manager certificate details, Helm release payloads, and Cozystack resource status.
    • Added host-level diagnostics (disk/memory/process/dmesg) and improved event/warning listings to aid troubleshooting.

`hack/cozyreport.sh` now collects materially more signal so a triage
artifact can show what is broken rather than just dumping pod logs:

- Flux controller logs (helm-controller, source-controller,
  notification-controller, kustomize-controller, last 2000 lines)
- Flux source resources (HelmRepository, OCIRepository, GitRepository,
  ExternalArtifact)
- Decoded Helm storage secrets for non-Ready HRs
  (`base64 -d | base64 -d | gzip -d`)
- Cluster events (all + warning-only filter)
- cert-manager Certificate / CertificateRequest / Order / Challenge
  resources + cert-manager logs
- `cozystack-operator` deployment logs (current + previous)
- `Application` / `ApplicationDefinition` / `Tenant` resources
- Sandbox host context per node: df, free, ps, dmesg,
  talosctl logs/dmesg/kubelet/containerd

New `hack/cozyreport-summary.sh` writes a `summary.txt` at the archive
root listing what is broken right now — first thing to read when
triaging an artifact.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: Claude <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the utility of the cozyreport diagnostic tool by broadening the scope of collected cluster state and adding an automated summary generation step. These changes aim to reduce the time required to triage E2E failures by providing a comprehensive snapshot of the cluster environment and a high-level overview of current issues directly within the diagnostic archive.

Highlights

  • Enhanced Diagnostic Data Collection: Expanded the cozyreport script to capture significantly more context, including Flux controller logs, cert-manager resources, Cozystack operator logs, and sandbox host system metrics.
  • Automated Triage Summary: Introduced a new executable, hack/cozyreport-summary.sh, which generates a summary.txt file at the root of the diagnostic archive to quickly highlight common failure points like non-ready HelmReleases, pods, and warning events.
  • Improved Helm Debugging: Added logic to decode and extract Helm storage secrets for non-ready HelmReleases, facilitating deeper investigation into failed deployments.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added size/L This PR changes 100-499 lines, ignoring generated files area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review kind/feature Categorizes issue or PR as related to a new feature labels May 2, 2026
@coderabbitai

coderabbitai Bot commented May 2, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Two shell scripts extend cluster diagnostics: a new hack/cozyreport-summary.sh queries live Kubernetes state for common failure signals; hack/cozyreport.sh is expanded to collect Cozystack, Flux, cert-manager, HelmRelease storage, Kubernetes events, Cozystack app CRs, and host/Talos diagnostics, then runs the summary before archiving.

Changes

Cluster Diagnostics Tooling

Layer / File(s) Summary
Live cluster summary
hack/cozyreport-summary.sh
New /bin/sh script (set -eu) that prints a timestamped report of: HelmReleases not Ready (if CRD exists); pods not Running/Succeeded/Completed (first 40); pods with ImagePullBackOff/ErrImagePull; recent OOMKilling events (last 20); recent Warning events (last 30); cert-manager Certificates not Ready (if CRD exists); Flux source objects not Ready across multiple source kinds (skips missing CRDs); PVCs/PVs not Bound; node Ready/DiskPressure/MemoryPressure.
Script initialization & orchestration
hack/cozyreport.sh (top)
Adds SCRIPT_DIR resolution and ensures summary integration at finalization.
Cozystack collection
hack/cozyreport.sh (cozystack/*)
Captures Cozystack deploy image, exports Cozystack ConfigMaps, and conditionally collects cozystack-operator logs (current + previous).
Flux collection
hack/cozyreport.sh (flux/*)
Collects Flux controller logs (current + previous) and exports Flux source objects into text and YAML for multiple source kinds.
cert-manager collection
hack/cozyreport.sh (cert-manager/*)
Gated on cert-manager CRDs: exports lists (certificates/requests/orders/challenges), writes full YAML + kubectl describe for non-Ready certificates, and collects cert-manager/webhook controller logs when deployments exist.
Kubernetes events
hack/cozyreport.sh (kubernetes/events-warnings.txt)
Exports non-Normal events sorted by .lastTimestamp into kubernetes/events-warnings.txt.
HelmRelease storage extraction
hack/cozyreport.sh (helmrelease handling)
Finds Helm storage secrets for a HelmRelease, decodes and decompresses latest .data.release (best-effort) into helm-release.json.
Cozystack apps enumeration
hack/cozyreport.sh (applications/*)
If related Cozystack CRDs exist, lists applications, applicationdefinitions, tenants and exports YAML + kubectl describe for items whose Ready condition != True.
Sandbox / host diagnostics
hack/cozyreport.sh (sandbox-host/*)
Gathers df -h, free -m, ps auxww, recent dmesg; if /workspace/talosconfig exists, runs talosctl to fetch node dmesg, kubelet, and containerd logs for nodes inferred from Kubernetes internal IPs (with a default fallback).
Summary run & archive
hack/cozyreport.sh (finalization)
Runs hack/cozyreport-summary.sh to create summary.txt (best-effort) before creating the tar archive.

Sequence Diagram

sequenceDiagram
    participant Report as cozyreport.sh
    participant Summary as cozyreport-summary.sh
    participant K8s as Kubernetes API
    participant Helm as Helm storage (Secrets)
    participant Host as Host filesystem / talosctl

    Report->>K8s: Collect Cozystack/operator logs & ConfigMaps
    Report->>K8s: Collect Flux controller logs and source objects
    Report->>K8s: Collect cert-manager resources and controller logs
    Report->>K8s: Collect non-Normal events (warnings)
    Report->>K8s: Query HelmReleases and locate Helm storage secrets
    Report->>Helm: Decode & decompress latest release payload -> helm-release.json
    Report->>K8s: Collect Cozystack app CRs (non-Ready)
    Report->>Host: Gather df, free, ps, dmesg
    alt /workspace/talosconfig exists
        Report->>Host: talosctl -> fetch node dmesg, kubelet, containerd logs
    end
    Report->>Summary: Run summary script to query live cluster state for broken resources
    Summary->>K8s: Query HelmReleases, pods, events, cert-manager, Flux sources, PVC/PV, nodes
    Summary->>Host: Write summary.txt
    Report->>Host: Create compressed archive
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

"I hop through logs both near and far,
I sniff the pods and read each star;
From Flux to Talos, every clue,
A cozy report stitched snug and true." 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: adding Flux, cert-manager, and host context collection plus the summary.txt feature to the cozyreport tooling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch daniil/split-cozyreport

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
Review rate limit: 6/8 reviews remaining, refill in 9 minutes and 34 seconds.

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

@dosubot dosubot Bot added area/ci Issues or PRs related to CI workflows, GitHub Actions, automation area/testing Issues or PRs related to testing (e2e, bats, unit tests) labels May 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hack/cozyreport-summary.sh`:
- Around line 31-34: The "## OOMKilled in last 30 min" heading is misleading
because the kubectl command (kubectl get events -A --field-selector
reason=OOMKilling --sort-by=.lastTimestamp) only limits count, not time; either
change the heading to "Recent OOMKilled events" or actually filter events to the
last 30 minutes: run kubectl get events -A -o json and use a JSON processor (jq
or python) to compare each event.metadata.creationTimestamp/.lastTimestamp
against (now - 30m), then sort by .lastTimestamp and print the tail as before;
update the echo line (echo "## OOMKilled in last 30 min") and replace the
kubectl pipeline accordingly so the output matches the label.
- Around line 53-56: The loop that prints non-ready Flux resources (for kind in
helmrepositories.source.toolkit.fluxcd.io
ocirepositories.source.toolkit.fluxcd.io
gitrepositories.source.toolkit.fluxcd.io) omits
externalartifacts.source.toolkit.fluxcd.io, so ExternalArtifact failures never
appear in summary.txt; update that loop to include
externalartifacts.source.toolkit.fluxcd.io (keeping the existing k extraction
${kind%%.*}) so ExternalArtifact resources are queried and printed the same way
as the other Flux kinds.

In `@hack/cozyreport.sh`:
- Around line 253-254: The call to hack/cozyreport-summary.sh fails unless the
CWD is the repo root; compute the script directory near the top (e.g., set
SCRIPT_DIR using: SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)) and
replace the invocation echo "Generating summary..." hack/cozyreport-summary.sh >
$REPORT_DIR/summary.txt 2>&1 || true with a resolved path using
"$SCRIPT_DIR/cozyreport-summary.sh" so the summary runs regardless of caller
CWD; keep REPORT_DIR usage the same.
- Around line 243-248: The script currently hardcodes the Talos node IPs
(192.168.123.11-13) so talosctl calls only capture those machines; replace the
fixed list in the for loop with a dynamic node enumeration using talosctl (e.g.,
capture the node list from a talosctl nodes/list command using --talosconfig
/workspace/talosconfig and iterate over that output), and add a safe fallback to
the original static list if the talosctl query fails; update the loop that calls
talosctl (the lines invoking talosctl --talosconfig /workspace/talosconfig -n
$node dmesg/logs) so it uses the dynamically discovered $node values and
preserves the existing DIR/talos-$node-*.txt naming and the "|| true" behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bc4c7dd7-4486-456c-a6fb-4429c2b8e05c

📥 Commits

Reviewing files that changed from the base of the PR and between 5786afe and aa72a23.

📒 Files selected for processing (2)
  • hack/cozyreport-summary.sh
  • hack/cozyreport.sh

Comment thread hack/cozyreport-summary.sh Outdated
Comment thread hack/cozyreport-summary.sh Outdated
Comment thread hack/cozyreport.sh
Comment thread hack/cozyreport.sh Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the diagnostic capabilities of the cozyreport utility by adding modules for Flux controller state, cert-manager, Kubernetes events, Helm release secrets, and Cozystack applications, alongside a new sandbox-host diagnostic module. I have provided feedback regarding potential logic errors in the Helm and Flux resource readiness checks, the need for robust CRD existence verification to prevent script termination, and a recommendation to dynamically discover node IPs for the sandbox-host module rather than using hardcoded values.

Comment thread hack/cozyreport-summary.sh Outdated
Comment on lines +13 to +15
kubectl get hr -A --no-headers 2>/dev/null \
| awk '$4 != "True" {printf " %s/%s — %s\n", $1, $2, $5}' \
| head -40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

There are two issues here:

  1. Logic Error: In the output of kubectl get hr -A, the READY column is typically the 3rd column ($3), and the STATUS message is the 4th ($4). Checking $4 != "True" will incorrectly flag all releases as not ready because $4 contains the status message string.
  2. Reliability: Since the script uses set -e (line 5), it will terminate immediately if the HelmRelease CRD is not installed in the cluster. It is safer to check for the CRD's existence first.
Suggested change
kubectl get hr -A --no-headers 2>/dev/null \
| awk '$4 != "True" {printf " %s/%s — %s\n", $1, $2, $5}' \
| head -40
if kubectl get crd helmreleases.helm.toolkit.fluxcd.io >/dev/null 2>&1; then
kubectl get hr -A --no-headers 2>/dev/null \
| awk '$3 != "True" {printf " %s/%s — %s\n", $1, $2, $4}' \
| head -40
fi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Two parts:

Column position: I think the analysis is off here. Cozystack ships Flux v2.7 (packages/system/fluxcd/values.yamlflux-instance.instance.distribution.version: 2.7.x), where helmreleases.helm.toolkit.fluxcd.io v2 printer columns are NAME AGE READY STATUS. With -A: NAMESPACE NAME AGE READY STATUS$4 is READY, $5 is the status message. The same $4 != "True" pattern is in the pre-existing cozyreport.sh:101 and works in our E2E. Keeping $4.

CRD guard: Adopted — wrapped the HR block in if kubectl get crd helmreleases.helm.toolkit.fluxcd.io >/dev/null 2>&1; then ... fi to match the cert-manager block pattern at line 45.

Fixed in b40ab29.

Comment thread hack/cozyreport-summary.sh Outdated
Comment on lines +53 to +56
for kind in helmrepositories.source.toolkit.fluxcd.io ocirepositories.source.toolkit.fluxcd.io gitrepositories.source.toolkit.fluxcd.io; do
kubectl get $kind -A --no-headers 2>/dev/null \
| awk -v k="${kind%%.*}" '$4 != "True" {printf " %s %s/%s — Ready=%s\n", k, $1, $2, $4}'
done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Similar to the HelmRelease check, if any of these Flux source CRDs are missing, the script will exit prematurely due to set -e. Adding a check for the CRD existence inside the loop ensures the script continues to other diagnostic sections.

Suggested change
for kind in helmrepositories.source.toolkit.fluxcd.io ocirepositories.source.toolkit.fluxcd.io gitrepositories.source.toolkit.fluxcd.io; do
kubectl get $kind -A --no-headers 2>/dev/null \
| awk -v k="${kind%%.*}" '$4 != "True" {printf " %s %s/%s — Ready=%s\n", k, $1, $2, $4}'
done
for kind in helmrepositories.source.toolkit.fluxcd.io ocirepositories.source.toolkit.fluxcd.io gitrepositories.source.toolkit.fluxcd.io; do
kubectl get crd $kind >/dev/null 2>&1 || continue
kubectl get $kind -A --no-headers 2>/dev/null \
| awk -v k="${kind%%.*}" '$4 != "True" {printf " %s %s/%s — Ready=%s\n", k, $1, $2, $4}'
done

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Adopted the CRD guard, plus two related changes the comment didn't surface:

  1. Added externalartifacts.source.toolkit.fluxcd.io to the loop (cozyreport.sh:37 already collects it; summary should match).
  2. Switched the loop from column-based awk to jsonpath against .status.conditions[?(@.type=="Ready")].status. The reason: printer columns differ between source kinds — HelmRepository v1 is URL/AGE/READY/STATUS while OCIRepository v1beta2 has different ordering, so a single $N field index is wrong for at least one of them. jsonpath sidesteps that.

Fixed in b40ab29.

Comment thread hack/cozyreport.sh Outdated
short=${kind%%.*}
if kubectl get crd $kind >/dev/null 2>&1; then
kubectl get $kind -A > $DIR/$short.txt 2>&1
kubectl get $kind -A --no-headers 2>/dev/null | awk 'NF >= 3 && $NF != "True" && $NF != "Ready"' | \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The use of $NF (the last column) to check for readiness is problematic. In standard kubectl output, the last column is AGE (e.g., "10m"). Since "10m" is never "True" or "Ready", this filter will always evaluate to true, causing the script to collect detailed diagnostics for every single resource regardless of its actual state. For namespaced resources like Application, the READY column is typically $3.

Suggested change
kubectl get $kind -A --no-headers 2>/dev/null | awk 'NF >= 3 && $NF != "True" && $NF != "Ready"' | \
kubectl get $kind -A --no-headers 2>/dev/null | awk '$3 != "True" && $3 != "Ready"' | \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Real bug — the cozystack apps CRDs end with AGE, so $NF was never "True"/"Ready" and we were collecting full yaml + describe for every Application/ApplicationDefinition/Tenant on the cluster. Switched the filter to jsonpath against .status.conditions[?(@.type=="Ready")].status, so only non-Ready resources get the detailed treatment.

Fixed in b40ab29.

Comment thread hack/cozyreport.sh Outdated
ps auxww > $DIR/ps.txt 2>&1
dmesg | tail -200 > $DIR/dmesg.txt 2>&1 || true
if [ -f /workspace/talosconfig ]; then
for node in 192.168.123.11 192.168.123.12 192.168.123.13; do

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The node IPs are hardcoded to the specific range used in the E2E environment. This makes the sandbox-host module useless on clusters with different networking. It is better to dynamically discover the node IPs from the cluster.

Suggested change
for node in 192.168.123.11 192.168.123.12 192.168.123.13; do
NODES=$(kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null)
for node in ${NODES:-192.168.123.11 192.168.123.12 192.168.123.13}; do

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same fix as in #discussion_r3176660510 — adopted dynamic kubectl get nodes discovery with the existing 192.168.123.11-13 list retained as fallback (${NODES:-...}) so the block still works if the apiserver is unreachable.

Fixed in b40ab29.

@github-actions github-actions Bot removed the size:L label May 4, 2026
- Resolve hack/cozyreport-summary.sh via SCRIPT_DIR so cozyreport.sh
  can be invoked from any working directory, not only the repo root.
- Discover Talos node IPs via `kubectl get nodes` (with the existing
  192.168.123.11-13 list as fallback) instead of hardcoding the E2E
  sandbox topology.
- Replace broken `awk '$NF != "True"'` filter on the cozystack-apps
  loop with a jsonpath check against the Ready condition; the previous
  filter compared AGE ("10m" etc.) against "True" and let every
  resource through, defeating the non-Ready filter.
- Switch the Flux source CRD summary loop from column parsing to
  jsonpath (column positions differ between HelmRepository and
  OCIRepository printer columns) and add ExternalArtifact, matching
  what cozyreport.sh already collects.
- Add `kubectl get crd` guards before HR/source CRD queries so the
  summary script does not abort under `set -eu` when Flux v2 is not
  installed.
- Relabel "OOMKilled in last 30 min" to "Recent OOMKilled events
  (last 20)" — the kubectl call only limits count, not time.

Surfaced from coderabbit and gemini review on #2553.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
@dosubot dosubot Bot added size:L and removed size/L This PR changes 100-499 lines, ignoring generated files labels May 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
hack/cozyreport.sh (1)

38-41: ⚡ Quick win

Skip missing Flux source CRDs before collecting artifacts.

This loop currently records kubectl errors into flux/*.txt and flux/*.yaml when one of the source CRDs is absent. hack/cozyreport-summary.sh already guards the same kinds, so mirroring that check here keeps the report clean on clusters without the full Flux source set.

Suggested fix
 for kind in helmrepositories.source.toolkit.fluxcd.io ocirepositories.source.toolkit.fluxcd.io gitrepositories.source.toolkit.fluxcd.io externalartifacts.source.toolkit.fluxcd.io; do
   short=${kind%%.*}
-  kubectl get $kind -A > $REPORT_DIR/flux/$short.txt 2>&1
-  kubectl get $kind -A -o yaml > $REPORT_DIR/flux/$short.yaml 2>&1
+  kubectl get crd "$kind" >/dev/null 2>&1 || continue
+  kubectl get "$kind" -A > "$REPORT_DIR/flux/$short.txt" 2>&1
+  kubectl get "$kind" -A -o yaml > "$REPORT_DIR/flux/$short.yaml" 2>&1
 done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/cozyreport.sh` around lines 38 - 41, Before running kubectl get for each
Flux source kind in the loop (the variable kind and short in
hack/cozyreport.sh), first check whether the corresponding CRD exists and skip
collection if it does not; implement this by querying the cluster for the CRD
(e.g., via kubectl get crd $kind or an equivalent API-resources check) and only
execute the two kubectl get commands that write to $REPORT_DIR/flux/$short.txt
and $REPORT_DIR/flux/$short.yaml when the CRD is present, so absent Flux source
CRDs do not produce error-filled report files.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@hack/cozyreport.sh`:
- Around line 38-41: Before running kubectl get for each Flux source kind in the
loop (the variable kind and short in hack/cozyreport.sh), first check whether
the corresponding CRD exists and skip collection if it does not; implement this
by querying the cluster for the CRD (e.g., via kubectl get crd $kind or an
equivalent API-resources check) and only execute the two kubectl get commands
that write to $REPORT_DIR/flux/$short.txt and $REPORT_DIR/flux/$short.yaml when
the CRD is present, so absent Flux source CRDs do not produce error-filled
report files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 28bd0d90-e759-4403-be66-fff38b226b47

📥 Commits

Reviewing files that changed from the base of the PR and between aa72a23 and b40ab29.

📒 Files selected for processing (2)
  • hack/cozyreport-summary.sh
  • hack/cozyreport.sh

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. Addresses the diagnostic-coverage gap surfaced from #2500 with a clean, additive change to two shell scripts. All bot findings from the first review pass are folded into b40ab29:

  • "OOMKilled in last 30 min" heading relabeled to match the actual --field-selector reason=OOMKilling semantics (no time bound) — pragmatic call to avoid pulling jq/python into an otherwise pure-sh script.
  • externalartifacts.source.toolkit.fluxcd.io now in the summary loop, with the loop switched from column-based awk to JSONPath so layout differences between source CRDs (HelmRepository's columns differ from OCIRepository) don't silently misclassify resources. Per-kind kubectl get crd … || continue guard keeps the script working on clusters without Flux v2.
  • Dynamic node IP discovery from kubectl get nodes with a fallback to the E2E sandbox IPs — the sandbox-host module now works on arbitrary clusters.
  • cozyreport-summary.sh invoked via $SCRIPT_DIR (resolved through CDPATH= + dirname $0) so cozyreport.sh works from any CWD, not just repo root.
  • kubectl get hr -A | awk '$4 != "True"' is correct against helm-controller v1.4.3 (api/v2/helmrelease_types.go exports Age/Ready/Status printcolumns; with -A columns are NAMESPACE NAME AGE READY STATUS, so $4 is Ready). The Gemini comment claiming $3 is wrong — keep what's there.
  • base64 -d | base64 -d | gzip -d for Helm storage Secrets is correct: helm itself base64-encodes the gzipped JSON, then Kubernetes wraps the resulting string in Secret data which is base64-encoded again, so two decodes are required.

E2E Tests is currently red on this PR, but the failure is in Install Cozystack → Wait for Cluster-API provider deployments on all three retry attempts — well before collect-report runs, and unrelated to anything in this diff (the new code only executes at the end of an install, on report collection). Looks like a CAPI bootstrap flake on the oracle runners. A clean re-run should pass; please push an empty commit to trigger one before merge so the gate is actually green rather than waved through.

Non-blocking nits worth knowing about, none required for merge:

  • Variable quoting in both scripts is sparse — $NAMESPACE, $NAME, $REPORT_DIR, etc. unquoted across most loops. Kubernetes resource names can't contain spaces (they're DNS-label-validated) so this won't bite in practice, but set -euo pipefail + consistent quoting would harden the scripts against future changes that pipe in less-trusted strings (e.g. message bodies from events).
  • cozyreport.sh doesn't set -e; cozyreport-summary.sh does. Inconsistent — first is best-effort by design ("collect what you can, log errors into the file"), second is fail-fast wrapped in || true at the call site. Worth a one-line comment at the top of cozyreport.sh explaining the choice so the next maintainer doesn't "fix" it.
  • Pipelines like kubectl get … | awk … swallow kubectl exit codes (no pipefail). For a diagnostic script, recoverable failure is fine, but it's worth a one-line set -o pipefail at the top of cozyreport-summary.sh (already set -eu) so failed kubectl calls surface as missing sections rather than silently empty ones.
  • The kubectl get events --field-selector reason=OOMKilling filter catches kernel-OOM events emitted by kubelet, but not container exit-137 cases that don't escalate to a node-level OOMKilling event (e.g. cgroup-only kills with no kernel pressure). For a future iteration, kubectl get pod -A -o jsonpath='{range .items[*]}{range .status.containerStatuses[?(@.lastState.terminated.reason=="OOMKilled")]}{…}{end}{end}' catches the container-state path. Out of scope here.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label May 4, 2026
@myasnikovdaniil
myasnikovdaniil enabled auto-merge May 4, 2026 13:54
@myasnikovdaniil
myasnikovdaniil merged commit d9023c9 into main May 4, 2026
20 of 22 checks passed
@myasnikovdaniil
myasnikovdaniil deleted the daniil/split-cozyreport branch May 4, 2026 15:40
@github-actions github-actions Bot added the size/L This PR changes 100-499 lines, ignoring generated files label May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci Issues or PRs related to CI workflows, GitHub Actions, automation area/testing Issues or PRs related to testing (e2e, bats, unit tests) area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review kind/feature Categorizes issue or PR as related to a new feature lgtm This PR has been approved by a maintainer size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants