Skip to content

Should the short volume form emit --mount for a source containing a colon? #111

Closed as not planned

Description

@lesnik512

Found by the phase-1 oracle in #109, which is exactly the outcome that issue predicted ("expect one or two to come back expressible").

ADR-0006 claims the single-letter short-form volume family is a legitimate rule-two refusal because "podman cannot mount either way". Measured on podman 4.9.3, that is true of the family's anonymous readings and false of its bind reading.

docker compose config v5.1.2 splits the family in two (measured locally):

entry Docker's reading
C:\data volume, target C:\data
v:/data volume, target v:/data
v: volume, target v:
C:\data:/var bind, source C:\data, target /var
C:data:/var bind, source <project_dir>/C:data, target /var

The first three ask for a non-absolute container path, and podman refuses every one: invalid container path. Those are rule two, and they are the rows now in tests/integration/refusals.py.

The last two are ordinary Linux binds. C:\data is a legal relative filename, and --mount does not re-split its value on colons the way a short -v spec does. Measured in the integration job on podman 4.9.3:

--mount type=bind,src=./C:\data,dst=/var                exit=0
--mount type=bind,src=C:\data,dst=/var                  exit=0
--mount type=bind,src=/home/runner/.../C:data,dst=/var  exit=0
-v /home/runner/.../C:data:/var                         exit=125  Error: invalid option type "/var"

So podman expresses the mount; emit._volume_flags does not, because it spells every short-form entry as -v "{source}:{destination}". Under ADR-0006 that makes the bind half a tracked limitation, "never a design position".

What this does not settle. Whether compose2pod should accept it is a separate call, and it is #86's question with the measurement finally attached. On Linux, volumes: ['C:\data:/var'] almost always means a Windows user pointed at a drive that is not there, and accepting it would silently bind a relative directory named C:\data. A refusal that says "this is a Windows path and this script runs on Linux" may well be the better tool even though podman would take the mount. The open work is to make the reason match the measurement, not necessarily to lift the refusal.

Options, roughly:

  1. Keep refusing, restate the reason as a deliberate limitation (and drop the false "podman cannot" from the message and the ADR). Cheapest, and arguably the right ergonomics.
  2. Accept, and emit --mount type=bind,src=...,dst=... for short-form entries whose source contains a colon. Correct by the letter of rule two; silently mounts a path the user probably did not mean.
  3. Accept only when the source resolves to an existing directory. Rejected on sight for making the verdict host-dependent, which ADR-0006 reserves for env_file and friends.

I lean to 1. Whichever way it goes, the bind rows then get a Refusal row or an explicit note in tests/integration/refusals.py, so the table stays a complete account of the family.

Blocked on that ruling, not on implementation.

Activity

  1. added
    bugSomething isn't working
    and removed
    bugSomething isn't working
    on Sep 20, 2026
  2. changed the title [-]The drive-qualified bind is a tracked limitation, not a rule-two refusal[/-] [+]Should the short volume form emit --mount for a source containing a colon?[/+] on Sep 20, 2026
  3. lesnik512 commented on Sep 20, 2026

    @lesnik512
    MemberAuthor

    Narrowed by #110, which folds in the measurement and the honest message but changes nothing about what compose2pod accepts.

    What is settled there:

    • The family splits on colon count, measured across eight shapes against docker compose config v5.1.2. One colon is an anonymous volume whose target is the whole string; two or more is a bind whose source keeps the drive colon.
    • podman 4.9.3 refuses every anonymous reading (invalid container path) and mounts every bind reading. Both verdicts are now standing assertions — REFUSALS and LIMITATIONS in tests/integration/refusals.py — so neither claim can go stale unnoticed.
    • The refusal message no longer says "podman cannot express the mount it makes" for the bind half. It now says the short form cannot emit it and points at the long form.
    • The long form already works, with no code change: {type: bind, source: 'C:\data', target: /var} emits --mount "type=bind,source=C:\data,target=/var", which is exactly the invocation measured at exit 0. So the capability is reachable today; only the short spelling is missing.

    That retires options 2 and 3 from the original write-up and leaves one question: should _volume_flags fall back to --mount type=bind when a short-form source contains a colon, or is refusing it the better tool?

    The case for leaving it refused is stronger than it looked when this was filed. On Linux, volumes: ['C:\data:/var'] almost always means a Windows user pointed at a drive that is not there; emitting --mount would silently bind a relative directory literally named C:\data and the failure would surface much later, as an empty mount rather than a clear error. The refusal names the real problem and names the escape hatch, and the escape hatch exists.

    Closing this as "working as intended" is a defensible outcome. Reopening the acceptance case needs a user who genuinely wants a colon in a bind source on Linux, which is what #86 never had.

  4. lesnik512 commented on Sep 20, 2026

    @lesnik512
    MemberAuthor

    Closing as working as intended, on the strength of what #110 measured.

    The capability is not missing. The long form already emits --mount "type=bind,source=C:\data,target=/var", which podman 4.9.3 mounts at exit 0, and LIMITATIONS in tests/integration/refusals.py now asserts that continuously, so the claim cannot rot. The refusal message names the short form's own limit rather than blaming podman, and points at the long form.

    That leaves only the ergonomic question, and the answer there is that refusing is the better tool. On Linux, volumes: ['C:\data:/var'] overwhelmingly means a Windows user pointed at a drive that is not present. Falling back to --mount would bind a relative directory literally named C:\data, and the mistake would surface much later as an empty mount instead of immediately as a clear error naming the escape hatch.

    Reopen if a real document wants a colon in a short-form bind source on Linux. That is the evidence #86 never had, and it is what should drive the change rather than symmetry with Docker's grammar.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions