|
1 | 1 | # GhostVM |
2 | 2 |
|
3 | | -GhostVM is a native macOS app and CLI tool for provisioning and managing macOS virtual machines on Apple Silicon using Apple's `Virtualization.framework`. VMs are stored as self-contained `.GhostVM` bundles. |
| 3 | +GhostVM is a native macOS app for creating and managing macOS virtual machines on Apple Silicon using Apple's `Virtualization.framework`. VMs are stored as self-contained `.GhostVM` bundles. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- Create macOS VMs with customizable CPU, memory, and disk |
| 8 | +- Download and manage restore images (IPSW) with built-in feed |
| 9 | +- Start, stop, suspend, and resume VMs |
| 10 | +- Create, revert, and delete snapshots |
| 11 | +- Shared folders between host and guest |
| 12 | +- Clipboard sync, file transfer, and URL forwarding via the GhostTools guest agent |
| 13 | +- Port forwarding through vsock tunnels |
| 14 | +- Per-VM Dock icons with a helper-per-VM architecture |
| 15 | +- `vmctl` CLI for headless VM management and scripting |
| 16 | +- `vmctl remote` for programmatic guest control (accessibility, pointer, keyboard) |
4 | 17 |
|
5 | 18 | ## Requirements |
6 | 19 |
|
7 | 20 | - macOS 15+ on Apple Silicon (arm64) |
8 | | -- Xcode 15+ and XcodeGen for building (`brew install xcodegen`) |
9 | | -- `com.apple.security.virtualization` entitlement (included in builds) |
| 21 | +- Xcode 15+ and XcodeGen (`brew install xcodegen`) |
10 | 22 |
|
11 | 23 | ## Building |
12 | 24 |
|
13 | 25 | ```bash |
14 | 26 | make # Show available targets |
| 27 | +make app # Build GhostVM.app |
15 | 28 | make cli # Build vmctl CLI |
16 | | -make app # Build GhostVM.app via xcodebuild |
| 29 | +make test # Run unit tests |
17 | 30 | make run # Build and run attached to terminal |
18 | 31 | make launch # Build and launch detached |
19 | | -make test # Run unit tests |
20 | | -make dist # Create distribution DMG with app + vmctl |
21 | | -make clean # Remove build artifacts and generated project |
| 32 | +make dist # Create distribution DMG |
| 33 | +make clean # Remove build artifacts |
22 | 34 | ``` |
23 | 35 |
|
24 | | -Builds are ad-hoc signed by default. Override `CODESIGN_ID` for a different identity. |
| 36 | +## Project Structure |
25 | 37 |
|
26 | | -## GUI App |
27 | | - |
28 | | -The GhostVM.app provides a SwiftUI interface for managing VMs: |
29 | | - |
30 | | -- Create macOS VMs with customizable CPU, memory, and disk |
31 | | -- Manage restore images (IPSW) with built-in download support |
32 | | -- Start, stop, suspend, and resume VMs |
33 | | -- Create, revert, and delete snapshots |
34 | | -- Configure shared folders (read-only or writable) |
35 | | -- VM menu with keyboard shortcuts for Start, Suspend, Shut Down, and Terminate |
36 | | - |
37 | | -## CLI Usage |
38 | | - |
39 | | -```bash |
40 | | -./vmctl --help |
41 | 38 | ``` |
42 | | - |
43 | | -**Commands:** |
44 | | - |
45 | | -- `init <bundle-path>` – Create a new macOS VM bundle |
46 | | - - Options: `--cpus N`, `--memory GiB`, `--disk GiB`, `--restore-image PATH`, `--shared-folder PATH`, `--writable` |
47 | | -- `install <bundle-path>` – Install macOS from restore image |
48 | | -- `start <bundle-path>` – Launch the VM (GUI by default) |
49 | | - - Options: `--headless`, `--shared-folder PATH`, `--writable|--read-only` |
50 | | -- `stop <bundle-path>` – Graceful shutdown |
51 | | -- `status <bundle-path>` – Report running state and config |
52 | | -- `resume <bundle-path>` – Resume from suspended state |
53 | | - - Options: `--headless`, `--shared-folder PATH`, `--writable|--read-only` |
54 | | -- `discard-suspend <bundle-path>` – Discard suspended state |
55 | | -- `snapshot <bundle-path> list` – List snapshots |
56 | | -- `snapshot <bundle-path> create|revert|delete <name>` – Manage snapshots |
57 | | - |
58 | | -Restore images are auto-discovered from `~/Downloads/*.ipsw` and `/Applications/Install macOS*.app`. |
59 | | - |
60 | | -## Examples |
61 | | - |
62 | | -```bash |
63 | | -make cli |
64 | | -./vmctl init ~/VMs/sandbox.GhostVM --cpus 6 --memory 16 --disk 128 |
65 | | -./vmctl install ~/VMs/sandbox.GhostVM |
66 | | -./vmctl start ~/VMs/sandbox.GhostVM |
67 | | -./vmctl stop ~/VMs/sandbox.GhostVM |
| 39 | +. |
| 40 | +├── Makefile # Build orchestration |
| 41 | +├── macOS/ |
| 42 | +│ ├── project.yml # XcodeGen project definition |
| 43 | +│ ├── GhostVM/ # Main SwiftUI app (VM manager/launcher) |
| 44 | +│ ├── GhostVMHelper/ # Per-VM helper process (display, toolbar, services) |
| 45 | +│ ├── GhostVMKit/ # Shared framework (types, VM controller, utilities) |
| 46 | +│ ├── GhostTools/ # Guest agent (runs inside VM, vsock communication) |
| 47 | +│ ├── GhostVMTests/ # Unit tests |
| 48 | +│ └── GhostVMUITests/ # UI tests |
| 49 | +└── Website/ # GitHub Pages site |
68 | 50 | ``` |
69 | 51 |
|
70 | | -**Suspend and Resume:** |
| 52 | +## CLI Usage |
71 | 53 |
|
72 | 54 | ```bash |
73 | | -# Use VM > Suspend menu (Cmd+Option+S) in the app, then: |
74 | | -./vmctl resume ~/VMs/sandbox.GhostVM |
| 55 | +vmctl init ~/VMs/sandbox.GhostVM --cpus 6 --memory 16 --disk 128 |
| 56 | +vmctl install ~/VMs/sandbox.GhostVM |
| 57 | +vmctl start ~/VMs/sandbox.GhostVM |
| 58 | +vmctl stop ~/VMs/sandbox.GhostVM |
75 | 59 | ``` |
76 | 60 |
|
77 | | -**Snapshots:** |
| 61 | +**Commands:** |
78 | 62 |
|
79 | | -```bash |
80 | | -./vmctl snapshot ~/VMs/sandbox.GhostVM list |
81 | | -./vmctl snapshot ~/VMs/sandbox.GhostVM create clean |
82 | | -./vmctl snapshot ~/VMs/sandbox.GhostVM revert clean |
83 | | -./vmctl snapshot ~/VMs/sandbox.GhostVM delete clean |
84 | | -``` |
| 63 | +| Command | Description | |
| 64 | +|---------|-------------| |
| 65 | +| `init <bundle>` | Create a new VM bundle (`--cpus`, `--memory`, `--disk`, `--restore-image`) | |
| 66 | +| `install <bundle>` | Install macOS from a restore image | |
| 67 | +| `start <bundle>` | Launch the VM (`--headless`, `--shared-folder`) | |
| 68 | +| `stop <bundle>` | Graceful shutdown | |
| 69 | +| `suspend` / `resume` | Suspend and resume VM state | |
| 70 | +| `status <bundle>` | Report running state and config | |
| 71 | +| `snapshot <bundle> list\|create\|revert\|delete` | Manage snapshots | |
| 72 | +| `list` | List all VMs and their status | |
| 73 | +| `remote <vm> screenshot` | Capture guest screenshot | |
| 74 | +| `remote <vm> elements` | Inspect accessibility tree | |
| 75 | +| `remote <vm> leftclick --label <text>` | Click a UI element | |
| 76 | +| `remote <vm> type --text <text>` | Type text into the guest | |
85 | 77 |
|
86 | 78 | ## Notes |
87 | 79 |
|
88 | | -- Disk images are raw sparse files (default 64 GiB) |
89 | | -- NAT networking via `VZNATNetworkDeviceAttachment` |
90 | | -- Shared folders use `VZVirtioFileSystemDeviceConfiguration` (read-only by default) |
91 | | -- Enable Remote Login (SSH) in guest for headless use |
| 80 | +- VMs use `VZNATNetworkDeviceAttachment` for networking |
| 81 | +- Shared folders use `VZVirtioFileSystemDeviceConfiguration` |
| 82 | +- GhostTools auto-installs to `/Applications` in the guest and auto-updates |
| 83 | +- Enable Remote Login (SSH) in the guest for headless use |
92 | 84 | - Apple's EULA requires macOS guests to run on Apple-branded hardware |
0 commit comments