Skip to content

Commit 663b4ef

Browse files
authored
Merge pull request #636 from jschoiRR/mold-main#2025
[Mold API, Agent, UI] VM 라이브 마이그레이션시 ConfigDrive iso 경로 설정 오류 수정, 비관리 인스턴서 가져오기 스토리지별 호환 로직 수정(rbd, gfs, clvm, local)
2 parents b9932e4 + d0b051f commit 663b4ef

File tree

6 files changed

+108
-23
lines changed

6 files changed

+108
-23
lines changed

api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ public class ApiServiceConfiguration implements Configurable {public static fina
3737
public static final ConfigKey<String> MonitoringWallPortalPort = new ConfigKey<String>("Advanced", String.class, "monitoring.wall.portal.port",
3838
"3000", "Monitoring Service Wall Portal Port.(ex:3000)", true);
3939
public static final ConfigKey<String> MonitoringWallPortalVmUri = new ConfigKey<String>("Advanced", String.class, "monitoring.wall.portal.vm.uri",
40-
"/d/uservm?kiosk&theme=light", "Monitoring Service Wall Portal VM Uri.(ex:/d/uservm?kiosk&theme=light)", true);
40+
"/d/uservm?kiosk", "Monitoring Service Wall Portal VM Uri.(ex:/d/uservm?kiosk)", true);
4141
public static final ConfigKey<String> MonitoringWallPortalHostUri = new ConfigKey<String>("Advanced", String.class, "monitoring.wall.portal.host.uri",
42-
"/d/Q3Jkjf54zs?kiosk&theme=light", "Monitoring Service Wall Portal Host Uri.(ex:/d/Q3Jkjf54zs?kiosk&theme=light)", true);
42+
"/d/Q3Jkjf54zs?kiosk", "Monitoring Service Wall Portal Host Uri.(ex:/d/Q3Jkjf54zs?kiosk)", true);
4343
public static final ConfigKey<String> MonitoringWallPortalClusterUri = new ConfigKey<String>("Advanced", String.class, "monitoring.wall.portal.cluster.uri",
44-
"/d/fasdasdasdw?kiosk&theme=light", "Monitoring Service Wall Portal Cluster Uri.(ex:/d/fasdasdasdw?kiosk&theme=light)", true);
44+
"/d/fasdasdasdw?kiosk", "Monitoring Service Wall Portal Cluster Uri.(ex:/d/fasdasdasdw?kiosk)", true);
4545
public static final ConfigKey<Boolean> EventDeleteEnabled = new ConfigKey<>("Advanced", Boolean.class, "event.delete.enabled",
4646
"false", "true if Event Delete Button is enabled, false otherwise)", false);
4747

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,6 +3792,81 @@ protected KVMStoragePoolManager getPoolManager() {
37923792
return storagePoolManager;
37933793
}
37943794

