Skip to content

exporter: add local exporter mode=delete#6561

Draft
crazy-max wants to merge 3 commits intomoby:masterfrom
crazy-max:exporter-local-mirror
Draft

exporter: add local exporter mode=delete#6561
crazy-max wants to merge 3 commits intomoby:masterfrom
crazy-max:exporter-local-mirror

Conversation

@crazy-max
Copy link
Copy Markdown
Member

@crazy-max crazy-max commented Mar 6, 2026

partially fixes #2805

This PR adds support for a mode attribute on the local exporter output path.

The default behavior remains mode=copy, which preserves destination files that are not present in the exported result. A new mode=delete behavior is added so the destination matches the exported result by removing stale files and directories.

Because mode=delete can remove files under the destination directory, this feature is intentionally explicit opt-in and should be used only with trusted build definitions and carefully reviewed output destinations.

On client side like Buildx we should probably have some safety gate like --allow local-output-delete (or equivalent) for remote Bake invocations. Optionally block/require explicit allow when dest=. with mode=delete?

Maybe we could have some kind of scope attribute like mode=delete,delete-scope=dist,assets so it only deletes stale files under those relative paths (and reject unsafe scopes like .. or absolute paths)?

Also the backup mode from the issue is intentionally left for a follow-up change. I think we would need changes in fsutil.Receive (or diff callbacks).

Copy link
Copy Markdown
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call it delete like rsync --delete. In Buildx I think we need more restrictions. I'd only allow it for subdirs there, with a second-level opt-in needed to mess with the main workdir or things outside it.

@crazy-max crazy-max changed the title exporter: add local exporter mode=mirror exporter: add local exporter mode=delete Mar 9, 2026
@crazy-max
Copy link
Copy Markdown
Member Author

I'd call it delete like rsync --delete. In Buildx I think we need more restrictions. I'd only allow it for subdirs there, with a second-level opt-in needed to mess with the main workdir or things outside it.

Agreed, renamed the mode from mirror to delete to align with rsync --delete semantics.

@crazy-max crazy-max force-pushed the exporter-local-mirror branch from 22b3c81 to 80b1312 Compare March 9, 2026 09:09
@crazy-max crazy-max requested a review from tonistiigi March 9, 2026 09:19
Copy link
Copy Markdown
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is problem with multi-platform outputs. Added regression test in https://github.com/moby/buildkit/compare/master...tonistiigi:buildkit:exporter-local-mirror-upt?expand=1

The way this seems to work is using the fsutil transfer in merge=false mode that is usually used for context transfer. This is good for performance as existing files are not transfered but there are a couple of problems with it:

  • The differ is metadata based. This is considered ok for context transfer for performance, but not sure if that is also the case for outputs. Especially because you can have reproducible builds. This would unexpectedly create wrong output results that should be avoided. I think outputs should use differ based on content checksum.
  • The differ is only safe if the output directory is immutable. If it is not then this could lead to breakouts. Using differ in here would require some refactoring. If that refactoring reduces performance then we should use different code for output and context transfer(where we can guarantee immutability).

