Skip to content

Conversation

@drutigliano19
Copy link

@drutigliano19 drutigliano19 commented Dec 12, 2025

IMPORTANT: Please do not create a Pull Request without creating an issue first.

Problem:
The existing vm-import-controller supports migration only from centralized virtualization platforms, specifically VMware and OpenStack. To broaden the controller’s capability and allow users to transition their workloads into Harvester from decentralized, bare-metal hypervisor environments, support for Kernel-based Virtual Machine (KVM) sources is required.

Solution:
This Pull Request introduces the architectural framework for KVM source migration by implementing the KVMSource Custom Resource Definition (CRD) and extending the main reconciliation logic to handle KVM environments.

  1. CRD Definition: Introduces the KVMSource CRD to store KVM host connectivity information, particularly the Libvirt remote URI (qemu+ssh://host/system) and a reference to a Kubernetes Secret containing secure SSH credentials.
  2. Control Plane: The controller utilizes the libvirtURI to establish a secure connection, retrieve the source VM’s domain XML metadata, and manage the VM state (e.g., issuing a graceful shutdown) prior to data transfer.
  3. Data Plane: The migration workflow orchestrates a conversion Job which uses the qemu+ssh connection and non-interactive SSH authentication to pull the disk image directly from the remote KVM host. This Job utilizes a tool to perform the mandatory conversion of the disk image (e.g., QCOW2) into the required raw disk format within the PVC scratch space.

Related Issue:
N/A

Test plan:

End-to-end tests have been performed to validate the migration lifecycle for KVM sources:

  • Verify the creation of a KVMSource CR and confirm that the controller successfully sets the status condition to clusterReady after validating the SSH/Libvirt connection.
  • Create a VirtualMachineImport CR referencing the new KVMSource.
  • Verify that the controller triggers a graceful shutdown of the KVM source guest (where possible).
  • Confirm that scratch PVCs are provisioned.
  • Confirm the final VirtualMachineImport status is updated to virtualMachineRunning.

Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
@drutigliano19 drutigliano19 force-pushed the feat/kvm-source branch 4 times, most recently from b9945b0 to b369f98 Compare December 18, 2025 22:01
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
@votdev
Copy link
Member

votdev commented Dec 22, 2025

I was only able to perform an import (until it failed) when patching the vish calls to virsh -c qemu+ssh://192.168.0.1/system in the sources.

On the host system i was also not able to run virsh dominfo debian13; i need to run virsh -c qemu+ssh://192.168.0.1/system dominfo debian13.

apiVersion: migration.harvesterhci.io/v1beta1
kind: KVMSource
metadata:
  name: kvm
  namespace: default
spec:
  libvirtURI: "qemu+ssh://192.168.0.1/system"
  credentials:
    name: kvm-credentials
    namespace: default
time="2025-12-22T17:09:39Z" level=info msg="Running preflight checks ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="Sanitizing the import spec ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="The sanitization of the import spec was successful" kind=VirtualMachineImport name=debian13 namespace=default spec.virtualMachineName=debian13 status.importedVirtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="Sanitizing the import spec ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="The sanitization of the import spec was successful" kind=VirtualMachineImport name=debian13 namespace=default spec.virtualMachineName=debian13 status.importedVirtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="Importing client disk images ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:39Z" level=info msg="Shutting down guest OS of the source VM" name=debian13 namespace=default spec.gracefulShutdownTimeoutSeconds=60 spec.sourceCluster.kind=KVMSource spec.sourceCluster.name=kvm spec.virtualMachineName=debian13
time="2025-12-22T17:09:40Z" level=info msg="VM debian13 is already powered off, skipping shutdown."
time="2025-12-22T17:09:40Z" level=info msg="Importing client disk images ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:40Z" level=info msg="Importing client disk images ..." name=debian13 namespace=default spec.virtualMachineName=debian13
time="2025-12-22T17:09:41Z" level=info msg="Exporting source VM" name=debian13 namespace=default spec.sourceCluster.kind=KVMSource spec.sourceCluster.name=kvm spec.virtualMachineName=debian13
time="2025-12-22T17:09:41Z" level=info msg="Downloading disk /var/lib/libvirt/images/debian13.qcow2 to /tmp/debian13-disk-0-2600694252"
time="2025-12-22T17:09:41Z" level=error msg="Failed to export source VM: failed to open remote file /var/lib/libvirt/images/debian13.qcow2: permission denied" name=debian13 namespace=default spec.sourceCluster.kind=KVMSource spec.sourceCluster.name=kvm spec.virtualMachineName=debian13
time="2025-12-22T17:09:41Z" level=error msg="The VM import has failed" name=debian13 namespace=default spec.virtualMachineName=debian13

@lewis100challenges
Copy link

Hello, I’d like to know more about the follow-up on this feature, because it’s much needed in my environment. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants