[PR #1155] [MERGED] fix(artifacts): recheck failed DMG detaches before reporting cleanup failure #2689

Closed
opened 2026-10-17 21:09:05 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1155
Author: @kaoru0822-kitauji
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @N0zoM1z0

Base: main ← Head: fix/dmg-cleanup-recheck


📝 Commits (2)

  • 5971c81 fix(artifacts): recheck failed DMG detaches before reporting cleanup failure
  • 9de9925 test(artifacts): share DMG detach fixtures to stay under the duplication gate

📊 Changes

2 files changed (+175 additions, -70 deletions)

View changed files

📝 src/artifacts/NativeDmgArtifactReader.ts (+46 -13)
📝 tests/boundary/providers/native/nativeDmgArtifactReader.test.ts (+129 -57)

📄 Description

Problem

NativeDmgArtifactReader.close() detaches each device once. When a detach fails, it asks hdiutil info once whether the device is still attached, and counts it as a cleanup failure if so. That single check is racy:

  • On APFS images, detaching the synthesized container also ejects the image disk. hdiutil info can still list the ejected device for a moment.
  • A volume that was just read can briefly report busy.

In both cases the cleanup actually succeeds or would succeed, but close() throws DMG detach or mount-root cleanup failed and keeps the mount root. Inventory and extraction callers then report the false failure.

This is the intermittent "Real Apple artifact CLI/MCP E2E" failure in verify:macos-bundle (for example on #1070, #1097 and fix/hopper-block-endpoints). Since #1103 added the cause to the message, the job log shows the mechanism:

DMG detach or mount-root cleanup failed for ".../MacFixture.dmg": hdiutil detach failed: {"arguments":["detach","/dev/disk23"],"exitCode":1,"stderr":"hdiutil: detach failed - No such file or directory\n"}

The device was already gone, but it was still counted as attached. The #1103 review raised the same missing recheck ("Recheck failed devices after completing the detach loop"), and it was still unaddressed on main.

Change

  • After the first detach pass, recheck the remaining devices up to three times, after 250, 500 and 1000 ms:
    • drop any device hdiutil info no longer lists;
    • retry the detach of any device still listed;
    • fail only for devices that stay attached through every recheck.
  • A successful pass skips the waits entirely. A truly stuck device still fails, with its latest hdiutil diagnostic and the mount root kept, as before.
  • NativeDmgHost gains an optional delay, so tests exercise the recheck without real waits. The attach-failure cleanup path goes through close() and gets the same behavior.

Verification

  • npm run test:focused -- tests/boundary/providers/native/nativeDmgArtifactReader.test.ts. Two new cases: a device listed once more after its container's detach ejected it, which matches the CI log; and a device that is busy on its first detach, then detaches within the same close. Both fail on main. The existing APFS, retained-attachment and attach-cleanup cases still pass.
  • The real-hdiutil test "classifies a real hdiutil verify refusal…" fails on this Mac identically on unmodified main. It's environmental and passes on CI runners.
  • Real macOS 26.7 check with this branch: 3 HFS+ and 5 APFS hdiutil create images through rea inspect-artifact. All succeeded, and hdiutil info showed no leftover devices.
  • npm run check:fast

No real Hopper or Ghidra verification was run, because this change does not touch those providers.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1155 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/dmg-cleanup-recheck` --- ### 📝 Commits (2) - [`5971c81`](https://github.com/morluto/rea/commit/5971c8165e45549bb42099fc28a0e610aca8807b) fix(artifacts): recheck failed DMG detaches before reporting cleanup failure - [`9de9925`](https://github.com/morluto/rea/commit/9de9925390930b53e78196fa2c9ade4d942ebf8f) test(artifacts): share DMG detach fixtures to stay under the duplication gate ### 📊 Changes **2 files changed** (+175 additions, -70 deletions) <details> <summary>View changed files</summary> 📝 `src/artifacts/NativeDmgArtifactReader.ts` (+46 -13) 📝 `tests/boundary/providers/native/nativeDmgArtifactReader.test.ts` (+129 -57) </details> ### 📄 Description ## Problem `NativeDmgArtifactReader.close()` detaches each device once. When a detach fails, it asks `hdiutil info` once whether the device is still attached, and counts it as a cleanup failure if so. That single check is racy: - On APFS images, detaching the synthesized container also ejects the image disk. `hdiutil info` can still list the ejected device for a moment. - A volume that was just read can briefly report busy. In both cases the cleanup actually succeeds or would succeed, but `close()` throws `DMG detach or mount-root cleanup failed` and keeps the mount root. Inventory and extraction callers then report the false failure. This is the intermittent "Real Apple artifact CLI/MCP E2E" failure in `verify:macos-bundle` (for example on #1070, #1097 and `fix/hopper-block-endpoints`). Since #1103 added the cause to the message, the job log shows the mechanism: ``` DMG detach or mount-root cleanup failed for ".../MacFixture.dmg": hdiutil detach failed: {"arguments":["detach","/dev/disk23"],"exitCode":1,"stderr":"hdiutil: detach failed - No such file or directory\n"} ``` The device was already gone, but it was still counted as attached. The #1103 review raised the same missing recheck ("Recheck failed devices after completing the detach loop"), and it was still unaddressed on `main`. ## Change - After the first detach pass, recheck the remaining devices up to three times, after 250, 500 and 1000 ms: - drop any device `hdiutil info` no longer lists; - retry the detach of any device still listed; - fail only for devices that stay attached through every recheck. - A successful pass skips the waits entirely. A truly stuck device still fails, with its latest `hdiutil` diagnostic and the mount root kept, as before. - `NativeDmgHost` gains an optional `delay`, so tests exercise the recheck without real waits. The attach-failure cleanup path goes through `close()` and gets the same behavior. ## Verification - `npm run test:focused -- tests/boundary/providers/native/nativeDmgArtifactReader.test.ts`. Two new cases: a device listed once more after its container's detach ejected it, which matches the CI log; and a device that is busy on its first detach, then detaches within the same close. Both fail on `main`. The existing APFS, retained-attachment and attach-cleanup cases still pass. - The real-`hdiutil` test "classifies a real hdiutil verify refusal…" fails on this Mac identically on unmodified `main`. It's environmental and passes on CI runners. - Real macOS 26.7 check with this branch: 3 HFS+ and 5 APFS `hdiutil create` images through `rea inspect-artifact`. All succeeded, and `hdiutil info` showed no leftover devices. - `npm run check:fast` No real Hopper or Ghidra verification was run, because this change does not touch those providers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:05 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2689
No description provided.