if outdir, ok := sp.outdirs[id]; ok {
return syncTargetDiffCopy(stream, outdir)
mode := outdir.mode
if v := opts[keyExporterMetaPrefix+ExporterMetaLocalDirMode]; len(v) > 0 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is used for context transfer to daemon and shouldn't allow client to control the receive behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
@crazy-max crazy-max force-pushed the exporter-local-mirror branch from 80b1312 to 117013b Compare March 25, 2026 14:05
@crazy-max
Copy link
Copy Markdown
Member Author

Looks like there is problem with multi-platform outputs. Added regression test in https://github.com/moby/buildkit/compare/master...tonistiigi:buildkit:exporter-local-mirror-upt?expand=1

The way this seems to work is using the fsutil transfer in merge=false mode that is usually used for context transfer. This is good for performance as existing files are not transfered but there are a couple of problems with it:

* The differ is metadata based. This is considered ok for context transfer for performance, but not sure if that is also the case for outputs. Especially because you can have reproducible builds. This would unexpectedly create wrong output results that should be avoided. I think outputs should use differ based on content checksum.

* The differ is only safe if the output directory is immutable. If it is not then this could lead to breakouts. Using differ in here would require some refactoring. If that refactoring reduces performance then we should use different code for output and context transfer(where we can guarantee immutability).

Completely forgot about multi-platform 🙈. I picked your commit adding new tests. I think mode=delete should export a complete fs view once, not per-platform and the receiver will stage that stream into a temp dir and then reconcile dest from the staged tree. The mode=copy keeps the current fast path.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
@crazy-max crazy-max marked this pull request as draft March 25, 2026 15:43
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
@crazy-max crazy-max removed this from the v0.29.0 milestone Mar 25, 2026
@crazy-max crazy-max force-pushed the exporter-local-mirror branch from 117013b to 21840d2 Compare March 30, 2026 14:43
@crazy-max
Copy link
Copy Markdown
Member Author

Looks like there is problem with multi-platform outputs. Added regression test in https://github.com/moby/buildkit/compare/master...tonistiigi:buildkit:exporter-local-mirror-upt?expand=1

Addressed in last commit. Now mode=delete no longer uses the context-transfer Merge: false receive path for outputs. The exporter builds the full final output tree first, then the receiver stages that tree and reconciles/deletes from there. That fixes the multi-platform case and avoids the differ/immutability issues you pointed out. I also picked up the extra regression test.

@crazy-max
Copy link
Copy Markdown
Member Author

Hum test fails on Windows https://github.com/moby/buildkit/actions/runs/23750766249/job/69192263818?pr=6561#step:8:268

=== Failed
=== FAIL: client TestIntegration/slice=3-4/TestExportLocalModeDeleteRemovesStaleDestinationFiles/worker=containerd (0.94s)
    client_test.go:7703: 
        	Error Trace:	D:/a/buildkit/buildkit/client/client_test.go:7703
        	            				D:/a/buildkit/buildkit/util/testutil/integration/run.go:105
        	            				D:/a/buildkit/buildkit/util/testutil/integration/run.go:253
        	Error:      	Received unexpected error:
        	            	open C:\Users\RUNNER~1\AppData\Local\Temp\TestIntegrationslice=3-4TestExportLocalModeDeleteRemovesStaleD1803502733\001\fresh.txt: The system cannot find the file specified.
        	Test:       	TestIntegration/slice=3-4/TestExportLocalModeDeleteRemovesStaleDestinationFiles/worker=containerd
    sandbox.go:202: stdout: D:\a\buildkit\buildkit\bin\buildkitd.exe --containerd-worker-gc=false --containerd-worker=true --containerd-worker-addr npipe:////./pipe/containerd-bktest_containerd1310009392 --containerd-worker-labels=org.mobyproject.buildkit.worker.sandbox=true --config=C:\Users\RUNNER~1\AppData\Local\Temp\bktest_config2335501482\buildkitd.toml --root C:\Users\RUNNER~1\AppData\Local\Temp\bktest_buildkitd2737705320 --addr npipe:////./pipe/buildkitd-bktest_buildkitd2737705320 --debug
    sandbox.go:202: stderr: D:\a\buildkit\buildkit\bin\buildkitd.exe --containerd-worker-gc=false --containerd-worker=true --containerd-worker-addr npipe:////./pipe/containerd-bktest_containerd1310009392 --containerd-worker-labels=org.mobyproject.buildkit.worker.sandbox=true --config=C:\Users\RUNNER~1\AppData\Local\Temp\bktest_config2335501482\buildkitd.toml --root C:\Users\RUNNER~1\AppData\Local\Temp\bktest_buildkitd2737705320 --addr npipe:////./pipe/buildkitd-bktest_buildkitd2737705320 --debug
    sandbox.go:205: > StartCmd 2026-03-30 14:51:28.2521723 +0000 UTC m=+229.614645801 D:\a\buildkit\buildkit\bin\buildkitd.exe --containerd-worker-gc=false --containerd-worker=true --containerd-worker-addr npipe:////./pipe/containerd-bktest_containerd1310009392 --containerd-worker-labels=org.mobyproject.buildkit.worker.sandbox=true --config=C:\Users\RUNNER~1\AppData\Local\Temp\bktest_config2335501482\buildkitd.toml --root C:\Users\RUNNER~1\AppData\Local\Temp\bktest_buildkitd2737705320 --addr npipe:////./pipe/buildkitd-bktest_buildkitd2737705320 --debug
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="debug handlers listening at npipe:////./pipe/buildkitd-debug-bktest_buildkitd2737705320"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=warning msg="using null network as the default"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="remote introspection plugin filters" filters="[type==io.containerd.runtime.v1 type==io.containerd.runtime.v2]"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=info msg="found worker \"ixjamihhlauq6icjdbnawh15q\", labels=map[org.mobyproject.buildkit.worker.containerd.namespace:buildkit org.mobyproject.buildkit.worker.containerd.uuid:4becd0d9-0ef9-4421-9937-ccde860a58b9 org.mobyproject.buildkit.worker.executor:containerd org.mobyproject.buildkit.worker.hostname:runnervm6wf0k org.mobyproject.buildkit.worker.network: org.mobyproject.buildkit.worker.sandbox:true org.mobyproject.buildkit.worker.selinux.enabled:false org.mobyproject.buildkit.worker.snapshotter:windows], platforms=[windows/amd64]"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=info msg="found 1 workers, default=\"ixjamihhlauq6icjdbnawh15q\""
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=warning msg="currently, only the default worker can be used."
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=info msg="running server on //./pipe/buildkitd-bktest_buildkitd2737705320"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="session started" spanID=69c795186ba8daa7 traceID=f98e99154fa58fe80303959800229c67
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="resolve exporter local with map[mode:delete]" spanID=f61f018b11e83405 traceID=5483fefed320483769fcc5f2090744bf
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="Calling proc (1)"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="Calling proc (2)"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="Calling proc (1)"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="Calling proc (2)"
    sandbox.go:205: time="2026-03-30T14:51:28Z" level=debug msg="session finished: <nil>" spanID=69c795186ba8daa7 traceID=f98e99154fa58fe80303959800229c67
    sandbox.go:205: > sending sigterm 2026-03-30 14:51:28.6957109 +0000 UTC m=+230.058183901
    sandbox.go:205: > sending SIGKILL 2026-03-30 14:51:28.6957109 +0000 UTC m=+230.058183901
    sandbox.go:205: > stopped 2026-03-30 14:51:28.7044207 +0000 UTC m=+230.066893701 exit status 1 1
    sandbox.go:202: stdout: D:\a\buildkit\buildkit\bin\containerd.exe --config C:\Users\RUNNER~1\AppData\Local\Temp\bktest_containerd1310009392\config.toml
    sandbox.go:202: stderr: D:\a\buildkit\buildkit\bin\containerd.exe --config C:\Users\RUNNER~1\AppData\Local\Temp\bktest_containerd1310009392\config.toml
    sandbox.go:205: > StartCmd 2026-03-30 14:51:27.7943287 +0000 UTC m=+229.156802801 D:\a\buildkit\buildkit\bin\containerd.exe --config C:\Users\RUNNER~1\AppData\Local\Temp\bktest_containerd1310009392\config.toml
    sandbox.go:205: time="2026-03-30T14:51:27.819469300Z" level=info msg="starting containerd" revision= version=2.2.2+unknown
    sandbox.go:205: time="2026-03-30T14:51:27.819469300Z" level=debug msg="Stackdump - waiting signal at Global\\stackdump-6320"
    sandbox.go:205: time="2026-03-30T14:51:27.854471100Z" level=info msg="loading plugin" id=io.containerd.internal.v1.opt type=io.containerd.internal.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855034000Z" level=info msg="loading plugin" id=io.containerd.content.v1.content type=io.containerd.content.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855034000Z" level=info msg="loading plugin" id=io.containerd.image-verifier.v1.bindir type=io.containerd.image-verifier.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855034000Z" level=info msg="loading plugin" id=io.containerd.warning.v1.deprecations type=io.containerd.warning.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855034000Z" level=info msg="loading plugin" id=io.containerd.event.v1.exchange type=io.containerd.event.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855034000Z" level=info msg="loading plugin" id=io.containerd.snapshotter.v1.windows-lcow type=io.containerd.snapshotter.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855682400Z" level=info msg="loading plugin" id=io.containerd.snapshotter.v1.blockcim type=io.containerd.snapshotter.v1
    sandbox.go:205: time="2026-03-30T14:51:27.855682400Z" level=info msg="skip loading plugin" error="host windows version doesn't support block CIMs: skip plugin" id=io.containerd.snapshotter.v1.blockcim type=io.containerd.snapshotter.v1
    sandbox.go:205: time="2026-03-30T14:51:27.856334400Z" level=info msg="loading plugin" id=io.containerd.snapshotter.v1.cimfs type=io.containerd.snapshotter.v1
    sandbox.go:205: time="2026-03-30T14:51:28.200721000Z" level=info msg="loading plugin" id=io.containerd.snapshotter.v1.windows type=io.containerd.snapshotter.v1
    sandbox.go:205: time="2026-03-30T14:51:28.202517300Z" level=info msg="loading plugin" id=io.containerd.metadata.v1.bolt type=io.containerd.metadata.v1
    sandbox.go:205: time="2026-03-30T14:51:28.203377700Z" level=info msg="metadata content store policy set" policy=shared
    sandbox.go:205: time="2026-03-30T14:51:28.215795900Z" level=info msg="loading plugin" id=io.containerd.gc.v1.scheduler type=io.containerd.gc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.nri.v1.nri type=io.containerd.nri.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=error msg="failed to initialize WASM support: WASM support is disabled (at build time)"
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="built-in NRI default validator is disabled"
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="runtime interface created"
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="created NRI interface"
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.differ.v1.windows-lcow type=io.containerd.differ.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.differ.v1.cimfs type=io.containerd.differ.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.differ.v1.blockcim type=io.containerd.differ.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="skip loading plugin" error="host OS version doesn't support block CIMs: skip plugin" id=io.containerd.differ.v1.blockcim type=io.containerd.differ.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.differ.v1.windows type=io.containerd.differ.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.lease.v1.manager type=io.containerd.lease.v1
    sandbox.go:205: time="2026-03-30T14:51:28.215881500Z" level=info msg="loading plugin" id=io.containerd.mount-manager.v1.bolt type=io.containerd.mount-manager.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.streaming.v1.manager type=io.containerd.streaming.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.transfer.v1.local type=io.containerd.transfer.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.containers-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.content-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.diff-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.images-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.introspection-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.namespaces-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.service.v1.snapshots-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.shim.v1.manager type=io.containerd.shim.v1
    sandbox.go:205: time="2026-03-30T14:51:28.221319800Z" level=info msg="loading plugin" id=io.containerd.runtime.v2.task type=io.containerd.runtime.v2
    sandbox.go:205: time="2026-03-30T14:51:28.222506400Z" level=info msg="loading plugin" id=io.containerd.service.v1.tasks-service type=io.containerd.service.v1
    sandbox.go:205: time="2026-03-30T14:51:28.222506400Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.containers type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223093200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.content type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.diff type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.events type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.images type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.introspection type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.leases type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.mounts type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.namespaces type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.sandbox.store.v1.local type=io.containerd.sandbox.store.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.cri.v1.images type=io.containerd.cri.v1
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="Get image filesystem path \"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\bktest_containerd1310009392\\\\root\\\\io.containerd.snapshotter.v1.windows\" for snapshotter \"windows\""
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="Start snapshots syncer"
    sandbox.go:205: time="2026-03-30T14:51:28.223158500Z" level=info msg="loading plugin" id=io.containerd.cri.v1.runtime type=io.containerd.cri.v1
    sandbox.go:205: time="2026-03-30T14:51:28.224995700Z" level=info msg="starting cri plugin" config="{\"containerd\":{\"defaultRuntimeName\":\"runhcs-wcow-process\",\"runtimes\":{\"runhcs-wcow-hypervisor\":{\"runtimeType\":\"io.containerd.runhcs.v1\",\"runtimePath\":\"\",\"PodAnnotations\":[\"io.microsoft.virtualmachine.*\"],\"ContainerAnnotations\":[\"io.microsoft.container.*\"],\"options\":{\"SandboxIsolation\":1,\"ScaleCpuLimitsToSandbox\":true},\"privileged_without_host_devices\":false,\"privileged_without_host_devices_all_devices_allowed\":false,\"cgroupWritable\":false,\"baseRuntimeSpec\":\"\",\"cniConfDir\":\"\",\"cniMaxConfNum\":0,\"snapshotter\":\"\",\"sandboxer\":\"podsandbox\",\"io_type\":\"\"},\"runhcs-wcow-process\":{\"runtimeType\":\"io.containerd.runhcs.v1\",\"runtimePath\":\"\",\"PodAnnotations\":null,\"ContainerAnnotations\":[\"io.microsoft.container.*\"],\"options\":null,\"privileged_without_host_devices\":false,\"privileged_without_host_devices_all_devices_allowed\":false,\"cgroupWritable\":false,\"baseRuntimeSpec\":\"\",\"cniConfDir\":\"\",\"cniMaxConfNum\":0,\"snapshotter\":\"\",\"sandboxer\":\"podsandbox\",\"io_type\":\"\"}},\"ignoreBlockIONotEnabledErrors\":false,\"ignoreRdtNotEnabledErrors\":false},\"cni\":{\"binDir\":\"\",\"binDirs\":[\"C:\\\\Program Files\\\\containerd\\\\cni\\\\bin\"],\"confDir\":\"C:\\\\Program Files\\\\containerd\\\\cni\\\\conf\",\"maxConfNum\":1,\"setupSerially\":false,\"confTemplate\":\"\",\"ipPref\":\"\",\"useInternalLoopback\":false},\"enableSelinux\":false,\"selinuxCategoryRange\":0,\"maxContainerLogLineSize\":16384,\"disableApparmor\":false,\"restrictOOMScoreAdj\":false,\"disableProcMount\":false,\"unsetSeccompProfile\":\"\",\"tolerateMissingHugetlbController\":false,\"disableHugetlbController\":false,\"device_ownership_from_security_context\":false,\"ignoreImageDefinedVolumes\":false,\"netnsMountsUnderStateDir\":false,\"enableUnprivilegedPorts\":false,\"enableUnprivilegedICMP\":false,\"enableCDI\":false,\"cdiSpecDirs\":null,\"drainExecSyncIOTimeout\":\"0s\",\"ignoreDeprecationWarnings\":null,\"containerdRootDir\":\"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\bktest_containerd1310009392\\\\root\",\"containerdEndpoint\":\"\\\\\\\\.\\\\pipe\\\\containerd-bktest_containerd1310009392\",\"rootDir\":\"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\bktest_containerd1310009392\\\\root\\\\io.containerd.grpc.v1.cri\",\"stateDir\":\"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\bktest_containerd1310009392\\\\state\\\\io.containerd.grpc.v1.cri\"}"
    sandbox.go:205: time="2026-03-30T14:51:28.224995700Z" level=info msg="loading plugin" id=io.containerd.podsandbox.controller.v1.podsandbox type=io.containerd.podsandbox.controller.v1
    sandbox.go:205: time="2026-03-30T14:51:28.225650500Z" level=info msg="loading plugin" id=io.containerd.sandbox.controller.v1.shim type=io.containerd.sandbox.controller.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226236200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.sandbox-controllers type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226762300Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.sandboxes type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.snapshots type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.streaming type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.tasks type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.transfer type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.version type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.monitor.container.v1.restart type=io.containerd.monitor.container.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.tracing.processor.v1.otlp type=io.containerd.tracing.processor.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="skip loading plugin" error="skip plugin: tracing endpoint not configured" id=io.containerd.tracing.processor.v1.otlp type=io.containerd.tracing.processor.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.internal.v1.tracing type=io.containerd.internal.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="skip loading plugin" error="skip plugin: tracing endpoint not configured" id=io.containerd.internal.v1.tracing type=io.containerd.internal.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.ttrpc.v1.otelttrpc type=io.containerd.ttrpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.226896200Z" level=info msg="loading plugin" id=io.containerd.grpc.v1.healthcheck type=io.containerd.grpc.v1
    sandbox.go:205: time="2026-03-30T14:51:28.227481800Z" level=info msg=serving... address="\\\\.\\pipe\\containerd-bktest_containerd1310009392debug"
    sandbox.go:205: time="2026-03-30T14:51:28.227481800Z" level=info msg=serving... address="\\\\.\\pipe\\containerd-bktest_containerd1310009392.ttrpc"
    sandbox.go:205: time="2026-03-30T14:51:28.227481800Z" level=info msg=serving... address="\\\\.\\pipe\\containerd-bktest_containerd1310009392"
    sandbox.go:205: time="2026-03-30T14:51:28.227481800Z" level=info msg="containerd successfully booted in 0.409621s"
    sandbox.go:205: time="2026-03-30T14:51:28.405370400Z" level=debug msg="prepare snapshot" key=ixt13xwalmflpf2uec4pmk04i parent= snapshotter=windows
    sandbox.go:205: time="2026-03-30T14:51:28.417533400Z" level=debug msg=createSnapshot
    sandbox.go:205: time="2026-03-30T14:51:28.457491200Z" level=debug msg="get snapshot mounts" key=ixt13xwalmflpf2uec4pmk04i snapshotter=windows
    sandbox.go:205: time="2026-03-30T14:51:28.501678000Z" level=debug msg="get snapshot mounts" key=ixt13xwalmflpf2uec4pmk04i snapshotter=windows
    sandbox.go:205: time="2026-03-30T14:51:28.525939600Z" level=debug msg="(*service).Write started" ref=history-ref_511759700-BxPz
    sandbox.go:205: time="2026-03-30T14:51:28.534233100Z" level=debug msg="(*service).Write started" ref=history-ref_514374300-ThU2
    sandbox.go:205: > sending sigterm 2026-03-30 14:51:28.7067437 +0000 UTC m=+230.069216701
    sandbox.go:205: > sending SIGKILL 2026-03-30 14:51:28.7067437 +0000 UTC m=+230.069216701
    sandbox.go:205: > stopped 2026-03-30 14:51:28.7115607 +0000 UTC m=+230.074033701 exit status 1 1
    --- FAIL: TestIntegration/slice=3-4/TestExportLocalModeDeleteRemovesStaleDestinationFiles/worker=containerd (0.94s)

Seems the destination cleanup happened but the root file was not materialized back. That leaves dest partially empty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Add mode attribute to local exporter

2 participants