Skip to content

# VirtualProg CLI (vpvm)

Command-Line Interface for VirtualProg Virtual Machine Manager

The `vpvm` command-line tool provides powerful automation and scripting capabilities for managing your virtual machines in VirtualProg. Control your VMs from the terminal, integrate with scripts, and automate your workflow — locally or on a remote machine.

## 🚀 Overview

The VirtualProg CLI (`vpvm`) enables you to:

- Start, stop, and control virtual machines from the terminal
- Create and manage snapshots and templates
- Check VM status and list all available VMs
- Automate workflows with shell scripts
- Integrate with CI/CD pipelines and automation tools
- Control remote instances of VirtualProg over the network

The CLI communicates with the VirtualProg app via a local HTTP API, ensuring seamless integration between GUI and command-line operations.

> Tip: Every command listed in this documentation is also available directly in the Web Dashboard CLI Terminal — click the `⌨ CLI` button in the dashboard header to open it without leaving the browser. See the Web Dashboard documentation for details.

## 📥 Installation

- Download the vpvm cli using Download Command Line from Top Help Menu
- Download the vpvm cli from https://makeprog.com/Products/VirtualProg/vpvm.zip and place it in a directory of your choice.
- Unzip the archive and move the `vpvm` binary to a directory in your `$PATH`.

### Adding to PATH (Optional)

For easier access, you can add `vpvm` to your system PATH:

    # Add to your ~/.zshrc or ~/.bash_profile
    export PATH="$PATH:{vpvm cli location}"

## 📋 Command Reference

### General Syntax

    vpvm <command> [--server <host>] [--port <port>] [--secure] [--trust-certificate] [--token <token>] [--format text|json] [arguments]

The `--server`, `--port`, `--secure`, `--trust-certificate`, and `--token` flags are optional and apply per-command. When omitted, `vpvm` connects to the local machine VirtualProg instance using its configured settings.

### Output Formats

All list and info commands support a `--format` flag that controls how output is printed:

Value | Description
--- | ---
`text` | Human-readable table/list (default)
`json` | Raw JSON response from the API — ideal for scripting with `jq` or other tools

Commands that support `--format`: `list`, `info`, `stats`, `logs`, `snapshot list`, `snapshot info`, `checkpoint list`, `checkpoint info`, `template list`, `template info`, `template config *list`, `network list`, `network info`, `network sources`, `config info`, `config disk list`, `config network list`, `config cd list`, `config serial list`, `config nbd list`, `images list`, `images browse`, `images status`, `usb list`

#### JSON output examples

    # List all VMs as JSON and filter running ones with jq
    vpvm list --format json | jq '.vms[] | select(.info.state == "running") | .name'

    # Get VM info as JSON and extract CPU count
    vpvm info ubuntu-22.04 --format json | jq '.cpu'

    # List snapshots and find the most recent one
    vpvm snapshot list ubuntu-22.04 --format json | jq '.snapshots | sort_by(.createdAt) | last | .name'

    # Export all network configs
    vpvm network list --format json > networks.json

    # Check disk sizes across all VMs in a script
    vpvm config disk list ubuntu-22.04 --format json | jq '.[].size'

    # List available images as JSON
    vpvm images list --format json

> Tip: JSON output passes the raw API response directly to stdout with no extra wrapping, so the structure matches what the HTTP API returns. Run `vpvm <command> --format json | jq .` to explore the schema.

### Available Commands and Subcommands

- `list [--format text|json]` — List all virtual machines
- `watch [--interval <s>]` — Real-time VM monitor (auto-refreshes, press q to quit)
- `info <vmname> [--format text|json]` — Info about VM
- `ip <vmname>` — Show the IP address(es) of a running VM
- `stats <vmname> [--format text|json]` — Statistics about VM Usage
- `start <vmname>` — Start a VM (comma-separated names to start multiple)
- `stop <vmname>` — Force stop a VM (comma-separated names to stop multiple)
- `shutdown <vmname>` — Gracefully shutdown a VM (comma-separated names to shutdown multiple)
- `pause <vmname>` — Pause a VM (comma-separated names to pause multiple)
- `resume <vmname>` — Resume a VM (comma-separated names to resume multiple)
- `suspend <vmname>` — Suspend a VM to disk (comma-separated names to suspend multiple)
- `restart <vmname>` — Restart a VM (comma-separated names to restart multiple)
- `delete <vmname>` — Delete a VM
- `clone <vmname> <newname>` — Clone a VM
- `rename <vmname> <newname>` — Rename a VM
- `status <vmname>` — Get VM status (comma-separated names to check multiple)
- `screenshot <vmname> [--format png|jpeg] [--quality <0.1-1.0>] [--output <path>]` — Capture a screenshot of a running VM
- `logs <vmname> [--limit <n>] [--format text|json]` — Show recent log entries for a VM
- `logs clear <vmname>` — Clear all logs for a VM
- `unlock <vmname> [--password <password>]` — Unlock a password-protected VM to allow config changes
- `lock <vmname>` — Re-lock a password-protected VM
- `images list [--format text|json]` — List ISO and IPSW image files available in the VirtualProg directory
- `images browse [--format text|json]` — Show all available macOS IPSW and Linux ISO images (built-in and custom) with download status
- `images get <alias|name>` — Download an image by alias or display name
- `images status [--format text|json]` — Show active image downloads and their progress
- `images add --name <n> --url <u> --type <linux|macos>` — Add a custom download entry to the catalog
- `images remove <alias|name> [--delete-file]` — Remove a custom catalog entry
- `images cancel [<alias|name>]` — Cancel an active download; omit argument to list active downloads
- `images delete <alias|name>` — Delete a downloaded ISO or IPSW file from disk
- `create <vmname> --os <linux|macos> --cpu <n> --memory <mb> --disk <gb> --image <alias|name|filename>` — Create a new VM from scratch
- `snapshot` — Manage VM snapshots (subcommands: `list [--format text|json]`, `info [--format text|json]`, `create`, `restore`, `delete`, `update`, `createvm`, `createtemplate`)
- `checkpoint` — Manage VM checkpoints, macOS 27+ only (subcommands: `list [--format text|json]`, `info [--format text|json]`, `create`, `restore`, `delete`, `update`)
- `template` — Manage VM templates (subcommands: `list [--format text|json]`, `info [--format text|json]`, `create`, `clone`, `update`, `createvm`, `delete`, `config`)
- `network` — Manage host networks (subcommands: `list [--format text|json]`, `info [--format text|json]`, `sources [--format text|json]`, `add`, `update`, `delete`)
- `balloon` — Query or adjust memory balloon for a running Linux VM (subcommands: `info`, `set`)
- `usb` — Manage USB passthrough for a running VM, macOS 27+ only (subcommands: `list [--format text|json]`, `attach --index <n>`, `detach --index <n>`)
- `servermode --enable | --disable | --info` — Enable, disable, or query Server Mode
- `config` — Configure all VM settings (subcommands: `info [--format text|json]`, `general`, `cpu`, `display`, `sound`, `input`, `startup`, `security`, `schedule`, `auto-snapshot`, `rosetta`, `restore-image`, `boot-disk`, `webhook`, `disk`, `network`, `cd`, `serial`, `nbd` — the `list` subcommand of `disk`, `network`, `cd`, `serial`, and `nbd` all support `[--format text|json]`)
- `token` — Manage scoped API tokens (subcommands: `list`, `create`, `rotate`, `disable`, `enable`, `revoke`)

#### Examples

    vpvm list
    vpvm watch
    vpvm watch --interval 5
    vpvm start ubuntu-22.04
    vpvm stop ubuntu-22.04
    vpvm info ubuntu-22.04
    vpvm stats ubuntu-22.04
    vpvm status ubuntu-22.04
    vpvm clone ubuntu-22.04 ubuntu-dev
    vpvm rename ubuntu-22.04 ubuntu-lts
    vpvm screenshot ubuntu-22.04
    vpvm logs ubuntu-22.04
    vpvm logs ubuntu-22.04 --limit 100
    vpvm logs clear ubuntu-22.04
    vpvm images list
    vpvm images browse
    vpvm images get ubuntu
    vpvm images get sequoia
    vpvm images add --name "My ISO" --url "https://example.com/custom.iso" --type linux
    vpvm images remove AlpineVirtual --delete-file
    vpvm images delete ubuntu
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu
    vpvm create "My Mac" --os macos --cpu 4 --memory 8192 --disk 80 --image sequoia
    vpvm snapshot list ubuntu-22.04
    vpvm snapshot list ubuntu-22.04 --format json
    vpvm snapshot info ubuntu-22.04 before-update
    vpvm snapshot create ubuntu-22.04 before-update
    vpvm snapshot createvm ubuntu-22.04 before-update my-new-vm
    vpvm checkpoint list ubuntu-22.04
    vpvm checkpoint info ubuntu-22.04 Vanilla
    vpvm checkpoint create ubuntu-22.04 Vanilla
    vpvm checkpoint restore ubuntu-22.04 Vanilla
    vpvm checkpoint delete ubuntu-22.04 Vanilla
    vpvm checkpoint update ubuntu-22.04 Vanilla --new-name "clean-state" --notes "Fresh install"
    vpvm template list
    vpvm template list --format json
    vpvm template info "My Template"
    vpvm template create ubuntu-22.04 "My Template"
    vpvm template clone "My Template" "My Template Copy"
    vpvm template createvm "My Template" new-vm
    vpvm network sources
    vpvm network add "My Network" --type Shared --subnet 192.168.50.0
    vpvm network update "My Network" --new-name "Fast Network" --mtu 9000
    vpvm network delete "My Network"
    vpvm config info general ubuntu-22.04
    vpvm config info general ubuntu-22.04 --format json
    vpvm config info startup ubuntu-22.04
    vpvm config cpu ubuntu-22.04 --cpu 4 --memory 8192
    vpvm config general ubuntu-22.04 --new-name "dev-server" --headless true
    vpvm config security ubuntu-22.04 --password "mypass"
    vpvm config disk list ubuntu-22.04
    vpvm config disk add ubuntu-22.04 --size 50
    vpvm config disk resize ubuntu-22.04 --disk "Disk 1" --size 128
    vpvm config network add ubuntu-22.04 --type "Default (NAT)"
    vpvm template config cpu "My Template" --cpu 8 --memory 16384
    vpvm usb list ubuntu-22.04
    vpvm usb attach ubuntu-22.04 --index 0
    vpvm usb detach ubuntu-22.04 --index 0
    vpvm servermode --enable
    vpvm servermode --disable
    vpvm servermode --info
    vpvm token list
    vpvm token create --label "CI Pipeline" --vms "ubuntu-dev,ubuntu-test" --scope operator --expires 2026-12-31
    vpvm token create --label "Admin Tool" --scope admin
    vpvm token rotate <tokenId>
    vpvm token disable <tokenId>
    vpvm token enable <tokenId>
    vpvm token revoke <tokenId>

