Skip to content

feat: relative parent paths on bind mount src - #4966

Merged
thaJeztah merged 1 commit into
docker:masterfrom
Benehiko:relative-mount-path
May 22, 2025
Merged

feat: relative parent paths on bind mount src#4966
thaJeztah merged 1 commit into
docker:masterfrom
Benehiko:relative-mount-path

Conversation

@Benehiko

@BenehikoBenehiko commented Mar 26, 2024

Copy link
Copy Markdown
Member

This is a follow-up PR of #3469

- What I did
The source value of -v/--volume/--mount is validated, if not absolute and contains the . prefix the value is converted to an absolute path. This prefix (.) is always required for source since the -v/--volume/--mount flags also support setting named volumes.

- How I did it

- How to verify it

  • CI tests
  • docker run --rm -v ../:/test busybox ls -l /test
  • docker run --rm --mount type=bind,source=../,target=/test busybox ls -l /test

- Description for the changelog

Add support for relative parent paths (`../`) on bind mount sources when using `docker run/create` with `-v/--volume` or `--mount type=bind` options.

- A picture of a cute animal (not mandatory but encouraged)
image

@codecov-commenter

codecov-commenter commented Mar 26, 2024

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 1 line in your changes missing coverage. Please review.

Files with missing linesPatch %Lines
cli/command/container/opts.go0.00%0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@thaJeztahthaJeztah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving a "request changes" as this may need discussion / consensus; the --mount "advanced" syntax has various parts that were intentionally lower level (and not applying magic, but instead "as provided").

Maybe it's ok to make this change (as it still requires "opt-in" through ./ as prefix), but it's good to double check if we don't overlook situations where this could be problematic.

(If not, then happy to remove my "request for changes")

@thaJeztah

Copy link
Copy Markdown
Member

Oh, wait; guess I'm reading wrong; this is adding ../ in addition to ./ for both? (and we already had ./ for the --mount syntax?

@Benehiko

Copy link
Copy Markdown
MemberAuthor

Oh, wait; guess I'm reading wrong; this is adding ../ in addition to ./ for both? (and we already had ./ for the --mount syntax?

Yes! :)

@thaJeztah

Copy link
Copy Markdown
Member

Gotcha! I'm slightly on the fence if this would be fixing a problem, or also potentially result in confusing / ambiguous situations;

docker run -it --rm alpine
/ # ls .
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
/ # ls ..
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
/ # ls ../../../../
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var

FWIW; the current directory case on its own already had some consequences (i.e., the path you specify will be used on thee daemon side to mount, where the daemon could be "a remote machine").

Before that patch, we didn't decide to add local resolving of the path, as technically it would be "incorrect" (or at least add to the expectation that bind-mounts happen from the client side); we ultimately chose to implement it as mounting the "current" directory was a very common use-case, and "worked" on either Docker Desktop or a local daemon.

@Benehiko

Copy link
Copy Markdown
MemberAuthor

I don't think this is fixing anything, more of a nice to have IMO. I'm sure there are situations where you'd like to specify a parent directory to bind the volume to while running from the current directory.

docker run --rm --mount type=bind,source=../../my-host/parent/directory,target=/test busybox ls -l /test

@Benehiko

Copy link
Copy Markdown
MemberAuthor

It seems based on the original discussion we allowed to have a relative path as long as it started with the . syntax.

From the above, I (personally) think it'd be ok to allow relative paths; with the constraints that relative paths MUST start with a period (.) and either followed by a path separator (/ or .\), or a colon (for the -v shorthand syntax); that way, relative paths can be used both for the --mount and for the -v / --volume short-hand syntax (without the ambiguity between some-dir being a volume name or a directory named some-dir).

#1203 (comment)

@akerouanton

Copy link
Copy Markdown
Member

or also potentially result in confusing / ambiguous situations;

The example you provide is a user problem. If users provide an invalid relative path, then it's going to do something wrong or at least not what they expect. But that's no different from invalid / wrong absolute path.

FWIW; the current directory case on its own already had some consequences (i.e., the path you specify will be used on thee daemon side to mount, where the daemon could be "a remote machine").

That's an orthogonal problem, and again that will happen with absolute path too. You can currently use -v $(pwd)/../../foobar:/mnt to achieve the same result as what this PR is going to solve. With the same consequences. It just takes more keystrokes and is a bad UX.

Additionally we could add a warning (or even forbid?) this syntax if the context doesn't point to a UNIX socket.

Before that patch, we didn't decide to add local resolving of the path

Yes, we did for ./. See

ifstrings.HasPrefix(hostPart, "."+string(filepath.Separator)) ||hostPart=="." {
ifabsHostPart, err:=filepath.Abs(hostPart); err==nil {
hostPart=absHostPart
}
}

@thaJeztah Your points are all valid but orthogonal to this change, so I don't think we need to block on this one. Any thoughts?

if parsed.Type == string(mounttypes.TypeBind) {
if hostPart, targetPath, ok := strings.Cut(bind, ":"); ok {
if strings.HasPrefix(hostPart, "."+string(filepath.Separator)) || hostPart == "." {
if !filepath.IsAbs(hostPart) && strings.HasPrefix(hostPart, ".") {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need to match . prefix. If there's a rationale behind that, could you expand on that please? 🙂 Also note that, this prefix matching will include hidden files too.

I think this should be just fine:

Suggested change
if!filepath.IsAbs(hostPart) &&strings.HasPrefix(hostPart, ".") {
if!filepath.IsAbs(hostPart) {

@BenehikoBenehikoMar 14, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK (see PR description)

This prefix (.) is always required for source since the -v/--volume/--mount flags also support setting named volumes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, indeed! 🙈 And looking at the constraints for volume names, we don't allow them to start with a dot. So all good I guess!

$ docker volume create .a Error response from daemon: create .a: ".a" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path

@vvolandvvoland left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@vvoland

Copy link
Copy Markdown
Collaborator

Adjusted the changelog entry a bit, let me know if something feels off.

@vvolandvvoland modified the milestones: 28.1.0, 28.2.0Apr 16, 2025

@thaJeztahthaJeztah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah

Copy link
Copy Markdown
Member

close/reopen to trigger CI

@thaJeztahthaJeztah reopened this May 22, 2025
@Benehiko

Copy link
Copy Markdown
MemberAuthor

I think i'll need to rebase, been a while

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
@Benehiko
Benehikoforce-pushed the relative-mount-path branch from 3342b07 to 761285bCompareMay 22, 2025 06:15
@thaJeztah

Copy link
Copy Markdown
Member

Yeah I was hoping it would re-read the things; thanks!

@thaJeztah
thaJeztah merged commit 881c68f into docker:masterMay 22, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@Benehiko@codecov-commenter@thaJeztah@akerouanton@vvoland@neersighted