Bug 1 — run() call in exception handler raises TypeError, masking the real error
In firecracker/microvm.py, _build_rootfs exception handler:
except Exception as e:
if tmp_dir:
run(f"umount {tmp_dir}", "unmounting") # ← bug
os.rmdir(tmp_dir)
raise VMMError(f"Failed to create image file: {e}")
run() is defined as def run(cmd, **kwargs) — one positional argument only. Passing "unmounting" as a second positional argument raises:
TypeError: run() takes 1 positional argument but 2 were given
This TypeError replaces the original exception e, so the real failure reason is permanently lost. The user sees:
Failed to build rootfs from Docker image: run() takes 1 positional argument but 2 were given
Bug 2 — Loop device and temp dir leaked on successful build
The success path never unmounts:
tmp_dir = tempfile.mkdtemp()
run(f"mount -o loop {file} {tmp_dir}")
with tarfile.open(tar_file, 'r') as tar:
tar.extractall(path=tmp_dir)
os.remove(tar_file)
# function returns here — tmp_dir is still mounted
Every call to build() that succeeds leaves a dangling loop device and an orphaned /tmp/tmp* directory on the host.
Fix
except Exception as e:
raise VMMError(f"Failed to create image file: {e}")
finally:
if tmp_dir:
run(f"umount {tmp_dir}") # correct signature, no extra positional arg
os.rmdir(tmp_dir)
finally guarantees cleanup on both success and failure paths
except only re-raises the real exception — e is preserved
Bug 1 —
run()call in exception handler raises TypeError, masking the real errorIn
firecracker/microvm.py,_build_rootfsexception handler:run()is defined asdef run(cmd, **kwargs)— one positional argument only. Passing"unmounting"as a second positional argument raises:This TypeError replaces the original exception
e, so the real failure reason is permanently lost. The user sees:Bug 2 — Loop device and temp dir leaked on successful build
The success path never unmounts:
Every call to
build()that succeeds leaves a dangling loop device and an orphaned/tmp/tmp*directory on the host.Fix
finallyguarantees cleanup on both success and failure pathsexceptonly re-raises the real exception —eis preserved