-
Notifications
You must be signed in to change notification settings - Fork 2.3k
[WIP]: Add Claude failure analysis to libvirt VPN and Power UPI workflows #83814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| approvers: | ||
| - deepsm007 | ||
| - multiarch-approvers | ||
| reviewers: | ||
| - multiarch-reviewers |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,150 @@ | ||||||||||||||||||||||||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "=== Libvirt E2E Failure Analyzer ===" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| JOB_NAME="${JOB_NAME:-unknown}" | ||||||||||||||||||||||||||||||||||||||||||
| BUILD_ID="${BUILD_ID:-unknown}" | ||||||||||||||||||||||||||||||||||||||||||
| JOB_TYPE="${JOB_TYPE:-}" | ||||||||||||||||||||||||||||||||||||||||||
| PULL_NUMBER="${PULL_NUMBER:-}" | ||||||||||||||||||||||||||||||||||||||||||
| REPO_OWNER="${REPO_OWNER:-}" | ||||||||||||||||||||||||||||||||||||||||||
| REPO_NAME="${REPO_NAME:-}" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "${TEST_NAME:-}" ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| if [[ "${JOB_NAME}" =~ (ocp-[^/]+)$ ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| TEST_NAME="${BASH_REMATCH[1]}" | ||||||||||||||||||||||||||||||||||||||||||
| elif [[ "${JOB_NAME}" =~ (e2e-[^/]+)$ ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| TEST_NAME="${BASH_REMATCH[1]}" | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| echo "ERROR: TEST_NAME is empty and could not be derived from JOB_NAME=${JOB_NAME} — skipping analysis." | ||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if [[ "${JOB_TYPE}" == "presubmit" && -n "${PULL_NUMBER}" ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| GCS_BUCKET_PATH="pr-logs/pull/${REPO_OWNER}_${REPO_NAME}/${PULL_NUMBER}/${JOB_NAME}/${BUILD_ID}" | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| GCS_BUCKET_PATH="logs/${JOB_NAME}/${BUILD_ID}" | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| GCSWEB_BASE="https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results" | ||||||||||||||||||||||||||||||||||||||||||
| PROW_JOB_URL="${GCSWEB_BASE}/${GCS_BUCKET_PATH}" | ||||||||||||||||||||||||||||||||||||||||||
| ARTIFACTS_BASE="${GCSWEB_BASE}/${GCS_BUCKET_PATH}/artifacts/${TEST_NAME}" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "Waiting for test step artifacts in GCS (TEST_NAME=${TEST_NAME} ARCH=${ARCH:-unset})..." | ||||||||||||||||||||||||||||||||||||||||||
| FAILURE_DETECTED=false | ||||||||||||||||||||||||||||||||||||||||||
| FAILED_STEP="" | ||||||||||||||||||||||||||||||||||||||||||
| MAX_WAIT=600 | ||||||||||||||||||||||||||||||||||||||||||
| POLL_INTERVAL=15 | ||||||||||||||||||||||||||||||||||||||||||
| WAITED=0 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| while [[ ${WAITED} -lt ${MAX_WAIT} ]]; do | ||||||||||||||||||||||||||||||||||||||||||
| for STEP_NAME in ${TEST_STEPS}; do | ||||||||||||||||||||||||||||||||||||||||||
| FINISHED_JSON=$(curl -sL "${ARTIFACTS_BASE}/${STEP_NAME}/finished.json" 2>/dev/null || true) | ||||||||||||||||||||||||||||||||||||||||||
| if echo "${FINISHED_JSON}" | jq -e '.passed == false' &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||
| echo "Detected failure in ${STEP_NAME}/finished.json (waited ${WAITED}s)" | ||||||||||||||||||||||||||||||||||||||||||
| FAILURE_DETECTED=true | ||||||||||||||||||||||||||||||||||||||||||
| FAILED_STEP="${STEP_NAME}" | ||||||||||||||||||||||||||||||||||||||||||
| break 2 | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| all_passed=true | ||||||||||||||||||||||||||||||||||||||||||
| saw_any=false | ||||||||||||||||||||||||||||||||||||||||||
| for STEP_NAME in ${TEST_STEPS}; do | ||||||||||||||||||||||||||||||||||||||||||
| FINISHED_JSON=$(curl -sL "${ARTIFACTS_BASE}/${STEP_NAME}/finished.json" 2>/dev/null || true) | ||||||||||||||||||||||||||||||||||||||||||
| if echo "${FINISHED_JSON}" | jq -e '.passed == true' &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||
| saw_any=true | ||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
| if echo "${FINISHED_JSON}" | jq -e '.passed == false' &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||
| all_passed=false | ||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
| all_passed=false | ||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||
| if [[ "${saw_any}" == "true" && "${all_passed}" == "true" ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| echo "Listed test steps passed — skipping analysis." | ||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo " Waiting for artifacts... (${WAITED}s/${MAX_WAIT}s)" | ||||||||||||||||||||||||||||||||||||||||||
| sleep "${POLL_INTERVAL}" | ||||||||||||||||||||||||||||||||||||||||||
| WAITED=$((WAITED + POLL_INTERVAL)) | ||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if [[ "${FAILURE_DETECTED}" == "false" ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| echo "Timed out waiting for failed-step artifacts after ${WAITED}s — skipping analysis." | ||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if ! command -v claude &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||
| echo "ERROR: Claude Code CLI not found — skipping analysis" | ||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "Claude Code CLI: $(claude --version 2>/dev/null || echo 'unknown')" | ||||||||||||||||||||||||||||||||||||||||||
| echo "Prow job URL: ${PROW_JOB_URL}" | ||||||||||||||||||||||||||||||||||||||||||
| echo "Failed step: ${FAILED_STEP}" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_PROMPT="IMPORTANT CI CONTEXT: | ||||||||||||||||||||||||||||||||||||||||||
| - You are running inside the CI job itself as a post-step. | ||||||||||||||||||||||||||||||||||||||||||
| - This step's artifact directory is: ${ARTIFACT_DIR} | ||||||||||||||||||||||||||||||||||||||||||
| - Other steps' artifacts (build-log, JUnit, install, gather) are available via GCS at: ${PROW_JOB_URL} | ||||||||||||||||||||||||||||||||||||||||||
| - You have network access to download artifacts from GCS using curl. | ||||||||||||||||||||||||||||||||||||||||||
| - Write the final analysis report to: ${ARTIFACT_DIR}/failure-analysis.md | ||||||||||||||||||||||||||||||||||||||||||
| - Use --fast mode (do NOT use AskUserQuestion). | ||||||||||||||||||||||||||||||||||||||||||
| - Do NOT prompt for JIRA export — just write the markdown analysis. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| LIBVIRT CONTEXT: | ||||||||||||||||||||||||||||||||||||||||||
| - These jobs install OpenShift on IBM Z (s390x) or IBM Power (ppc64le) KVM guests via UPI libvirt. | ||||||||||||||||||||||||||||||||||||||||||
| - Workflows: openshift-e2e-libvirt-vpn, openshift-e2e-libvirt-vpn-fips, openshift-e2e-libvirt-upi, openshift-e2e-libvirt-upi-fips. | ||||||||||||||||||||||||||||||||||||||||||
| - Z uses cluster profile libvirt-s390x-vpn. Power uses libvirt-ppc64le-s2s. | ||||||||||||||||||||||||||||||||||||||||||
| - Install steps: upi-conf-libvirt, upi-install-libvirt. Test step: openshift-e2e-libvirt-test. | ||||||||||||||||||||||||||||||||||||||||||
| - ARCH is ${ARCH:-unknown}. | ||||||||||||||||||||||||||||||||||||||||||
| - Power (ppc64le) injects chrony to clock.corp.redhat.com. Z (s390x) RHCOS 10 KVM guests may have a broken PHC refclock; LPAR NTP is the libvirt gateway 192.168.<subnet>.1. | ||||||||||||||||||||||||||||||||||||||||||
| - Serial jobs (TEST_TYPE=conformance-serial) include oc adm upgrade recommend, which fails when NodeClockNotSynchronising fires. | ||||||||||||||||||||||||||||||||||||||||||
| - Prefer evidence from junit, install logs, node journals, and MachineConfigs over speculation." | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||
| echo "Running Claude with /ci:prow-job-analysis skill..." | ||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| set +e | ||||||||||||||||||||||||||||||||||||||||||
| timeout 1200 claude -p "/ci:prow-job-analysis ${PROW_JOB_URL} --fast" \ | ||||||||||||||||||||||||||||||||||||||||||
| --append-system-prompt "${SYSTEM_PROMPT}" \ | ||||||||||||||||||||||||||||||||||||||||||
| --allowedTools "Bash Read Write Edit Grep Glob WebFetch Skill" \ | ||||||||||||||||||||||||||||||||||||||||||
| --max-turns 100 \ | ||||||||||||||||||||||||||||||||||||||||||
| --model "${CLAUDE_MODEL}" \ | ||||||||||||||||||||||||||||||||||||||||||
| --verbose \ | ||||||||||||||||||||||||||||||||||||||||||
| --output-format stream-json \ | ||||||||||||||||||||||||||||||||||||||||||
| 2> "${ARTIFACT_DIR}/claude-failure-analysis.log" \ | ||||||||||||||||||||||||||||||||||||||||||
| | tee "${ARTIFACT_DIR}/claude-failure-analysis.json" | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+113
to
+122
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
file='ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh'
printf '%s\n' '--- target lines ---'
cat -n "$file" | sed -n '1,145p'
printf '%s\n' '--- related Claude and tee usage ---'
rg -n -C 3 'claude|stream-json|tee|SYSTEM_PROMPT|PROW_JOB_URL|ARTIFACT_DIR' ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure ci-operator/step-registry --glob '*-commands.sh' | head -n 300
printf '%s\n' '--- repository diff summary ---'
git diff --stat -- "$file"
git status --short -- "$file"Repository: openshift/release Length of output: 44562 🌐 Web query:
💡 Result: When using the Claude Code CLI, the --output-format stream-json flag enables a machine-readable, newline-delimited JSON output stream, which is ideal for programmatic consumption [1][2]. When combined with --verbose and --include-partial-messages, the CLI emits detailed, real-time events as the agent processes the request [1][2]. Each line of the stream is a JSON object representing an event [1][2]. While formal documentation for every top-level event type is limited, the stream typically includes messages such as system, assistant, stream_event, and result [3]. The final line of the stream is always a result message containing the final response text, cost information, and session metadata [1][2]. For scenarios involving tool calls, the CLI emits tool_use and tool_result blocks [4][5]. If you need to include partial streaming events (such as text tokens being generated in real-time), you must use the --include-partial-messages flag [4][1]. You can filter these events using tools like jq to extract specific data, such as text_delta updates [1][3]. Key flags for this workflow include: --output-format stream-json: Sets the output to newline-delimited JSON [1][2]. --verbose: Enables detailed logging [6]. --include-partial-messages: Includes partial stream events (like text deltas) in the output [4][5]. --forward-subagent-text: If subagents are used, this flag allows you to emit subagent text and thinking blocks as assistant/user messages, enabling the reconstruction of subagent transcripts [4][5]. For advanced use cases or when building a streaming consumer, it is recommended to refer to the Agent SDK streaming output documentation, as it provides a more comprehensive reference for event types, message flows, and data schemas than the current CLI-specific documentation [3]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
script = Path("ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh").read_text()
old = ''' --output-format stream-json \\
2> "${ARTIFACT_DIR}/claude-failure-analysis.log" \\
| tee "${ARTIFACT_DIR}/claude-failure-analysis.json"'''
new = ''' --output-format stream-json \\
> "${ARTIFACT_DIR}/claude-failure-analysis.json" \\
2> "${ARTIFACT_DIR}/claude-failure-analysis.log"'''
print("old pipeline present:", old in script)
print("proposed redirection present:", new in script)
print("tee occurrence count:", script.count("| tee"))
print("artifact parser reads captured JSON:", 'grep \\'"type":"result"\\' "${ARTIFACT_DIR}/claude-failure-analysis.json"' in script)
PY
printf '%s\n' '--- Claude CLI references and version configuration ---'
rg -n -C 2 'claude(-code)?|CLAUDE_MODEL|output-format|stream-json' . \
--glob '!vendor/**' --glob '!node_modules/**' --glob '!build/**' --glob '!dist/**' \
| head -n 250Repository: openshift/release Length of output: 413 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
script = Path(
"ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/"
"openshift-e2e-libvirt-analyze-e2e-failure-commands.sh"
).read_text()
old = """ --output-format stream-json \\
2> "${ARTIFACT_DIR}/claude-failure-analysis.log" \\
| tee "${ARTIFACT_DIR}/claude-failure-analysis.json" """
new = """ --output-format stream-json \\
> "${ARTIFACT_DIR}/claude-failure-analysis.json" \\
2> "${ARTIFACT_DIR}/claude-failure-analysis.log" """
print("old pipeline present:", old.rstrip() in script)
print("proposed redirection present:", new.rstrip() in script)
print("tee occurrence count:", script.count("| tee"))
print(
"artifact parser reads captured JSON:",
'claude-failure-analysis.json" 2>/dev/null' in script,
)
PY
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
printf '%s\n' '{"type":"tool_result","content":"artifact-derived value"}' \
| tee "$tmpdir/captured.json" >/dev/null
printf '%s\n' 'captured file:'
cat "$tmpdir/captured.json"
printf '%s\n' 'tee stdout was redirected: no stream content appeared above the captured file.'Repository: openshift/release Length of output: 326 Stop streaming Claude output to CI logs.
Proposed fix --verbose \
--output-format stream-json \
- 2> "${ARTIFACT_DIR}/claude-failure-analysis.log" \
- | tee "${ARTIFACT_DIR}/claude-failure-analysis.json"
+ > "${ARTIFACT_DIR}/claude-failure-analysis.json" \
+ 2> "${ARTIFACT_DIR}/claude-failure-analysis.log"📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||||||||||||||||||||||
| CLAUDE_EXIT=$? | ||||||||||||||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if [[ "${CLAUDE_EXIT}" -eq 124 ]]; then | ||||||||||||||||||||||||||||||||||||||||||
| echo "Claude timed out — report may be incomplete" | ||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| TOKENS_JSON=$(grep '"type":"result"' "${ARTIFACT_DIR}/claude-failure-analysis.json" 2>/dev/null \ | ||||||||||||||||||||||||||||||||||||||||||
| | head -1 \ | ||||||||||||||||||||||||||||||||||||||||||
| | jq '{ | ||||||||||||||||||||||||||||||||||||||||||
| total_cost_usd: (.total_cost_usd // 0), | ||||||||||||||||||||||||||||||||||||||||||
| duration_ms: (.duration_ms // 0), | ||||||||||||||||||||||||||||||||||||||||||
| num_turns: (.num_turns // 0), | ||||||||||||||||||||||||||||||||||||||||||
| input_tokens: (.usage.input_tokens // 0), | ||||||||||||||||||||||||||||||||||||||||||
| output_tokens: (.usage.output_tokens // 0), | ||||||||||||||||||||||||||||||||||||||||||
| cache_read_input_tokens: (.usage.cache_read_input_tokens // 0), | ||||||||||||||||||||||||||||||||||||||||||
| cache_creation_input_tokens: (.usage.cache_creation_input_tokens // 0) | ||||||||||||||||||||||||||||||||||||||||||
| }' 2>/dev/null \ | ||||||||||||||||||||||||||||||||||||||||||
| || echo '{"total_cost_usd":0,"duration_ms":0,"num_turns":0,"input_tokens":0,"output_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0}') | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "${TOKENS_JSON}" > "${SHARED_DIR}/claude-failure-analysis-tokens.json" 2>/dev/null || true | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||
| echo "=== Failure Analysis Complete ===" | ||||||||||||||||||||||||||||||||||||||||||
| echo "Claude exit code: ${CLAUDE_EXIT}" | ||||||||||||||||||||||||||||||||||||||||||
| echo "Analysis: ${ARTIFACT_DIR}/failure-analysis.md" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "path": "openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-ref.yaml", | ||
| "owners": { | ||
| "approvers": [ | ||
| "deepsm007", | ||
| "multiarch-approvers" | ||
| ], | ||
| "reviewers": [ | ||
| "multiarch-reviewers" | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||||||
| ref: | ||||||||||
| as: openshift-e2e-libvirt-analyze-e2e-failure | ||||||||||
| from_image: | ||||||||||
| namespace: ci | ||||||||||
| name: claude-ai-helpers | ||||||||||
| tag: latest | ||||||||||
| best_effort: true | ||||||||||
| commands: openshift-e2e-libvirt-analyze-e2e-failure-commands.sh | ||||||||||
| timeout: 30m0s | ||||||||||
| grace_period: 30s | ||||||||||
|
Comment on lines
+9
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Reserve time after polling for report handling. The script can poll for 600 seconds and then run Increase the ref timeout or reduce the Claude timeout to leave a cleanup buffer. Proposed fix- timeout: 30m0s
+ timeout: 35m0s📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| env: | ||||||||||
| - name: CLAUDE_CODE_USE_VERTEX | ||||||||||
| default: "1" | ||||||||||
| documentation: |- | ||||||||||
| Enable Vertex AI for Claude Code. | ||||||||||
| - name: CLOUD_ML_REGION | ||||||||||
| default: "global" | ||||||||||
| documentation: |- | ||||||||||
| Google Cloud region for Vertex AI. | ||||||||||
| - name: ANTHROPIC_VERTEX_PROJECT_ID | ||||||||||
| default: "openshift-ci-prow-agents" | ||||||||||
| documentation: |- | ||||||||||
| Google Cloud project ID for Vertex AI authentication. | ||||||||||
| - name: GOOGLE_APPLICATION_CREDENTIALS | ||||||||||
| default: "/var/run/claude-code-service-account/google-token" | ||||||||||
| documentation: |- | ||||||||||
| Path to the Google Cloud service account JSON key file for Vertex AI authentication. | ||||||||||
| - name: CLAUDE_MODEL | ||||||||||
| default: "claude-opus-4-6" | ||||||||||
| documentation: |- | ||||||||||
| Claude model to use for test failure analysis. | ||||||||||
| - name: TEST_NAME | ||||||||||
| default: "" | ||||||||||
| documentation: |- | ||||||||||
| ci-operator test name (as: field), used to build the GCS artifact path. | ||||||||||
| When empty, derived from JOB_NAME (the ocp-* or e2e-* suffix). | ||||||||||
| - name: TEST_STEPS | ||||||||||
| default: "openshift-e2e-libvirt-test upi-install-libvirt" | ||||||||||
| documentation: |- | ||||||||||
| Space-separated inner step names to poll for finished.json. | ||||||||||
| resources: | ||||||||||
| requests: | ||||||||||
| cpu: 100m | ||||||||||
| memory: 256Mi | ||||||||||
| credentials: | ||||||||||
| - namespace: test-credentials | ||||||||||
| name: sa-claude-openshift-ci | ||||||||||
| mount_path: /var/run/claude-code-service-account | ||||||||||
| documentation: |- | ||||||||||
| Post-step that uses Claude to analyze libvirt e2e failures (IBM Z VPN and Power UPI). | ||||||||||
| Uses the existing CI Vertex service account; no per-user API key is required. | ||||||||||
| Only runs when a listed test/install step failed. On success, exits early. | ||||||||||
| Produces ARTIFACT_DIR/failure-analysis.md. | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Bound every GCS polling request.
curlhas no transfer timeout at either site. A stalled GCS connection blocks the loop and prevents analysis until the outer step timeout terminates the post-step.ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh#L43-L43: add connection and transfer timeouts to the first polling request.ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh#L55-L55: add the same timeouts to the pass-state polling request.Proposed fix
📍 Affects 1 file
ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh#L43-L43(this comment)ci-operator/step-registry/openshift/e2e/libvirt/analyze-e2e-failure/openshift-e2e-libvirt-analyze-e2e-failure-commands.sh#L55-L55🤖 Prompt for AI Agents