Skip to content

Fix transitive depends_on with oneshot/healthy conditions and podma… - #1476

Open
allen-munsch wants to merge 2 commits into
containers:mainfrom
allen-munsch:fix/depends_on_transitive
Open

Fix transitive depends_on with oneshot/healthy conditions and podma…#1476
allen-munsch wants to merge 2 commits into
containers:mainfrom
allen-munsch:fix/depends_on_transitive

Conversation

@allen-munsch

@allen-munsch allen-munsch commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

…n 5.x/6.x dependency graph bugs

Changes:
Only add --requires for service_started (RUNNING) dependencies. Oneshot (service_completed_successfully) and health-checked (service_healthy) dependencies are handled by check_dep_conditions at start time, avoiding broken transitive --requires chains when intermediate containers have already exited (podman 5.x dependency graph bug).

Parse required and restart properties from depends_on entries (default true). required: false allows a dependency to be absent without error. restart: false prevents a dependency change from restarting dependents.

Batch-start all containers in a single podman start call so podman can resolve the full --requires graph atomically, fixing a podman 6.x regression where one-at-a-time starts fail when a transitive dependency is already running.

After batch start, retry containers stuck in "Created" state up to 3 times — podman's graph resolver can fail on them when transitive dependencies are already running, but a retry after the batch succeeds.

check_dep_conditions waits per-container with asyncio.gather instead of a single blocking loop for all deps, so a missing non-required dependency doesn't block others.

Only restart dependents when dep.restart is True.

Tests: 423/423 unit tests pass. Manual integration verified against podman 4.9.3 linux/amd64, 5.4.2 linux/arm64 engine.

several representative matrices were tested via nekto act


repro compose yaml:

version: "3"
# Minimum reproduction of transitive depends_on bug with oneshot containers.
#
# Podman 5.x: fails when an intermediate container (init) exits after
# completing — podman's dependency graph resolver can't handle a --requires
# chain where a middle node has already finished.
#
# Podman 6.x: regression podman#25633 — starting one-at-a-time fails when
# a transitive dependency is already running.
#
# This compose works with the patch applied because:
# 1. Only service_started (RUNNING) deps get --requires; oneshot/healthy
#    deps are handled at start time by check_dep_conditions.
# 2. Containers are batch-started so podman sees the full dependency graph.
# 3. Containers stuck in "Created" state (after batch-start fails on a
#    transitive dep) are retried individually.

services:
  server:
    image: docker.io/alpine:latest
    command: ["sleep", "infinity"]

  init:
    image: docker.io/alpine:latest
    command: ["echo", "init done"]
    depends_on:
      server:
        condition: service_started

  app:
    image: docker.io/alpine:latest
    command: ["sleep", "infinity"]
    depends_on:
      init:
        condition: service_completed_successfully

@allen-munsch
allen-munsch marked this pull request as draft June 16, 2026 22:31
@allen-munsch
allen-munsch force-pushed the fix/depends_on_transitive branch 3 times, most recently from dda833d to 214f360 Compare June 16, 2026 23:30
@allen-munsch
allen-munsch marked this pull request as ready for review June 16, 2026 23:49
@allen-munsch

Copy link
Copy Markdown
Contributor Author

sorry for burning up build minutes

its just a rough sketch, but was a big friction point, seemed to fix the issue, doing a drop in replacement of docker

ran into some issues with some cert gen sidecars when switching over

Comment thread podman_compose.py
Comment thread tests/unit/test_depends_on.py Outdated
Comment thread podman_compose.py
@allen-munsch
allen-munsch force-pushed the fix/depends_on_transitive branch from 214f360 to 909dc4f Compare June 20, 2026 16:31
 1. `container_to_args` - only add `--requires` for `service_started` (RUNNING) deps; oneshot/healthy handled
    by `check_dep_conditions`
 2. `ServiceDependency` -> frozen `@dataclass` with `__post_init__` enum conversion
 3. `calc_dependents` - `cast()` for mypy type narrowing
 4. `flat_deps` - `condition` field in `ServiceDependency()` constructor
 5. `check_dep_conditions` - version-aware skip for health-check conditions on podman < 4.6.0
 6. `compose_up` - `restart` field filter for dependents
 7. `compose_up` detach - batch-start all containers in one `podman start` call (fixes podman 6.x regression),
    retry Created containers, sequential `check_dep_conditions` calls

`tests/unit/test_depends_on.py` - updated `test_depends_on_properties` to compare full `ServiceDependency`
objects
`newsfragments/fix_transitive_depends_on_oneshot_healthy.bugfix` - release note

Signed-off-by: allen-munsch <james.a.munsch@gmail.com>
@p12tic

p12tic commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Looks great, thank you! Please resorve merge conflict and I can then merge the PR.

Signed-off-by: allen-munsch <james.a.munsch@gmail.com>
@allen-munsch

Copy link
Copy Markdown
Contributor Author

resolved the conflict, is this flake, related, or a separate thing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants