henry3260 opened a new pull request, #76393:
URL: https://github.com/apache/airflow/pull/76393

   `KubernetesPodOperator` waited out the full `startup_timeout` when an init 
container's image could not be pulled.
   
   `detect_pod_terminate_early_issues` scanned only 
`status.container_statuses`. While init containers run, the main container 
reports `PodInitializing`, which matches neither `FATAL_STATES` nor 
`TRANSIENT_STATES`, so the detector returned `None` and the caller kept 
polling. A typo in an init container image therefore cost the default 120s 
instead of failing immediately.
   
   The detector now scans `init_container_statuses` too, init containers first, 
so a fatal init container image is reported ahead of the main container's 
`PodInitializing`. This reaches all three callers: `await_pod_start`, 
`await_pod_completion`, and the re-defer guard in `trigger_reentry`.
   
   The error also names the stuck container now:
   
   ```
   Image for container 'init' cannot be pulled, unable to start: 
ImagePullBackOff
   Back-off pulling image "nonexistent:latest"
   ```
   
   Previously neither the raised error nor `_read_pod_container_states` 
identified the container, and that log omits init containers entirely and runs 
behind the non-default `log_events_on_failure`.
   
   Builds on #65490, which introduced the transient-pattern allowlist this 
reuses.
   
   ### Notes for reviewers
   
   Two things the Gen-AI review checklist flags, both deliberate:
   
   - **Two existing tests were modified.** 
`test_start_pod_raises_fast_error_on_image_error` and its synchronous 
counterpart changed because the error text now names the container. That is the 
behaviour change itself, not an accommodation of a regression.
   - **One added case passes without this branch.** The `main_container` half 
of the `("InvalidImageName", '... "timeout-worker:Bad Tag"')` row is a 
deliberate behaviour test. It pins the refactor to a single fatal/transient 
condition, which is otherwise unguarded: mutating that condition so the fatal 
branch also consults the message fails exactly those two cases and nothing 
else. The `init_container` half does fail without the branch.
   
   ### Known related gap, not addressed here
   
   The transient check matches the whole kubelet message, so a genuinely 
missing image whose name happens to contain a transient pattern (for example 
`timeout-worker`, which contains `timeout`) is still treated as transient and 
waits out `startup_timeout`. That predates this change and has the same 
user-visible symptom through a different trigger.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5, 1M context)
   
   Generated-by: Claude Code (Opus 5, 1M context) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to