From cb9cc53fa4f8af6199fc53fa51acbc2de47db147 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Tue, 10 Mar 2026 14:50:54 +0530 Subject: [PATCH 1/5] Fix duplicate dummy template 'kvm-default-vm-import-dummy-template' entries --- .../org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 13fa2608016c..1313681e3433 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -1550,9 +1550,11 @@ private ServiceOfferingVO getServiceOfferingForImportInstance(Long serviceOfferi protected VMTemplateVO getTemplateForImportInstance(Long templateId, Hypervisor.HypervisorType hypervisorType) { VMTemplateVO template; if (templateId == null) { - template = templateDao.findByName(VM_IMPORT_DEFAULT_TEMPLATE_NAME); + boolean isKVMHypervisor = Hypervisor.HypervisorType.KVM.equals(hypervisorType); + String templateName = (isKVMHypervisor) ? KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME : VM_IMPORT_DEFAULT_TEMPLATE_NAME; + template = templateDao.findByName(templateName); if (template == null) { - template = createDefaultDummyVmImportTemplate(Hypervisor.HypervisorType.KVM == hypervisorType); + template = createDefaultDummyVmImportTemplate(isKVMHypervisor); if (template == null) { throw new InvalidParameterValueException(String.format("Default VM import template with unique name: %s for hypervisor: %s cannot be created. Please use templateid parameter for import", VM_IMPORT_DEFAULT_TEMPLATE_NAME, hypervisorType.toString())); } From 08cf2be96e905e24425484feb13e5c91fb4d2031 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Tue, 10 Mar 2026 15:02:51 +0530 Subject: [PATCH 2/5] Update guest os id of dummy template to 99 (Other Linux (64-bit)) from existing id: 1 (CentOS 4.5 (32-bit)) --- .../src/main/resources/META-INF/db/schema-42200to42210.sql | 2 ++ .../java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42200to42210.sql b/engine/schema/src/main/resources/META-INF/db/schema-42200to42210.sql index a8a3d3f7bd4f..2326a855f32e 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42200to42210.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42200to42210.sql @@ -33,3 +33,5 @@ UPDATE `cloud`.`alert` SET type = 34 WHERE name = 'ALERT.VR.PRIVATE.IFACE.MTU'; -- Update configuration 'kvm.ssh.to.agent' description and is_dynamic fields UPDATE `cloud`.`configuration` SET description = 'True if the management server will restart the agent service via SSH into the KVM hosts after or during maintenance operations', is_dynamic = 1 WHERE name = 'kvm.ssh.to.agent'; + +UPDATE `cloud`.`vm_template` SET guest_os_id = 99 WHERE name = 'kvm-default-vm-import-dummy-template'; diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 1313681e3433..1311f7df1eb7 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -326,7 +326,7 @@ private VMTemplateVO createDefaultDummyVmImportTemplate(boolean isKVM) { try { template = VMTemplateVO.createSystemIso(templateDao.getNextInSequence(Long.class, "id"), templateName, templateName, true, "", true, 64, Account.ACCOUNT_ID_SYSTEM, "", - "VM Import Default Template", false, 1); + "VM Import Default Template", false, 99); template.setState(VirtualMachineTemplate.State.Inactive); template = templateDao.persist(template); if (template == null) { From 5d88f30a321d13d9e3ddec8548e1556879743bfc Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Wed, 11 Mar 2026 14:02:15 +0530 Subject: [PATCH 3/5] update migration path to remove duplicate dummy templates --- .../cloudstack/vm/UnmanagedVMsManager.java | 2 + .../upgrade/dao/Upgrade42200to42210.java | 50 +++++++++++++++++++ .../StorageSystemDataMotionStrategy.java | 4 +- .../vm/UnmanagedVMsManagerImpl.java | 2 - 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java index b6233b9c2704..e1963313eb6f 100644 --- a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java +++ b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java @@ -26,6 +26,8 @@ public interface UnmanagedVMsManager extends VmImportService, UnmanageVMService, PluggableService, Configurable { + String VM_IMPORT_DEFAULT_TEMPLATE_NAME = "system-default-vm-import-dummy-template.iso"; + String KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME = "kvm-default-vm-import-dummy-template"; ConfigKey UnmanageVMPreserveNic = new ConfigKey<>("Advanced", Boolean.class, "unmanage.vm.preserve.nics", "false", "If set to true, do not remove VM nics (and its MAC addresses) when unmanaging a VM, leaving them allocated but not reserved. " + "If set to false, nics are removed and MAC addresses can be reassigned", true, ConfigKey.Scope.Zone); diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java index c9610f7b9ff5..c5e2b308746b 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java @@ -16,6 +16,14 @@ // under the License. package com.cloud.upgrade.dao; +import org.apache.cloudstack.vm.UnmanagedVMsManager; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; + public class Upgrade42200to42210 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate { @Override @@ -27,4 +35,46 @@ public String[] getUpgradableVersionRange() { public String getUpgradedVersion() { return "4.22.1.0"; } + + @Override + public void performDataMigration(Connection conn) { + removeDuplicateDummyTemplates(conn); + } + + private void removeDuplicateDummyTemplates(Connection conn) { + List templateIds = new ArrayList<>(); + try (PreparedStatement selectStmt = conn.prepareStatement(String.format("SELECT id FROM cloud.vm_template WHERE name='%s' ORDER BY id ASC", UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME))) { + ResultSet rs = selectStmt.executeQuery(); + while (rs.next()) { + templateIds.add(rs.getLong(1)); + } + + if (templateIds.size() <= 1) { + return; + } + + Long firstTemplateId = templateIds.get(0); + + String updateTemplateSql = "UPDATE cloud.vm_instance SET vm_template_id = ? WHERE vm_template_id = ?"; + String deleteTemplateSql = "DELETE FROM cloud.vm_template WHERE id = ?"; + + try (PreparedStatement updateTemplateStmt = conn.prepareStatement(updateTemplateSql); + PreparedStatement deleteTemplateStmt = conn.prepareStatement(deleteTemplateSql)) { + for (int i = 1; i < templateIds.size(); i++) { + Long duplicateTemplateId = templateIds.get(i); + + // Update VM references + updateTemplateStmt.setLong(1, firstTemplateId); + updateTemplateStmt.setLong(2, duplicateTemplateId); + updateTemplateStmt.executeUpdate(); + + // Delete duplicate dummy template + deleteTemplateStmt.setLong(1, duplicateTemplateId); + deleteTemplateStmt.executeUpdate(); + } + } + } catch (Exception e) { + logger.warn("Failed to clean duplicate kvm-default-vm-import-dummy-template entries", e); + } + } } diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java index 275f41de43a2..bcade3a371c4 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java @@ -148,8 +148,8 @@ import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; -import static org.apache.cloudstack.vm.UnmanagedVMsManagerImpl.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME; -import static org.apache.cloudstack.vm.UnmanagedVMsManagerImpl.VM_IMPORT_DEFAULT_TEMPLATE_NAME; +import static org.apache.cloudstack.vm.UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME; +import static org.apache.cloudstack.vm.UnmanagedVMsManager.VM_IMPORT_DEFAULT_TEMPLATE_NAME; public class StorageSystemDataMotionStrategy implements DataMotionStrategy { protected Logger logger = LogManager.getLogger(getClass()); diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 1311f7df1eb7..12405fbf7036 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -201,8 +201,6 @@ import static org.apache.cloudstack.vm.ImportVmTask.Step.Importing; public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager { - public static final String VM_IMPORT_DEFAULT_TEMPLATE_NAME = "system-default-vm-import-dummy-template.iso"; - public static final String KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME = "kvm-default-vm-import-dummy-template"; protected Logger logger = LogManager.getLogger(UnmanagedVMsManagerImpl.class); private static final List importUnmanagedInstancesSupportedHypervisors = Arrays.asList(Hypervisor.HypervisorType.VMware, Hypervisor.HypervisorType.KVM); From a02e455cea7b47fb856302e9deee45e31a3b7e41 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Wed, 11 Mar 2026 14:12:30 +0530 Subject: [PATCH 4/5] review comments --- .../org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 12405fbf7036..0403c7fa571f 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -202,6 +202,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager { protected Logger logger = LogManager.getLogger(UnmanagedVMsManagerImpl.class); + private static final long OTHER_LINUX_64_GUEST_OS_ID = 99; private static final List importUnmanagedInstancesSupportedHypervisors = Arrays.asList(Hypervisor.HypervisorType.VMware, Hypervisor.HypervisorType.KVM); @@ -324,7 +325,7 @@ private VMTemplateVO createDefaultDummyVmImportTemplate(boolean isKVM) { try { template = VMTemplateVO.createSystemIso(templateDao.getNextInSequence(Long.class, "id"), templateName, templateName, true, "", true, 64, Account.ACCOUNT_ID_SYSTEM, "", - "VM Import Default Template", false, 99); + "VM Import Default Template", false, OTHER_LINUX_64_GUEST_OS_ID); template.setState(VirtualMachineTemplate.State.Inactive); template = templateDao.persist(template); if (template == null) { @@ -1554,7 +1555,7 @@ protected VMTemplateVO getTemplateForImportInstance(Long templateId, Hypervisor. if (template == null) { template = createDefaultDummyVmImportTemplate(isKVMHypervisor); if (template == null) { - throw new InvalidParameterValueException(String.format("Default VM import template with unique name: %s for hypervisor: %s cannot be created. Please use templateid parameter for import", VM_IMPORT_DEFAULT_TEMPLATE_NAME, hypervisorType.toString())); + throw new InvalidParameterValueException(String.format("Default VM import template with unique name: %s for hypervisor: %s cannot be created. Please use templateid parameter for import", templateName, hypervisorType.toString())); } } } else { From 026bd09316eb0d55cbf43e28aa7c7ec0e872e692 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Thu, 12 Mar 2026 11:46:03 +0530 Subject: [PATCH 5/5] review changes --- .../java/com/cloud/upgrade/dao/Upgrade42200to42210.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java index c5e2b308746b..813351d75341 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42200to42210.java @@ -38,10 +38,10 @@ public String getUpgradedVersion() { @Override public void performDataMigration(Connection conn) { - removeDuplicateDummyTemplates(conn); + removeDuplicateKVMImportTemplates(conn); } - private void removeDuplicateDummyTemplates(Connection conn) { + private void removeDuplicateKVMImportTemplates(Connection conn) { List templateIds = new ArrayList<>(); try (PreparedStatement selectStmt = conn.prepareStatement(String.format("SELECT id FROM cloud.vm_template WHERE name='%s' ORDER BY id ASC", UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME))) { ResultSet rs = selectStmt.executeQuery(); @@ -53,6 +53,7 @@ private void removeDuplicateDummyTemplates(Connection conn) { return; } + logger.info("Removing duplicate template " + UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME + " entries"); Long firstTemplateId = templateIds.get(0); String updateTemplateSql = "UPDATE cloud.vm_instance SET vm_template_id = ? WHERE vm_template_id = ?"; @@ -74,7 +75,7 @@ private void removeDuplicateDummyTemplates(Connection conn) { } } } catch (Exception e) { - logger.warn("Failed to clean duplicate kvm-default-vm-import-dummy-template entries", e); + logger.warn("Failed to remove duplicate template " + UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME + " entries", e); } } }