3795+
public void detachAndAttachConfigDriveISO(final Connect conn, final String vmName, VirtualMachineTO to) {
3796+
// detach and re-attach configdrive ISO
3797+
List<DiskDef> disks = getDisks(conn, vmName);
3798+
DiskDef configdrive = null;
3799+
for (DiskDef disk : disks) {
3800+
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM && CONFIG_DRIVE_ISO_DISK_LABEL.equals(disk.getDiskLabel())) {
3801+
configdrive = disk;
3802+
}
3803+
}
3804+
3805+
if (configdrive != null) {
3806+
try {
3807+
LOGGER.debug(String.format("Detaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath()));
3808+
String result = attachOrDetachConfigDriveISO(conn, vmName, to, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID);
3809+
if (result != null) {
3810+
LOGGER.warn(String.format("Detach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result));
3811+
}
3812+
LOGGER.debug(String.format("Attaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath()));
3813+
result = attachOrDetachConfigDriveISO(conn, vmName, to, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID);
3814+
if (result != null) {
3815+
LOGGER.warn(String.format("Attach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result));
3816+
}
3817+
} catch (final LibvirtException | InternalErrorException | URISyntaxException e) {
3818+
final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString();
3819+
LOGGER.warn(msg, e);
3820+
}
3821+
}
3822+
}
3823+
3824+
public synchronized String attachOrDetachConfigDriveISO(final Connect conn, final String vmName, VirtualMachineTO to, String cdPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException,
3825+
InternalErrorException {
3826+
String isoPath = "";
3827+
DiskTO configDriveDisk = null;
3828+
for (DiskTO disk : to.getDisks()) {
3829+
if (disk.getPath() != null && disk.getPath().contains("configdrive")) {
3830+
configDriveDisk = disk;
3831+
break;
3832+
}
3833+
}
3834+
isoPath = getVolumePath(conn, configDriveDisk, to.isConfigDriveOnHostCache());
3835+
DiskDef iso = new DiskDef();
3836+
if (isAttach && StringUtils.isNotBlank(isoPath) && configDriveDisk !=null && isoPath.lastIndexOf("/") > 0) {
3837+
if (isoPath.startsWith(getConfigPath() + "/" + ConfigDrive.CONFIGDRIVEDIR) && isoPath.contains(vmName)) {
3838+
iso.defISODisk(isoPath, diskSeq, DiskDef.DiskType.FILE);
3839+
} else {
3840+
final DataTO diskData = configDriveDisk.getData();
3841+
final String dataName = configDriveDisk.getPath();
3842+
final DataStoreTO store = diskData.getDataStore();
3843+
isoPath = store.getUrl().split("\\?")[0] + File.separator + dataName;
3844+
3845+
final int index = isoPath.lastIndexOf("/");
3846+
final String path = isoPath.substring(0, index);
3847+
final String name = isoPath.substring(index + 1);
3848+
final KVMStoragePool storagePool = storagePoolManager.getStoragePoolByURI(path);
3849+
final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name);
3850+
final DiskDef.DiskType diskType = getDiskType(isoVol);
3851+
isoPath = isoVol.getPath();
3852+
iso.defISODisk(isoPath, diskSeq, diskType);
3853+
}
3854+
} else {
3855+
iso.defISODisk(null, diskSeq, DiskDef.DiskType.FILE);
3856+
}
3857+
final String result = attachOrDetachDevice(conn, true, vmName, iso.toString());
3858+
if (result == null && !isAttach) {
3859+
final List<DiskDef> disks = getDisks(conn, vmName);
3860+
for (final DiskDef disk : disks) {
3861+
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM
3862+
&& (diskSeq == null || disk.getDiskLabel().equals(iso.getDiskLabel()))) {
3863+
cleanupDisk(disk);
3864+
}
3865+
}
3866+
}
3867+
return result;
3868+
}
3869+
37953870
public void detachAndAttachConfigDriveISO(final Connect conn, final String vmName) {
37963871
// detach and re-attach configdrive ISO
37973872
List<DiskDef> disks = getDisks(conn, vmName);

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.libvirt.Domain;
3535
import org.libvirt.DomainBlockInfo;
3636
import org.libvirt.LibvirtException;
37+
import org.libvirt.StoragePool;
38+
import org.libvirt.StorageVol;
3739

3840
import java.util.ArrayList;
3941
import java.util.HashMap;
@@ -120,7 +122,6 @@ private UnmanagedInstanceTO getUnmanagedInstance(LibvirtComputingResource libvir
120122

121123
final UnmanagedInstanceTO instance = new UnmanagedInstanceTO();
122124
instance.setName(domain.getName());
123-
124125
instance.setCpuCores((int) LibvirtComputingResource.countDomainRunningVcpus(domain));
125126
if (parser.getCpuTuneDef() !=null) {
126127
instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores());
@@ -221,7 +222,17 @@ private List<UnmanagedInstanceTO.Disk> getUnmanagedInstanceDisks(List<LibvirtVMD
221222
disk.setDatastoreType(diskDef.getDiskType().toString());
222223
disk.setDatastorePort(diskDef.getSourceHostPort());
223224
disk.setImagePath(diskDef.getSourcePath());
224-
disk.setDatastoreName(disk.getDatastorePath());
225+
try {
226+
String rbdImagePath = "";
227+
if (diskDef.getSourcePath().contains("/dev/rbd")) {
228+
rbdImagePath = diskDef.getSourcePath().replace("/dev/rbd/", "");
229+
}
230+
StorageVol storageVolLookupByPath = conn.storageVolLookupByPath("".equals(rbdImagePath) ? diskDef.getSourcePath() : rbdImagePath);
231+
StoragePool sp = storageVolLookupByPath.storagePoolLookupByVolume();
232+
disk.setDatastoreName(sp.getName());
233+
} catch (LibvirtException e) {
234+
throw new RuntimeException(e);
235+
}
225236
disk.setFileBaseName(getDiskRelativePath(diskDef));
226237
disks.add(disk);
227238
}

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0.
229229
dconn = libvirtUtilitiesHelper.retrieveQemuConnection(destinationUri);
230230

231231
if (to.getType() == VirtualMachine.Type.User) {
232-
libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName);
232+
libvirtComputingResource.detachAndAttachConfigDriveISO(conn, vmName, to);
233233
}
234234

235235
//run migration in thread so we can monitor it
@@ -899,7 +899,7 @@ private boolean findSourceNode(Document doc, Node diskNode, String vmName, Strin
899899
Node sourceNode = diskChildNode;
900900
NamedNodeMap sourceNodeAttributes = sourceNode.getAttributes();
901901
Node sourceNodeAttribute = sourceNodeAttributes.getNamedItem("file");
902-
if ( sourceNodeAttribute.getNodeValue().contains(vmName)) {
902+
if ( sourceNodeAttribute != null && sourceNodeAttribute.getNodeValue().contains(vmName)) {
903903
diskNode.removeChild(diskChildNode);
904904
Element newChildSourceNode = doc.createElement("source");
905905
newChildSourceNode.setAttribute("file", isoPath);

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -544,20 +544,8 @@ private StoragePool getStoragePool(final UnmanagedInstanceTO.Disk disk, final Da
544544
final String dsPath = disk.getDatastorePath();
545545
final String dsType = disk.getDatastoreType();
546546
final String dsName = disk.getDatastoreName();
547-
logger.debug("### DataStore [Host:%s, Path:%s, Type:%s, Uuid:%s" ,dsHost, dsPath, dsType, dsName);
548-
if (dsType != null) {
549-
List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath);
550-
for (StoragePool pool : pools) {
551-
if (pool.getDataCenterId() == zone.getId() &&
552-
(pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId())) &&
553-
volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) {
554-
storagePool = pool;
555-
break;
556-
}
557-
}
558-
}
559-
560-
if (storagePool == null) {
547+
logger.debug(String.format("### DataStore [Host:%s, Path:%s, Type:%s, Name:%s]" , dsHost, dsPath, dsType, dsName));
548+
if (dsName != null) {
561549
List<StoragePoolVO> pools = primaryDataStoreDao.listPoolsByCluster(cluster.getId());
562550
pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId()));
563551
for (StoragePool pool : pools) {
@@ -570,6 +558,17 @@ private StoragePool getStoragePool(final UnmanagedInstanceTO.Disk disk, final Da
570558
}
571559
}
572560
}
561+
if (storagePool == null) {
562+
List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath);
563+
for (StoragePool pool : pools) {
564+
if (pool.getDataCenterId() == zone.getId() &&
565+
(pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId())) &&
566+
volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) {
567+
storagePool = pool;
568+
break;
569+
}
570+
}
571+
}
573572
if (storagePool == null) {
574573
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()));
575574
}

ui/src/views/plugins/IFrameWall.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ export default {
5353
var uri = wallPortalProtocol + '://' + wallPortalDomain + ':' + wallPortalPort
5454
if (typeof hypervisortype !== 'undefined' && hypervisortype !== null && hypervisortype !== '') {
5555
const clusterUriPath = items.filter(x => x.name === 'monitoring.wall.portal.cluster.uri')[0]?.value
56-
this.uriInfo = uri + clusterUriPath
56+
this.uriInfo = uri + clusterUriPath + '&theme=light'
5757
} else {
5858
const hostUriPath = items.filter(x => x.name === 'monitoring.wall.portal.host.uri')[0]?.value
59-
this.uriInfo = uri + hostUriPath + '&var-host=' + this.resource.ipaddress
59+
this.uriInfo = uri + hostUriPath + '&theme=light&var-host=' + this.resource.ipaddress
6060
}
6161
this.uriCreateOk = true
6262
})

0 commit comments

Comments
 (0)