## 🆕 Getting Help

You can view detailed help for any command or subcommand using the `--help` flag:

    vpvm --help
    vpvm snapshot --help
    vpvm snapshot create --help
    vpvm template --help

This will display all available options, arguments, and descriptions for each command.

## 📖 Detailed Usage

### Starting a Virtual Machine

Start a stopped VM or resume a paused/suspended VM:

    vpvm start ubuntu-22.04

Output:

    Request completed successfully.
    Started ubuntu-22.04

Note: If the VM is paused or suspended, you'll be prompted to use the `resume` command instead.

### Stopping a Virtual Machine

Force stop a running VM (equivalent to pulling the power plug):

    vpvm stop ubuntu-22.04

Output:

    Request completed successfully.
    Stopped ubuntu-22.04

⚠️ Warning: This performs a hard shutdown. Use `shutdown` for graceful shutdown.

### Graceful Shutdown

Gracefully shutdown a running VM (sends ACPI shutdown signal):

    vpvm shutdown ubuntu-22.04

Output:

    Request completed successfully.
    Shutdown ubuntu-22.04

✅ Recommended: Always use `shutdown` instead of `stop` to avoid data corruption.

### Pausing and Resuming

Pause a running VM (freezes execution):

    vpvm pause ubuntu-22.04

Resume a paused VM:

    vpvm resume ubuntu-22.04

Use Cases: - Temporarily free up CPU resources - Quick pause/resume without full shutdown - Preserve exact VM state

### Suspending a Virtual Machine

Suspend VM to disk (saves memory state):

    vpvm suspend ubuntu-22.04

Benefits: - Saves RAM contents to disk - Instant resume later - No VM boot time required

Resume:

    vpvm resume ubuntu-22.04

### Restarting a Virtual Machine

Restart a running VM:

    vpvm restart ubuntu-22.04

Output:

    Request completed successfully.
    Restarted ubuntu-22.04

### Locking and Unlocking Password-Protected VMs

When a VM has a password set, it is locked by default. Locked VMs reject all control operations (start, stop, clone, etc.) and all configuration changes until explicitly unlocked.

#### Unlocking a VM

    vpvm unlock ubuntu-22.04

If `--password` is omitted, `vpvm` prompts for the password securely (input is hidden):

    Password for 'ubuntu-22.04':
    Request completed successfully.
    VM unlocked

You can also supply the password inline for scripting:

    vpvm unlock ubuntu-22.04 --password "mypassword"

The unlock is held in memory by VirtualProg for the current session. It is automatically cleared when the VM stops.

#### Locking a VM

To re-lock a VM before the session ends:

    vpvm lock ubuntu-22.04

    Request completed successfully.
    VM 'ubuntu-22.04' locked successfully

Only VMs that have a password configured can be locked. Attempting to lock a VM with no password returns an error.

#### Typical Workflow

    # Unlock the VM
    vpvm unlock ubuntu-22.04

    # Make configuration changes
    vpvm config cpu ubuntu-22.04 --cpu 4 --memory 8192

    # Re-lock when done
    vpvm lock ubuntu-22.04

### Checking VM Status

Get the current state of a virtual machine:

    vpvm status ubuntu-22.04

Possible States: - `running` - VM is currently running - `stopped` - VM is stopped - `paused` - VM is paused - `suspended` - VM is suspended to disk

Output:

    running

### Getting VM Info

Show full configuration and runtime details for a VM:

    vpvm info ubuntu-22.04

Output:

      Name            : ubuntu-22.04
      OS              : Linux
      Distro          : Ubuntu
      CPU             : 4
      Memory          : 8192 MB
      State           : running
      Disks           : Disk 1 (64 GB, Dynamic, VirtIo)
      Networks        : Network 1 (Default (NAT)) - 192.168.64.5
      IP Address      : 192.168.64.5
      Port Forwarding : Network 1: SSH 2222→22/TCP
      Favorite        : No
      Tag Color       : None
      Headless        : No
      Auto Start      : No
      Schedule        : Disabled
      Description     : Development server
      Created At      : 2025-01-15T00:00:00Z

The IP Address line shows only when the VM is running and an IP has been resolved. For VMs with multiple adapters, all IPs appear separated by commas. The Networks field also includes the IP inline alongside the adapter name and type.

### Getting a VM's IP Address

Print the current IP address(es) of a running VM — useful for scripting SSH connections and other automation:

    vpvm ip ubuntu-22.04

Output (running VM):

    192.168.64.5

For a VM with multiple network adapters, each resolved IP is printed on its own line:

    192.168.64.5
    10.0.1.42

Output (stopped VM):

    VM is not running

Output (VM still booting / IP not yet assigned):

    No IP address found (VM may still be booting)

#### Shell substitution

Because the command prints a bare IP with no decoration, it works directly in shell substitution:

    ssh user@$(vpvm ip ubuntu-22.04)

    scp file.tar.gz user@$(vpvm ip ubuntu-22.04):~/

### Getting VM Stats

Show usage statistics for a VM:

    vpvm stats ubuntu-22.04

Output:

      Name           : ubuntu-22.04
      Total Uptime   : 12h 34m
      Last Started   : 2025-06-01 09:00
      Last Stopped   : 2025-06-01 21:34
      Total Sessions : 5

### Bulk Operations on Multiple VMs

The `start`, `stop`, `shutdown`, `pause`, `resume`, `suspend`, `restart`, and `status` commands all accept a comma-separated list of VM names, so you can act on multiple VMs in a single command.

    # Start multiple VMs at once
    vpvm start ubuntu-22.04,debian-12,macos-sonoma

    # Shutdown multiple VMs
    vpvm shutdown ubuntu-22.04,debian-12

    # Check status of several VMs
    vpvm status ubuntu-22.04,debian-12,macos-sonoma

Multi-VM output — each VM is listed on its own line with its result:

    ubuntu-22.04: Started ubuntu-22.04
    debian-12: Started debian-12
    macos-sonoma: error – VM is already running

For `status`, each line shows the current state:

    ubuntu-22.04: running
    debian-12: stopped
    macos-sonoma: running

VM names with spaces — wrap the whole comma-separated string in quotes:

    vpvm start "My Dev VM,Work VM,Test VM"

Note: `delete`, `clone`, and `rename` remain single-VM commands — bulk execution is intentionally not supported for destructive or two-argument operations.

### Listing All Virtual Machines

Display all VMs with their current state, OS, CPU, memory, and IP address:

    vpvm list

Output:

    ─────────────────────────────────────────────────────────────────────────
     NAME          STATE          OS       CPU  MEMORY      IP ADDRESS
    ─────────────────────────────────────────────────────────────────────────
     ubuntu-22.04  ● running      Linux      4  8192 MB     192.168.64.5
     macos-sonoma  ○ stopped      macOS      2  4096 MB     -
     debian-12     ○ stopped      Linux      2  2048 MB     -
    ─────────────────────────────────────────────────────────────────────────
     3 VMs

The IP ADDRESS column appears only when at least one VM is running and has a resolved IP. Stopped VMs show `-`. For VMs with multiple network adapters, all IPs are shown separated by commas.

### Cloning a Virtual Machine

Create a copy of an existing VM:

    vpvm clone ubuntu-22.04 ubuntu-dev

Output:

    Request completed successfully.
    Cloning ubuntu-22.04 to ubuntu-dev

Requirements: - Source VM must be stopped - New VM name must be unique - Sufficient disk space required

Use Cases: - Create development/testing environments - Duplicate VM configurations - Quick VM provisioning

### Renaming a Virtual Machine

Rename an existing VM:

    vpvm rename ubuntu-22.04 ubuntu-dev

Output:

    Request completed successfully.
    Renamed ubuntu-22.04 to ubuntu-dev

Requirements: - VM must be stopped - New name must be unique

### Deleting a Virtual Machine

Permanently delete a VM:

    vpvm delete test-vm

Output:

    Request completed successfully.
    Deleted test-vm

⚠️ Warning: This action cannot be undone. The VM and all its data will be permanently deleted.

Requirements: - VM must be stopped - VM must not be password protected

### Configuring a VM

The `config` command group lets you change any setting on a VM. Each sub-command targets a specific settings panel. The VM does not need to be stopped for most settings — hardware changes (CPU, memory, display) typically require a stop/start.

#### Syntax

    vpvm config <sub-command> <vmname> [options]

Use `vpvm config <sub-command> --help` to see all options for a specific sub-command.

#### Inspecting Current Values

Before modifying a setting, use `config info` to see the current values for any section:

    vpvm config info <section> <vmname>

Supported sections: `general`, `cpu`, `display`, `sound`, `input`, `startup`, `security`, `schedule`, `auto-snapshot`, `rosetta`, `boot-disk`, `restore-image`

Examples:

    # See current general settings before renaming
    vpvm config info general ubuntu-22.04

    # Check startup and autopause settings
    vpvm config info startup ubuntu-22.04

    # Review security flags before changing them
    vpvm config info security ubuntu-22.04

    # Check current schedule
    vpvm config info schedule ubuntu-22.04

Sample output (`config info startup`):

      Auto Start           : false
      Startup Delay (s)    : 0
      Sleep Behavior       : Do Nothing
      Shutdown Behavior    : Shutdown
      Window Close         : Ask
      Auto Pause           : false
      Auto Pause Minutes   : 30
      Auto Pause Action    : Pause
      Battery Pause        : false
      Battery Level (%)    : 20
      Battery Pause Action : Pause

The same command works for templates:

    vpvm template config info startup "My Template"

#### General settings

    # Rename a VM
    vpvm config general ubuntu-22.04 --new-name "dev-server"

    # Set a description and enable headless mode
    vpvm config general ubuntu-22.04 --descr "CI build machine" --headless true

    # Enable nested virtualisation
    vpvm config general ubuntu-22.04 --nested-virt true

Option | Description
--- | ---
`--new-name` | New VM name
`--descr` | Description / notes
`--distro` | Distro / version (e.g. `Ubuntu`, `Debian`, `Sequoia`)
`--headless true\|false` | Start without opening a display window
`--fullscreen true\|false` | Open in fullscreen on start
`--nested-virt true\|false` | Enable nested virtualisation
`--entropy true\|false` | Enable VirtIO entropy device

#### CPU & Memory

    vpvm config cpu ubuntu-22.04 --cpu 4 --memory 8192
    vpvm config cpu ubuntu-22.04 --balloon true

Option | Description
--- | ---
`--cpu` | Number of CPU cores
`--memory` | RAM in MB
`--balloon true\|false` | Enable memory balloon device

#### Display

    vpvm config display ubuntu-22.04 --auto false --width 1920 --height 1080 --ppi 96

Option | Description
--- | ---
`--active true\|false` | Show or hide the display window
`--auto true\|false` | `true` = auto resolution (follows host); `false` = force resolution
`--width` / `--height` | Resolution in pixels (used when `--auto false`)
`--ppi` | Pixels per inch

