Skip to content

Commit

Permalink
support --mount type=bind,bind-nonrecursive,...
Browse files Browse the repository at this point in the history
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Jan 10, 2019
1 parent d04b616 commit a7b5f2d
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 8 deletions.
4 changes: 4 additions & 0 deletions cli/command/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
if err = validateAPIVersion(containerConfig, dockerCli.Client().ClientVersion()); err != nil {
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts)
if err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions cli/command/container/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/signal"
"github.com/docker/go-connections/nat"
"github.com/pkg/errors"
Expand Down Expand Up @@ -869,3 +870,12 @@ func validateAttach(val string) (string, error) {
}
return val, errors.Errorf("valid streams are STDIN, STDOUT and STDERR")
}

func validateAPIVersion(c *containerConfig, serverAPIVersion string) error {
for _, m := range c.HostConfig.Mounts {
if m.BindOptions != nil && m.BindOptions.NonRecursive && versions.LessThan(serverAPIVersion, "1.40") {
return errors.Errorf("bind-nonrecursive requires API v1.40 or later")
}
}
return nil
}
4 changes: 4 additions & 0 deletions cli/command/container/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ func runRun(dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copt
reportError(dockerCli.Err(), "run", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
if err = validateAPIVersion(containerConfig, dockerCli.Client().ClientVersion()); err != nil {
reportError(dockerCli.Err(), "run", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
return runContainer(dockerCli, ropts, copts, containerConfig)
}

Expand Down
4 changes: 4 additions & 0 deletions cli/command/service/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *serviceOptions
return err
}

if err = validateAPIVersion(service, dockerCli.Client().ClientVersion()); err != nil {
return err
}

specifiedSecrets := opts.secrets.Value()
if len(specifiedSecrets) > 0 {
// parse and validate secrets
Expand Down
10 changes: 10 additions & 0 deletions cli/command/service/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/defaults"
Expand Down Expand Up @@ -909,3 +910,12 @@ const (
flagConfigRemove = "config-rm"
flagIsolation = "isolation"
)

func validateAPIVersion(c swarm.ServiceSpec, serverAPIVersion string) error {
for _, m := range c.TaskTemplate.ContainerSpec.Mounts {
if m.BindOptions != nil && m.BindOptions.NonRecursive && versions.LessThan(serverAPIVersion, "1.40") {
return errors.Errorf("bind-nonrecursive requires API v1.40 or later")
}
}
return nil
}
47 changes: 40 additions & 7 deletions docs/reference/commandline/service_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,34 @@ volumes in a service:
<td></td>
<td>
<p>The Engine mounts binds and volumes <tt>read-write</tt> unless <tt>readonly</tt> option
is given when mounting the bind or volume.
is given when mounting the bind or volume. Note that setting <tt>readonly</tt> for a
bind-mount does not make its submounts <tt>readonly</tt> on the current Linux implementation. See also <tt>bind-nonrecursive</tt>.
<ul>
<li><tt>true</tt> or <tt>1</tt> or no value: Mounts the bind or volume read-only.</li>
<li><tt>false</tt> or <tt>0</tt>: Mounts the bind or volume read-write.</li>
</ul></p>
</td>
</tr>
</table>

#### Options for Bind Mounts

The following options can only be used for bind mounts (`type=bind`):


<table>
<tr>
<th>Option</th>
<th>Description</th>
</tr>
<tr>
<td><b>bind-propagation</b></td>
<td>
<p>See the <a href="#bind-propagation">bind propagation section</a>.</p>
</td>
</tr>
<tr>
<td><b>consistency</b></td>
<td></td>
<td>
<p>The consistency requirements for the mount; one of
<ul>
Expand All @@ -384,9 +402,24 @@ volumes in a service:
</p>
</td>
</tr>
<tr>
<td><b>bind-nonrecursive</b></td>
<td>
By default, submounts are recursively bind-mounted as well. However, this behavior can be confusing when a
bind mount is configured with <tt>readonly</tt> option, because submounts are not mounted as read-only.
Set <tt>bind-nonrecursive</tt> to disable recursive bind-mount.<br />
<br />
A value is optional:<br />
<br />
<ul>
<li><tt>true</tt> or <tt>1</tt>: Disables recursive bind-mount.</li>
<li><tt>false</tt> or <tt>0</tt>: Default if you do not provide a value. Enables recursive bind-mount.</li>
</ul>
</td>
</tr>
</table>

#### Bind Propagation
##### Bind propagation

Bind propagation refers to whether or not mounts created within a given
bind mount or named volume can be propagated to replicas of that mount. Consider
Expand Down Expand Up @@ -423,7 +456,7 @@ volumes do not support bind propagation.
For more information about bind propagation, see the
[Linux kernel documentation for shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).

#### Options for Named Volumes
#### Options for named volumes

The following options can only be used for named volumes (`type=volume`):

Expand Down Expand Up @@ -459,9 +492,9 @@ The following options can only be used for named volumes (`type=volume`):
the Engine copies those files and directories into the volume, allowing
the host to access them. Set <tt>volume-nocopy</tt> to disable copying files
from the container's filesystem to the volume and mount the empty volume.<br />

A value is optional:

<br />
A value is optional:<br />
<br />
<ul>
<li><tt>true</tt> or <tt>1</tt>: Default if you do not provide a value. Disables copying.</li>
<li><tt>false</tt> or <tt>0</tt>: Enables copying.</li>
Expand Down
8 changes: 7 additions & 1 deletion man/docker-run.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,12 +453,18 @@ according to RFC4862.

* `src`, `source`: mount source spec for `bind` and `volume`. Mandatory for `bind`.
* `dst`, `destination`, `target`: mount destination spec.
* `ro`, `read-only`: `true` or `false` (default).
* `ro`, `readonly`: `true` or `false` (default).

**Note**: setting `readonly` for a bind mount does not make its submounts
read-only on the current Linux implementation. See also `bind-nonrecursive`.

Options specific to `bind`:

* `bind-propagation`: `shared`, `slave`, `private`, `rshared`, `rslave`, or `rprivate`(default). See also `mount(2)`.
* `consistency`: `consistent`(default), `cached`, or `delegated`. Currently, only effective for Docker for Mac.
* `bind-nonrecursive`: `true` or `false` (default). If set to `true`,
submounts are not recursively bind-mounted. This option is useful for
`readonly` bind mount.

Options specific to `volume`:

Expand Down
8 changes: 8 additions & 0 deletions opts/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ func (m *MountOpt) Set(value string) error {
case "volume-nocopy":
volumeOptions().NoCopy = true
continue
case "bind-nonrecursive":
bindOptions().NonRecursive = true
continue
}
}

Expand All @@ -100,6 +103,11 @@ func (m *MountOpt) Set(value string) error {
mount.Consistency = mounttypes.Consistency(strings.ToLower(value))
case "bind-propagation":
bindOptions().Propagation = mounttypes.Propagation(strings.ToLower(value))
case "bind-nonrecursive":
bindOptions().NonRecursive, err = strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("invalid value for %s: %s", key, value)
}
case "volume-nocopy":
volumeOptions().NoCopy, err = strconv.ParseBool(value)
if err != nil {
Expand Down

0 comments on commit a7b5f2d

Please sign in to comment.