use of com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FilesystemDef in project cloudstack by apache.
the class LibvirtComputingResource method createVbd.
public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException {
final Map<String, String> details = vmSpec.getDetails();
final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
boolean isSecureBoot = false;
boolean isWindowsTemplate = false;
Collections.sort(disks, new Comparator<DiskTO>() {
@Override
public int compare(final DiskTO arg0, final DiskTO arg1) {
return arg0.getDiskSeq() > arg1.getDiskSeq() ? 1 : -1;
}
});
boolean isUefiEnabled = MapUtils.isNotEmpty(details) && details.containsKey(GuestDef.BootType.UEFI.toString());
if (isUefiEnabled) {
isSecureBoot = isSecureMode(details.get(GuestDef.BootType.UEFI.toString()));
}
if (vmSpec.getOs().toLowerCase().contains("window")) {
isWindowsTemplate = true;
}
for (final DiskTO volume : disks) {
KVMPhysicalDisk physicalDisk = null;
KVMStoragePool pool = null;
final DataTO data = volume.getData();
if (volume.getType() == Volume.Type.ISO && data.getPath() != null) {
DataStoreTO dataStore = data.getDataStore();
String dataStoreUrl = null;
if (data.getPath().startsWith(ConfigDrive.CONFIGDRIVEDIR) && vmSpec.isConfigDriveOnHostCache() && data instanceof TemplateObjectTO) {
String configDrivePath = getConfigPath() + "/" + data.getPath();
physicalDisk = new KVMPhysicalDisk(configDrivePath, ((TemplateObjectTO) data).getUuid(), null);
physicalDisk.setFormat(PhysicalDiskFormat.FILE);
} else if (dataStore instanceof NfsTO) {
NfsTO nfsStore = (NfsTO) data.getDataStore();
dataStoreUrl = nfsStore.getUrl();
physicalDisk = getPhysicalDiskFromNfsStore(dataStoreUrl, data);
} else if (dataStore instanceof PrimaryDataStoreTO) {
// In order to support directly downloaded ISOs
PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) dataStore;
if (primaryDataStoreTO.getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
String psHost = primaryDataStoreTO.getHost();
String psPath = primaryDataStoreTO.getPath();
dataStoreUrl = "nfs://" + psHost + File.separator + psPath;
physicalDisk = getPhysicalDiskFromNfsStore(dataStoreUrl, data);
} else if (primaryDataStoreTO.getPoolType().equals(StoragePoolType.SharedMountPoint) || primaryDataStoreTO.getPoolType().equals(StoragePoolType.Filesystem)) {
physicalDisk = getPhysicalDiskPrimaryStore(primaryDataStoreTO, data);
}
}
} else if (volume.getType() != Volume.Type.ISO) {
final PrimaryDataStoreTO store = (PrimaryDataStoreTO) data.getDataStore();
physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
pool = physicalDisk.getPool();
}
String volPath = null;
if (physicalDisk != null) {
volPath = physicalDisk.getPath();
}
if (volume.getType() != Volume.Type.ISO && physicalDisk != null && physicalDisk.getFormat() == PhysicalDiskFormat.QCOW2 && (pool.getType() == StoragePoolType.NetworkFilesystem || pool.getType() == StoragePoolType.SharedMountPoint || pool.getType() == StoragePoolType.Filesystem || pool.getType() == StoragePoolType.Gluster)) {
setBackingFileFormat(physicalDisk.getPath());
}
// check for disk activity, if detected we should exit because vm is running elsewhere
if (_diskActivityCheckEnabled && physicalDisk != null && physicalDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
s_logger.debug("Checking physical disk file at path " + volPath + " for disk activity to ensure vm is not running elsewhere");
try {
HypervisorUtils.checkVolumeFileForActivity(volPath, _diskActivityCheckTimeoutSeconds, _diskActivityInactiveThresholdMilliseconds, _diskActivityCheckFileSizeMin);
} catch (final IOException ex) {
throw new CloudRuntimeException("Unable to check physical disk file for activity", ex);
}
s_logger.debug("Disk activity check cleared");
}
// if params contains a rootDiskController key, use its value (this is what other HVs are doing)
DiskDef.DiskBus diskBusType = getDiskModelFromVMDetail(vmSpec);
if (diskBusType == null) {
diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator(), isUefiEnabled);
}
DiskDef.DiskBus diskBusTypeData = getDataDiskModelFromVMDetail(vmSpec);
if (diskBusTypeData == null) {
diskBusTypeData = (diskBusType == DiskDef.DiskBus.SCSI) ? diskBusType : DiskDef.DiskBus.VIRTIO;
}
final DiskDef disk = new DiskDef();
int devId = volume.getDiskSeq().intValue();
if (volume.getType() == Volume.Type.ISO) {
disk.defISODisk(volPath, devId, isUefiEnabled);
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
disk.setBusType(DiskDef.DiskBus.SCSI);
}
} else {
if (diskBusType == DiskDef.DiskBus.SCSI) {
disk.setQemuDriver(true);
disk.setDiscard(DiscardType.UNMAP);
}
setDiskIoDriver(disk);
if (pool.getType() == StoragePoolType.RBD) {
/*
For RBD pools we use the secret mechanism in libvirt.
We store the secret under the UUID of the pool, that's why
we pass the pool's UUID as the authSecret
*/
disk.defNetworkBasedDisk(physicalDisk.getPath().replace("rbd:", ""), pool.getSourceHost(), pool.getSourcePort(), pool.getAuthUserName(), pool.getUuid(), devId, diskBusType, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
} else if (pool.getType() == StoragePoolType.PowerFlex) {
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData);
} else if (pool.getType() == StoragePoolType.Gluster) {
final String mountpoint = pool.getLocalPath();
final String path = physicalDisk.getPath();
final String glusterVolume = pool.getSourceDir().replace("/", "");
disk.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), pool.getSourceHost(), pool.getSourcePort(), null, null, devId, diskBusType, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
} else if (pool.getType() == StoragePoolType.CLVM || physicalDisk.getFormat() == PhysicalDiskFormat.RAW) {
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData);
} else {
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
}
} else {
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
} else {
if (isSecureBoot) {
disk.defFileBasedDisk(physicalDisk.getPath(), devId, DiskDef.DiskFmtType.QCOW2, isWindowsTemplate);
} else {
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusType, DiskDef.DiskFmtType.QCOW2);
}
}
}
}
if (data instanceof VolumeObjectTO) {
final VolumeObjectTO volumeObjectTO = (VolumeObjectTO) data;
disk.setSerial(diskUuidToSerial(volumeObjectTO.getUuid()));
setBurstProperties(volumeObjectTO, disk);
if (volumeObjectTO.getCacheMode() != null) {
disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase()));
}
}
if (vm.getDevices() == null) {
s_logger.error("There is no devices for" + vm);
throw new RuntimeException("There is no devices for" + vm);
}
vm.getDevices().addDevice(disk);
}
if (vmSpec.getType() != VirtualMachine.Type.User) {
if (_sysvmISOPath != null) {
final DiskDef iso = new DiskDef();
iso.defISODisk(_sysvmISOPath);
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
iso.setBusType(DiskDef.DiskBus.SCSI);
}
vm.getDevices().addDevice(iso);
}
}
// For LXC, find and add the root filesystem, rbd data disks
if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) {
for (final DiskTO volume : disks) {
final DataTO data = volume.getData();
final PrimaryDataStoreTO store = (PrimaryDataStoreTO) data.getDataStore();
if (volume.getType() == Volume.Type.ROOT) {
final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
final FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/");
vm.getDevices().addDevice(rootFs);
} else if (volume.getType() == Volume.Type.DATADISK) {
final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
final KVMStoragePool pool = physicalDisk.getPool();
if (StoragePoolType.RBD.equals(pool.getType())) {
final int devId = volume.getDiskSeq().intValue();
final String device = mapRbdDevice(physicalDisk);
if (device != null) {
s_logger.debug("RBD device on host is: " + device);
final DiskDef diskdef = new DiskDef();
diskdef.defBlockBasedDisk(device, devId, DiskDef.DiskBus.VIRTIO);
diskdef.setQemuDriver(false);
vm.getDevices().addDevice(diskdef);
} else {
throw new InternalErrorException("Error while mapping RBD device on host");
}
}
}
}
}
}
Aggregations