#### Sound & Input

    vpvm config sound ubuntu-22.04 --input true --output true
    vpvm config input ubuntu-22.04 --keyboard Mac --mouse Mac

#### Startup & Shutdown

    vpvm config startup ubuntu-22.04 --auto-start true --sleep-behavior Pause
    vpvm config startup ubuntu-22.04 --auto-pause true --auto-pause-minutes 30 --auto-pause-action Suspend

Option | Values
--- | ---
`--auto-start` | `true\|false`
`--startup-delay` | Seconds
`--sleep-behavior` | `"Do Nothing"`, `Pause`, `Suspend`, `Shutdown`, `Stop`
`--shutdown-behavior` | `"Do Nothing"`, `Suspend`, `Shutdown`, `Stop`
`--window-close` | `Ask`, `Suspend`, `Shutdown`, `Stop`, `Background`
`--auto-pause` | `true\|false`
`--auto-pause-minutes` | Minutes of inactivity
`--auto-pause-action` | `"Do Nothing"`, `Pause`, `Suspend`, `Shutdown`, `Stop`
`--auto-pause-battery` | `true\|false`
`--auto-pause-battery-level` | Battery percentage threshold
`--auto-pause-battery-action` | `"Do Nothing"`, `Pause`, `Suspend`, `Shutdown`, `Stop`

#### Security

    # Set a password (plain text — hashed automatically)
    vpvm config security ubuntu-22.04 --password "mypassword"

    # Remove the password
    vpvm config security ubuntu-22.04 --clear-password

    # Disable clipboard sharing
    vpvm config security ubuntu-22.04 --clipboard false

Option | Description
--- | ---
`--password` | Set a new password (plain text, hashed before sending)
`--clear-password` | Remove the existing password
`--clipboard true\|false` | Allow clipboard access
`--screenshot true\|false` | Allow screenshots
`--screen-record true\|false` | Allow screen recording
`--stats true\|false` | Allow stats access

#### Schedule

    vpvm config schedule ubuntu-22.04 --enabled true --days "1,2,3,4,5" --start-time "09:00" --stop-time "18:00"

Option | Description
--- | ---
`--enabled true\|false` | Enable the schedule
`--days` | Comma-separated day numbers: 1=Mon … 7=Sun
`--start-time` | Start time in HH:mm
`--stop-time` | Stop time in HH:mm
`--clear-start-time` | Remove the scheduled start time
`--clear-stop-time` | Remove the scheduled stop time

#### Auto Snapshots

    vpvm config auto-snapshot ubuntu-22.04 --enabled true --type Daily --max 7 --prefix "auto"

Option | Values
--- | ---
`--enabled` | `true\|false`
`--type` | `On Start`, `Daily`, `Weekly`, `Monthly`, `On Shutdown`
`--max` | Maximum snapshots to keep
`--prefix` | Snapshot name prefix

#### Rosetta (Linux VMs only)

    vpvm config rosetta ubuntu-22.04 --enabled true --mount-name "rosetta"

#### Boot Disk & Restore Image

    # Set boot device by name (disk, CD/DVD, or NBD name), Auto, or Recovery (macOS only)
    vpvm config boot-disk ubuntu-22.04 --device "Disk 1"

    # Set macOS restore image
    vpvm config restore-image my-macos-vm --image sequoia

#### Webhooks

    # Add a webhook URL
    vpvm config webhook ubuntu-22.04 --add "https://hooks.example.com/vm-state"

    # Remove a webhook URL
    vpvm config webhook ubuntu-22.04 --remove "https://hooks.example.com/vm-state"

    # List current webhook URLs
    vpvm config webhook ubuntu-22.04 --list

    # Remove all webhook URLs
    vpvm config webhook ubuntu-22.04 --clear

#### Disk Management

    # List disks (name, UUID, size, type, interface)
    vpvm config disk list ubuntu-22.04

    # Add a new disk
    vpvm config disk add ubuntu-22.04 --size 50 --interface VirtIo --type Dynamic

    # Remove a disk (by name or UUID)
    vpvm config disk remove ubuntu-22.04 --disk "Disk 2"

    # Update disk settings
    vpvm config disk update ubuntu-22.04 --disk "Disk 1" --cache-mode Auto --read-only false

    # Resize a disk (VM must be stopped; shrinking is not supported)
    vpvm config disk resize ubuntu-22.04 --disk "Disk 1" --size 128

    # Relocate macOS recovery partition after resizing a fixed disk
    vpvm config disk relocate-recovery macos-vm --disk "Disk 1"

Option | Description
--- | ---
`--disk` | Disk name (e.g. `"Disk 1"`) or UUID
`--size` | Size in GB
`--interface` | `VirtIo\|NVME`
`--type` | `Dynamic\|Fixed`
`--cache-mode` | `Auto\|Cached\|Uncached`
`--sync-mode` | `Full\|FSync\|None`
`--read-only` | `true\|false`

#### Network Adapter Management

    # List network adapters (different from host networks)
    vpvm config network list ubuntu-22.04

    # Add a network adapter
    vpvm config network add ubuntu-22.04 --type "Default (NAT)"

    # Remove a network adapter
    vpvm config network remove ubuntu-22.04 --net "Network 1"

    # Update adapter settings
    vpvm config network update ubuntu-22.04 --net "Network 1" --type "en0"

    # Add a port forwarding rule
    vpvm config network pf-add ubuntu-22.04 --net "Network 1" --host-port 2222 --guest-port 22

    # Remove a port forwarding rule
    vpvm config network pf-remove ubuntu-22.04 --net "Network 1" --rule "SSH"

    # List port forwarding rules
    vpvm config network pf-list ubuntu-22.04 --net "Network 1"

> Run `vpvm network sources` to see all valid network type values.

#### CD/DVD Management

    vpvm config cd list ubuntu-22.04
    vpvm config cd add ubuntu-22.04 --image ubuntu
    vpvm config cd remove ubuntu-22.04 --cd "CD/DVD 1"
    vpvm config cd update ubuntu-22.04 --cd "CD/DVD 1" --image alpine

#### Serial Port Management

    vpvm config serial list ubuntu-22.04
    vpvm config serial add ubuntu-22.04 --mode Console --theme Dark
    vpvm config serial remove ubuntu-22.04 --serial "Serial Port 1"

#### Network Block Device (NBD) Management

    vpvm config nbd list ubuntu-22.04
    vpvm config nbd add ubuntu-22.04 --url nbd://192.168.1.5/disk0
    vpvm config nbd remove ubuntu-22.04 --nbd "Network Block Device 1"

### Listing Available Boot Images

Before creating a VM, list the ISO and IPSW files available in the VirtualProg directory:

    vpvm images list

Output:

    ISO images (Linux):

      ubuntu-22.04-server.iso
      debian-12.iso

    IPSW images (macOS):

      (none)

Place your ISO or IPSW files directly in the VirtualProg data directory to make them available here.

### Creating a VM from Scratch

Create a new VM with the same parameters as Quick Create in the GUI:

    # Create a Linux VM — using a catalog alias (recommended)
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu

    # Create a Linux VM — using the full catalog name
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image "Ubuntu 26.04 LTS"

    # Create a Linux VM — using a raw filename (still works)
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu.iso

    # Create a macOS VM (arm64 only)
    vpvm create "My Mac" --os macos --cpu 4 --memory 8192 --disk 80 --image sequoia

Output:

    Request completed successfully.
    VM 'My Ubuntu' creation started (Linux, 2 CPU, 4096 MB, 64 GB, image: Ubuntu_26.04_arm64.iso). Use 'vpvm info My Ubuntu' to check when ready.

Parameters:

Option | Required | Description
--- | --- | ---
`<vmname>` | ✅ | Name for the new VM
`--os` | ✅ | `linux` or `macos`
`--cpu` | ✅ | Number of CPU cores
`--memory` | ✅ | RAM in MB (e.g. `4096` for 4 GB)
`--disk` | ✅ | Disk size in GB
`--image` | ✅ | Catalog alias, full name, or filename (e.g. `ubuntu`, `"Ubuntu 26.04 LTS"`, `Ubuntu_26.04_arm64.iso`). Run `vpvm images browse` to see all available aliases.

Requirements: - VirtualProg must be running - The image must be downloaded — use `vpvm images get <alias>` first if needed - Linux VMs require an `.iso` file; macOS VMs require an `.ipsw` file - VM name must be unique

### Downloading Boot Images

Download macOS IPSW or Linux ISO images directly to the VirtualProg directory. The download happens inside the VirtualProg app, so it works for both local and remote connections.

#### Browsing the Catalog

Show all available images — built-in and custom — with their current download status:

    vpvm images browse

Output:

    TYPE    ALIAS               NAME                      FILE                             STATUS
    ────────────────────────────────────────────────────────────────────────────────────────────
    macOS   latest              Latest Supported          RestoreImage.ipsw                Not Downloaded
    macOS   tahoe               Tahoe (26.4.1)            Tahoe_26.4.1.ipsw               Not Downloaded
    macOS   sequoia             Sequoia (15.6.1)          Sequoia_15.6.1.ipsw             ✓ Downloaded
    Linux   ubuntu              Ubuntu 26.04 LTS          Ubuntu_26.04_arm64.iso           Not Downloaded
    Linux   ubuntu-server       Ubuntu Server 26.04 LTS   Ubuntu_Server_26.04_arm64.iso   Not Downloaded
    ...
    Linux   custom-a1b2c3d4     My Custom ISO             my_custom_iso.iso                Not Downloaded  [custom]

Custom entries are shown inline alongside built-in ones, marked with a `[custom]` tag.

#### Downloading an Image

Use `vpvm images get` with an alias or display name to start a download. Both built-in and custom entries are supported — there is no separate command for each type.

    # Download by alias
    vpvm images get ubuntu
    vpvm images get sequoia
    vpvm images get latest

    # Download by display name (quote names with spaces)
    vpvm images get "Ubuntu 26.04 LTS"
    vpvm images get "Sequoia (15.6.1)"
    vpvm images get "My Custom ISO"

Available macOS aliases:

Alias | macOS Version
--- | ---
`latest` | Latest Supported (auto-detected)
`tahoe` | Tahoe 26.4.1
`sequoia` | Sequoia 15.6.1
`sonoma` | Sonoma 14.6.1
`ventura` | Ventura 13.6
`monterey` | Monterey 12.6.1

Available Linux aliases:

Alias | Distribution
--- | ---
`ubuntu` | Ubuntu 26.04 LTS
`ubuntu-server` | Ubuntu Server 26.04 LTS
`fedora` | Fedora 43 Workstation
`opensuse-leap` | openSUSE Leap 16.0
`opensuse-tumbleweed` | openSUSE Tumbleweed
`alpine` | Alpine 3.23.4
`kali` | Kali 2026.1
`popos` | Pop!_OS 24.04
`debian` | Debian 13.4.0
`nixos` | NixOS 25.11
`rocky` | Rocky 10.1

> Note: macOS IPSW downloads are only supported on Apple Silicon (arm64).

#### Live Download Progress

While downloading, the CLI shows an inline progress bar with speed and ETA:

    Downloading Ubuntu_26.04_arm64.iso   63% [============>       ]  2.1 GB / 3.3 GB  18.2 MB/s  ETA 1m 04s

When complete:

    ✅ Ubuntu_26.04_arm64.iso — Complete (3.3 GB)

#### Checking Download Status

Use `vpvm images status` to see all currently active downloads and their progress:

    vpvm images status

Example output:

    ubuntu-26.04-live-server-arm64.iso  [downloading]   42%

#### Cancelling a Download

Press Ctrl+C during an active `vpvm images get` command to cancel gracefully. Or cancel by alias or name from another terminal:

    # Cancel by alias
    vpvm images cancel ubuntu

    # Cancel by display name
    vpvm images cancel "Ubuntu 26.04 LTS"

    # Run with no argument to see all active downloads and their identifiers
    vpvm images cancel

#### Deleting a Downloaded Image

Remove a downloaded ISO or IPSW from the VirtualProg directory. Any active download for the file is cancelled automatically before deletion.

    # Delete by alias
    vpvm images delete sequoia
    vpvm images delete ubuntu

    # Delete by display name
    vpvm images delete "Sequoia (15.6.1)"
    vpvm images delete "Ubuntu 26.04 LTS"

#### Typical Workflow

    # 1. See what's available and what's already downloaded
    vpvm images browse

    # 2. Download the image you need (alias or name, your choice)
    vpvm images get ubuntu

    # 3. Create the VM using the alias — no need to type the full filename
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu

    # 4. Clean up the ISO after creating the VM
    vpvm images delete ubuntu

### Custom Image Catalog

In addition to the built-in images, you can add your own ISO or IPSW download URLs to the catalog. Custom entries appear alongside built-in ones in both the GUI and `vpvm images browse`.

#### Adding a Custom Entry

    vpvm images add --name "Ubuntu Nightly" \
      --url "https://cdimage.ubuntu.com/daily-live/current/noble-desktop-arm64.iso" \
      --type linux

    # macOS IPSW example
    vpvm images add --name "My IPSW" \
      --url "https://example.com/custom.ipsw" \
      --type macos

- `--type` must be `linux` or `macos`
- The alias (e.g. `custom-a1b2c3d4`) is auto-generated and shown in `vpvm images browse`
- The filename is auto-detected from the URL; use `--file` to override it

#### Downloading a Custom Entry

Custom entries use the same `get` command as built-in images — just pass the alias or name:

    # Use the auto-generated alias
    vpvm images get custom-a1b2c3d4

    # Or use the display name
    vpvm images get "Ubuntu Nightly"

#### Removing a Custom Entry

    # Remove the catalog entry only (downloaded file kept on disk)
    vpvm images remove AlpineVirtual

    # Remove the catalog entry AND delete the downloaded ISO/IPSW from disk
    vpvm images remove AlpineVirtual --delete-file

    # Also works with the auto-generated alias
    vpvm images remove custom-a1b2c3d4 --delete-file

- You can pass the entry name (e.g. `AlpineVirtual`) or the auto-generated alias (e.g. `custom-a1b2c3d4`)
- Without `--delete-file`, the downloaded file is left on disk
- With `--delete-file`, the file is deleted immediately with no confirmation

### Taking a Screenshot

Capture the current display of a running VM and save it as an image file:

    vpvm screenshot ubuntu-22.04

Output:

    ✅ Screenshot saved: ubuntu-22.04-1746700800.png

By default, the screenshot is saved as a PNG file in the current directory, named `<vmname>-<timestamp>.png`.

#### Options

Option | Description | Default
--- | --- | ---
`--output <path>` | File path to save the screenshot | `<vmname>-<timestamp>.png` in current directory
`--format png\|jpeg` | Image format | `png`
`--quality <0.1-1.0>` | JPEG compression quality (jpeg only) | `0.85`

#### Examples

    # PNG screenshot saved to the current directory
    vpvm screenshot ubuntu-22.04

    # Save to a specific path
    vpvm screenshot ubuntu-22.04 --output ~/Desktop/vm.png

    # JPEG at default quality
    vpvm screenshot ubuntu-22.04 --format jpeg

    # JPEG at reduced quality (smaller file size)
    vpvm screenshot ubuntu-22.04 --format jpeg --quality 0.6 --output ~/Desktop/vm.jpg

    # Screenshot from a remote VirtualProg instance
    vpvm screenshot ubuntu-22.04 --server 192.168.1.10 --port 49152

Requirements: - The VM must be running - The VM window must be open in VirtualProg, or Background Screenshots must be enabled in Settings

### Viewing VM Logs

Display the most recent log entries for a VM:

    vpvm logs ubuntu-22.04

Output:

      50 log entries

      2026-01-01 12:00:00  INFO   VM started successfully
      2026-01-01 12:00:05  ERROR  Disk mount failed

By default, the last 50 entries are shown. Use `--limit` to adjust:

    vpvm logs ubuntu-22.04 --limit 100

#### Options

Option | Description | Default
--- | --- | ---
`--limit <n>` | Maximum number of log entries to display | `50`

Requirements: - Logging must be enabled in VirtualProg (Settings > Logging)

### Clearing VM Logs

Remove all stored log entries for a specific VM:

    vpvm logs clear ubuntu-22.04

Output:

    Logs cleared for 'ubuntu-22.04'

Requirements: - Logging must be enabled in VirtualProg (Settings > Logging)

### Monitoring VMs in Real Time

Display a live, auto-refreshing table of all VMs and their current state:

    vpvm watch

Output:

    VirtualProg Monitor                              Updated: 2026-01-01 12:00:05
    ──────────────────────────────────────────────────────────────────────────────
     Name            State        OS       CPU    Memory      IP Address
    ──────────────────────────────────────────────────────────────────────────────
     ubuntu-22.04    ● running    Linux      4    8192 MB     192.168.64.5
     macos-sequoia   ○ stopped    macOS      2    4096 MB     -
     dev-server      ◐ paused     Linux      2    2048 MB     -
    ──────────────────────────────────────────────────────────────────────────────
     3 VMs                                      Press q to quit · interval: 2s

State indicators: `●` running · `○` stopped · `◐` paused or suspended

#### Options

Option | Description | Default
--- | --- | ---
`--interval <s>` | Refresh interval in seconds | `2`

#### Examples

    # Monitor with default 2-second refresh
    vpvm watch

    # Slower refresh for low-bandwidth remote connections
    vpvm watch --interval 10

    # Monitor a remote VirtualProg instance
    vpvm watch --server 192.168.1.10 --port 49152 --token <token>

Press `q`, `Q`, or `ESC` to exit.

## 📸 Working with Snapshots

Snapshots allow you to capture and restore VM states at specific points in time. Learn more about snapshots in the Snapshots documentation.

### Creating a Snapshot

Capture the current state of a VM:

    vpvm snapshot create ubuntu-22.04 backup-before-update

To include optional notes:

    vpvm snapshot create ubuntu-22.04 backup-before-update --notes "Before kernel upgrade"

Output:

    Request completed successfully.
    Creating snapshot backup-before-update for ubuntu-22.04

Requirements: - VM must be stopped (not paused or suspended) - Snapshot name must be unique for that VM - Sufficient disk space required

Best Practices: - Create snapshots before major updates - Use descriptive names (include dates or purposes) - Use `--notes` to record the reason or context for the snapshot - Don't rely on snapshots for long-term backups

### Listing Snapshots

View all snapshots for a specific VM:

    vpvm snapshot list ubuntu-22.04

Output:

    clean-install
    backup-before-update
    pre-kernel-upgrade

### Snapshot Details

Get detailed information about a specific snapshot, including its hardware configuration captured at the time of creation:

    vpvm snapshot info ubuntu-22.04 backup-before-update

Output:

      Name             : backup-before-update
      VM               : ubuntu-22.04
      Auto             : No
      Created At       : 2025-04-10T14:32:00Z
      OS Distro        : Ubuntu
      CPU              : 4
      Memory           : 8192 MB
      Disks            : 64 GB (Dynamic)
      Networks         : Default (NAT)
      Port Forwarding  : None
      Headless         : No
      Auto Start       : No
      Schedule         : Disabled

Notes: The `Notes` field is shown only if notes were added when the snapshot was created.

### Restoring a Snapshot

Revert a VM to a previous snapshot state:

    vpvm snapshot restore ubuntu-22.04 backup-before-update

Output:

    Request completed successfully.
    Restoring snapshot backup-before-update for ubuntu-22.04

⚠️ Warning: This will overwrite the current VM state. Current data will be lost unless you create a snapshot first.

Requirements: - VM must be stopped - Snapshot must exist

### Deleting a Snapshot

Remove a snapshot to free up disk space:

    vpvm snapshot delete ubuntu-22.04 old-snapshot

Output:

    Request completed successfully.
    Deleted snapshot old-snapshot for ubuntu-22.04

### Updating a Snapshot

Rename a snapshot or update its notes without creating a new one:

    vpvm snapshot update ubuntu-22.04 backup-before-update --new-name "pre-kernel-upgrade"

To update notes only:

    vpvm snapshot update ubuntu-22.04 pre-kernel-upgrade --notes "Kernel 6.8, clean state"

To update both at once:

    vpvm snapshot update ubuntu-22.04 pre-kernel-upgrade --new-name "kernel-6.8-base" --notes "Kernel 6.8, clean state"

Output:

    Request completed successfully.
    Snapshot updated successfully

Notes: - Both `--new-name` and `--notes` are optional — omit either to leave it unchanged - The new name must be unique among snapshots for that VM - Passing `--notes ""` clears the existing notes

### Creating a VM from a Snapshot

Deploy a new VM directly from a snapshot — no need to restore it first:

    vpvm snapshot createvm ubuntu-22.04 before-update my-new-vm

Output:

    Request completed successfully.
    Creating VM my-new-vm from snapshot before-update of ubuntu-22.04

Requirements: - New VM name must be unique - Snapshot must exist for the specified VM

### Creating a Template from a Snapshot

Create a reusable template directly from a snapshot — no need to restore it into a VM first:

    vpvm snapshot createtemplate ubuntu-22.04 before-update "Ubuntu 22.04 Clean"

To include optional notes:

    vpvm snapshot createtemplate ubuntu-22.04 before-update "Ubuntu 22.04 Clean" --notes "Clean install, no extra packages"

Output:

    Request completed successfully.
    Creating template 'Ubuntu 22.04 Clean' from snapshot 'before-update' of 'ubuntu-22.04'

Requirements: - VM must not be password protected - Template name must be unique - Snapshot must exist for the specified VM

## 🔖 Working with Checkpoints

