This is an automated email from the ASF dual-hosted git repository. dahn pushed a commit to branch 4.20 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.20 by this push: new 75147b78116 [Vmware to KVM Migration] Display virt-v2v and ovftool versions for supported hosts for migration (#11019) 75147b78116 is described below commit 75147b781163958200287aa9979e60bf602b2f89 Author: Nicolas Vazquez <nicovazque...@gmail.com> AuthorDate: Mon Jun 23 07:49:51 2025 -0300 [Vmware to KVM Migration] Display virt-v2v and ovftool versions for supported hosts for migration (#11019) * [Vmware to KVM Migration] Display virt-v2v and ovftool versions for supported hosts for migration * Fix UI display * Address review comments * Fix ovftool and version display - also display versions on host details view --- api/src/main/java/com/cloud/host/Host.java | 9 ++++--- .../com/cloud/agent/manager/AgentManagerImpl.java | 17 ++++++++++++- .../kvm/resource/LibvirtComputingResource.java | 29 ++++++++++++++++++++-- .../wrapper/LibvirtReadyCommandWrapper.java | 8 ++++++ ui/public/locales/en.json | 2 ++ ui/src/views/infra/HostInfo.vue | 16 ++++++++++++ ui/src/views/tools/ImportUnmanagedInstance.vue | 6 +++++ 7 files changed, 81 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/cloud/host/Host.java b/api/src/main/java/com/cloud/host/Host.java index 56b4ed75a31..a3b6ccadc01 100644 --- a/api/src/main/java/com/cloud/host/Host.java +++ b/api/src/main/java/com/cloud/host/Host.java @@ -53,9 +53,12 @@ public interface Host extends StateObject<Status>, Identity, Partition, HAResour return strs; } } - public static final String HOST_UEFI_ENABLE = "host.uefi.enable"; - public static final String HOST_VOLUME_ENCRYPTION = "host.volume.encryption"; - public static final String HOST_INSTANCE_CONVERSION = "host.instance.conversion"; + + String HOST_UEFI_ENABLE = "host.uefi.enable"; + String HOST_VOLUME_ENCRYPTION = "host.volume.encryption"; + String HOST_INSTANCE_CONVERSION = "host.instance.conversion"; + String HOST_OVFTOOL_VERSION = "host.ovftool.version"; + String HOST_VIRTV2V_VERSION = "host.virtv2v.version"; /** * @return name of the machine. diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java index 9137d1c1dff..aff528efede 100644 --- a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java @@ -54,6 +54,7 @@ import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.ThreadContext; @@ -703,11 +704,25 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl Map<String, String> detailsMap = readyAnswer.getDetailsMap(); if (detailsMap != null) { String uefiEnabled = detailsMap.get(Host.HOST_UEFI_ENABLE); + String virtv2vVersion = detailsMap.get(Host.HOST_VIRTV2V_VERSION); + String ovftoolVersion = detailsMap.get(Host.HOST_OVFTOOL_VERSION); logger.debug("Got HOST_UEFI_ENABLE [{}] for host [{}]:", uefiEnabled, host); - if (uefiEnabled != null) { + if (ObjectUtils.anyNotNull(uefiEnabled, virtv2vVersion, ovftoolVersion)) { _hostDao.loadDetails(host); + boolean updateNeeded = false; if (!uefiEnabled.equals(host.getDetails().get(Host.HOST_UEFI_ENABLE))) { host.getDetails().put(Host.HOST_UEFI_ENABLE, uefiEnabled); + updateNeeded = true; + } + if (StringUtils.isNotBlank(virtv2vVersion) && !virtv2vVersion.equals(host.getDetails().get(Host.HOST_VIRTV2V_VERSION))) { + host.getDetails().put(Host.HOST_VIRTV2V_VERSION, virtv2vVersion); + updateNeeded = true; + } + if (StringUtils.isNotBlank(ovftoolVersion) && !ovftoolVersion.equals(host.getDetails().get(Host.HOST_OVFTOOL_VERSION))) { + host.getDetails().put(Host.HOST_OVFTOOL_VERSION, ovftoolVersion); + updateNeeded = true; + } + if (updateNeeded) { _hostDao.saveDetails(host); } } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 13518de5cb3..7fb3839860f 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -17,6 +17,8 @@ package com.cloud.hypervisor.kvm.resource; import static com.cloud.host.Host.HOST_INSTANCE_CONVERSION; +import static com.cloud.host.Host.HOST_OVFTOOL_VERSION; +import static com.cloud.host.Host.HOST_VIRTV2V_VERSION; import static com.cloud.host.Host.HOST_VOLUME_ENCRYPTION; import java.io.BufferedReader; @@ -3766,7 +3768,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv cmd.setIqn(getIqn()); cmd.getHostDetails().put(HOST_VOLUME_ENCRYPTION, String.valueOf(hostSupportsVolumeEncryption())); cmd.setHostTags(getHostTags()); - cmd.getHostDetails().put(HOST_INSTANCE_CONVERSION, String.valueOf(hostSupportsInstanceConversion())); + boolean instanceConversionSupported = hostSupportsInstanceConversion(); + cmd.getHostDetails().put(HOST_INSTANCE_CONVERSION, String.valueOf(instanceConversionSupported)); + if (instanceConversionSupported) { + cmd.getHostDetails().put(HOST_VIRTV2V_VERSION, getHostVirtV2vVersion()); + } + if (hostSupportsOvfExport()) { + cmd.getHostDetails().put(HOST_OVFTOOL_VERSION, getHostOvfToolVersion()); + } HealthCheckResult healthCheckResult = getHostHealthCheckResult(); if (healthCheckResult != HealthCheckResult.IGNORE) { cmd.setHostHealthCheckResult(healthCheckResult == HealthCheckResult.SUCCESS); @@ -5368,8 +5377,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return exitValue == 0; } + public String getHostVirtV2vVersion() { + if (!hostSupportsInstanceConversion()) { + return ""; + } + String cmd = String.format("%s | awk '{print $2}'", INSTANCE_CONVERSION_SUPPORTED_CHECK_CMD); + String version = Script.runSimpleBashScript(cmd); + return StringUtils.isNotBlank(version) ? version.split(",")[0] : ""; + } + + public String getHostOvfToolVersion() { + if (!hostSupportsOvfExport()) { + return ""; + } + return Script.runSimpleBashScript(OVF_EXPORT_TOOl_GET_VERSION_CMD); + } + public boolean ovfExportToolSupportsParallelThreads() { - String ovfExportToolVersion = Script.runSimpleBashScript(OVF_EXPORT_TOOl_GET_VERSION_CMD); + String ovfExportToolVersion = getHostOvfToolVersion(); if (StringUtils.isBlank(ovfExportToolVersion)) { return false; } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java index 8f23e79e4a3..485254c6bb9 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java @@ -47,6 +47,14 @@ public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyComman hostDetails.put(Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString()); } + if (libvirtComputingResource.hostSupportsInstanceConversion()) { + hostDetails.put(Host.HOST_VIRTV2V_VERSION, libvirtComputingResource.getHostVirtV2vVersion()); + } + + if (libvirtComputingResource.hostSupportsOvfExport()) { + hostDetails.put(Host.HOST_OVFTOOL_VERSION, libvirtComputingResource.getHostOvfToolVersion()); + } + return new ReadyAnswer(command, hostDetails); } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index f3ab19bb88a..026880e38fd 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1089,7 +1089,9 @@ "label.host": "IP address", "label.host.alerts": "Hosts in alert state", "label.host.name": "Host name", +"label.host.ovftool.version": "OVFTool Version", "label.host.tag": "Host tag", +"label.host.virtv2v.version": "Virt-v2v Version", "label.hostcontrolstate": "Compute Resource Status", "label.hostid": "Host", "label.hostname": "Host", diff --git a/ui/src/views/infra/HostInfo.vue b/ui/src/views/infra/HostInfo.vue index 259445154a0..a6d8fe8595e 100644 --- a/ui/src/views/infra/HostInfo.vue +++ b/ui/src/views/infra/HostInfo.vue @@ -56,6 +56,22 @@ </div> </div> </a-list-item> + <a-list-item v-if="host.details && host.details['host.virtv2v.version']"> + <div> + <strong>{{ $t('label.host.virtv2v.version') }}</strong> + <div> + {{ host.details['host.virtv2v.version'] }} + </div> + </div> + </a-list-item> + <a-list-item v-if="host.details && host.details['host.ovftool.version']"> + <div> + <strong>{{ $t('label.host.ovftool.version') }}</strong> + <div> + {{ host.details['host.ovftool.version'] }} + </div> + </div> + </a-list-item> <a-list-item v-if="host.hosttags"> <div> <strong>{{ $t('label.hosttags') }}</strong> diff --git a/ui/src/views/tools/ImportUnmanagedInstance.vue b/ui/src/views/tools/ImportUnmanagedInstance.vue index 50a0d631808..95c14f141d2 100644 --- a/ui/src/views/tools/ImportUnmanagedInstance.vue +++ b/ui/src/views/tools/ImportUnmanagedInstance.vue @@ -944,6 +944,12 @@ export default { } else { host.name = host.name + ' (' + this.$t('label.not.supported') + ')' } + if (host.details['host.virtv2v.version']) { + host.name = host.name + ' (virt-v2v=' + host.details['host.virtv2v.version'] + ')' + } + if (host.details['host.ovftool.version']) { + host.name = host.name + ' (ovftool=' + host.details['host.ovftool.version'] + ')' + } }) }) },