Skip to content

Change CLI / Client to use Mounts API as default API #3974

Description

@thaJeztah

Description

Change CLI to use Mounts API as default API

Current situation:

  • The -v / --volume flag uses the classic Binds field / API
  • The --mount flag uses the Mounts field / API
  • The --tmpfs flag uses the Tmpfs field / API
  • The --device flag uses the Devices field / API (but some other fields related to that).
  • TBD: --shm-size (sets size for /dev/shm)

What's the issue?

Effectively, all of these flags are (indirectly for some) related to adding "mounts" to the container, but passed through different options. On the daemon side, those options need to be "merged" in order to validate if there's conflicts.

For example; a --tmpfs and -v using the same target path in the container causes an error;

docker container create --name test \
-v myvolume:/tmpfs1 \
--tmpfs /tmpfs1 \
nginx:alpine
Error response from daemon: Duplicate mount point: /tmpfs1

Similarly, using -v and --mount wth the same target;

docker container create --name test \
-v myvolume:/vol \
--mount type=volume,src=myvolume,dst=/vol \
nginx:alpine
Error response from daemon: Duplicate mount point: /vol

Currently, setting those options, sets different fields in the HostConfig;

docker container create --name test \
-v myvolume:/vol1 \
--mount type=volume,src=myvolume,dst=/vol2 \
-v $(pwd):/bind1 \
--mount type=bind,src=$(pwd),dst=/bind2 \
--tmpfs /tmpfs1 \
nginx:alpine
docker container inspect --format '{{json .HostConfig.Binds }}'test| jq .
[
"myvolume:/vol1",
"/host_mnt/Users/thajeztah/go/src/github.com/docker/cli:/bind1"
]
docker container inspect --format '{{json .HostConfig.Mounts }}'test| jq .
[
{
"Type": "volume",
"Source": "myvolume",
"Target": "/vol2"
},
{
"Type": "bind",
"Source": "/host_mnt/Users/thajeztah/go/src/github.com/docker/cli",
"Target": "/bind2"
}
]
docker container inspect --format '{{json .HostConfig.Tmpfs }}'test| jq .
{
"/tmpfs1": ""
}

But (at least --volume and --mount) end up in the same list of Mounts in the container config (top-level, not in HostConfig);

docker container inspect --format '{{json .Mounts }}'test| jq .
[
{
"Type": "volume",
"Name": "myvolume",
"Source": "/var/lib/docker/volumes/myvolume/_data",
"Destination": "/vol1",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/host_mnt/Users/thajeztah/go/src/github.com/docker/cli",
"Destination": "/bind1",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "myvolume",
"Source": "/var/lib/docker/volumes/myvolume/_data",
"Destination": "/vol2",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/host_mnt/Users/thajeztah/go/src/github.com/docker/cli",
"Destination": "/bind2",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]

Unify the API

We should look at migrating all of those options to use the same (Mounts) API (where possible). Some of this must depend on the API version used, as older API versions may not have all features required.

The -v / --volume flag

Starting with moby/moby#43484 (related to moby/moby#43483), the Mounts field / API provides a CreateMountpoint option, which brings feature-parity between the Binds and Mounts API.

  • When using API v1.42 or up, convert -v (Binds) options to --mount (Mounts)
  • For bind-mounts, use the CreateMountpoint option
  • For API version v1.41 and below, continue using the Binds flag for bind-mounts
  • Consider using the Mounts API for (named/anonymous) volumes on API < v1.42
  • When using -v, convert relative paths to absolute paths (see Handle relative source mounts #3469) this should not be done with the --mount flag (at least not currently), which was designed to not convert paths.

The --tmpfs flag

⚠️ we need to verify if the Mounts option provides all options that can be passed in the --tmpfs microformat

  • rw
  • noexec
  • nosuid
  • size=65536k

The --device flag

For --device, more work will be needed. The Mounts API does not yet provide a type=device option (but we could consider adding).

Currently threre's (at least) 3 fields in HostConfig (indirectly) related to devices. From a quick glance, these options are "global" options (so not "per device"), but we can look at these mode in-depth and consider if making (some of) those options on --mount (or --device with an advanced syntax) would make sense;

"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,

The --shm-size flag

This is a bit of a stretch, but effectively, --shm-size overrides the size for the /dev/shm mount in the container.

  • 👍 we could consider making --shm-size an implicit --mount type=tmpfs,dst=/dev/shm,tmpfs-size=<size>
  • 👎 this "sets in stone" that shm must be a mount at /dev/shm (probably ok), but also assumes that this option only is used for Linux (are there equivalents on other platforms?)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions