123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package daemon // import "github.com/docker/docker/integration/daemon"
- import (
- "context"
- "runtime"
- "testing"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/mount"
- "github.com/docker/docker/api/types/volume"
- "github.com/docker/docker/integration/internal/container"
- "github.com/docker/docker/testutil/daemon"
- "gotest.tools/v3/assert"
- "gotest.tools/v3/skip"
- )
- func TestLiveRestore(t *testing.T) {
- skip.If(t, runtime.GOOS == "windows", "cannot start multiple daemons on windows")
- t.Run("volume references", testLiveRestoreVolumeReferences)
- }
- func testLiveRestoreVolumeReferences(t *testing.T) {
- t.Parallel()
- d := daemon.New(t)
- d.StartWithBusybox(t, "--live-restore", "--iptables=false")
- defer func() {
- d.Stop(t)
- d.Cleanup(t)
- }()
- c := d.NewClientT(t)
- ctx := context.Background()
- runTest := func(t *testing.T, policy string) {
- t.Run(policy, func(t *testing.T) {
- volName := "test-live-restore-volume-references-" + policy
- _, err := c.VolumeCreate(ctx, volume.VolumeCreateBody{Name: volName})
- assert.NilError(t, err)
- // Create a container that uses the volume
- m := mount.Mount{
- Type: mount.TypeVolume,
- Source: volName,
- Target: "/foo",
- }
- cID := container.Run(ctx, t, c, container.WithMount(m), container.WithCmd("top"), container.WithRestartPolicy(policy))
- defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
- // Stop the daemon
- d.Restart(t, "--live-restore", "--iptables=false")
- // Try to remove the volume
- err = c.VolumeRemove(ctx, volName, false)
- assert.ErrorContains(t, err, "volume is in use")
- _, err = c.VolumeInspect(ctx, volName)
- assert.NilError(t, err)
- })
- }
- t.Run("restartPolicy", func(t *testing.T) {
- runTest(t, "always")
- runTest(t, "unless-stopped")
- runTest(t, "on-failure")
- runTest(t, "no")
- })
- // Make sure that the local volume driver's mount ref count is restored
- // Addresses https://github.com/moby/moby/issues/44422
- t.Run("local volume with mount options", func(t *testing.T) {
- v, err := c.VolumeCreate(ctx, volume.VolumeCreateBody{
- Driver: "local",
- Name: "test-live-restore-volume-references-local",
- DriverOpts: map[string]string{
- "type": "tmpfs",
- "device": "tmpfs",
- },
- })
- assert.NilError(t, err)
- m := mount.Mount{
- Type: mount.TypeVolume,
- Source: v.Name,
- Target: "/foo",
- }
- cID := container.Run(ctx, t, c, container.WithMount(m), container.WithCmd("top"))
- defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
- d.Restart(t, "--live-restore", "--iptables=false")
- // Try to remove the volume
- // This should fail since its used by a container
- err = c.VolumeRemove(ctx, v.Name, false)
- assert.ErrorContains(t, err, "volume is in use")
- // Remove that container which should free the references in the volume
- err = c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
- assert.NilError(t, err)
- // Now we should be able to remove the volume
- err = c.VolumeRemove(ctx, v.Name, false)
- assert.NilError(t, err)
- })
- }
|