docker / docker/cli

Change CLI / Client to use Mounts API as default API

Open
#3,974 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

area/api kind/feature kind/refactor
Dominant language
Go
Stars
6.1k
Forks
2.2k
Avg merge
1d 15h
Merged PRs (30d)
43

Description

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 https://github.com/moby/moby/pull/43484 (related to https://github.com/moby/moby/issues/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 https://github.com/docker/cli/pull/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?)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how the CLI handles the -v/--volume, --mount, --tmpfs, --device, and --shm-size flags and populates HostConfig. Check the API-version split for Mounts and verify which tmpfs options are supported. Done means compatible flags use the Mounts API where possible without breaking older API versions or device handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go
Domain
api, cli
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.