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/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/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())); } 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 })