feat(image): mount personalized developer disk images#34
Conversation
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR adds personalized Developer Disk Image mounting support, including ZIP archive preparation, manifest parsing, Apple TSS ticket requests, mobile image mounter orchestration, public session APIs, CLI commands, and tests. ChangesPersonalized DDI mount flow
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Sources/RorkDevice/DeveloperDiskImage/DeveloperDiskImageStore.swift`:
- Around line 454-459: Normalize ZIP entry paths before checking duplicates in
DeveloperDiskImageStore so aliases like repeated separators or "./" resolve to
the same key. Update the guard around entry.path to validate canonical path
components and use the normalized archive path when calling paths.insert,
ensuring extraction dedupes equivalent entries consistently.
- Around line 299-309: The downloader in DeveloperDiskImageStore uses a
URLSession without redirect handling, so non-HTTPS redirects are currently
allowed. Update the DeveloperDiskImageDownloadLimitDelegate used by URLSession
to implement
urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:) and
reject any redirect whose newRequest URL scheme is not https by cancelling it;
keep the allow path for valid HTTPS redirects.
In `@Sources/RorkDevice/DeveloperDiskImage/MobileImageMounterClient.swift`:
- Around line 82-98: The `personalizationManifest(for:)` recovery path is too
broad and converts transport failures, explicit device `Error`/`DetailedError`
replies, and malformed responses into `PersonalizationManifestUnavailable`.
Narrow the `do/catch` and response validation so only the specific “no cached
manifest / service closed” case maps to that sentinel, and rethrow or surface
the other failures instead. Keep the fallback in `mount(...)` limited to the
true reusable-manifest miss, and add a regression test covering an explicit
device error response to protect this boundary.
In `@Sources/RorkDeviceCLI/RorkDeviceCommand.swift`:
- Around line 803-817: Reject empty or all-whitespace cache directory overrides
in the image auto command by mirroring the existing --path validation before
`DeveloperDiskImageStore` is constructed. Update `validate()` or the
`cacheDirectory` handling in `RorkDeviceCommand` so `--cache-directory ""` and
whitespace-only values fail early instead of reaching `run()`, where the current
`URL(fileURLWithPath:)` fallback can create the store in an unintended location.
Use the same style of check already applied to `source()`/`--path`, and keep the
default `DeveloperDiskImageStore()` behavior when no valid override is provided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 29df5b96-da6e-476e-9001-5e3c55f909bc
📒 Files selected for processing (17)
Package.resolvedPackage.swiftSources/RorkDevice/DeveloperDiskImage/AppleTSSClient.swiftSources/RorkDevice/DeveloperDiskImage/DeveloperDiskImageStore.swiftSources/RorkDevice/DeveloperDiskImage/MobileImageMounterClient.swiftSources/RorkDevice/DeveloperDiskImage/PersonalizedDeveloperDiskImage.swiftSources/RorkDevice/Public/DeveloperDiskImageMountResult.swiftSources/RorkDevice/Public/DeviceSession.swiftSources/RorkDeviceCLI/RorkDeviceCommand.swiftTHIRD_PARTY_NOTICES.mdTests/RorkDeviceCLITests/RorkDeviceCLITests.swiftTests/RorkDeviceTests/AppleTSSClientTests.swiftTests/RorkDeviceTests/DeveloperDiskImageSessionTests.swiftTests/RorkDeviceTests/DeveloperDiskImageStoreTests.swiftTests/RorkDeviceTests/MobileImageMounterClientTests.swiftTests/RorkDeviceTests/PersonalizedDeveloperDiskImageTests.swiftThirdPartyLicenses/ZIPFoundation-LICENSE.txt
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Package.swift`:
- Line 214: The RorkDeviceTests target is unconditionally depending on
ZipArchive, unlike RorkDevice which is gated by zipArchivePlatforms, so the test
target can fail on unsupported platforms. Update the test target in
Package.swift to apply the same platform gate for the ZipArchive product, and in
the ZipArchive-based test file guard the import ZipArchive plus any archive
fixture tests with `#if` canImport(ZipArchive) so the tests only build where the
library is available.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f8b61639-6d00-40f5-9fe7-9688cf928cb2
📒 Files selected for processing (9)
Package.resolvedPackage.swiftSources/RorkDevice/DeveloperDiskImage/AppleTSSClient.swiftSources/RorkDevice/DeveloperDiskImage/DeveloperDiskImageStore.swiftSources/RorkDevice/DeveloperDiskImage/HTTPSOnlyURLSessionDelegate.swiftSources/RorkDevice/Public/DeviceSession.swiftTHIRD_PARTY_NOTICES.mdTests/RorkDeviceTests/AppleTSSClientTests.swiftTests/RorkDeviceTests/DeveloperDiskImageStoreTests.swift
✅ Files skipped from review due to trivial changes (2)
- THIRD_PARTY_NOTICES.md
- Package.resolved
🚧 Files skipped from review as they are similar to previous changes (3)
- Sources/RorkDevice/DeveloperDiskImage/HTTPSOnlyURLSessionDelegate.swift
- Tests/RorkDeviceTests/AppleTSSClientTests.swift
- Sources/RorkDevice/DeveloperDiskImage/AppleTSSClient.swift
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Follow-up commit 421d3e4 removes the temporary |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
rorkai/swift-zip-archivefork for bounded streaming extraction across native and WASI buildsDeviceSessionand therorkdevice image mount/image autocommandsWhy
iOS 17+ exposes developer services such as CoreDevice AppService only after a personalized Developer Disk Image is mounted. InstallationProxy remains sufficient for basic installed-app queries, but richer CoreDevice operations need this mount flow.
The library intentionally does not hardcode or endorse a DDI archive provider. Callers supply an HTTPS URL and the exact expected SHA-256, allowing applications and distributions to make their own legal and trust decisions.
Flow
flowchart TD A["HTTPS archive + pinned SHA-256"] --> B["Download or reuse digest-keyed cache"] B --> C["Validate and extract Restore directory"] C --> D["Check iOS 17+, Developer Mode, and ECID"] D --> E["Look up mounted personalized image"] E -->|Already mounted| K["Return alreadyMounted"] E -->|Not mounted| F["Query hardware identifiers and select BuildIdentity"] F --> G["Query device-side personalization manifest"] G -->|Manifest available| I["Upload DMG and mount with trust cache"] G -->|Manifest unavailable| H["Reopen service, query nonce, request Apple TSS ticket"] H --> I I --> J["Return mounted and require a fresh CoreDevice tunnel"]Security
Compatibility
RorkDeviceAPI break relative tomainValidation
swift test: 403 tests passed, 1 physical-device smoke test skipped, 0 failuresswift test --disable-automatic-resolution --filter DeveloperDiskImageSessionTests: 5 tests passed with the checked-in dependency pinsswift build -c release --product rorkdeviceswift build --swift-sdk swift-6.3.2-RELEASE_wasm --target RorkDeviceWebswiftly run swift build +6.0.3 --product rorkdevicewith the matching macOS 15.4 SDKswift package diagnose-api-breaking-changes origin/main --products RorkDevice: no breaking changesimage mountagainst a connected iPhone with an already-mounted personalized imageimage autodownloads, authenticates, extracts, caches, and reaches mounted-image detection against the same iPhoneThe connected phone already had a personalized image mounted, and unmounting was rejected while it was locked, so the live check did not repeat the destructive upload/mount branch.
Summary by CodeRabbit
DeviceSessionAPIs and a CLIimage mount/image autoworkflow.DeveloperDiskImageMountResultplus machine-readable newline-delimited JSON output (--json) with ticket-source and tunnel-restart guidance.