Before this commit migration to c8d would apply when
`TEST_INTEGRATION_USE_GRAPHDRIVER` is empty/unset (which is the default
scenario).
This caused fresh Windows installations to default to containerd image
store and panic:
```
PS C:\Users\Administrator\Desktop> .\dockerd.exe --debug
time="2025-09-01T12:45:42.182741200Z" level=info msg="Starting up"
time="2025-09-01T12:45:42.225128900Z" level=debug msg="Listener created for HTTP on npipe (//./pipe/docker_engine)"
time="2025-09-01T12:45:42.231740900Z" level=info msg="OTEL tracing is not configured, using no-op tracer provider"
time="2025-09-01T12:45:42.263475300Z" level=info msg="Windows default isolation mode: process"
time="2025-09-01T12:45:42.263475300Z" level=debug msg="Stackdump - waiting signal at Global\\stackdump-7780"
time="2025-09-01T12:45:42.273230800Z" level=debug msg="Using default logging driver json-file"
time="2025-09-01T12:45:42.273230800Z" level=debug msg="No quota support for local volumes in C:\\ProgramData\\docker\\volumes: Filesystem does not support, or has not enabled quotas"
time="2025-09-01T12:45:42.301881100Z" level=info msg="Loading containers: start."
time="2025-09-01T12:45:42.302302800Z" level=info msg="[graphdriver] trying configured driver: windowsfilter"
time="2025-09-01T12:45:42.302302800Z" level=debug msg="WindowsGraphDriver InitFilter at C:\\ProgramData\\docker\\windowsfilter"
time="2025-09-01T12:45:42.303028000Z" level=debug msg="Initialized graph driver windowsfilter"
time="2025-09-01T12:45:42.323007600Z" level=info msg="Enabling containerd snapshotter because migration set with no containers and 0 images in graph driver" total=0
time="2025-09-01T12:45:42.323007600Z" level=info msg="Starting daemon with containerd snapshotter integration enabled"
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x88 pc=0x16522c4]
goroutine 1 [running]:
github.com/containerd/containerd/v2/client.(*Client).IntrospectionService(0x3153e60?)
/go/src/github.com/docker/docker/vendor/github.com/containerd/containerd/v2/client/client.go:731 +0x24
github.com/moby/moby/v2/daemon.NewDaemon({0x3153e60, 0xc0001360f0}, 0xc0000fa008, 0xc00025c5a0, 0xc0002deee0)
/go/src/github.com/docker/docker/daemon/daemon.go:1276 +0x35ad
github.com/moby/moby/v2/daemon/command.(*daemonCLI).start(0xc0000da320, {0x3153df0, 0x4704c60})
/go/src/github.com/docker/docker/daemon/command/daemon.go:262 +0xa09
github.com/moby/moby/v2/daemon/command.runDaemon({0x3153df0, 0x4704c60}, 0xc0000da320)
/go/src/github.com/docker/docker/daemon/command/docker_windows.go:28 +0x8a
github.com/moby/moby/v2/daemon/command.newDaemonCommand.func1(0xc000147508, {0xc000500f60?, 0x7?, 0x2cf8c90?})
/go/src/github.com/docker/docker/daemon/command/docker.go:45 +0xd1
github.com/spf13/cobra.(*Command).execute(0xc000147508, {0xc00006a0f0, 0x1, 0x1})
/go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0xc000147508)
/go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:1148 +0x46f
github.com/spf13/cobra.(*Command).Execute(...)
/go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:1071
github.com/spf13/cobra.(*Command).ExecuteContext(...)
/go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:1064
github.com/moby/moby/v2/daemon/command.daemonRunner.Run({0x3127160?}, {0x3153df0, 0x4704c60})
/go/src/github.com/docker/docker/daemon/command/docker.go:111 +0x6e
main.main()
/go/src/github.com/docker/docker/cmd/dockerd/main.go:38 +0x122
```
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -785,6 +785,10 @@ func (daemon *Daemon) IsSwarmCompatible() error {
|
| 785 | 785 |
return daemon.config().IsSwarmCompatible() |
| 786 | 786 |
} |
| 787 | 787 |
|
| 788 |
+func useContainerdByDefault() bool {
|
|
| 789 |
+ return os.Getenv("TEST_INTEGRATION_USE_GRAPHDRIVER") == "" && runtime.GOOS != "windows"
|
|
| 790 |
+} |
|
| 791 |
+ |
|
| 788 | 792 |
// NewDaemon sets up everything for the daemon to be able to service |
| 789 | 793 |
// requests from the webserver. |
| 790 | 794 |
func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.Store, authzMiddleware *authorization.Middleware) (_ *Daemon, retErr error) {
|
| ... | ... |
@@ -894,7 +898,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 894 | 894 |
log.G(ctx).WithField("env", os.Environ()).Info("Migration to containerd is enabled, driver will be switched to snapshotter if there are no images or containers")
|
| 895 | 895 |
} |
| 896 | 896 |
} |
| 897 |
- if config.Features["containerd-snapshotter"] {
|
|
| 897 |
+ if config.Features["containerd-snapshotter"] && useContainerdByDefault() {
|
|
| 898 | 898 |
log.G(ctx).Warn(`"containerd-snapshotter" is now the default and no longer needed to be set`) |
| 899 | 899 |
} |
| 900 | 900 |
|
| ... | ... |
@@ -1113,11 +1117,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 1113 | 1113 |
case "windowsfilter": |
| 1114 | 1114 |
// Docker WCOW graphdriver |
| 1115 | 1115 |
case "": |
| 1116 |
- // Use graph driver but enable migration |
|
| 1116 |
+ // Use graph driver unless opted-in to containerd store |
|
| 1117 | 1117 |
driverName = "windowsfilter" |
| 1118 |
- if os.Getenv("TEST_INTEGRATION_USE_GRAPHDRIVER") == "" {
|
|
| 1119 |
- // Don't force migration if graph driver is explicit |
|
| 1120 |
- migrationThreshold = 0 |
|
| 1118 |
+ if useContainerdByDefault() || config.Features["containerd-snapshotter"] {
|
|
| 1119 |
+ driverName = "windows" |
|
| 1121 | 1120 |
} |
| 1122 | 1121 |
default: |
| 1123 | 1122 |
log.G(ctx).Infof("Using non-default snapshotter %s", driverName)
|
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"os" |
| 7 | 7 |
"path/filepath" |
| 8 |
+ "runtime" |
|
| 8 | 9 |
"strings" |
| 9 | 10 |
"testing" |
| 10 | 11 |
|
| ... | ... |
@@ -190,7 +191,7 @@ func (e *Execution) IsUserNamespaceInKernel() bool {
|
| 190 | 190 |
// UsingSnapshotter returns whether containerd snapshotters are used for the |
| 191 | 191 |
// tests by checking if the "TEST_INTEGRATION_USE_GRAPHDRIVER" is empty |
| 192 | 192 |
func (e *Execution) UsingSnapshotter() bool {
|
| 193 |
- return os.Getenv("TEST_INTEGRATION_USE_GRAPHDRIVER") == ""
|
|
| 193 |
+ return os.Getenv("TEST_INTEGRATION_USE_GRAPHDRIVER") == "" && runtime.GOOS != "windows"
|
|
| 194 | 194 |
} |
| 195 | 195 |
|
| 196 | 196 |
// HasExistingImage checks whether there is an image with the given reference. |