> macOS 27 or later required. Checkpoint commands are only available when VirtualProg is running on macOS 27 (Tahoe) or newer. On earlier hosts, all `checkpoint` subcommands return an error.

Checkpoints are fast, space-efficient point-in-time saves of a VM's disk state. Unlike snapshots, checkpoints use a layered overlay stack — each checkpoint freezes the current layer and adds a new writable layer on top. This makes creation and restore very fast, and uses only the space needed for changes between layers.

The checkpoint stack is linear: the most recent checkpoint is always at the top. Because of this, only the top (Latest) checkpoint can be deleted, and only checkpoints below the Latest can be restored.

Requirements for all checkpoint commands:

- Host must be running macOS 27 or later
- The VM must be stopped
- The VM's primary disk must be a Dynamic disk

Learn more about checkpoints in the Checkpoints documentation.

### Creating a Checkpoint

Save the current disk state of a stopped VM:

    vpvm checkpoint create ubuntu-22.04 Vanilla

To include optional notes:

    vpvm checkpoint create ubuntu-22.04 Vanilla --notes "Fresh install, no packages"

Output:

    Request completed successfully.
    Creating checkpoint 'Vanilla' for 'ubuntu-22.04'

Requirements: - VM must be stopped - Checkpoint name must be unique for that VM - VM must have at least one Dynamic disk

### Listing Checkpoints

View all checkpoints for a VM, ordered from oldest to newest:

    vpvm checkpoint list ubuntu-22.04

Output:

    CHECKPOINT
      Vanilla   2026-06-13T10:00:00Z
      DevTools  2026-06-13T11:30:00Z

The last item in the list is the Latest (most recent) checkpoint — the current state of the disk stack.

### Checkpoint Details

Get the metadata for a specific checkpoint:

    vpvm checkpoint info ubuntu-22.04 DevTools

Output:

      Name     : DevTools
      Date     : 2026-06-13T11:30:00Z
      Favorite : No
      Notes    : Added Xcode and Homebrew

The `Notes` field is shown only when notes were added. Use `--format json` to get the raw API response.

### Restoring a Checkpoint

Rewind the VM's disk to the state captured at an earlier checkpoint:

    vpvm checkpoint restore ubuntu-22.04 Vanilla

Output:

    Request completed successfully.
    Restoring checkpoint 'Vanilla' for 'ubuntu-22.04'

> Only checkpoints below the Latest can be restored. The Latest checkpoint is the current disk state — there is nothing to restore to.

Requirements: - VM must be stopped - The checkpoint must not be the Latest (most recent) checkpoint

### Deleting a Checkpoint

Remove the most recent checkpoint from the stack:

    vpvm checkpoint delete ubuntu-22.04 DevTools

Output:

    Request completed successfully.
    Deleting checkpoint 'DevTools' for 'ubuntu-22.04'

> Only the Latest (most recent) checkpoint can be deleted. Removing an older checkpoint in the middle of the stack would break all newer layers built on top of it.

Requirements: - VM must be stopped - The checkpoint must be the Latest (most recent) checkpoint

### Updating a Checkpoint

Rename a checkpoint or update its notes without creating a new one:

    vpvm checkpoint update ubuntu-22.04 Vanilla --new-name "clean-install"

To update notes only:

    vpvm checkpoint update ubuntu-22.04 clean-install --notes "Fresh install, SSH enabled"

To update both at once:

    vpvm checkpoint update ubuntu-22.04 clean-install --new-name "base" --notes "Fresh install, SSH enabled"

Output:

    Request completed successfully.
    Checkpoint updated successfully

Notes: - Both `--new-name` and `--notes` are optional — omit either to leave it unchanged - The new name must be unique among checkpoints for that VM - Passing `--notes ""` clears the existing notes

### Checkpoint Quick Reference

    # List all checkpoints for a VM
    vpvm checkpoint list ubuntu-22.04

    # Get details for a specific checkpoint
    vpvm checkpoint info ubuntu-22.04 Vanilla

    # Create a checkpoint (VM must be stopped)
    vpvm checkpoint create ubuntu-22.04 Vanilla
    vpvm checkpoint create ubuntu-22.04 Vanilla --notes "Before installing Xcode"

    # Restore a checkpoint (VM must be stopped; cannot restore the Latest)
    vpvm checkpoint restore ubuntu-22.04 Vanilla

    # Delete the most recent checkpoint (VM must be stopped; Latest only)
    vpvm checkpoint delete ubuntu-22.04 DevTools

    # Rename a checkpoint
    vpvm checkpoint update ubuntu-22.04 Vanilla --new-name "clean-install"

    # Update notes only
    vpvm checkpoint update ubuntu-22.04 clean-install --notes "SSH enabled, no extra packages"

    # Get raw JSON output
    vpvm checkpoint list ubuntu-22.04 --format json
    vpvm checkpoint info ubuntu-22.04 Vanilla --format json

## 📦 Working with Templates

Templates enable quick VM deployment from pre-configured states. Learn more in the Templates documentation.

### Creating a Template

Create a reusable template from an existing VM:

    vpvm template create ubuntu-22.04 "Ubuntu 22.04 Base"

To include optional notes:

    vpvm template create ubuntu-22.04 "Ubuntu 22.04 Base" --notes "Base install with dev tools"

Output:

    Request completed successfully.
    Creating template Ubuntu 22.04 Base from ubuntu-22.04

Requirements: - VM must be stopped (not paused or suspended) - VM must not be password protected - Template name must be unique

Best Practices: - Create templates from clean, configured VMs - Include software and settings you frequently use - Use `--notes` to document what's included in the template

### Listing Templates

View all available templates:

    vpvm template list

Output:

    Ubuntu 22.04 Base
    macOS Sonoma Clean
    Debian 12 Dev

### Getting Template Info

Show full details for a template:

    vpvm template info "Ubuntu 22.04 Base"

Output:

      Name           : Ubuntu 22.04 Base
      Source VM      : ubuntu-22.04
      OS             : Linux
      Distro         : Ubuntu
      CPU            : 4
      Memory         : 8192 MB
      Disks          : disk0: 64 GB
      Networks       : net0: Default (NAT)
      Port Forwarding: host:2222 → guest:22
      Headless       : No
      Auto Start     : No
      Schedule       : -
      Notes          : Base install with dev tools
      Created At     : 2025-01-15

### Cloning a Template

Create a copy of an existing template under a new name:

    vpvm template clone "Ubuntu 22.04 Base" "Ubuntu 22.04 Staging"

To include optional notes:

    vpvm template clone "Ubuntu 22.04 Base" "Ubuntu 22.04 Staging" --notes "Staging copy"

Output:

    Request completed successfully.
    Cloning template 'Ubuntu 22.04 Base' as 'Ubuntu 22.04 Staging'

Requirements: - Source template must exist - New template name must be unique

### Creating a VM from a Template

Deploy a new VM from a template:

    vpvm template createvm "Ubuntu 22.04 Base" my-new-vm

Output:

    Request completed successfully.
    Creating VM my-new-vm from template Ubuntu 22.04 Base

Requirements: - New VM name must be unique

### Deleting a Template

Remove a template you no longer need:

    vpvm template delete "Old Template"

Output:

    Request completed successfully.
    Deleted template Old Template

### Updating a Template

Rename a template or update its notes without recreating it:

    vpvm template update "My Template" --new-name "Ubuntu 24.04 Base"

To update notes only:

    vpvm template update "Ubuntu 24.04 Base" --notes "Clean install, SSH enabled"

To update both at once:

    vpvm template update "Ubuntu 24.04 Base" --new-name "ubuntu-base" --notes "Clean install, SSH enabled"

Output:

    Request completed successfully.
    Template updated successfully

Notes: - Both `--new-name` and `--notes` are optional — omit either to leave it unchanged - The new name must be unique among all templates - Passing `--notes ""` clears the existing notes

## 🌐 Managing Custom Networks

> macOS Tahoe 26 or later required. The `network add`, `network update`, and `network delete` commands require VirtualProg to be running on macOS 26 (Tahoe) or newer.

Custom networks let you define shared (NAT) or host-only networks with a specific subnet, mask, and MTU — giving VMs a stable, predictable IP range and isolating traffic as needed.

### Listing Networks

    vpvm network list

Output:

    Default (NAT)
    Dev Network
    Isolated

### Viewing Network Details

    vpvm network info "Dev Network"

Output:

      Name           : Dev Network
      Type           : Shared
      Enabled        : Yes
      Subnet         : 192.168.50.0
      Mask           : 255.255.255.0
      MTU            : 1500
      IPv6           : No
      IPv6 Prefix    : -
      Ext. Interface : -

### Creating a Network

    vpvm network add <name> [options]

Option | Description | Default
--- | --- | ---
`--type` | `Shared` (NAT) or `Host` (host-only) | `Shared`
`--subnet` | Network address ending in `.0` (e.g. `192.168.50.0`). Random if omitted | (random)
`--mask` | Subnet mask | `255.255.255.0`
`--mtu` | MTU value 1280–9000 | `1500`
`--interface` | Physical interface ID for Shared type (e.g. `en0`). Omit for Automatic | (Automatic)
`--ipv6` | Enable IPv6 (Shared type only) | off
`--ipv6-prefix` | IPv6 ULA prefix starting with `fd` (required when `--ipv6` is set) | —
`--disabled` | Create the network in disabled state | (enabled)

Examples:

    # Shared network with a specific subnet
    vpvm network add "Dev Network" --type Shared --subnet 192.168.50.0

    # Host-only network
    vpvm network add "Isolated" --type Host --subnet 10.99.0.0 --mask 255.255.0.0

    # Shared network with IPv6
    vpvm network add "IPv6 Net" --type Shared --subnet 172.20.10.0 --ipv6 --ipv6-prefix "fd12:3456::"

    # Large MTU for high-performance workloads
    vpvm network add "Jumbo" --type Host --subnet 10.10.10.0 --mtu 9000

### Updating a Network

    vpvm network update <name> [options]

Option | Description
--- | ---
`--new-name` | Rename the network
`--type` | Change type: `Shared` or `Host`
`--subnet` | New subnet address
`--mask` | New subnet mask
`--mtu` | New MTU value 1280–9000
`--interface` | New physical interface ID
`--ipv6` / `--no-ipv6` | Enable or disable IPv6
`--ipv6-prefix` | New IPv6 prefix
`--enable` / `--disable` | Enable or disable the network

> All virtual machines that use the network must be stopped before updating. If any are running, the command fails with a message listing the blocking VMs.

Examples:

    # Rename a network
    vpvm network update "Dev Network" --new-name "Production"

    # Change MTU
    vpvm network update "Dev Network" --mtu 9000

    # Disable a network
    vpvm network update "Dev Network" --disable

    # Change type and subnet together
    vpvm network update "Dev Network" --type Host --subnet 10.50.0.0

### Deleting a Network

    vpvm network delete <name>

> A network cannot be deleted while it is assigned to any virtual machine. Remove the network from all VMs first, then delete it.

