Parallels‑style virtualization & integration features built on Apple's Virtualization.framework.
DISCLAIMER: Early research prototype. Not production‑ready. Expect breaking changes.
- Goals
- Current Features
- Quick Start
- Linux ARM Images
- Windows 11 ARM (Future)
- Architecture Overview
- Testing
- Development Commands
- Security & Validation
- Snapshot Layering
- Vsock & Integration
- Roadmap
- Contributing
- FAQ
- YAML Configuration & Automation
- References
- High‑quality Type‑2 virtualization on Apple Silicon (ARM64)
- Run Linux ARM and (future) Windows 11 ARM guests
- Provide integration features: snapshots, shared folders, clipboard, vsock channels, future coherence/window streaming
- Clean Swift architecture with testable core and optional SwiftUI GUI
- Swift package:
VMCore
library +vmcli
CLI + minimal SwiftUI app (VMStudioApp
) - Persistent VM configuration store under
~/.vmstudio/vms/<id>/config.json
- Linux kernel boot (attach kernel+initrd+cmdline) and serial console streaming
- Snapshots: metadata +
SnapshotMetadata
& plannedDiskLayer
(overlay placeholders) - Networking: NAT, bridged selection (if interface available), host‑only placeholder, port forward metadata + runtime stub
- Shared folders: virtio‑fs single exported folder (first entry) prototype
- Vsock channel: framed protocol (
VSOK
magic) + clipboard channel + host listener (HostVsockTransport
) - Async start lifecycle & delegate callbacks (state, console, error)
- Security / configuration validation (memory bounds, shared folder path existence)
- Minimal SwiftUI GUI listing VMs & showing console output
Planned / in progress: snapshot CoW implementation, multi-folder virtio‑fs, real TCP port proxy, richer agent integration, coherence graphics.
- macOS 13+ on Apple Silicon (M1/M2/M3)
- Xcode 15 / Command Line Tools (Swift 5.9+)
- Virtualization entitlement (CLI can run without signing for dev; GUI app will need signing for distribution)
git clone https://github.com/pynip/hypervisor-arm-macos.git
cd hypervisor-arm-macos
swift build
swift test
./.build/debug/vmcli create --name demo --cpu 4 --mem 4096 --disk ./demo.img:20
./.build/debug/vmcli list
- macOS 13+ on Apple Silicon (M1/M2/M3)
- Xcode 15 / Command Line Tools (Swift 5.9+)
- Virtualization entitlement (CLI can run without signing for dev; GUI app will need signing for distribution)
git clone https://github.com/pynip/hypervisor-arm-macos.git
cd hypervisor-arm-macos
swift build
swift test
./.build/debug/vmcli create --name demo --cpu 4 --mem 4096 --disk ./demo.img:20
./.build/debug/vmcli list
# Example using an extracted Linux ARM64 kernel + initrd
./.build/debug/vmcli attachLinuxBoot --id <UUID> \
--kernel /absolute/path/to/vmlinuz \
--initrd /absolute/path/to/initrd \
--cmdline "console=hvc0 root=/dev/vda1 rw"
./.build/debug/vmcli enableConsole --id <UUID>
./.build/debug/vmcli start --id <UUID> --followConsole
./.build/debug/vmcli addPortForward --id <UUID> --host 8080 --guest 80
./.build/debug/vmcli setNetworkMode --id <UUID> --mode bridged --iface en0
./.build/debug/vmcli listInterfaces
./.build/debug/vmcli addSharedFolder --id <UUID> --host /absolute/path --guest /mnt/host [--ro]
./.build/debug/vmcli snapshot --id <UUID> --name initial
./.build/debug/vmcli listSnapshots --id <UUID>
./.build/debug/vmcli pushClipboard --text "Hello Guest"
open Package.swift # then run the VMStudioApp target in Xcode
- Ubuntu Server ARM64: https://ubuntu.com/download/server/arm
- Fedora ARM: https://alt.fedoraproject.org/alt/
- Debian ARM64: https://www.debian.org/ports/arm64/
- Alpine ARM64 (kernel + initramfs friendly): https://alpinelinux.org/downloads/
For direct kernel boot you typically extract:
cp /boot/vmlinuz-linux ./vmlinuz
cp /boot/initrd.img ./initrd
Ensure the root device specified in --cmdline
matches your disk layout.
Apple’s Virtualization.framework does not ship Windows tooling. Obtain a Windows 11 ARM ISO via the Windows Insider Preview (licensed). Steps (planned):
- Convert ISO to raw disk, install via UEFI (macOS virtualization supports only ARM hardware model for macOS guests; Windows uses generic ARM machine path).
- Add virtio drivers (if required) & guest agent for vsock.
- Enable integration features (clipboard, folders, coherence) after agent ports exist.
We will document legally compliant acquisition steps once Windows support layer is implemented.
See architecture.md
for deep dive (components, threading, snapshot design, vsock framing, GUI pieces, future research).
Key code locations:
Area | Path |
---|---|
Core models & controller | Sources/VMCore |
CLI tool | Sources/VMCLI |
SwiftUI prototype | Sources/VMStudioApp |
Vsock & clipboard | Sources/VMCore/VsockChannel.swift |
Snapshots metadata | VMModels.swift (SnapshotMetadata , DiskLayer ) |
Guest agent (Rust skeleton) | agent/ |
Protocol specs | docs/ |
Run unit tests:
swift test
Tests cover configuration builder, snapshot metadata creation, vsock codec framing, clipboard loopback, persistence, delegate transitions.
Purpose | Command |
---|---|
Build debug | swift build |
Run CLI help | ./.build/debug/vmcli help |
Run SwiftUI app | Open in Xcode and run target VMStudioApp |
- Configuration validator checks memory upper bounds (<=128GB), shared folder existence, bridged interface name
- Future: signature validation for plugins & agent binaries; restricted capability negotiation over vsock
Current: metadata only with planned overlay file paths per disk (DiskLayer
).
Planned: block‑level CoW (e.g., 4 MiB granularity) with checksums & optional compression; background merge when chain depth grows.
VsockCodec
handles binary framingHostVsockTransport
(port 7000) attaches listener- Clipboard implemented; upcoming channels: metrics, window frames, input events
- Core models, persistence, Linux boot path
- Console & async lifecycle
- Vsock channel + clipboard
- Snapshot metadata scaffold
- Bridged networking selection
- SwiftUI prototype
- CoW snapshot data
- Multi shared folder virtio‑fs
- Real port proxy & vsock agent handshake
- Coherence (window streaming)
- Windows ARM guest enablement
Full phased plan: see plan.md
.
This repo now includes a YAML-driven workflow for consistent setup.
Artifacts:
vm-config.example.yaml
– Copy tovm-config.yaml
and adjust to define a VM.vmstudio.yaml
– High-level automation tasks (build/test/run) & defaults.scripts/vmstudio.py
– Python orchestrator parsing both YAML files..github/workflows/ci.yml
– CI pipeline (macOS build/test + YAML validation + LOC dry run).
- Copy example:
cp vm-config.example.yaml vm-config.yaml $EDITOR vm-config.yaml
- (Optional) Adjust automation in
vmstudio.yaml
(e.g., disable tests). - Run orchestrator:
It will: validate config -> build -> test -> (placeholder) run VM.
python3 scripts/vmstudio.py
The automation glues YAML to actual Swift Package Manager commands and vmcli
invocations.
-
Validation Phase (
validate-config
task)- Loads
vm-config.yaml
. - Ensures mandatory fields (cpu, memoryMB, disks, boot, network) exist.
- Emits warnings for missing kernel/initrd paths when
boot.kind=linuxKernel
. - Warns about missing shared folder host paths instead of failing hard (developer friendly).
- Loads
-
Build Phase (
swiftBuild
task)- Executes
swift build
(debug) orswift build -c release
depending onbuild.swiftTarget
invmstudio.yaml
. - Extra CLI flags can be added via
build.swiftFlags
(e.g.--sanitize=thread
).
- Executes
-
Test Phase (
swiftTest
task)- Runs
swift test
only ifbuild.test: true
. - Skipped automatically when
Package.swift
is absent (graceful degradation for docs-only forks).
- Runs
-
Run Phase (
runVM
task)- Creates sparse disk images for any listed disk not present using
truncate -s <sizeGB>G
. - Calls
vmcli create
with name / cpu / memory / primary disk. - (Future) Will map
name
to real VM UUID, attach kernel viaattachLinuxBoot
, and then callstart --followConsole
.
- Creates sparse disk images for any listed disk not present using
YAML Field | vmcli Argument / Behavior |
---|---|
name | create --name <name> |
cpu | --cpu <cpu> |
memoryMB | --mem <memoryMB> |
disks[0].path + sizeGB | --disk path:size (first disk only currently) |
network.mode | (stored in config; actual mode change via setNetworkMode future automation) |
network.portForwards[] | Will invoke addPortForward (future) |
boot.linuxKernel.* | Will invoke attachLinuxBoot (future) |
sharedFolders[] | Will invoke addSharedFolder (future) |
Switch to release build:
build:
swiftTarget: release
swiftFlags: ["-Xswiftc","-O"]
test: true
Then rerun:
python3 scripts/vmstudio.py
Symptom | Likely Cause | Fix |
---|---|---|
[error] vmcli not built yet |
Build step skipped or failed | Check earlier log, run swift build manually |
Kernel path warning | Provided path absent | Set absolute path to extracted vmlinuz /initrd |
Shared folder warning | Host path missing | Create directory or remove entry |
Swift not available | Running on system without Xcode/CLI tools | Install Xcode Command Line Tools (xcode-select --install ) |
Edit scripts/vmstudio.py
:
- Locate
action_run_vm
. - After creation, add logic to parse
vmcli list
and capture the generated VM ID. - Invoke subsequent commands:
run([vmcli,'attachLinuxBoot','--id', vm_id,'--kernel', vm_cfg.boot.kernel,'--initrd', vm_cfg.boot.initrd,'--cmdline', vm_cfg.boot.cmdline]) run([vmcli,'enableConsole','--id', vm_id]) run([vmcli,'start','--id', vm_id,'--followConsole'])
GitHub Actions workflow ci.yml
conditionally runs build/test only when Package.swift
exists. This makes forks or documentation branches lightweight while still validating YAML integrity.
- No execution of arbitrary shell embedded in YAML (fields are data-only).
- Disk creation uses
truncate
(allocates sparse image; consider enforcing size limits if user-provided YAML is untrusted).
- Automatic kernel/initrd download helper commands.
- Port forward application at runtime (host TCP listener proxying to vsock or guest IP).
- Dynamic generation of multiple virtio-fs exports when framework support implemented.
- Snapshot chain management commands derived from
snapshots.maxDepth
.
Field | Type | Notes |
---|---|---|
name | string | VM display name |
cpu | int | vCPU count >=1 |
memoryMB | int | RAM in MB >=256 |
disks[] | list | path/sizeGB/type/boot; creates sparse if missing |
boot.kind | enum | linuxKernel (current) / efi (future) |
network.mode | enum | nat / bridged / hostOnly (stub) |
network.portForwards[] | list | hostPort/guestPort/protocol |
sharedFolders[] | list | hostPath/guestPath/readOnly |
integration.clipboard | bool | toggle clipboard channel |
snapshots.enable | bool | metadata snapshots toggle |
- Add new task actions in
vmstudio.py
(search foraction_
). - Toggle CI behavior by editing
.github/workflows/ci.yml
. - Future: generate dynamic LOC badge, multi-disk boot, real run invocation mapping name→UUID.
Use provided script to obtain a test ARM64 kernel/initrd (Ubuntu mainline example):
./scripts/fetch_kernel.sh ./kernel-cache
Then update vm-config.yaml
:
boot:
kind: linuxKernel
kernel: /absolute/path/to/kernel-cache/vmlinuz
initrd: /absolute/path/to/kernel-cache/initrd
cmdline: "console=hvc0 root=/dev/vda1 rw"
- Code of Conduct:
CODE_OF_CONDUCT.md
- Contributing Guide:
CONTRIBUTING.md
- Security Policy:
SECURITY.md
CI updates badges/loc.svg
and replaces the placeholder loc-dynamic
token in README on pushes to main. Manual run:
python scripts/update_loc_badge.py --write-readme
git add badges/loc.svg README.md
git commit -m "chore: update LOC badge"
We welcome early experimentation & feedback.
- Fork & create a branch (feature/short-description)
- Run tests (
swift test
) - Add / update docs for any new user-facing feature
- Submit PR with clear description & rationale
- Swift: Follow Swift API Design Guidelines; prefer explicit over implicit clarity
- Tests: Provide at least one positive + one edge case
- Logging: Use
LoggerFacade
categories
- Conventional style (suggested):
feat:
,fix:
,docs:
,chore:
,test:
MIT – see LICENSE
.
Q: Why metadata-only snapshots?
A: Establish format & layering semantics before implementing CoW logic.
Q: Why only first shared folder?
A: Simplicity; virtio‑fs aggregation & multi-export strategy pending.
Q: Does Windows ARM work now?
A: Not yet; roadmap includes UEFI install + integration tooling.
Q: Can I use this for production workloads?
A: No—prototype quality, expect breaking changes.
- Apple Virtualization: https://developer.apple.com/documentation/virtualization
- Parallels Desktop: https://www.parallels.com/
- QEMU Project: https://www.qemu.org/
- Ubuntu ARM: https://ubuntu.com/download/server/arm
- Debian ARM64: https://www.debian.org/ports/arm64/
- Fedora ARM: https://alt.fedoraproject.org/alt/
- Alpine Linux: https://alpinelinux.org/
Last updated: 2025‑10‑11
To generate/update the LOC badge automatically, add a script & GitHub Action later:
cloc . --json > loc.json
LOC=$(jq '.SUM.code' loc.json)
echo "" # commit updated README or badge asset
Module docs: see modules/README.md
for per-component details.