Skip to content

fix: remove the staged script when a command fails - #481

Merged
tas50 merged 1 commit into
mainfrom
fix/temp-file-cleanup
Aug 23, 2026
Merged

fix: remove the staged script when a command fails#481
tas50 merged 1 commit into
mainfrom
fix/temp-file-cleanup

Conversation

@tas50

@tas50 tas50 commented Aug 23, 2026

Copy link
Copy Markdown
Member

The bug

Container#execute stages the command as a script under .kitchen/temp, uploads it to the container, and deletes the local copy. The delete sat between the upload and the exec:

create_temp_file(temp_file, command)
create_dir_on_container(@config, remote_path)
upload(temp_file, remote_path)

::File.delete(temp_file)        # <- skipped if anything above raises

container_exec(@config, "/bin/bash #{remote_path}/#{filename}")
rescue => e
  raise "Failed to execute command on Linux container. #{e}"

Any failure before that line leaves the script behind.

Confirmed

Removing the container out from under a kitchen exec — which is what a container that has exited looks like to the driver:

after a successful exec : 0 file(s) left
after a failing exec    : 1 file(s) left
   docker-cbdc94fe-ee7e-45d9-b293-d1f895773a2b.sh

One file per failed attempt, and nothing ever clears them, so .kitchen/temp fills up over a run of failing converges. Minor, but it is a leak the code plainly intends not to have.

The fix

Delete in an ensure, in both the Linux and Windows containers — they share the shape of this method and both had it.

Deliberately not addressed

The uploaded copy inside the container is never removed either — three execs leave three scripts in the container's temp directory:

scripts left in the container's /tmp: 3

Those go when the container does, and removing them would add a docker exec round trip per command for no real benefit. Flagging it rather than changing it; happy to if you'd rather.

Verified after the change

after a successful exec : 0 file(s) left
after a failing exec    : 0 file(s) left

Specs

New #execute group in spec/linux_container_spec.rb: the staged script is removed after a successful run, after a failed upload, and after a failed command — plus one pinning that the command really is what gets written to the script.

$ bundle exec rake
43 files inspected, no offenses detected
277 examples, 0 failures

$ bundle exec rake doc
clean, 100.00% documented

🤖 Generated with Claude Code

Container#execute stages the command as a script under .kitchen/temp, uploads
it, and deletes the local copy. The delete sat between the upload and the exec,
so any failure before it left the script behind:

    after a successful exec : 0 file(s) left
    after a failing exec    : 1 file(s) left

Confirmed by removing the container out from under a kitchen exec, which is
what a container that has exited looks like to the driver. One file is left per
failed attempt, and nothing ever clears them, so .kitchen/temp fills up over a
run of failing converges.

Deleting in an ensure instead, in both the Linux and Windows containers, which
share the shape of this method.

Not addressed here: the uploaded copy inside the container is never removed
either, so a converge leaves one script per command in the container's temp
directory. Those go when the container does, and removing them would add a
docker exec round trip per command, so it is left alone deliberately.

Verified after the change: nothing is left behind after either a successful or
a failing exec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tas50
tas50 merged commit 44de85e into main Aug 23, 2026
107 checks passed
@tas50
tas50 deleted the fix/temp-file-cleanup branch August 23, 2026 16:15
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