Skip to content

fix(parallels): macOS leases connect when Tools cannot report the guest - #1745

Open
saariuslystoned wants to merge 2 commits into
openclaw:mainfrom
saariuslystoned:fix/parallels-macos-bootstrap
Open

fix(parallels): macOS leases connect when Tools cannot report the guest#1745
saariuslystoned wants to merge 2 commits into
openclaw:mainfrom
saariuslystoned:fix/parallels-macos-bootstrap

Conversation

@saariuslystoned

Copy link
Copy Markdown

What Problem This Solves

Fixes an issue where users acquiring Apple-silicon macOS guests through the Parallels provider would see a healthy full clone remain unready when Parallels Tools could not report the guest IP or execute the guest-preparation command.

It also lets macOS desktop sessions authenticate with the real guest account credential instead of requiring only the generated legacy VNC credential.

Why This Change Was Made

Parallels Tools remains the preferred discovery and preparation path. For macOS only, operators can configure a trusted host-side bootstrap identity. When Tools publishes no IP, Crabbox matches the clone's exact normalized NIC MAC against an unexpired Parallels DHCP lease, rejects missing, malformed, stale, duplicate-ambiguous results, verifies the configured SSH port, and streams the existing preparation script over SSH. Normal sync and run traffic then uses Crabbox's generated per-lease key.

For desktop access, the Parallels provider implements the same provider credential contract used by other macOS providers. The account password is accepted only from trusted user configuration or CRABBOX_PARALLELS_PASSWORD; there is no password CLI flag, repository configuration cannot select it, and it is removed from target-facing child environments. The password is never written to the guest, passed on argv, or used to reset the macOS account.

Linux and Windows retain their existing behavior. Linked-clone behavior is unchanged.

User Impact

Operators can use Crabbox to acquire and drive full-clone macOS guests on local or remote Parallels hosts even when the macOS Parallels Tools guest-info channel is unavailable. Existing configurations remain Tools-first and backward-compatible.

New optional trusted configuration:

  • parallels.bootstrapKey / CRABBOX_PARALLELS_BOOTSTRAP_KEY
  • parallels.password / CRABBOX_PARALLELS_PASSWORD

Evidence

Live integration against a remote Apple-silicon Parallels host:

  • created and started a full macOS clone;
  • resolved the guest through exact MAC-to-DHCP matching;
  • verified TCP/22 and bootstrapped the generated per-lease key;
  • synchronized 2,114 files / 32.5 MiB;
  • ran /usr/bin/sw_vers -productVersion and received 26.5.2;
  • automatically stopped and deleted the disposable clone;
  • verified the base VM was restored healthy and no lease key or clone remained.

The desktop credential routing is covered by focused and race tests. A direct live ARD screenshot is not claimed in this PR.

Post-rebase verification:

go test ./internal/providers/parallels ./internal/cli -run 'Parallels|DesktopCredentials|ConfigShow|TrustedFile|Repository.*Password' -count=1
go test -race ./internal/providers/parallels ./internal/cli -run 'Parallels|DesktopCredentials|ConfigShow|TrustedFile|Repository.*Password' -count=1
go vet ./internal/providers/parallels ./internal/cli
go build -trimpath -o bin/crabbox ./cmd/crabbox

All passed on 13ea9a99fd409eaa9633e9291fb788936dd03536.

@clawsweeper

clawsweeper Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@steipete

steipete commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Maintainer triage at 13ea9a99fd409eaa9633e9291fb788936dd03536: I approved the four held hosted workflows. Two source-backed repairs remain before landing:

  1. Restore the exact claim's proven SSH port before DHCP discovery. Resolve currently constructs the client and calls WaitForIP before applyParallelsClaimSSHPort; the new DHCP path probes c.Cfg.SSHPort. A retained port-22 lease resolved with the generic 2222 default can therefore fail discovery before its saved endpoint is applied. Cover a separate reuse invocation with no Tools-reported IP and only the saved port reachable.
  2. Apply the account-password environment boundary to the host/bootstrap command path too. parallelsSSHTarget denies CRABBOX_PARALLELS_PASSWORD, but BootstrapMacOSOverSSH goes through hostCommand, whose LocalCommandRequest has no denylist; the direct prlctl and doctor paths also bypass that target helper. Add synthetic child-environment coverage for these paths without printing or placing password values on argv. This is a source inspection, not evidence that a real password was exposed.

After repair, retain the native clone/SSH proof and add final-head saved-port reuse, actual account-authenticated desktop interaction, and independent cleanup confirmation for the task-owned clone. The source VM and unrelated VMs must remain untouched. No VM or credential changes were made during this triage.

@steipete

steipete commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

CI follow-up at unchanged head 13ea9a99fd409eaa9633e9291fb788936dd03536: the approved CI run has completed. Go test, Go modules, and Go coverage all fail the same TestProvidersDescribeBuiltBinaryContract assertion, not three independent failures. Release Check, Connector E2E, and Docs UI Proof passed.

The new --parallels-bootstrap-key flag changes run --help; the checked-in contract in internal/cli/providers_describe_binary_test.go:184–187 still expects 61,825 bytes, while CI produced 61,947. Please inspect the intended help delta, then deliberately update the hash and byte-count contract. There is no separate fixture generator in the inspected sources. Focused verification: go test ./internal/cli -run '^TestProvidersDescribeBuiltBinaryContract$' -count=1.

Refreshing that contract does not resolve the saved-port reuse, child password-environment boundary, or native desktop/lifecycle proof requirements in the earlier review. No rerun was requested for this deterministic failure, and no VM or credential state was changed.

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.

2 participants