diff --git a/planning/releases/0.4.0.md b/planning/releases/0.4.0.md new file mode 100644 index 0000000..b392c20 --- /dev/null +++ b/planning/releases/0.4.0.md @@ -0,0 +1,68 @@ +# compose2pod 0.4.0 — Podman 5.x support: the script owns `/etc/hosts` + +Generated scripts now own `/etc/hosts` outright instead of asking Podman to +populate it with pod-level `--add-host`. Every container runs under `--no-hosts` +and bind-mounts a hosts file compose2pod writes at run time. Because Podman no +longer manages the file, the pre-6.0.0 bug that wiped it can no longer fire — +pod-internal name resolution is now correct on **every** Podman version, +including the 5.x line that has no fix for that bug. The `Podman >= 6.0.0` +requirement is gone. + +## Why + +Before 6.0.0, a container stopping inside a multi-container pod made Podman +regenerate the pod's shared `/etc/hosts` and delete every entry — wiping the +`--add-host` set that was the pod's only source of name resolution. A +`service_completed_successfully` dependency (a migration that runs and exits) +triggered it, producing a `could not translate host name` failure deep inside an +unrelated service, minutes after the script appeared to succeed. + +The fix ([containers/podman#28494](https://github.com/containers/podman/pull/28494)) +first shipped in Podman 6.0.0 and was **never backported to any 5.x** — verified +against the `v5.8` release notes and tag containment for 5.8.0–5.8.5. Anyone +pinned to a Fedora-based Podman 5.x image could not get a fixed Podman, and the +0.3.0 run-time version guard could only *warn*, not fix. This release removes the +cause instead of warning about it. + +## Change + +- **The script owns `/etc/hosts`.** `podman pod create` and every `podman run` + now carry `--no-hosts`; no `--add-host` is emitted. The script writes a full + hosts file to a `mktemp` path — `127.0.0.1 localhost`, `::1 localhost`, each + service alias/hostname → `127.0.0.1`, each `extra_hosts` host → its address — + and bind-mounts it read-only into every container as + `-v "$hostsfile":/etc/hosts:ro,z`, removing it on teardown. The `z` relabel is + mandatory on SELinux-enforcing hosts (Fedora) and a no-op elsewhere. +- **Works on any Podman.** With `--no-hosts`, Podman never rewrites the file, so + the stop-wipe cannot occur regardless of version. Behavior is identical on 5.x + and 6.x. +- **The Podman-version guard is removed.** The run-time warning 0.3.0 added + existed only to flag the now-impossible bug, so it is deleted along with the + documented version floor. + +## Downstream + +- **No pre-editing needed on Podman 5.x.** Compose files with a run-to-completion + dependency that previously lost name resolution now work unchanged. +- **`host.containers.internal` / `host.docker.internal` are no longer provided.** + Under `--no-hosts`, compose2pod cannot resolve Podman's gateway IP to synthesize + them (Docker Compose on Linux does not add them by default either). A service + that needs to reach the host adds an explicit `extra_hosts` entry with the + address it wants. +- **Everything else is unchanged.** The alias/hostname resolution set, the + `extra_hosts` merge, and the conflict rule (a name landing on two addresses is + refused) behave exactly as before — only the mechanism that carries them to the + container changed. + +## Internals + +- Tests at 100% line coverage (enforced); `ruff select=ALL`, `ty`, `eof-fixer` + clean; the conformance harness (real Docker CLI) and integration harness (real + Podman) both green — the integration suite exercises name resolution surviving a + completion container's stop. +- The mechanism was validated end-to-end in a Fedora CoreOS VM before it was + written: with `--no-hosts` and the bind-mounted file, a container's stop leaves + the hosts file byte-identical, and the missing `:z` relabel was caught there + (an un-relabeled mount is unreadable inside the container). See + `planning/changes/2026-07-20.01-own-etc-hosts-via-no-hosts.md` for the full + rationale, the upstream research, and the rejected alternatives.