Skip to content

fix(cleaner-agent): force-prune unused volumes when disk/inode threshold is hit - #164

Draft
openswe-shared-services[bot] wants to merge 1 commit into
masterfrom
open-swe/ccs-45-inode-exhaustion-volume-purge
Draft

openswe-shared-services[bot] wants to merge 1 commit into
masterfrom
open-swe/ccs-45-inode-exhaustion-volume-purge

Conversation

@openswe-shared-services

@openswe-shared-services openswe-shared-services Bot commented Sep 17, 2026

Copy link
Copy Markdown

What

Adds a final emergency step to cleaner-agent.sh that runs docker volume prune --force when disk/inode usage is still above START_DISK_USAGE_THRESHOLD/START_INODES_USAGE_THRESHOLD (0.9) after the existing container/volume/image cleanup and image-purge steps.

Why

Triage of CCS-45 (justpark-inc, SaaS Classic, system/linux_paying_plan tier) found that hosted builds intermittently fail with "out of disk space" while starting at 95%+ inode utilization, even though byte usage is well under the volume size.

Root cause hypothesis: a dind pod is reused for multiple builds (CLEAN_PERIOD_BUILDS/CLEAN_PERIOD_SECONDS). During that shared lifetime, the only watchdog is cleaner-agent.sh, which trips at 90% disk/inode usage but:

  • clean_volumes()/clean_images() (cleaner/functions.sh) skip anything touched within VOLUMES_RETAIN_PERIOD/IMAGE_RETAIN_PERIOD (deliberately long on this tier to help build-cache hit rate),
  • its own last-resort purge only targets images (docker image prune ... --filter until=3h), never volumes.

The only unconditional full reclaim (docker system prune -a --volumes --force) lives in docker-clean.sh, but that only runs when the pod itself is torn down (run.sh, gated by CLEAN_DOCKER). So a pod that gets a burst of build activity can sit pinned above the inode threshold for the rest of its life, and whichever build lands on it next starts already near capacity.

This adds a volume-aware step to the mid-lifetime emergency path: docker volume prune only removes volumes not attached to any container, so it's safe to run unconditionally (never touches an in-progress build) and gives the watchdog a way to actually reclaim inode-heavy dangling volumes without waiting for pod teardown.

Also adds a matching docker_volume_cleaner_agent_actions_volume_purges Prometheus gauge in monitor/metrics.sh, following the existing metric pattern, so this new action is observable.

Notes

  • Follow-up to the triage report on CCS-45 (internal Linear ticket, test copy of CF-2350).
  • This does not change clean_volumes()'s existing retain-period behavior — it only adds a stronger last-resort step, same tier as the existing image purge.
  • Bumped service.yaml version per repo convention.

Made by Open SWE · anthropic:claude-sonnet-5 (medium)

Security Report — codefresh/dind

Fixed CVEs: 0

Fixed issues: 0

…old is hit

The mid-lifetime watchdog (cleaner-agent.sh) trips at 90% disk/inode
usage but its clean_volumes()/clean_images() steps skip anything
touched within VOLUMES_RETAIN_PERIOD/IMAGE_RETAIN_PERIOD, and its own
last-resort step only prunes images. A dind pod reused across several
builds can stay pinned above the inode threshold for the rest of its
life, so the next build to land on it starts already near capacity
(CCS-45).

Add an unconditional 'docker volume prune' as a final emergency step -
it only removes volumes not attached to a running container, so it
never touches an in-progress build.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
@codefresh-git-integration

Copy link
Copy Markdown

/e2e

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant