# How to Automate iOS VM Creation with vphone-cli: Complete Orchestration Guide

> Automate iOS VM creation with vphone-cli. Streamline provisioning from firmware prep to verification with one command, eliminating manual scripting for efficient orchestration.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: how-to-guide
- Published: 2026-09-09

---

**vphone-cli automates the entire iOS virtual machine provisioning workflow through a single `vm create` command, orchestrated by `VPhoneCreateOrchestrator` to execute eight distinct stages from firmware preparation to first-boot verification without manual shell scripting.**

The **Lakr233/vphone-cli** repository provides a native Swift implementation that replaces the historic [`scripts/setup_machine.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/setup_machine.sh) approach. By invoking the `vm create` subcommand defined in [`VPhoneVMCreateCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVMCreateCLI.swift), developers trigger a fully-typed pipeline that downloads IPSWs, patches firmware, and restores the system using the `VPhoneCreateOrchestrator` class.

## The vphone-cli VM Creation Architecture

The automation layer centers on two primary components. The **`VPhoneVMCreateCommand`** struct parses command-line arguments—including variant selection (`regular`, `dev`, `jb`, `exp`, or `less`), disk sizing, and IPSW sources—and delegates execution to the **`VPhoneCreateOrchestrator`**. This orchestrator implements the complete workflow previously distributed across multiple bash scripts, now unified within [`sources/vphone-cli/VPhoneCreateOrchestrator.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneCreateOrchestrator.swift).

## Eight-Stage Automation Pipeline

When you execute `vphone-cli vm create`, the orchestrator proceeds through the following sequential stages:

### 1. Pre-flight Validation

Before allocating resources, the orchestrator detects nested virtualization environments. The **`isNestedVMHost()`** method (located at lines 76–82 in [`VPhoneCreateOrchestrator.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneCreateOrchestrator.swift)) checks if the host is itself a virtual machine, aborting immediately because PV=3 guests cannot run inside another VM. This prevents wasted compute cycles on incompatible infrastructure.

### 2. Bundle Creation

The orchestrator initializes the VM container using **`VPhoneBundleOps.NewBundleSpec`**. During this stage, the **`run()`** method (lines 72–79) creates the bundle directory structure with specified CPU, memory, and disk parameters, establishing the virtualized hardware profile that subsequent stages will populate.

### 3. Firmware Preparation

This stage downloads and merges the iPhone IPSW and cloudOS IPSW archives. The **`runFWPrepare()`** function (lines 10–12) invokes the bundled [`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_prepare.sh) helper, passing environment variables including `IPHONE_SOURCE`, `CLOUDOS_SOURCE`, and `VPHONE_PYTHON` to manage the Python interpreter path and IPSW URLs. The script caches the merged result in a seal-volume directory for subsequent patching operations.

### 4. Firmware Patching

With the base firmware cached, **`runFWPatch()`** (lines 33–36) executes the in-process **`FirmwarePipeline.patchAll`** method from [`FirmwarePatcher/FirmwarePipeline.swift`](https://github.com/Lakr233/vphone-cli/blob/main/FirmwarePatcher/FirmwarePipeline.swift). This pipeline applies variant-specific modifications (`regular`, `dev`, `jb`, `exp`, or `less`) to the seal-volume image, preparing the custom firmware without intermediate shell calls.

### 5. Restore Phase

The orchestrator launches the VM in DFU mode and initiates the restore sequence via **`runRestorePhase()`** (lines 58–78). This function fetches a signed SHSH blob through the `pmd3 bridge`, executes the `restore-update` process, and records the restored iOS and cloudOS version strings. It also monitors for post-restore panic markers to detect early boot failures before proceeding.

### 6. Custom Firmware Installation (Non-less Variants)

For all variants except `less`, **`runCFWInstall()`** (lines 84–92) mounts the host disk image and copies the patched firmware into `Disk.img`. This stage handles privilege escalation using **`makeSudoAskpassScript()`**, which generates a non-interactive authentication helper when the `--sudo-password` flag is provided, enabling automated installation in CI environments.

### 7. First-Boot Initialization

The **`runFirstBoot()`** method (lines 100–112) boots the patched VM and injects configuration commands defined in **`VPhoneBootPatterns.firstBootCommands`**. This sequence completes system setup inside the guest, with optional interactive pauses for manual verification if the `--confirm` flag is specified.

### 8. Boot Analysis and Cleanup

Finally, **`runBootAnalysis()`** (lines 118–126) launches a headless VM instance to verify that the bash prompt appears correctly, or detects panic states using regex patterns from [`VPhoneBootPatterns.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneBootPatterns.swift). The orchestrator then optionally removes intermediate build artifacts via cleanup logic in **`run()`** (lines 31–34) to conserve disk space.

## Practical Command-Line Usage

### Basic Non-Interactive Creation

Create a `regular` variant VM named `myVM` with a 64 GB virtual disk:

```bash
vphone-cli vm create myVM \
  --variant regular \
  --iphone-source https://example.com/iPhone13,14.5.ipsw \
  --cloudos-source https://example.com/cloudOS13.7.ipsw \
  --disk-size 64

```

### Debugging with Verbose Output

Enable internal trace logging using the `-vvv` flag:

```bash
vphone-cli -vvv vm create myVM \
  --variant jb \
  --iphone-source /path/to/iPhone13.5.ipsw \
  --cloudos-source /path/to/cloudOS13.3.ipsw

```

### Patch-Less Variant (Requires Root)

The `less` variant skips CFW installation and must run with elevated privileges:

```bash
sudo vphone-cli vm create myVM \
  --variant less \
  --iphone-source /path/to/iPhone13.5.ipsw \
  --cloudos-source /path/to/cloudOS13.3.ipsw

```

### Automated Sudo Authentication

Pass credentials non-interactively for CI pipelines:

```bash
vphone-cli vm create myVM \
  --variant dev \
  --iphone-source https://example.com/iPhone13.5.ipsw \
  --cloudos-source https://example.com/cloudOS13.3.ipsw \
  --sudo-password "$MY_SUDO_PWD"

```

### Preserving Build Artifacts

Retain intermediate files for forensic analysis:

```bash
vphone-cli vm create myVM \
  --keep-artifacts \
  --variant exp

```

## Core Implementation Files

- **[`VPhoneVMCreateCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVMCreateCLI.swift)** – Defines the `vphone-cli vm create` argument interface and option parsing.
- **[`VPhoneCreateOrchestrator.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneCreateOrchestrator.swift)** – Implements the eight-stage pipeline including `runFWPrepare()`, `runFWPatch()`, and `runRestorePhase()`.
- **[`VPhoneResources.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneResources.swift)** – Manages cache paths for IPSW files, seal-volumes, and DEB packages; resolves the bundled Python interpreter via `VPHONE_PYTHON`.
- **[`VPhoneProcessRunner.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneProcessRunner.swift)** – Provides `Process` wrapper utilities for streaming output, privilege escalation, and foreground execution.
- **[`VPhoneBootPatterns.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneBootPatterns.swift)** – Contains regex patterns for detecting VM readiness, kernel panics, and device identity extraction.
- **[`VPhoneBundleOps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneBundleOps.swift)** – Handles directory creation and specification of virtual hardware resources.
- **[`FirmwarePatcher/FirmwarePipeline.swift`](https://github.com/Lakr233/vphone-cli/blob/main/FirmwarePatcher/FirmwarePipeline.swift)** – Implements the per-variant firmware modification logic consumed by `runFWPatch()`.
- **[`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_prepare.sh)** – Bash helper for IPSW downloading and merging invoked during firmware preparation.
- **[`scripts/cfw_install_host.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install_host.sh)** – Host-mount installation script for the CFW install stage.

## Summary

- **Single-command automation** via `vphone-cli vm create` eliminates manual shell scripting.
- **Native Swift orchestration** through `VPhoneCreateOrchestrator` provides type-safe error handling and reproducibility.
- **Eight-stage pipeline** covers validation, firmware preparation, patching, restoration, and verification.
- **Variant flexibility** supports `regular`, `dev`, `jb`, `exp`, and `less` firmware configurations.
- **CI/CD compatibility** via `--sudo-password` and non-interactive authentication hooks.

## Frequently Asked Questions

### What is the difference between the "less" variant and other variants?

The `less` variant skips the custom firmware installation stage entirely, requiring the user to manually manage the root filesystem, and must execute with `sudo` privileges. Other variants (`regular`, `dev`, `jb`, `exp`) proceed through the full pipeline including automatic CFW installation via `runCFWInstall()`.

### Can vphone-cli create VMs inside a virtual machine?

No. The `isNestedVMHost()` function explicitly detects when the host environment is itself a virtual machine and aborts the creation process because the virtualization architecture (PV=3) used for these iOS guests cannot operate within nested hypervisors.

### How does the tool handle Python dependencies for firmware operations?

The orchestrator locates the bundled Python interpreter through [`VPhoneResources.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneResources.swift), setting the `VPHONE_PYTHON` environment variable when invoking [`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_prepare.sh). This ensures consistent script execution regardless of system Python configurations.

### Where are downloaded IPSW files cached?

The `VPhoneResources` module manages dedicated cache directories for IPSW archives, seal-volume images, and DEB packages within the application support directory, preventing redundant downloads across multiple VM creation runs.