VMware API Integration: hyper2kvm leverages hypersdk (VMware’s modern Python SDK, formerly known as pyvmomi/pyVmomi) for enterprise-grade, type-safe vCenter/vSphere API access.
hyper2kvm (Control-Plane + Data-Plane Hybrid)hyper2kvmhyper2kvm)Before following this guide, you should have:
hyper2kvm is a specialized tool for integrating with VMware vSphere, treating it in a realistic manner: inventory and orchestration exist in one domain, while disk byte movement operates in another. This intentional separation ensures the vSphere integration remains fast, predictable, and highly debuggable. By avoiding the mixing of control-plane and data-plane operations, the tool prevents common pitfalls like performance bottlenecks in large inventories or hidden failures during exports.
The philosophy is embodied in two key files:
hyper2kvm/vsphere/vmware_client.py: The reusable engine, designed async-first for multi-mode exports (e.g., conversion, downloads).hyper2kvm/vsphere/<vsphere_cli_entry>.py (VsphereMode): The action-driven CLI entrypoint, which orchestrates user commands and delegates to the engine.This structure allows for modular reuse: the engine can be imported independently for scripting, while the CLI provides a user-friendly interface.
The core principles guide the tool’s behavior to address real-world vSphere challenges:
pyvmomi / pyVim / pyVmomi): Handles resolution of inventory objects, datacenters, hosts, snapshots, Changed Block Tracking (CBT), and datastore browsing with enterprise-grade, type-safe API access./folder / VDDK): Focuses solely on moving bytes, such as exporting/converting disks or downloading VM folders.
In hyper2kvm, hypersdk is strictly used to find and describe resources (e.g., locating a VM or disk), after which a dedicated data-plane mechanism takes over for efficient byte transfer. This prevents overhead from blending discovery with heavy I/O operations.vCenter inventories can be massive, and naive “list everything” approaches lead to sluggish tools. To counter this:
VMwareClient makes inventory printing opt-in via print_vm_names.get_vm_by_name) are prioritized over repeated CreateContainerView traversals, ensuring operations scale well in enterprise environments.hyper2kvm resolves a common failure where libvirt rejects cluster-only paths:
host/<cluster> (frequently rejected).host/<cluster-or-compute>/<esx-host> , or fallback to host/<esx-host> .
This fix prevents errors like “Path … does not specify a host system” when constructing vpx://... URIs.Operators need control over operations to avoid surprises. hyper2kvm exposes distinct data-plane modes:
qcow2/raw formats, potentially inspecting/modifying the guest.VMwareClient is async-first, leveraging asyncio for benefits in downloads and subprocess log streaming.VsphereMode remains synchronous but incorporates concurrency via ThreadPoolExecutor for parallel tasks like file downloads.vSphere failures often involve cryptic issues (e.g., TLS mismatches, invalid thumbprints, path errors, or verbose stderr). vmware_client.py addresses this with:
asyncio LimitOverrunError from tools emitting excessively long lines without newlines.The vSphere integration follows these core principles:
host/<cluster>/<esx-host> formatgraph TB
subgraph HV["hyper2kvm vSphere Integration"]
CLI[VsphereMode.py<br/>CLI Entrypoint<br/>Sync w/ Threads]
Engine[VMwareClient.py<br/>Reusable Engine<br/>Async-First]
DataPlane[Data-Plane<br/>Bytes Movement]
CLI <--> Engine
Engine <--> DataPlane
subgraph CP["Control-Plane"]
CP1[pyvmomi/pyVim]
CP2[Connect/Session]
CP3[DC/Host Cache]
CP4[VM Lookup]
CP5[Disk Enum]
CP6[Snapshot/CBT]
CP7[DS Browsing]
end
subgraph AF["Actions/Flags"]
AF1[Wires to Options]
AF2[Calls Engine]
end
subgraph DP["Data-Plane Modes"]
DP1[Direct Export]
DP2[HTTP Download]
DP3[VDDK Disk Pull]
end
subgraph CBT["CBT Sync Workflow"]
CBT1[1. Enable CBT]
CBT2[2. Quiesced Snap]
CBT3[3. Query Changes]
CBT4[4. Range HTTP Pull]
CBT1 --> CBT2 --> CBT3 --> CBT4
end
Engine --> CP1
Engine --> CP2
Engine --> CP3
Engine --> CP4
Engine --> CP5
Engine --> CP6
Engine --> CP7
CLI --> AF1
CLI --> AF2
DataPlane --> DP1
DataPlane --> DP2
DataPlane --> DP3
end
style CLI fill:#FF9800,stroke:#E65100,color:#fff
style Engine fill:#2196F3,stroke:#1565C0,color:#fff
style DataPlane fill:#4CAF50,stroke:#2E7D32,color:#fff
style CP fill:#9C27B0,stroke:#6A1B9A,color:#fff
style DP fill:#00BCD4,stroke:#006064,color:#fff
style CBT fill:#F44336,stroke:#C62828,color:#fff
graph LR
subgraph Modes["Export Mode Options via ExportOptions.export_mode"]
Export["export Default<br/>━━━━━━━<br/>✓ Converted Output<br/>✓ qcow2/raw Local<br/>✓ Direct Export<br/>✓ VDDK/SSH Transport"]
Download["download_only<br/>━━━━━━━<br/>✓ Exact VM Folder<br/>✓ Byte-for-Byte<br/>✓ HTTPS /folder<br/>✓ Globs/Concurrency"]
VDDK["vddk_download<br/>━━━━━━━<br/>✓ Single Disk Raw<br/>✓ Fast VDDK Pull<br/>✓ No Conversion<br/>✓ Sector Reads"]
end
style Export fill:#4CAF50,stroke:#2E7D32,color:#fff
style Download fill:#2196F3,stroke:#1565C0,color:#fff
style VDDK fill:#FF9800,stroke:#E65100,color:#fff
flowchart TD
User[User/CLI] --> VsphereMode[VsphereMode]
VsphereMode --> AsyncExport[VMwareClient.async_export_vm]
AsyncExport --> ModeCheck{Export Mode?}
ModeCheck -->|export| ExportMode[Direct Export<br/>Convert]
ModeCheck -->|download_only| DownloadOnly[Download Only<br/>Exact Copy]
ModeCheck -->|vddk_download| VDDKDownload[VDDK Disk<br/>Download]
ExportMode --> Output1[Local qcow2/raw]
DownloadOnly --> Output2[VM Folder Files]
VDDKDownload --> Output3[Raw Disk Image]
style User fill:#9C27B0,stroke:#6A1B9A,color:#fff
style VsphereMode fill:#FF9800,stroke:#E65100,color:#fff
style AsyncExport fill:#2196F3,stroke:#1565C0,color:#fff
style ModeCheck fill:#FFC107,stroke:#F57C00,color:#000
style ExportMode fill:#4CAF50,stroke:#2E7D32,color:#fff
style DownloadOnly fill:#00BCD4,stroke:#006064,color:#fff
style VDDKDownload fill:#F44336,stroke:#C62828,color:#fff
style Output1 fill:#8BC34A,stroke:#558B2F,color:#fff
style Output2 fill:#8BC34A,stroke:#558B2F,color:#fff
style Output3 fill:#8BC34A,stroke:#558B2F,color:#fff
hyper2kvmThe control-plane leverages pyvmomi for non-I/O tasks:
SmartConnect for establishing connections and retrieving session cookies.Key Patterns:
si.RetrieveContent() → content for root access.CreateContainerView for scoped views of VMs/hosts/datacenters.list_vm_names.SearchDatastore_Task and SearchDatastoreSubFolders_Task for directory listings.hyper2kvmexport_mode="export"):
VMwareClient.vddk-libdir for VDDK transport.output_dir.vddk or ssh./folder Download-Only Mode (export_mode="download_only"):
https://<vc>/folder/<ds_path>?dcPath=<dc>&dsName=<ds>.pyvmomi (si._stub.cookie).ds_path is URL-encoded with slashes preserved (quote(..., safe="/")).VMwareClient: Async downloads with aiohttp + aiofiles (if available), controlled concurrency via download_only_concurrency, and globs/max files for safety.VsphereMode: File listing via datastore browser, parallel downloads with ThreadPoolExecutor, mirrors layout under --output-dir.export_mode="vddk_download"):
VMwareClient.[ds] folder/disk.vmdk).VDDKESXClient for sector downloads to local files.vddk-libdir validation (must contain libvixDiskLib.so), thumbprint normalization/auto-computation (unless no_verify), rate-limited progress logging.Currently, hyper2kvm features dual implementations for download-only:
VMwareClient.async_download_only_vm(): Async, with globs, concurrency, and reuse focus.VsphereMode action download_only_vm: Sync with thread pool, CLI-oriented.
This duplication is temporary for behavior stabilization. Long-term plan:VsphereMode) becomes a thin layer.VMwareClient.export_vm(ExportOptions(export_mode="download_only", ...)).hyper2kvm (Control-Plane + Data-Plane Hybrid)cbt_sync exemplifies the split’s value for incremental workflows:
Control-Plane Steps:
QueryChangedDiskAreas(...).Data-Plane Step:
Range: bytes=<start>-<end>) and write to local disk at the offset.
This transforms vSphere into an efficient incremental block source, avoiding full disk re-downloads.hyper2kvm# -*- coding: utf-8 -*-: Ensures safe handling of logs and VM names in diverse environments.from __future__ import annotations: Mitigates runtime type-evaluation issues and simplifies optional imports.hyper2kvm)| Need | Mode | Transport/Details |
|——|——|——————-|
| Converted qcow2/raw | export_mode="export" | vddk or ssh |
| Exact VM folder contents from datastore | export_mode="download_only" | HTTP /folder |
| One disk as raw bytes via VDDK | export_mode="vddk_download" | VDDK client |
| Incremental updates on local disk | cbt_sync | CBT + ranged HTTP reads |
# Export VM
python -m hyper2kvm vsphere \
--vcenter vcenter.example.com \
--username admin@vsphere.local \
--password-file ~/.vcenter_pass \
--vs-action export-vm \
--vs-vm-name production-web \
--output-dir /data/exports
# Download exact VM folder contents
python -m hyper2kvm vsphere \
--vcenter vcenter.example.com \
--username admin \
--vs-action download-vm \
--vs-vm-name backup-server \
--output-dir /backups
# Use VDDK for high-speed transfer
python -m hyper2kvm vsphere \
--vcenter vcenter.example.com \
--username admin \
--vs-action vddk-export \
--vs-vm-name database-01 \
--vddk-libdir /usr/lib/vmware-vix-disklib \
--output-dir /data/vms
from hyper2kvm.vmware.clients.client import VMwareClient
from hyper2kvm.vmware.vsphere.mode import ExportOptions
# Initialize client
client = VMwareClient(
host='vcenter.example.com',
user='admin@vsphere.local',
pwd='password'
)
# Configure export
options = ExportOptions(
vm_name='web-server',
output_dir='/data/exports',
export_mode='export',
transport='vddk',
vddk_libdir='/usr/lib/vmware-vix-disklib'
)
# Execute export
await client.async_export_vm(options)
prefer_cached_vm_lookup for repetitive tasks; tune download_only_concurrency to balance load.no_verify but auto-computes thumbprints; passwords use secure temp files.ExportOptions dataclass for easy customization; add extra_args for export processing.For code-level details, see vmware_client.py. If further expansions or examples are needed, provide specifics!
Continue your migration journey:
Found an issue? Report it on GitHub