Example:

    vpvm network delete "Old Network"

## 💾 Managing VM Disks

VM disk management uses the `config disk` subcommand group. The `--disk` option accepts either the disk name (e.g. `"Disk 1"`) or its UUID — use `config disk list` to see both.

For template disks, use the `template config disk` subcommand group described in the next section.

### Listing Disks

Show all disks attached to a VM, including their names, UUIDs, sizes, types, and interface:

    vpvm config disk list ubuntu-22.04

Output:

    #   NAME      UUID                                  SIZE    TYPE     INTERFACE
    1   Disk 1    a1b2c3d4-e5f6-7890-abcd-ef1234567890  64 GB   Dynamic  VirtIo
    2   Disk 2    b2c3d4e5-f6a7-8901-bcde-f01234567891  32 GB   Fixed    NVMe

### Adding a Disk

    vpvm config disk add ubuntu-22.04 --size 50 --interface VirtIo --type Dynamic

### Removing a Disk

    vpvm config disk remove ubuntu-22.04 --disk "Disk 2"

### Updating Disk Settings

Change cache mode or read-only state without affecting data:

    vpvm config disk update ubuntu-22.04 --disk "Disk 1" --cache-mode Auto --read-only false

### Resizing a Disk

Expand an existing disk to a new size (in GB). The VM must be stopped before resizing.

    # Resize by disk name
    vpvm config disk resize ubuntu-22.04 --disk "Disk 1" --size 128

    # Resize by disk UUID
    vpvm config disk resize ubuntu-22.04 --disk a1b2c3d4-e5f6-7890-abcd-ef1234567890 --size 128

Output:

    Request completed successfully.
    Disk resized to 128 GB

Requirements: - VM must be fully stopped (not paused or suspended) - New size must be larger than the current size — shrinking is not supported

### Relocating the macOS Recovery Partition

After resizing a fixed disk on a macOS VM, the recovery partition may no longer be at the expected location. Use this command to move it to the correct position so macOS recovery tools work properly.

    vpvm config disk relocate-recovery macos-vm --disk "Disk 1"

Output:

    Request completed successfully.
    Recovery partition relocated

Requirements: - Disk must be of type Fixed (not Dynamic) - Target must be a macOS VM - VM must be stopped

### Disk Command Quick Reference

    # List all disks
    vpvm config disk list ubuntu-22.04

    # Add a new disk
    vpvm config disk add ubuntu-22.04 --size 50

    # Remove a disk
    vpvm config disk remove ubuntu-22.04 --disk "Disk 2"

    # Update disk settings
    vpvm config disk update ubuntu-22.04 --disk "Disk 1" --cache-mode Auto

    # Resize by name (VM must be stopped)
    vpvm config disk resize ubuntu-22.04 --disk "Disk 1" --size 128

    # Resize by UUID
    vpvm config disk resize ubuntu-22.04 --disk a1b2c3d4-e5f6-7890-abcd-ef1234567890 --size 128

    # Relocate macOS recovery partition
    vpvm config disk relocate-recovery macos-vm --disk "Disk 1"

## 💾 Managing Template Disks

Template disk operations live under the `template config disk` subcommand group, keeping them alongside all other template configuration commands. The `--disk` option accepts either the disk name (e.g. `"Disk 1"`) or its UUID — use `template config disk list` to see both.

### Listing Template Disks

    vpvm template config disk list "Ubuntu 22.04 Base"

Output:

    NAME      UUID                                  SIZE    TYPE     INTERFACE
    Disk 1    a1b2c3d4-e5f6-7890-abcd-ef1234567890  64 GB   Dynamic  VirtIo

### Adding a Template Disk

    vpvm template config disk add "Ubuntu 22.04 Base" --size 50 --interface VirtIo --type Dynamic

### Removing a Template Disk

    vpvm template config disk remove "Ubuntu 22.04 Base" --disk "Disk 2"

### Resizing a Template Disk

    # Resize by disk name
    vpvm template config disk resize "Ubuntu 22.04 Base" --disk "Disk 1" --size 128

    # Resize by UUID
    vpvm template config disk resize "Ubuntu 22.04 Base" --disk a1b2c3d4-e5f6-7890-abcd-ef1234567890 --size 128

Requirements: - New size must be larger than the current size — shrinking is not supported

### Relocating the macOS Recovery Partition on a Template Disk

After resizing a fixed disk on a macOS template, relocate the recovery partition:

    vpvm template config disk relocate-recovery "My macOS Template" --disk "Disk 1"

Requirements: - Disk must be of type Fixed (not Dynamic) - Target must be a macOS template

### Template Disk Quick Reference

    # List template disks
    vpvm template config disk list "My Template"

    # Add a template disk
    vpvm template config disk add "My Template" --size 50

    # Remove a template disk
    vpvm template config disk remove "My Template" --disk "Disk 2"

    # Resize template disk by name
    vpvm template config disk resize "My Template" --disk "Disk 1" --size 128

    # Resize template disk by UUID
    vpvm template config disk resize "My Template" --disk a1b2c3d4-e5f6-7890-abcd-ef1234567890 --size 128

    # Relocate macOS recovery partition on template
    vpvm template config disk relocate-recovery "My macOS Template" --disk "Disk 1"

## 🎈 Memory Balloon

Memory ballooning lets you adjust how much RAM a running Linux VM can use — without rebooting. The guest's `virtio_balloon` kernel driver cooperates with the host to inflate or deflate the balloon, reclaiming or releasing memory dynamically.

> Memory balloon commands only apply to Linux VMs that have the Memory Balloon device enabled in their CPU & Memory settings. macOS guests do not support this feature.

### Checking Balloon Status

    vpvm balloon info <vmname>

Shows whether the balloon device is present and what the current target memory is:

      Has Balloon    : yes
      Target Memory  : 2048 MB
      Configured Max : 4096 MB

Field | Description
--- | ---
Has Balloon | Whether a VirtIO balloon device is configured for this VM
Target Memory | The memory the host is currently asking the guest to use
Configured Max | The total RAM the VM was created with

Example:

    vpvm balloon info ubuntu-22.04

### Setting the Balloon Target

    vpvm balloon set <vmname> --target <MB>

Instructs the guest to use at most `<MB>` megabytes of RAM. The value is clamped between 256 MB and the VM's configured maximum.

Option | Description
--- | ---
`--target <MB>` | Target memory in megabytes

Examples:

    # Ask the guest to use only 1 GB
    vpvm balloon set ubuntu-22.04 --target 1024

    # Restore the guest to its full configured memory
    vpvm balloon set ubuntu-22.04 --target 4096

> The balloon target is advisory — the guest kernel decides how much memory to actually return. Changes take effect within a few seconds on a cooperative guest.

## 🔌 USB Passthrough

> macOS 27 or later required. USB passthrough commands are only available when VirtualProg is running on macOS 27 (Tahoe) or newer.

USB passthrough lets you connect physical USB devices from the host Mac to a running virtual machine. The VM sees the device as if it were plugged in directly.

Requirements for all USB commands:

- Host must be running macOS 27 or later
- The VM must be running
- USB passthrough must be enabled in the VM's configuration (Settings > USB)

### Listing USB Devices

Show all USB devices available on the host and which ones are currently attached to a VM:

    vpvm usb list ubuntu-22.04

Output:

    Available USB devices:
      [0] SanDisk Ultra USB 3.0
      [1] Logitech USB Keyboard
      [2] Apple USB-C to USB Adapter

    Attached to VM:
      [1] Logitech USB Keyboard

Each device is shown with its index — use this number with `attach` and `detach`.

### Attaching a USB Device

Attach a host USB device to a running VM by its index:

    vpvm usb attach ubuntu-22.04 --index 0

Output:

    Request completed successfully.

> Use `vpvm usb list <vmname>` first to find the index of the device you want to attach.

### Detaching a USB Device

Detach a USB device that is currently passed through to a VM:

    vpvm usb detach ubuntu-22.04 --index 0

Output:

    Request completed successfully.

> The index used for detach comes from the Attached to VM section of `vpvm usb list`.

### USB Quick Reference

    # List available and attached USB devices for a running VM
    vpvm usb list ubuntu-22.04

    # List as JSON (for scripting)
    vpvm usb list ubuntu-22.04 --format json

    # Attach device at index 0 to the VM
    vpvm usb attach ubuntu-22.04 --index 0

    # Detach the device at index 0 from the VM
    vpvm usb detach ubuntu-22.04 --index 0

## 🔑 Managing Access Tokens

Scoped tokens grant limited API access to specific VMs without sharing your master authentication token. Each token has an access level (Operator or Admin) and can optionally expire. Use `vpvm token` subcommands to manage them from the terminal.

> Token management always uses the master token for authentication — scoped tokens cannot create, disable, or revoke other tokens.

### Listing Tokens

    vpvm token list

Returns a JSON list of all tokens with their Token IDs, labels, VM scope, access level, status, and last-used time.

### Creating a Token

    vpvm token create --label <label> [--vms <vm-names>] [--scope operator|admin] [--expires <yyyy-MM-dd>]

Option | Description | Default
--- | --- | ---
`--label` | Human-readable name for the token (required) | —
`--vms` | Comma-separated VM names, or `*` for all VMs | `*` (all VMs)
`--scope` | `operator` or `admin` | `operator`
`--expires` | Expiry date in yyyy-MM-dd format — omit for no expiry | (never)
`--templates` | Grant access to the Templates tab (requires `--scope admin` and `--vms *`) | (off)
`--networks` | Grant access to the Networks tab (requires `--scope admin` and `--vms *`) | (off)
`--images` | Grant access to the Images tab (requires `--scope admin` and `--vms *`) | (off)

The response includes the one-time secret — copy it before the session ends; it cannot be retrieved later. The Token ID is also returned and can be looked up at any time with `vpvm token list`.

Examples:

    # Operator token for two VMs, expires on a specific date
    vpvm token create --label "CI Pipeline" --vms "ubuntu-dev,ubuntu-test" --scope operator --expires 2026-12-31

    # Admin token for all VMs, no expiry
    vpvm token create --label "Automation Tool" --scope admin

    # Admin token with all extended permissions
    vpvm token create --label "Infra Bot" --scope admin --templates --networks --images

    # Operator token scoped to a single VM
    vpvm token create --label "Monitor Script" --vms "ubuntu-prod" --scope operator

Access levels:

Scope | Permissions
--- | ---
`operator` | Start, stop, pause, resume, restart VMs. Read info, status, snapshots. Cannot edit configuration.
`admin` | Full access — all Operator operations plus editing VM configuration, disks, networks, and snapshots.

### Updating a Token

    vpvm token update <tokenId> [--label <name>] [--vms <vm-names>] [--scope operator|admin] [--expires <yyyy-MM-dd>]

Only the options you pass are changed — omitted options are left untouched.

