mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #40451 from cpuguy83/40446_check_other_mounts
Check tmpfs mounts before create anon volume
This commit is contained in:
commit
ce21a16833
3 changed files with 69 additions and 3 deletions
|
@ -46,7 +46,9 @@ func (daemon *Daemon) createContainerOSSpecificSettings(container *container.Con
|
||||||
|
|
||||||
// Skip volumes for which we already have something mounted on that
|
// Skip volumes for which we already have something mounted on that
|
||||||
// destination because of a --volume-from.
|
// destination because of a --volume-from.
|
||||||
if container.IsDestinationMounted(destination) {
|
if container.HasMountFor(destination) {
|
||||||
|
logrus.WithField("container", container.ID).WithField("destination", spec).Debug("mountpoint already exists, skipping anonymous volume")
|
||||||
|
// Not an error, this could easily have come from the image config.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
path, err := container.GetResourcePath(destination)
|
path, err := container.GetResourcePath(destination)
|
||||||
|
|
|
@ -534,3 +534,50 @@ func TestCreateWithInvalidHealthcheckParams(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure that anonymous volumes can be overritten by tmpfs
|
||||||
|
// https://github.com/moby/moby/issues/40446
|
||||||
|
func TestCreateTmpfsOverrideAnonymousVolume(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "windows does not support tmpfs")
|
||||||
|
defer setupTest(t)()
|
||||||
|
client := testEnv.APIClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
id := ctr.Create(ctx, t, client,
|
||||||
|
ctr.WithVolume("/foo"),
|
||||||
|
ctr.WithTmpfs("/foo"),
|
||||||
|
ctr.WithVolume("/bar"),
|
||||||
|
ctr.WithTmpfs("/bar:size=999"),
|
||||||
|
ctr.WithCmd("/bin/sh", "-c", "mount | grep '/foo' | grep tmpfs && mount | grep '/bar' | grep tmpfs"),
|
||||||
|
)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{Force: true})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
inspect, err := client.ContainerInspect(ctx, id)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
// tmpfs do not currently get added to inspect.Mounts
|
||||||
|
// Normally an anoynmous volume would, except now tmpfs should prevent that.
|
||||||
|
assert.Assert(t, is.Len(inspect.Mounts, 0))
|
||||||
|
|
||||||
|
chWait, chErr := client.ContainerWait(ctx, id, container.WaitConditionNextExit)
|
||||||
|
assert.NilError(t, client.ContainerStart(ctx, id, types.ContainerStartOptions{}))
|
||||||
|
|
||||||
|
timeout := time.NewTimer(30 * time.Second)
|
||||||
|
defer timeout.Stop()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-timeout.C:
|
||||||
|
t.Fatal("timeout waiting for container to exit")
|
||||||
|
case status := <-chWait:
|
||||||
|
var errMsg string
|
||||||
|
if status.Error != nil {
|
||||||
|
errMsg = status.Error.Message
|
||||||
|
}
|
||||||
|
assert.Equal(t, int(status.StatusCode), 0, errMsg)
|
||||||
|
case err := <-chErr:
|
||||||
|
assert.NilError(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
mounttypes "github.com/docker/docker/api/types/mount"
|
mounttypes "github.com/docker/docker/api/types/mount"
|
||||||
|
@ -77,12 +78,12 @@ func WithMount(m mounttypes.Mount) func(*TestContainerConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithVolume sets the volume of the container
|
// WithVolume sets the volume of the container
|
||||||
func WithVolume(name string) func(*TestContainerConfig) {
|
func WithVolume(target string) func(*TestContainerConfig) {
|
||||||
return func(c *TestContainerConfig) {
|
return func(c *TestContainerConfig) {
|
||||||
if c.Config.Volumes == nil {
|
if c.Config.Volumes == nil {
|
||||||
c.Config.Volumes = map[string]struct{}{}
|
c.Config.Volumes = map[string]struct{}{}
|
||||||
}
|
}
|
||||||
c.Config.Volumes[name] = struct{}{}
|
c.Config.Volumes[target] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +94,22 @@ func WithBind(src, target string) func(*TestContainerConfig) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTmpfs sets a target path in the container to a tmpfs
|
||||||
|
func WithTmpfs(target string) func(config *TestContainerConfig) {
|
||||||
|
return func(c *TestContainerConfig) {
|
||||||
|
if c.HostConfig.Tmpfs == nil {
|
||||||
|
c.HostConfig.Tmpfs = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
spec := strings.SplitN(target, ":", 2)
|
||||||
|
var opts string
|
||||||
|
if len(spec) > 1 {
|
||||||
|
opts = spec[1]
|
||||||
|
}
|
||||||
|
c.HostConfig.Tmpfs[spec[0]] = opts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithIPv4 sets the specified ip for the specified network of the container
|
// WithIPv4 sets the specified ip for the specified network of the container
|
||||||
func WithIPv4(network, ip string) func(*TestContainerConfig) {
|
func WithIPv4(network, ip string) func(*TestContainerConfig) {
|
||||||
return func(c *TestContainerConfig) {
|
return func(c *TestContainerConfig) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue