Pārlūkot izejas kodu

introduce CreateMountpoint for parity between binds and mounts

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Nicolas De Loof 3 gadi atpakaļ
vecāks
revīzija
304fbf0804

+ 34 - 0
api/server/router/container/container_routes.go

@@ -16,6 +16,7 @@ import (
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/api/types/mount"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/api/types/versions"
 	containerpkg "github.com/docker/docker/container"
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
@@ -513,9 +514,42 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
 		}
 		}
 	}
 	}
 
 
+	if hostConfig != nil && versions.LessThan(version, "1.42") {
+		for _, m := range hostConfig.Mounts {
+			// Ignore BindOptions.CreateMountpoint because it was added in API 1.42.
+			if bo := m.BindOptions; bo != nil {
+				bo.CreateMountpoint = false
+			}
+
+			// These combinations are invalid, but weren't validated in API < 1.42.
+			// We reset them here, so that validation doesn't produce an error.
+			if o := m.VolumeOptions; o != nil && m.Type != mount.TypeVolume {
+				m.VolumeOptions = nil
+			}
+			if o := m.TmpfsOptions; o != nil && m.Type != mount.TypeTmpfs {
+				m.TmpfsOptions = nil
+			}
+			if bo := m.BindOptions; bo != nil {
+				// Ignore BindOptions.CreateMountpoint because it was added in API 1.42.
+				bo.CreateMountpoint = false
+			}
+		}
+	}
+
 	if hostConfig != nil && versions.GreaterThanOrEqualTo(version, "1.42") {
 	if hostConfig != nil && versions.GreaterThanOrEqualTo(version, "1.42") {
 		// Ignore KernelMemory removed in API 1.42.
 		// Ignore KernelMemory removed in API 1.42.
 		hostConfig.KernelMemory = 0
 		hostConfig.KernelMemory = 0
+		for _, m := range hostConfig.Mounts {
+			if o := m.VolumeOptions; o != nil && m.Type != mount.TypeVolume {
+				return errdefs.InvalidParameter(fmt.Errorf("VolumeOptions must not be specified on mount type %q", m.Type))
+			}
+			if o := m.BindOptions; o != nil && m.Type != mount.TypeBind {
+				return errdefs.InvalidParameter(fmt.Errorf("BindOptions must not be specified on mount type %q", m.Type))
+			}
+			if o := m.TmpfsOptions; o != nil && m.Type != mount.TypeTmpfs {
+				return errdefs.InvalidParameter(fmt.Errorf("TmpfsOptions must not be specified on mount type %q", m.Type))
+			}
+		}
 	}
 	}
 
 
 	if hostConfig != nil && runtime.GOOS == "linux" && versions.LessThan(version, "1.42") {
 	if hostConfig != nil && runtime.GOOS == "linux" && versions.LessThan(version, "1.42") {

+ 4 - 0
api/swagger.yaml

@@ -380,6 +380,10 @@ definitions:
             description: "Disable recursive bind mount."
             description: "Disable recursive bind mount."
             type: "boolean"
             type: "boolean"
             default: false
             default: false
+          CreateMountpoint:
+            description: "Create mount point on host if missing"
+            type: "boolean"
+            default: false
       VolumeOptions:
       VolumeOptions:
         description: "Optional configuration for the `volume` type."
         description: "Optional configuration for the `volume` type."
         type: "object"
         type: "object"

+ 3 - 2
api/types/mount/mount.go

@@ -82,8 +82,9 @@ const (
 
 
 // BindOptions defines options specific to mounts of type "bind".
 // BindOptions defines options specific to mounts of type "bind".
 type BindOptions struct {
 type BindOptions struct {
-	Propagation  Propagation `json:",omitempty"`
-	NonRecursive bool        `json:",omitempty"`
+	Propagation      Propagation `json:",omitempty"`
+	NonRecursive     bool        `json:",omitempty"`
+	CreateMountpoint bool        `json:",omitempty"`
 }
 }
 
 
 // VolumeOptions represents the options for a mount of type volume.
 // VolumeOptions represents the options for a mount of type volume.

+ 1 - 1
daemon/volumes.go

@@ -216,7 +216,7 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
 			}
 			}
 		}
 		}
 
 
-		if mp.Type == mounttypes.TypeBind {
+		if mp.Type == mounttypes.TypeBind && (cfg.BindOptions == nil || !cfg.BindOptions.CreateMountpoint) {
 			mp.SkipMountpointCreation = true
 			mp.SkipMountpointCreation = true
 		}
 		}
 
 

+ 4 - 0
docs/api/version-history.md

@@ -97,6 +97,10 @@ keywords: "API, Docker, rcli, REST, documentation"
 * `POST /containers/create` on Linux now respects the `HostConfig.ConsoleSize` property.
 * `POST /containers/create` on Linux now respects the `HostConfig.ConsoleSize` property.
   Container is immediately created with the desired terminal size and clients no longer
   Container is immediately created with the desired terminal size and clients no longer
   need to set the desired size on their own.
   need to set the desired size on their own.
+* `POST /containers/create` allow to set `CreateMountpoint` for host path to be
+  created if missing. This brings parity with `Binds`
+* `POST /containers/create` rejects request if BindOptions|VolumeOptions|TmpfsOptions
+  is set with a non-matching mount Type.
 
 
 ## v1.41 API changes
 ## v1.41 API changes