liverestore: Don't remove --rm
containers on restart
When live-restore is enabled, containers with autoremove enabled shouldn't be forcibly killed when engine restarts. They still should be removed if they exited while the engine was down though. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
f6533a1df1
commit
c5ea3d595c
2 changed files with 67 additions and 3 deletions
|
@ -495,9 +495,12 @@ func (daemon *Daemon) restore(cfg *configStore) error {
|
|||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
// Remove the container if live-restore is disabled or if the container has already exited.
|
||||
if !cfg.LiveRestoreEnabled || !alive {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
|
@ -381,6 +382,66 @@ func TestLiveRestore(t *testing.T) {
|
|||
_ = testutil.StartSpan(baseContext, t)
|
||||
|
||||
t.Run("volume references", testLiveRestoreVolumeReferences)
|
||||
t.Run("autoremove", testLiveRestoreAutoRemove)
|
||||
}
|
||||
|
||||
func testLiveRestoreAutoRemove(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRootless(), "restarted rootless daemon will have a new process namespace")
|
||||
|
||||
t.Parallel()
|
||||
ctx := testutil.StartSpan(baseContext, t)
|
||||
|
||||
run := func(t *testing.T) (*daemon.Daemon, func(), string) {
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t, "--live-restore", "--iptables=false")
|
||||
t.Cleanup(func() {
|
||||
d.Stop(t)
|
||||
d.Cleanup(t)
|
||||
})
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
apiClient := d.NewClientT(t)
|
||||
|
||||
cID := container.Run(ctx, t, apiClient,
|
||||
container.WithBind(tmpDir, "/v"),
|
||||
// Run until a 'stop' file is created.
|
||||
container.WithCmd("sh", "-c", "while [ ! -f /v/stop ]; do sleep 0.1; done"),
|
||||
container.WithAutoRemove)
|
||||
t.Cleanup(func() { apiClient.ContainerRemove(ctx, cID, containertypes.RemoveOptions{Force: true}) })
|
||||
finishContainer := func() {
|
||||
file, err := os.Create(filepath.Join(tmpDir, "stop"))
|
||||
assert.NilError(t, err, "Failed to create 'stop' file")
|
||||
file.Close()
|
||||
}
|
||||
return d, finishContainer, cID
|
||||
}
|
||||
|
||||
t.Run("engine restart shouldnt kill alive containers", func(t *testing.T) {
|
||||
d, finishContainer, cID := run(t)
|
||||
|
||||
d.Restart(t, "--live-restore", "--iptables=false")
|
||||
|
||||
apiClient := d.NewClientT(t)
|
||||
_, err := apiClient.ContainerInspect(ctx, cID)
|
||||
assert.NilError(t, err, "Container shouldn't be removed after engine restart")
|
||||
|
||||
finishContainer()
|
||||
|
||||
poll.WaitOn(t, container.IsRemoved(ctx, apiClient, cID))
|
||||
})
|
||||
t.Run("engine restart should remove containers that exited", func(t *testing.T) {
|
||||
d, finishContainer, cID := run(t)
|
||||
|
||||
d.Stop(t)
|
||||
|
||||
finishContainer()
|
||||
time.Sleep(time.Millisecond * 200)
|
||||
|
||||
d.Start(t, "--live-restore", "--iptables=false")
|
||||
|
||||
poll.WaitOn(t, container.IsRemoved(ctx, d.NewClientT(t), cID))
|
||||
})
|
||||
}
|
||||
|
||||
func testLiveRestoreVolumeReferences(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue