Repository navigation
Refusal messages cite podman four different ways, and one cites it only in a docstring #121
Description
Noted in passing across #110, #112 and #117, each of which made it slightly worse. Filing it so it stops being a footnote.
ADR-0006 says the rule-two/limitation distinction is "held apart in the refusal messages as well as here". That only works if a reader can tell the categories apart by reading them. Today:
| site | what the user sees |
|---|---|
parsing.py bind 'create_host_path' |
is not supported (podman cannot express it) |
parsing.py volume 'nocopy' |
is not supported (podman cannot express it) |
resources.py:64 reservations.<field> |
is not supported (no podman equivalent) |
parsing.py nested subpath (#117) |
is not supported (podman 5.1 adds the mount option, and compose2pod supports podman 4.9 and up) |
parsing.py drive-shaped anonymous volume (#110) |
...and podman refuses a container path that is not absolute (name a one-character volume through the long form instead) — mid-sentence prose, no suffix at all |
parsing.py volume 'type' cluster/npipe |
volume 'type' must be one of ['bind', 'volume', 'tmpfs', 'image'] — cites podman only in the docstring, never to the user |
Four spellings for what is often the same claim, plus one refusal whose podman reason never leaves the source file.
The last row is the interesting one. The docstring says "cluster/npipe types are refused (podman cannot express them)", so the reason exists and was thought about; the message just lists the allowed values. A user reading it learns what compose2pod wants, not why podman cannot have it — and per ADR-0006 that reason is the thing that makes the refusal legitimate rather than arbitrary.
What a fix has to get right
These are not all the same claim, so collapsing them to one string would be worse than the status quo:
- podman cannot express it at any version —
create_host_path,nocopy, cluster/npipe. - podman expresses it, but above the supported floor —
subpath(fix: declare podman 4.9 the floor and refuse every subpath above it #117). Version-bound, and it goes away when the floor rises. - podman refuses the thing the document asks for — the drive-shaped anonymous volume, where podman rejects the container path itself.
- not podman's doing at all — the short-form-cannot-emit half of fix: refuse each drive-shaped volume reading for its own measured reason #110, and
network_modeunder ADR-0003 (fix: refuse network_mode with its own pod-model reason #119), which deliberately says nothing about podman.
So the deliverable is a small vocabulary with one phrasing per category, applied at every site, and preferably one helper per category so a new refusal picks a category rather than a sentence. The _reject_subpath helper added in #117 is roughly the shape, for one category.
Not urgent, and not worth a dedicated PR if #118 or #109 phase 3 ends up touching these sites anyway — both of them read the refusal messages, and phase 3's completeness gate would benefit from categories it can filter on rather than prose it has to match.
Activity
lesnik512 commentedon Sep 20, 2026
#125 narrowed this to a list. The gate it added keys on
compose2pod/podman.pyattribute names rather than on message prose, so this issue is no longer a prerequisite for anything — but the messages it names are now exactly enumerable, as the rows intests/integration/refusals.pythat carry nosite/claim:anonymous-volume-relative-targetanonymous volume 'a' must be an absolute pathlong-form-relative-targetvolume 'target' must be an absolute pathlong-form-type-clustervolume 'type' must be one of ['bind', 'volume', 'tmpfs', 'image']long-form-type-npipedrive-qualified-bind...which the short form cannot emitdrive-relative-bindThe last two need no change: the limit there is the short form's, not podman's, and the message says so. That leaves four messages that state a rule while keeping its reason to themselves — each measured by a row proving podman refuses the mount, so the reason exists and is simply not told to the user.
One caveat on the
typepair, which is why this is not a find-and-replace:volume 'type' must be one of [...]also fires for a typo likebnid, which Docker refuses too. That is rule one, not rule two. Giving the whole message a podman clause would attach a podman reason to a refusal podman has nothing to do with — so it wants the same split by reason that #110 gave the drive-shaped family, not a suffix.Anything added to this list is caught going forward: a new refusal citing podman without a measurement now fails
tests/test_podman_claim_coverage.py.feat: tell the user podman's reason in the four refusals that kept it (…