Option | Description
--- | ---
`--label` | New human-readable label
`--vms` | New VM list — comma-separated names or `*` for all VMs
`--scope` | New access level: `operator` or `admin`
`--expires` | New expiry date (yyyy-MM-dd), or empty string `""` to clear expiry
`--templates` | Grant access to Templates tab (requires `--scope admin` and `--vms *`)
`--networks` | Grant access to Networks tab (requires `--scope admin` and `--vms *`)
`--images` | Grant access to Images tab (requires `--scope admin` and `--vms *`)

Examples:

    # Extend expiry on an existing token
    vpvm token update a1b2c3d4-e5f6-7890-abcd-ef1234567890 --expires 2027-01-01

    # Rename a token and change its scope
    vpvm token update a1b2c3d4-e5f6-7890-abcd-ef1234567890 --label "Infra Bot" --scope admin

    # Clear expiry (make token permanent)
    vpvm token update a1b2c3d4-e5f6-7890-abcd-ef1234567890 --expires ""

### Rotating a Token Secret

    vpvm token rotate <tokenId>

Regenerates the bearer secret for a token. The old secret is invalidated immediately; the new secret is printed once and cannot be retrieved later. All other token settings (label, scope, VM list, expiry) are preserved.

Example:

    vpvm token rotate a1b2c3d4-e5f6-7890-abcd-ef1234567890

### Disabling a Token

    vpvm token disable <tokenId>

Temporarily blocks the token without deleting it. Any request using a disabled token is rejected. The token can be re-enabled at any time.

Example:

    vpvm token disable a1b2c3d4-e5f6-7890-abcd-ef1234567890

### Enabling a Token

    vpvm token enable <tokenId>

Restores a disabled token to active status.

Example:

    vpvm token enable a1b2c3d4-e5f6-7890-abcd-ef1234567890

### Revoking a Token

    vpvm token revoke <tokenId>

Permanently deletes the token. Any client using it will lose access immediately. This cannot be undone.

Example:

    vpvm token revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890

### Using a Scoped Token

Pass the token's secret via `--token` or the `VPVM_TOKEN` environment variable. All scoped-token restrictions apply — VM scope and access-level limits are enforced server-side.

    # Per-command
    vpvm list --server 192.168.1.10 --port 49152 --token <secret>
    vpvm start ubuntu-dev --server 192.168.1.10 --port 49152 --token <secret>

    # Environment variable (set once for a session)
    export VPVM_TOKEN=<secret>
    export VPVM_SERVER=192.168.1.10
    export VPVM_PORT=49152
    vpvm list
    vpvm start ubuntu-dev

Attempting an operation outside the token's VM scope or access level returns an error.

### Token Quick Reference

    # List all tokens
    vpvm token list

    # Create an Operator token for specific VMs (expires on a specific date)
    vpvm token create --label "Weekly Job" --vms "ubuntu-ci" --scope operator --expires 2026-07-15

    # Create an Admin token for all VMs, no expiry
    vpvm token create --label "Admin Script" --scope admin

    # Update a token's expiry date
    vpvm token update <tokenId> --expires 2027-01-01

    # Rename a token and restrict its VM list
    vpvm token update <tokenId> --label "New Name" --vms "ubuntu-dev,ubuntu-ci"

    # Disable a token (pauses access without deleting)
    vpvm token disable <tokenId>

    # Re-enable a disabled token
    vpvm token enable <tokenId>

    # Permanently revoke a token
    vpvm token revoke <tokenId>

## 🖥️ Server Mode

Server Mode suppresses informational and error alert popups on the host Mac, keeping the Web Dashboard responsive during remote control sessions. When enabled, alerts are logged silently instead of blocking the UI. Confirmation dialogs are always shown regardless of this setting.

Enable, disable, or query Server Mode from the terminal — useful for scripting headless or remote setups:

    # Enable Server Mode
    vpvm servermode --enable

    # Disable Server Mode
    vpvm servermode --disable

    # Check current state
    vpvm servermode --info

Output:

    Request completed successfully.
    Server mode enabled.

    Request completed successfully.
    Server mode is disabled.

You can also toggle Server Mode from the Tools menu or the status bar icon in the VirtualProg app — a checkmark indicates it is active.

> Tip: Use `vpvm servermode --info` in scripts to check the current state before enabling or disabling, avoiding unnecessary toggles.

## 🔧 Advanced Usage

### Remote Access

By default, `vpvm` connects to VirtualProg running on the same Mac. Use the following flags on any command to target a remote VirtualProg instance:

Flag | Env Variable | Description | Default
--- | --- | --- | ---
`--server <host>` | `VPVM_SERVER` | IP address or hostname of the remote machine | `127.0.0.1`
`--port <port>` | `VPVM_PORT` | Port the VirtualProg CLI server is listening on | Configured in VirtualProg settings
`--token <token>` | `VPVM_TOKEN` | Authentication token | Configured in VirtualProg settings
`--secure` | `VPVM_SECURE=1` | Use HTTPS instead of HTTP | `false`
`--trust-certificate` | `VPVM_TRUST_CERT=1` | Accept any HTTPS certificate, including self-signed ones | `false`

Flags take priority over environment variables, which take priority over local defaults.

Requirements for remote access:

- The CLI Server must be enabled in VirtualProg settings on the remote machine
- External Access must be enabled if connecting from a different machine
- The token must match the one configured in VirtualProg settings on the remote machine

Using flags (per-command):

    # List VMs on a remote machine
    vpvm list --server 192.168.1.10 --port 49152 --token mytoken

    # Start a VM on a remote machine
    vpvm start my-vm --server 192.168.1.10 --port 49152 --token mytoken

    # Check status on a remote machine
    vpvm status my-vm --server 192.168.1.10 --token mytoken

    # Connect over HTTPS with a self-signed certificate
    vpvm list --server 192.168.1.10 --port 49152 --token mytoken --secure --trust-certificate

Using environment variables (set once):

    export VPVM_SERVER=192.168.1.10
    export VPVM_PORT=49152
    export VPVM_TOKEN=mytoken

    # All commands now connect to the remote instance automatically
    vpvm list
    vpvm watch
    vpvm start ubuntu-22.04

This is ideal for CI pipelines, shell profiles, or scripts that always target the same remote host.

When `--server` (or `VPVM_SERVER`) is provided, `vpvm` operates in remote mode and skips the local VirtualProg auto-launch check — the remote instance is assumed to be already running. Flags such as `--token`, `--port`, and `--trust-certificate` can be used independently without triggering remote mode, allowing you to customise local connections (e.g. override the token or trust a self-signed local HTTPS certificate).

### Shell Scripting

Automate VM management with shell scripts. You can use comma-separated names for concise multi-VM commands:

    # Start several VMs in one command
    vpvm start web-server,database,cache

Or loop when logic per-VM is needed:

    #!/bin/bash
    # Start development VMs with a delay between each

    VMS=("web-server" "database" "cache")

    for vm in "${VMS[@]}"; do
        echo "Starting $vm..."
        vpvm start "$vm"
        sleep 2
    done

    echo "All development VMs started!"

### Checking VM State Before Operations

    #!/bin/bash
    VM_NAME="ubuntu-22.04"

    STATUS=$(vpvm status "$VM_NAME" | tail -n 1)

    if [ "$STATUS" == "running" ]; then
        echo "VM is already running"
        exit 0
    fi

    echo "Starting VM..."
    vpvm start "$VM_NAME"

### Automated Snapshot Workflow

    #!/bin/bash
    # Create daily snapshot before starting work

    VM="dev-machine"
    DATE=$(date +%Y-%m-%d)
    SNAPSHOT="daily-$DATE"

    echo "Creating snapshot: $SNAPSHOT"
    vpvm snapshot create "$VM" "$SNAPSHOT"

    echo "Starting VM..."
    vpvm start "$VM"

### Batch VM Operations

Shutdown a known set of VMs in one command:

    vpvm shutdown web-server,database,cache

Stop all currently running VMs dynamically:

    #!/bin/bash
    # Get list of all VMs and shut down any that are running
    VMS=$(vpvm list all | tail -n 1 | tr ',' ' ')

    for vm in $VMS; do
        STATUS=$(vpvm status "$vm" | tail -n 1)
        if [ "$STATUS" == "running" ]; then
            echo "Shutting down $vm..."
            vpvm shutdown "$vm"
            sleep 5
        fi
    done

    echo "All VMs shut down!"

## 📊 Error Handling

### Common Errors and Solutions

#### VM Does Not Exist

    Request errored.
    VM 'vmname' does not exist

Solution: Check VM name with `vpvm list all` and ensure correct spelling.

#### VM Already Running

    Request errored.
    VM is already running

Solution: Check status with `vpvm status <vmname>` before starting.

#### VM Not Running

    Request errored.
    VM is not running

Solution: Start the VM first with `vpvm start <vmname>`.

#### Password Protected VM

    Request errored.
    VM 'ubuntu-22.04' is password protected. Run 'vpvm unlock ubuntu-22.04' to unlock it first.

Solution: Run `vpvm unlock <vmname>` and enter the VM password. Once unlocked, retry the operation. Use `vpvm lock <vmname>` to re-lock the VM when you are done.

#### VM Must Be Stopped

    Request errored.
    Please stop the VM before <operation>

Solution: Use `vpvm shutdown <vmname>` or `vpvm stop <vmname>` first.

#### Template Already Exists

    Request errored.
    Template with name 'templatename' already exists

Solution: Use a different template name or delete the existing template first.

#### Snapshot Not Found

    Request errored.
    Snapshot 'snapshotname' not found

Solution: List available snapshots with `vpvm snapshot list <vmname>`.

## 🔄 Integration with VirtualProg GUI

The CLI seamlessly integrates with the VirtualProg GUI:

- Auto-launch: If VirtualProg is not running, `vpvm` automatically launches it
- Live updates: Changes made via CLI are reflected in the GUI
- Event notifications: Both CLI and GUI operations trigger system notifications
- Shared state: All operations work on the same VM data

Note: The VirtualProg app must remain running for CLI commands to work (it will auto-launch if not running).

## 🎯 Best Practices

### Do's ✅

- Always use `shutdown` instead of `stop` for graceful VM shutdown
- Create snapshots before risky operations (updates, configuration changes)
- Use descriptive names for VMs, snapshots, and templates
- Check VM status before performing operations
- Test scripts with non-critical VMs first
- Keep template names unique and descriptive

### Don'ts ❌

- Don't use `stop` unless absolutely necessary (risks data corruption)
- Don't delete snapshots/templates without verification
- Don't clone or snapshot password-protected VMs (remove protection first)
- Don't run operations on VMs that are paused/suspended (stop or resume first)
- Don't rely solely on CLI - use GUI for complex configurations

## 🛠️ Troubleshooting

### VirtualProg Not Responding

If CLI commands hang or don't respond:

1. Check if VirtualProg is running: `ps aux | grep VirtualProg`
2. Restart VirtualProg from Applications
3. Check system logs for errors
4. Contact support if issues persist

