From 8b6c3e728361ab59a5445acb24929313ed18ae1d Mon Sep 17 00:00:00 2001 From: JS Choi <77760789+jschoiRR@users.noreply.github.com> Date: Tue, 29 Apr 2025 14:50:33 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EB=B9=84=EA=B4=80=EB=A6=AC=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=84=9C=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EA=B8=B0=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=EB=B3=84=20?= =?UTF-8?q?=ED=98=B8=ED=99=98=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95(rb?= =?UTF-8?q?d,=20gfs,=20clvm,=20local)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rtGetUnmanagedInstancesCommandWrapper.java | 15 +++++++++-- .../vm/UnmanagedVMsManagerImpl.java | 27 +++++++++---------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java index 4cce47b8b6af..24621dccfc45 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java @@ -34,6 +34,8 @@ import org.libvirt.Domain; import org.libvirt.DomainBlockInfo; import org.libvirt.LibvirtException; +import org.libvirt.StoragePool; +import org.libvirt.StorageVol; import java.util.ArrayList; import java.util.HashMap; @@ -120,7 +122,6 @@ private UnmanagedInstanceTO getUnmanagedInstance(LibvirtComputingResource libvir final UnmanagedInstanceTO instance = new UnmanagedInstanceTO(); instance.setName(domain.getName()); - instance.setCpuCores((int) LibvirtComputingResource.countDomainRunningVcpus(domain)); if (parser.getCpuTuneDef() !=null) { instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores()); @@ -221,7 +222,17 @@ private List getUnmanagedInstanceDisks(List pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath); - for (StoragePool pool : pools) { - if (pool.getDataCenterId() == zone.getId() && - (pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId())) && - volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) { - storagePool = pool; - break; - } - } - } - - if (storagePool == null) { + logger.debug(String.format("### DataStore [Host:%s, Path:%s, Type:%s, Name:%s]" , dsHost, dsPath, dsType, dsName)); + if (dsName != null) { List pools = primaryDataStoreDao.listPoolsByCluster(cluster.getId()); pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId())); for (StoragePool pool : pools) { @@ -570,6 +558,17 @@ private StoragePool getStoragePool(final UnmanagedInstanceTO.Disk disk, final Da } } } + if (storagePool == null) { + List pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath); + for (StoragePool pool : pools) { + if (pool.getDataCenterId() == zone.getId() && + (pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId())) && + volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) { + storagePool = pool; + break; + } + } + } if (storagePool == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Storage pool for disk %s(%s) with datastore: %s not found in zone ID: %s", disk.getLabel(), disk.getDiskId(), disk.getDatastoreName(), zone.getUuid())); } From 9f7bde77cf3f8479547e244f56dda161aa5bc483 Mon Sep 17 00:00:00 2001 From: JS Choi <77760789+jschoiRR@users.noreply.github.com> Date: Sun, 4 May 2025 13:42:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?iframe=20=EB=AA=A8=EB=8B=88=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20=ED=85=8C=EB=A7=88=20=EC=83=89=EC=83=81=20=ED=9D=B0?= =?UTF-8?q?=EC=83=89=EC=9C=BC=EB=A1=9C=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/cloudstack/config/ApiServiceConfiguration.java | 6 +++--- ui/src/views/plugins/IFrameWall.vue | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java index 3c3fc0dc40f0..89f758030a4c 100644 --- a/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java +++ b/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java @@ -37,11 +37,11 @@ public class ApiServiceConfiguration implements Configurable {public static fina public static final ConfigKey MonitoringWallPortalPort = new ConfigKey("Advanced", String.class, "monitoring.wall.portal.port", "3000", "Monitoring Service Wall Portal Port.(ex:3000)", true); public static final ConfigKey MonitoringWallPortalVmUri = new ConfigKey("Advanced", String.class, "monitoring.wall.portal.vm.uri", - "/d/uservm?kiosk&theme=light", "Monitoring Service Wall Portal VM Uri.(ex:/d/uservm?kiosk&theme=light)", true); + "/d/uservm?kiosk", "Monitoring Service Wall Portal VM Uri.(ex:/d/uservm?kiosk)", true); public static final ConfigKey MonitoringWallPortalHostUri = new ConfigKey("Advanced", String.class, "monitoring.wall.portal.host.uri", - "/d/Q3Jkjf54zs?kiosk&theme=light", "Monitoring Service Wall Portal Host Uri.(ex:/d/Q3Jkjf54zs?kiosk&theme=light)", true); + "/d/Q3Jkjf54zs?kiosk", "Monitoring Service Wall Portal Host Uri.(ex:/d/Q3Jkjf54zs?kiosk)", true); public static final ConfigKey MonitoringWallPortalClusterUri = new ConfigKey("Advanced", String.class, "monitoring.wall.portal.cluster.uri", - "/d/fasdasdasdw?kiosk&theme=light", "Monitoring Service Wall Portal Cluster Uri.(ex:/d/fasdasdasdw?kiosk&theme=light)", true); + "/d/fasdasdasdw?kiosk", "Monitoring Service Wall Portal Cluster Uri.(ex:/d/fasdasdasdw?kiosk)", true); public static final ConfigKey EventDeleteEnabled = new ConfigKey<>("Advanced", Boolean.class, "event.delete.enabled", "false", "true if Event Delete Button is enabled, false otherwise)", false); diff --git a/ui/src/views/plugins/IFrameWall.vue b/ui/src/views/plugins/IFrameWall.vue index 8eb2257ed38e..62945d6071f7 100644 --- a/ui/src/views/plugins/IFrameWall.vue +++ b/ui/src/views/plugins/IFrameWall.vue @@ -53,10 +53,10 @@ export default { var uri = wallPortalProtocol + '://' + wallPortalDomain + ':' + wallPortalPort if (typeof hypervisortype !== 'undefined' && hypervisortype !== null && hypervisortype !== '') { const clusterUriPath = items.filter(x => x.name === 'monitoring.wall.portal.cluster.uri')[0]?.value - this.uriInfo = uri + clusterUriPath + this.uriInfo = uri + clusterUriPath + '&theme=light' } else { const hostUriPath = items.filter(x => x.name === 'monitoring.wall.portal.host.uri')[0]?.value - this.uriInfo = uri + hostUriPath + '&var-host=' + this.resource.ipaddress + this.uriInfo = uri + hostUriPath + '&theme=light&var-host=' + this.resource.ipaddress } this.uriCreateOk = true }) From ef11a9404da0608dfc3cde0344e59e96022e9e47 Mon Sep 17 00:00:00 2001 From: JS Choi <77760789+jschoiRR@users.noreply.github.com> Date: Sun, 4 May 2025 13:45:02 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EA=B0=80=EC=83=81=EB=A8=B8=EC=8B=A0=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=8B=9C=20configdrive=20iso=20=EA=B2=BD=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resource/LibvirtComputingResource.java | 75 +++++++++++++++++++ .../wrapper/LibvirtMigrateCommandWrapper.java | 4 +- 2 files changed, 77 insertions(+), 2 deletions(-) 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 7252514d4e18..41953347a79f 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 @@ -3792,6 +3792,81 @@ protected KVMStoragePoolManager getPoolManager() { return storagePoolManager; } + public void detachAndAttachConfigDriveISO(final Connect conn, final String vmName, VirtualMachineTO to) { + // detach and re-attach configdrive ISO + List disks = getDisks(conn, vmName); + DiskDef configdrive = null; + for (DiskDef disk : disks) { + if (disk.getDeviceType() == DiskDef.DeviceType.CDROM && CONFIG_DRIVE_ISO_DISK_LABEL.equals(disk.getDiskLabel())) { + configdrive = disk; + } + } + + if (configdrive != null) { + try { + LOGGER.debug(String.format("Detaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); + String result = attachOrDetachConfigDriveISO(conn, vmName, to, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID); + if (result != null) { + LOGGER.warn(String.format("Detach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result)); + } + LOGGER.debug(String.format("Attaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); + result = attachOrDetachConfigDriveISO(conn, vmName, to, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID); + if (result != null) { + LOGGER.warn(String.format("Attach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result)); + } + } catch (final LibvirtException | InternalErrorException | URISyntaxException e) { + final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString(); + LOGGER.warn(msg, e); + } + } + } + + public synchronized String attachOrDetachConfigDriveISO(final Connect conn, final String vmName, VirtualMachineTO to, String cdPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException, + InternalErrorException { + String isoPath = ""; + DiskTO configDriveDisk = null; + for (DiskTO disk : to.getDisks()) { + if (disk.getPath() != null && disk.getPath().contains("configdrive")) { + configDriveDisk = disk; + break; + } + } + isoPath = getVolumePath(conn, configDriveDisk, to.isConfigDriveOnHostCache()); + DiskDef iso = new DiskDef(); + if (isAttach && StringUtils.isNotBlank(isoPath) && configDriveDisk !=null && isoPath.lastIndexOf("/") > 0) { + if (isoPath.startsWith(getConfigPath() + "/" + ConfigDrive.CONFIGDRIVEDIR) && isoPath.contains(vmName)) { + iso.defISODisk(isoPath, diskSeq, DiskDef.DiskType.FILE); + } else { + final DataTO diskData = configDriveDisk.getData(); + final String dataName = configDriveDisk.getPath(); + final DataStoreTO store = diskData.getDataStore(); + isoPath = store.getUrl().split("\\?")[0] + File.separator + dataName; + + final int index = isoPath.lastIndexOf("/"); + final String path = isoPath.substring(0, index); + final String name = isoPath.substring(index + 1); + final KVMStoragePool storagePool = storagePoolManager.getStoragePoolByURI(path); + final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name); + final DiskDef.DiskType diskType = getDiskType(isoVol); + isoPath = isoVol.getPath(); + iso.defISODisk(isoPath, diskSeq, diskType); + } + } else { + iso.defISODisk(null, diskSeq, DiskDef.DiskType.FILE); + } + final String result = attachOrDetachDevice(conn, true, vmName, iso.toString()); + if (result == null && !isAttach) { + final List disks = getDisks(conn, vmName); + for (final DiskDef disk : disks) { + if (disk.getDeviceType() == DiskDef.DeviceType.CDROM + && (diskSeq == null || disk.getDiskLabel().equals(iso.getDiskLabel()))) { + cleanupDisk(disk); + } + } + } + return result; + } + public void detachAndAttachConfigDriveISO(final Connect conn, final String vmName) { // detach and re-attach configdrive ISO List disks = getDisks(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java index e15a32876927..e8ec7818941d 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java @@ -229,7 +229,7 @@ Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0. dconn = libvirtUtilitiesHelper.retrieveQemuConnection(destinationUri); if (to.getType() == VirtualMachine.Type.User) { - libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName); + libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName, to); } //run migration in thread so we can monitor it @@ -899,7 +899,7 @@ private boolean findSourceNode(Document doc, Node diskNode, String vmName, Strin Node sourceNode = diskChildNode; NamedNodeMap sourceNodeAttributes = sourceNode.getAttributes(); Node sourceNodeAttribute = sourceNodeAttributes.getNamedItem("file"); - if ( sourceNodeAttribute.getNodeValue().contains(vmName)) { + if ( sourceNodeAttribute != null && sourceNodeAttribute.getNodeValue().contains(vmName)) { diskNode.removeChild(diskChildNode); Element newChildSourceNode = doc.createElement("source"); newChildSourceNode.setAttribute("file", isoPath);