Merge pull request #51693 from vvoland/51692-docker-29.x

[docker-29.x backport] daemon: clean up dead containers on start
This commit is contained in:
Paweł Gronowski
2025-12-11 20:50:59 +00:00
committed by GitHub
2 changed files with 36 additions and 5 deletions

View File

@@ -641,18 +641,25 @@ func (daemon *Daemon) restore(ctx context.Context, cfg *configStore, containers
}
group.Wait()
for id := range removeContainers {
for id, c := range removeContainers {
group.Add(1)
go func(cid string) {
go func(cid string, c *container.Container) {
_ = sem.Acquire(context.Background(), 1)
defer group.Done()
defer sem.Release(1)
if c.State.IsDead() {
if err := daemon.cleanupContainer(c, backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(ctx).WithField("container", cid).WithError(err).Error("failed to remove dead container")
}
return
}
if err := daemon.containerRm(&cfg.Config, cid, &backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(ctx).WithField("container", cid).WithError(err).Error("failed to remove container")
}
sem.Release(1)
group.Done()
}(id)
}(id, c)
}
group.Wait()

View File

@@ -8,6 +8,7 @@ import (
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/internal/testutil/daemon"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/fs"
@@ -107,3 +108,26 @@ func TestRemoveInvalidContainer(t *testing.T) {
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
assert.Check(t, is.ErrorContains(err, "No such container"))
}
func TestRemoveDeadContainersOnDaemonRestart(t *testing.T) {
skip.If(t, testEnv.IsRemoteDaemon)
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME: Windows CI does not support multiple daemons yet")
ctx := setupTest(t)
d := daemon.New(t)
d.StartWithBusybox(ctx, t)
defer d.Stop(t)
apiClient := d.NewClientT(t)
container.Run(ctx, t, apiClient, container.WithCmd("top"), container.WithAutoRemove)
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true})
assert.NilError(t, err)
assert.Check(t, is.Len(list.Items, 1))
d.Restart(t)
list, err = apiClient.ContainerList(ctx, client.ContainerListOptions{All: true})
assert.NilError(t, err)
assert.Check(t, is.Len(list.Items, 0))
}