### HTTP Server Not Available

The CLI uses an HTTP server on localhost. If you get connection errors:

1. Verify VirtualProg is running
2. Check HTTP port settings in VirtualProg preferences
3. Ensure no firewall is blocking localhost connections

### Performance Issues

If CLI commands are slow:

1. Close unused VMs to free resources
2. Check system disk space
3. Restart VirtualProg to clear cache
4. Consider upgrading hardware for better performance

## 💡 Tips and Tricks

### Quick Status Check

Create a shell alias for quick VM status:

    # Add to ~/.zshrc or ~/.bash_profile
    alias vmstatus='vpvm status'

Usage: `vmstatus ubuntu-22.04`

### VM Management Dashboard

Create a simple dashboard script:

    #!/bin/bash
    echo "=== VirtualProg VM Status ==="
    VMS=$(vpvm list all | tail -n 1 | tr ',' ' ')

    for vm in $VMS; do
        status=$(vpvm status "$vm" | tail -n 1)
        printf "%-20s : %s\n" "$vm" "$status"
    done

### Automated Backup Workflow

    #!/bin/bash
    # Weekly snapshot backup script

    VM="production-vm"
    WEEK=$(date +%U)
    SNAPSHOT="week-$WEEK-backup"

    # Stop VM
    vpvm shutdown "$VM"
    sleep 10

    # Create snapshot
    vpvm snapshot create "$VM" "$SNAPSHOT"

    # Start VM
    vpvm start "$VM"

    echo "Weekly backup completed: $SNAPSHOT"

## 📚 Related Documentation

- VirtualProg Main Documentation
- Snapshots Guide
- Checkpoints Guide
- Templates Guide
- Dashboard & Statistics
- Log Viewer

## 📬 Support

Need help with the CLI?

- Email: support@makeprog.com
- Email: makeprog@gmail.com
- Mac App Store

## 📝 Examples Quick Reference

### Basic Operations

    # List all VMs
    vpvm list

    # Start a VM
    vpvm start ubuntu-22.04

    # Start multiple VMs at once (comma-separated)
    vpvm start ubuntu-22.04,debian-12,macos-sonoma

    # Check status
    vpvm status ubuntu-22.04

    # Check status of multiple VMs
    vpvm status ubuntu-22.04,debian-12

    # Get detailed VM info
    vpvm info ubuntu-22.04

    # Get IP address (useful for SSH scripting)
    vpvm ip ubuntu-22.04
    ssh user@$(vpvm ip ubuntu-22.04)

    # Graceful shutdown
    vpvm shutdown ubuntu-22.04

    # Shutdown multiple VMs
    vpvm shutdown ubuntu-22.04,debian-12

    # Stop (force)
    vpvm stop ubuntu-22.04

### Pause/Resume/Suspend

    # Pause VM
    vpvm pause ubuntu-22.04

    # Resume VM
    vpvm resume ubuntu-22.04

    # Suspend to disk
    vpvm suspend ubuntu-22.04

    # Restart VM
    vpvm restart ubuntu-22.04

### Snapshots

    # Create snapshot
    vpvm snapshot create ubuntu-22.04 before-update

    # List snapshots
    vpvm snapshot list ubuntu-22.04

    # View snapshot details
    vpvm snapshot info ubuntu-22.04 before-update

    # Restore snapshot
    vpvm snapshot restore ubuntu-22.04 before-update

    # Create VM from snapshot
    vpvm snapshot createvm ubuntu-22.04 before-update my-new-vm

    # Delete snapshot
    vpvm snapshot delete ubuntu-22.04 old-snapshot

### Checkpoints (macOS 27+)

    # List checkpoints (ordered oldest → newest; last = Latest)
    vpvm checkpoint list ubuntu-22.04

    # View details for a specific checkpoint
    vpvm checkpoint info ubuntu-22.04 Vanilla

    # Create a checkpoint (VM must be stopped)
    vpvm checkpoint create ubuntu-22.04 Vanilla --notes "Before installing Xcode"

    # Restore a checkpoint (VM must be stopped; cannot restore Latest)
    vpvm checkpoint restore ubuntu-22.04 Vanilla

    # Delete the most recent checkpoint (VM must be stopped; Latest only)
    vpvm checkpoint delete ubuntu-22.04 DevTools

    # Rename a checkpoint or update its notes
    vpvm checkpoint update ubuntu-22.04 Vanilla --new-name "clean-install"
    vpvm checkpoint update ubuntu-22.04 clean-install --notes "SSH enabled"

### Templates

    # Create template
    vpvm template create ubuntu-22.04 "My Template"

    # List templates
    vpvm template list

    # Get template info
    vpvm template info "My Template"

    # Clone a template
    vpvm template clone "My Template" "My Template Copy"

    # Delete template
    vpvm template delete "Old Template"

    # Create VM from template
    vpvm template createvm "My Template" new-vm

### Configure VM

    # Inspect current values before changing
    vpvm config info general ubuntu-22.04
    vpvm config info startup ubuntu-22.04
    vpvm config info security ubuntu-22.04

    # Change CPU and memory
    vpvm config cpu ubuntu-22.04 --cpu 4 --memory 8192

    # Enable headless mode and set a description
    vpvm config general ubuntu-22.04 --headless true --descr "My dev server"

    # Set a password (plain text, hashed automatically)
    vpvm config security ubuntu-22.04 --password "mypassword"

    # Remove the password
    vpvm config security ubuntu-22.04 --clear-password

    # Disable clipboard sharing
    vpvm config security ubuntu-22.04 --clipboard false

    # Enable auto-start
    vpvm config startup ubuntu-22.04 --auto-start true

    # Schedule VM start/stop (Mon–Fri, 09:00–18:00)
    vpvm config schedule ubuntu-22.04 --enabled true --days "1,2,3,4,5" --start-time "09:00" --stop-time "18:00"

    # List available network sources
    vpvm network sources

    # Add a network adapter
    vpvm config network add ubuntu-22.04 --type "Default (NAT)"

    # Update a network adapter
    vpvm config network update ubuntu-22.04 --net "Network 1" --type "en0"

    # Add port forwarding
    vpvm config network pf-add ubuntu-22.04 --net "Network 1" --host-port 2222 --guest-port 22

    # Configure template settings
    vpvm template config cpu "My Template" --cpu 8 --memory 16384

### Screenshots

    # PNG screenshot (saved to current directory)
    vpvm screenshot ubuntu-22.04

    # Save to a specific path
    vpvm screenshot ubuntu-22.04 --output ~/Desktop/vm.png

    # JPEG at reduced quality
    vpvm screenshot ubuntu-22.04 --format jpeg --quality 0.6 --output ~/Desktop/vm.jpg

    # Screenshot from a remote instance
    vpvm screenshot ubuntu-22.04 --server 192.168.1.10 --port 49152

### Create VM

    # List available images first
    vpvm images list

    # Create a Linux VM — by alias (recommended)
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu

    # Create a Linux VM — by raw filename (also works)
    vpvm create "My Ubuntu" --os linux --cpu 2 --memory 4096 --disk 64 --image ubuntu.iso

    # Create a macOS VM (arm64 only)
    vpvm create "My Mac" --os macos --cpu 4 --memory 8192 --disk 80 --image sequoia

### Disks

    # List VM disks (shows name, UUID, size, type, interface)
    vpvm config disk list ubuntu-22.04

    # Add a new disk
    vpvm config disk add ubuntu-22.04 --size 50

    # Remove a disk
    vpvm config disk remove ubuntu-22.04 --disk "Disk 2"

    # Resize a VM disk — by name or UUID (VM must be stopped)
    vpvm config disk resize ubuntu-22.04 --disk "Disk 1" --size 128
    vpvm config disk resize ubuntu-22.04 --disk a1b2c3d4-e5f6-7890-abcd-ef1234567890 --size 128

    # Relocate macOS recovery partition on VM (fixed disks only)
    vpvm config disk relocate-recovery macos-vm --disk "Disk 1"

    # List template disks
    vpvm template config disk list "My Template"

    # Add a template disk
    vpvm template config disk add "My Template" --size 50

    # Resize a template disk
    vpvm template config disk resize "My Template" --disk "Disk 1" --size 128

    # Relocate macOS recovery partition on template
    vpvm template config disk relocate-recovery "My macOS Template" --disk "Disk 1"

### Networks (macOS Tahoe 26+)

    # List custom networks
    vpvm network list

    # View details
    vpvm network info "My Network"

    # Create a shared network
    vpvm network add "Dev Network" --type Shared --subnet 192.168.50.0

    # Create a host-only network
    vpvm network add "Isolated" --type Host --subnet 10.99.0.0

    # Rename a network
    vpvm network update "Dev Network" --new-name "Production"

    # Change MTU
    vpvm network update "Dev Network" --mtu 9000

    # Delete a network
    vpvm network delete "Old Network"

### USB Passthrough (macOS 27+)

    # List available and attached USB devices
    vpvm usb list ubuntu-22.04

    # Attach device at index 0 to the VM
    vpvm usb attach ubuntu-22.04 --index 0

    # Detach device at index 0 from the VM
    vpvm usb detach ubuntu-22.04 --index 0

### Server Mode

    # Check current state
    vpvm servermode --info

    # Enable Server Mode (suppresses alert popups during remote sessions)
    vpvm servermode --enable

    # Disable Server Mode
    vpvm servermode --disable

### Access Tokens

    # List all tokens
    vpvm token list

    # Create an Operator token for specific VMs (expires on a specific date)
    vpvm token create --label "CI Pipeline" --vms "ubuntu-dev,ubuntu-test" --scope operator --expires 2026-12-31

    # Create an Admin token for all VMs, no expiry
    vpvm token create --label "Admin Tool" --scope admin

    # Disable a token (pauses access without deleting)
    vpvm token disable <tokenId>

    # Re-enable a disabled token
    vpvm token enable <tokenId>

    # Permanently revoke a token
    vpvm token revoke <tokenId>

### Advanced

    # Clone VM
    vpvm clone ubuntu-22.04 ubuntu-dev

    # Delete VM
    vpvm delete test-vm

    # Restart VM
    vpvm restart ubuntu-22.04

### Remote Access

    # List VMs on a remote machine
    vpvm list --server 192.168.1.10 --port 49152 --token mytoken

    # Start a VM remotely
    vpvm start my-vm --server 192.168.1.10 --port 49152 --token mytoken

    # Check remote VM status
    vpvm status my-vm --server 192.168.1.10 --token mytoken

    # Create a snapshot on a remote machine
    vpvm snapshot create my-vm backup --server 192.168.1.10 --token mytoken

    # Connect over HTTPS, trusting a self-signed certificate
    vpvm list --server 192.168.1.10 --port 49152 --token mytoken --secure --trust-certificate

VirtualProg CLI empowers developers, sysadmins, and power users with complete command-line control over virtual machines — perfectly integrated with the VirtualProg GUI experience.