Skip to content

fix(build): an interrupted BuildKit export leaves its OCI tar behind, filling the disk #50

Open

Description

@aitrawog

Finding

A build that fails AFTER BuildKit has exported its OCI tar leaves the tar in
~/.cache/charly/buildkitd/export/, and nothing ever sweeps it. Measured while
running the pod: / engine: containerd proof bed for opencharly/charly#1109:
the directory held 3.6 GB of stale *.oci.tar files and the root filesystem
was at 100 % (290 MB free), which made the next build fail:

#18 exporting to oci image format
#18 sending tarball 1.4s done
#18 ERROR: failed to copy to tar: rpc error: code = ResourceExhausted desc = write /home/atrawog/.cache/charly/buildkitd/export/ghcr.io_opencharly_probe-engine-image_2026.309.1935.oci.tar: no space left on device

The directory contents before cleanup (the small entries are 0-byte leftovers
from earlier failures):

$ du -sh ~/.cache/charly/buildkitd/export
3.6G
$ find ~/.cache/charly/buildkitd/export -type f -size +1M -printf '%s %p\n' | sort -n
82038784   .../ghcr.io_opencharly_probe-engine-image_2026.309.1935.oci.tar
137593856  .../ghcr.io_opencharly_marketplace-app_check-marketplace-2026.296.2336.oci.tar
482291712  .../ghcr.io_opencharly_pod-crabbox-nested_check-pod-crabbox-nested-engine-2026.309.1419.oci.tar
915448320  .../ghcr.io_opencharly_pod-crabbox-desktop_2026.309.0343.oci.tar
1100418048 .../ghcr.io_opencharly_arch-builder_2026.305.2216.oci.tar
1101324288 .../ghcr.io_opencharly_arch-builder_2026.309.0335.oci.tar

RCA

  • Mechanism. plugin-build exports through
    --output type=oci,dest=<export>/<ref>.oci.tar and removes the tar only on
    the SUCCESS path: candy/plugin-build/buildkit.go around the
    os.Remove(dest) call after the load/import. A buildctl failure while
    writing the tar (disk full), or any failure between export and import, skips
    that removal, so the partial/full tar survives indefinitely.
  • Missed control. No owner sweeps ~/.cache/charly/buildkitd/export/;
    charly clean has no arm for it, and buildkit.go's own comment says the
    removal is a no-op once the rename consumed the file — it never considered
    the failure path. Nothing reports the directory's growth.
  • Blast radius. Every later build on the host: a full root filesystem makes
    the next export fail with ResourceExhausted, and the failure looks like a
    product/image defect in the bed rather than a cache leak.
  • Root fix. Create the export path with a defer os.Remove(dest) at the
    point it is named (so buildctl failure and import failure both clean it), and
    add a bounded startup sweep of *.oci.tar files older than a stated window
    in the export dir (or an arm in charly clean) so pre-existing leaks drain.

Why this is filed rather than fixed here

It is a pre-existing, separable defect in the export owner (plugin-build),
not in the plugin-deploy-pod change whose gate measured it. That change is
correct and complete without the fix. This issue is the RCA home for the
cleanup.

Agent: containerd-crabbox-program/engine
Assisted-by: Claude Code ollama-cloud/deepseek-v4.1-flash:cloud (analysed on a live system)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions