daemon: Fix container restore with automatic driver selection

Fix a bug causing containers not being loaded when storage driver wasn't
chosen explicitly.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
Paweł Gronowski
2025-08-18 15:23:32 +02:00
parent 555e3939c9
commit 86ae7a56d2
2 changed files with 29 additions and 4 deletions

View File

@@ -1146,6 +1146,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
return nil, err
}
// NewStoreFromOptions will determine the driver if driverName is empty
// so we need to update the driverName to match the driver used.
driverName = layerStore.DriverName()
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
if err := configureKernelSecuritySupport(&cfgStore.Config, layerStore.DriverName()); err != nil {
@@ -1344,6 +1348,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
return nil, err
}
if driverName == "" {
return nil, errors.New("driverName is empty. Please report it as a bug! As a workaround, please set the storage driver explicitly")
}
driverContainers, ok := containers[driverName]
// Log containers which are not loaded with current driver
if (!ok && len(containers) > 0) || len(containers) > 1 {
@@ -1352,7 +1360,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
continue
}
for id := range all {
log.G(ctx).WithField("container", id).Debugf("not restoring container because it was created with another storage driver (%s)", driver)
log.G(ctx).WithField("container", id).
WithField("driver", driver).
WithField("current_driver", driverName).
Debugf("not restoring container because it was created with another storage driver (%s)", driver)
}
}
}

View File

@@ -3,6 +3,7 @@ package daemon
import (
"testing"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/v2/testutil"
"github.com/moby/moby/v2/testutil/daemon"
"gotest.tools/v3/assert"
@@ -27,8 +28,9 @@ func TestDefaultStorageDriver(t *testing.T) {
}
// TestGraphDriverPersistence tests that when a daemon starts with graphdrivers,
// then is restarted without explicit storage configuration, it continues to use
// graphdrivers instead of migrating to containerd snapshotters automatically.
// pulls images and creates containers, then is restarted without explicit
// graphdriver configuration, it continues to use graphdrivers instead of
// migrating to containerd snapshotters automatically.
func TestGraphDriverPersistence(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "Windows does not support running sub-daemons")
t.Setenv("DOCKER_DRIVER", "")
@@ -51,6 +53,14 @@ func TestGraphDriverPersistence(t *testing.T) {
assert.Check(t, info.DriverStatus[0][1] != "io.containerd.snapshotter.v1")
prevDriver := info.Driver
containerResp, err := c.ContainerCreate(ctx, &containertypes.Config{
Image: testImage,
Cmd: []string{"echo", "test"},
}, nil, nil, nil, "test-container")
assert.NilError(t, err, "Failed to create container")
containerID := containerResp.ID
d.Stop(t)
// Phase 2: Start daemon again WITHOUT explicit graphdriver configuration
@@ -63,6 +73,10 @@ func TestGraphDriverPersistence(t *testing.T) {
assert.Check(t, is.Equal(info.Driver, prevDriver))
// Verify our image is still there
_, err := c.ImageInspect(ctx, testImage)
_, err = c.ImageInspect(ctx, testImage)
assert.NilError(t, err, "Test image should still be available after daemon restart")
// Verify our container is still there
_, err = c.ContainerInspect(ctx, containerID)
assert.NilError(t, err, "Test container should still exist after daemon restart")
}