operator(campaign): fail loud on empty extracted classes - #24
Conversation
A war-only target image exposes WEB-INF/classes only at runtime, not in its image layers, so the extract-classes initContainer copies nothing and the driver reports a silent coveragePct=0 — indistinguishable from a genuinely low run. Add a verify-classes initContainer that fails the pod (→ campaign Failed) when no .class files landed in the extract dir, with a message pointing at spec.driver.classesPath / the war-only cause. Only the fixed dest dir is referenced (no user input), so the shell string stays injection-safe. envtest 29/29 (launch test asserts both initContainers + the verify check). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JuGqspSB9zpA5AyvHJBiDK
|
@claude please review. Focus: (1) verify-classes shell correctness + injection-safety (only the fixed dest dir interpolated; find -name '*.class' -print -quit); (2) failing the whole Job (generic DriverFailed reason) vs a distinct status condition for empty-classes; (3) initContainer ordering + reusing the runner image. envtest 29/29. |
|
Claude finished @ianp94's task in 2m 3s —— View job Review
Reviewed 1.
|
…view #24) The verify-classes message only reached pod logs, so `kubectl get closurejvmcampaign` still showed the generic "DriverFailed" — loud only to someone who thinks to inspect init-container logs. Now verify-classes also writes its reason to the termination message, and the reconciler, on a backoff-exhausted Job, looks up the driver pod's initContainer statuses and surfaces a non-zero-terminated one's name + message as the campaign condition (Reason=InitContainerFailed), falling back to DriverFailed for a driver crash. envtest 30/30 (adds a spec asserting the verify-classes reason reaches status). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JuGqspSB9zpA5AyvHJBiDK
|
Great point — a fail-loud that's only loud in pod logs is half the win. Implemented your suggestion in `7fb91cc`:
On your other notes: the `sh -c` correctness/injection-safety, ordering, and image reuse you confirmed — no changes there. The 3×-identical-fast-failure under `BackoffLimit` is pre-existing init behavior; cheap since it fails during init. Merging. |
Addresses the follow-up from the #20 review: a driver run that extracts no
.classfiles (the classic case: a war-only target image, whoseWEB-INF/classesonly materializes at runtime, not in the image layers — DD-025 §7b) currently lets the driver run and report a silentcoveragePct=0, indistinguishable from a genuinely low run.Change
A second initContainer
verify-classesruns afterextract-classesand fails the pod (→BackoffLimitexhausted → campaignFailed) when no.classfiles landed in the extract dir, with a message pointing atspec.driver.classesPathand the war-only cause:It references only the fixed dest dir (
campaignClassesDir) — no user input in the shell string, so the injection-safety property from #19 is preserved (unlike the free-formclassesPath, which is stillexec'd without a shell inextract-classes).Scope note
This is the fail-loud half of the war-only follow-up. Full war-only support (extracting classes from
ROOT.war/lib jars so such images work without the e2e's explode-the-war workaround) remains a separate, larger backlog item. With this, a war-only image fails clearly instead of silently — a strict improvement.Validation
envtest 29/29 — the launch test now asserts both initContainers and that
verify-classesrunssh -ccheckingcampaignClassesDirfor.classfiles. The e2e (which explodes the war) is unaffected: classes are present, soverify-classespasses.@claude please review — focus on: (1) the
verify-classesshell command correctness + injection-safety (only the fixed dest dir is interpolated;find ... -name '*.class' -print -quit); (2) whether failing the whole Job (genericDriverFailedcampaign reason) is the right UX vs. a distinct status condition; (3) initContainer ordering / image choice (reuses the runner image).🤖 Generated with Claude Code