Successfully integrated the hyper2kvm pipeline and libvirt VM definition functionality into the web dashboard, providing a complete end-to-end VM migration workflow through the browser.
File: web/dashboard-react/src/components/JobSubmissionForm.tsx
const [formData, setFormData] = useState<Record<string, any>>({
// ... existing fields ...
// Pipeline integration (NEW)
enable_pipeline: false,
hyper2kvm_path: '/home/tt/hyper2kvm/hyper2kvm',
pipeline_inspect: true,
pipeline_fix: true,
pipeline_convert: true,
pipeline_validate: true,
pipeline_compress: true,
compress_level: 6,
// Libvirt integration (NEW)
libvirt_integration: false,
libvirt_uri: 'qemu:///system',
libvirt_autostart: false,
libvirt_bridge: 'virbr0',
libvirt_pool: 'default',
});
{/* Pipeline Integration */}
<div style=>
<h3 style=>
Pipeline integration <span style=>(hyper2kvm + libvirt)</span>
</h3>
{/* Enable Pipeline Checkbox */}
{/* hyper2kvm Path Input */}
{/* Compression Level Input */}
{/* Pipeline Stages Checkboxes (4 stages) */}
{/* Libvirt Integration Section (collapsible) */}
</div>
Features:
#f0583a)File: daemon/models/job.go
type ExportOptions struct {
// ... existing fields ...
// Pipeline integration options (NEW)
EnablePipeline bool `json:"enable_pipeline,omitempty"`
Hyper2KVMPath string `json:"hyper2kvm_path,omitempty"`
PipelineInspect bool `json:"pipeline_inspect,omitempty"`
PipelineFix bool `json:"pipeline_fix,omitempty"`
PipelineConvert bool `json:"pipeline_convert,omitempty"`
PipelineValidate bool `json:"pipeline_validate,omitempty"`
PipelineCompress bool `json:"pipeline_compress,omitempty"`
CompressLevel int `json:"compress_level,omitempty"`
// Libvirt integration options (NEW)
LibvirtIntegration bool `json:"libvirt_integration,omitempty"`
LibvirtURI string `json:"libvirt_uri,omitempty"`
LibvirtAutoStart bool `json:"libvirt_autostart,omitempty"`
LibvirtBridge string `json:"libvirt_bridge,omitempty"`
LibvirtPool string `json:"libvirt_pool,omitempty"`
}
Impact:
omitempty)/jobs/submitNew Files:
web/dashboard-react/PIPELINE_INTEGRATION.md - Web UI integration guideWEB_UX_INTEGRATION_SUMMARY.md - This summary document┌─────────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐
│ Browser │────>│ Daemon API │────>│ vSphere │────>│hyper2kvm│────>│ libvirt │
│ Form │ │ /jobs/submit│ │ Provider │ │ Pipeline │ │ KVM │
└─────────────┘ └──────────────┘ └────────────┘ └────────────┘ └──────────┘
│ │ │ │ │
Submit Validate Export Convert Define VM
Options & Queue VM Disk in KVM
http://localhost:8080Request: POST /jobs/submit
{
"name": "Ubuntu Server Migration",
"provider": "vsphere",
"vcenter_url": "vcenter.company.com",
"datacenter": "DC1",
"username": "administrator@vsphere.local",
"password": "SecurePassword123",
"vm_path": "/DC1/vm/Production/ubuntu-server",
"output_dir": "/var/lib/libvirt/images/ubuntu-server",
"format": "ova",
"options": {
"parallel_downloads": 3,
"remove_cdrom": true,
"enable_pipeline": true,
"hyper2kvm_path": "/home/tt/hyper2kvm/hyper2kvm",
"pipeline_inspect": true,
"pipeline_fix": true,
"pipeline_convert": true,
"pipeline_validate": true,
"pipeline_compress": true,
"compress_level": 6,
"libvirt_integration": true,
"libvirt_uri": "qemu:///system",
"libvirt_autostart": true,
"libvirt_bridge": "br0",
"libvirt_pool": "default"
}
}
Response: 200 OK
{
"job_ids": ["job-abc123"],
"accepted": 1,
"rejected": 0,
"timestamp": "2024-01-15T10:30:00Z"
}
Request: GET /jobs/job-abc123
Response:
{
"id": "job-abc123",
"status": "running",
"progress": 65,
"message": "Running hyper2kvm pipeline: FIX stage - updating GRUB configuration",
"started_at": "2024-01-15T10:30:00Z",
"metadata": {
"export_completed": true,
"manifest_generated": true,
"pipeline_stage": "fix",
"stages_completed": ["inspect", "fix"],
"stages_remaining": ["convert", "validate"]
}
}
Response:
{
"id": "job-abc123",
"status": "completed",
"progress": 100,
"message": "Export completed successfully with pipeline integration",
"started_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:47:30Z",
"result": {
"output_path": "/var/lib/libvirt/images/ubuntu-server",
"format": "ova",
"size": 8589934592,
"duration": "17m30s",
"files": [
"/var/lib/libvirt/images/ubuntu-server/ubuntu-server.ovf",
"/var/lib/libvirt/images/ubuntu-server/ubuntu-server-disk1.vmdk"
],
"metadata": {
"manifest_path": "/var/lib/libvirt/images/ubuntu-server/manifest.json",
"pipeline_success": true,
"pipeline_duration": "12m15s",
"converted_path": "/var/lib/libvirt/images/ubuntu-server.qcow2",
"libvirt_domain": "ubuntu-server",
"libvirt_uri": "qemu:///system",
"pipeline_stages": {
"inspect": "completed",
"fix": "completed",
"convert": "completed",
"validate": "completed"
}
}
}
}
┌─────────────────────────────────────────────────────────┐
│ Pipeline integration (hyper2kvm + libvirt) │
│ │
│ ☐ Enable hyper2kvm pipeline after export │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Pipeline integration (hyper2kvm + libvirt) │
│ │
│ ☑ Enable hyper2kvm pipeline after export │
│ │
│ hyper2kvm Path Compression Level (1-9) │
│ /home/tt/hyper2kvm... [6] │
│ │
│ Pipeline Stages │
│ ☑ INSPECT (detect OS) ☑ FIX (fstab, grub) │
│ ☑ CONVERT (→ qcow2) ☑ VALIDATE (integrity) │
│ │
│ ───────────────────────────────────────────────────── │
│ │
│ ☑ Define VM in libvirt after conversion │
│ │
│ Libvirt URI Network Bridge │
│ qemu:///system virbr0 │
│ │
│ Storage Pool ☑ Enable VM auto-start │
│ default │
└─────────────────────────────────────────────────────────┘
cd /home/ssahani/go/github/hypersdk
go build ./cmd/hyperd
./hyperd
# In browser
http://localhost:8080
/DC1/vm/test-vm)/tmp/test-export# Watch job status
curl http://localhost:8080/jobs?all=true | jq
# Watch specific job
curl http://localhost:8080/jobs/JOB_ID | jq
# Check converted qcow2 image
ls -lh /tmp/test-export/*.qcow2
# Check libvirt domain
virsh list --all
# Check manifest
cat /tmp/test-export/manifest.json | jq
| Provider | Export | Manifest | Pipeline | Libvirt |
|---|---|---|---|---|
| vSphere | ✅ | ✅ | ✅ | ✅ |
| AWS | ✅ | ✅ | ⚠️* | ⚠️* |
| Azure | ✅ | ✅ | ⚠️* | ⚠️* |
| GCP | ✅ | ✅ | ⚠️* | ⚠️* |
| Hyper-V | ✅ | ✅ | ⚠️* | ⚠️* |
| OCI | ✅ | ⚠️ | ❌ | ❌ |
| OpenStack | ✅ | ⚠️ | ❌ | ❌ |
| Alibaba | ✅ | ⚠️ | ❌ | ❌ |
| Proxmox | ✅ | ⚠️ | ❌ | ❌ |
⚠️ = Supported but requires manual disk download first (cloud exports go to object storage)
If hyper2kvm fails, the export still succeeds:
{
"status": "completed_with_warnings",
"result": {
"output_path": "/tmp/test-export",
"metadata": {
"pipeline_success": false,
"pipeline_error": "hyper2kvm: disk conversion failed: insufficient disk space"
}
}
}
User can:
If libvirt VM definition fails, conversion still completes:
{
"status": "completed_with_warnings",
"result": {
"output_path": "/tmp/test-export",
"metadata": {
"pipeline_success": true,
"converted_path": "/tmp/test-export/vm.qcow2",
"libvirt_error": "virsh define failed: permission denied - run as root or add user to libvirt group"
}
}
}
User can:
virsh define /path/to/domain.xmlcd web/dashboard-react
npm install
npm run dev
Access: http://localhost:5173
cd web/dashboard-react
npm run build
Output: daemon/dashboard/static-react/
Served by daemon at: http://localhost:8080
providers/common/pipeline.go - Pipeline executorproviders/common/libvirt.go - Libvirt integratorweb/dashboard-react/PIPELINE_INTEGRATION.md - Documentationweb/dashboard-react/src/components/JobSubmissionForm.tsx - Added pipeline UIdaemon/models/job.go - Extended ExportOptions modelproviders/vsphere/export_options.go - Added pipeline fields (already done)The web UX now provides a complete, user-friendly interface for VM migrations with integrated hyper2kvm conversion and libvirt VM definition. Users can perform end-to-end migrations entirely through the browser, from export to KVM-ready VM in a single operation.
✅ Implementation Complete ✅ Build Verified ✅ Documentation Created ✅ Ready for Testing