mirror of https://github.com/apache/cloudstack.git
Linstor: add support for ISO block devices and direct download (#9792)
This commit is contained in:
parent
a73841a693
commit
d54b105a03
|
|
@ -2983,6 +2983,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
return dataPath;
|
return dataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean useBLOCKDiskType(KVMPhysicalDisk physicalDisk) {
|
||||||
|
return physicalDisk != null &&
|
||||||
|
physicalDisk.getPool().getType() == StoragePoolType.Linstor &&
|
||||||
|
physicalDisk.getFormat() != null &&
|
||||||
|
physicalDisk.getFormat()== PhysicalDiskFormat.RAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DiskDef.DiskType getDiskType(KVMPhysicalDisk physicalDisk) {
|
||||||
|
return useBLOCKDiskType(physicalDisk) ? DiskDef.DiskType.BLOCK : DiskDef.DiskType.FILE;
|
||||||
|
}
|
||||||
|
|
||||||
public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException {
|
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 Map<String, String> details = vmSpec.getDetails();
|
||||||
final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
|
final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
|
||||||
|
|
@ -3028,7 +3039,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
physicalDisk = getPhysicalDiskFromNfsStore(dataStoreUrl, data);
|
physicalDisk = getPhysicalDiskFromNfsStore(dataStoreUrl, data);
|
||||||
} else if (primaryDataStoreTO.getPoolType().equals(StoragePoolType.SharedMountPoint) ||
|
} else if (primaryDataStoreTO.getPoolType().equals(StoragePoolType.SharedMountPoint) ||
|
||||||
primaryDataStoreTO.getPoolType().equals(StoragePoolType.Filesystem) ||
|
primaryDataStoreTO.getPoolType().equals(StoragePoolType.Filesystem) ||
|
||||||
primaryDataStoreTO.getPoolType().equals(StoragePoolType.StorPool)) {
|
primaryDataStoreTO.getPoolType().equals(StoragePoolType.StorPool) ||
|
||||||
|
primaryDataStoreTO.getPoolType().equals(StoragePoolType.Linstor)) {
|
||||||
physicalDisk = getPhysicalDiskPrimaryStore(primaryDataStoreTO, data);
|
physicalDisk = getPhysicalDiskPrimaryStore(primaryDataStoreTO, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3078,8 +3090,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
final DiskDef disk = new DiskDef();
|
final DiskDef disk = new DiskDef();
|
||||||
int devId = volume.getDiskSeq().intValue();
|
int devId = volume.getDiskSeq().intValue();
|
||||||
if (volume.getType() == Volume.Type.ISO) {
|
if (volume.getType() == Volume.Type.ISO) {
|
||||||
|
final DiskDef.DiskType diskType = getDiskType(physicalDisk);
|
||||||
disk.defISODisk(volPath, devId, isUefiEnabled);
|
disk.defISODisk(volPath, devId, isUefiEnabled, diskType);
|
||||||
|
|
||||||
if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
|
if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
|
||||||
disk.setBusType(DiskDef.DiskBus.SCSI);
|
disk.setBusType(DiskDef.DiskBus.SCSI);
|
||||||
|
|
@ -3171,7 +3183,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
|
|
||||||
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
||||||
final DiskDef iso = new DiskDef();
|
final DiskDef iso = new DiskDef();
|
||||||
iso.defISODisk(sysvmISOPath);
|
iso.defISODisk(sysvmISOPath, DiskDef.DiskType.FILE);
|
||||||
if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
|
if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
|
||||||
iso.setBusType(DiskDef.DiskBus.SCSI);
|
iso.setBusType(DiskDef.DiskBus.SCSI);
|
||||||
}
|
}
|
||||||
|
|
@ -3384,7 +3396,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
List<DiskDef> disks = getDisks(conn, vmName);
|
List<DiskDef> disks = getDisks(conn, vmName);
|
||||||
DiskDef configdrive = null;
|
DiskDef configdrive = null;
|
||||||
for (DiskDef disk : disks) {
|
for (DiskDef disk : disks) {
|
||||||
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM && disk.getDiskLabel() == CONFIG_DRIVE_ISO_DISK_LABEL) {
|
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM && CONFIG_DRIVE_ISO_DISK_LABEL.equals(disk.getDiskLabel())) {
|
||||||
configdrive = disk;
|
configdrive = disk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3414,11 +3426,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
final String name = isoPath.substring(index + 1);
|
final String name = isoPath.substring(index + 1);
|
||||||
final KVMStoragePool secondaryPool = storagePoolManager.getStoragePoolByURI(path);
|
final KVMStoragePool secondaryPool = storagePoolManager.getStoragePoolByURI(path);
|
||||||
final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
|
final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
|
||||||
|
final DiskDef.DiskType diskType = getDiskType(isoVol);
|
||||||
isoPath = isoVol.getPath();
|
isoPath = isoVol.getPath();
|
||||||
|
|
||||||
iso.defISODisk(isoPath, diskSeq);
|
iso.defISODisk(isoPath, diskSeq, diskType);
|
||||||
} else {
|
} else {
|
||||||
iso.defISODisk(null, diskSeq);
|
iso.defISODisk(null, diskSeq, DiskDef.DiskType.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String result = attachOrDetachDevice(conn, true, vmName, iso.toString());
|
final String result = attachOrDetachDevice(conn, true, vmName, iso.toString());
|
||||||
|
|
@ -3426,7 +3439,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
final List<DiskDef> disks = getDisks(conn, vmName);
|
final List<DiskDef> disks = getDisks(conn, vmName);
|
||||||
for (final DiskDef disk : disks) {
|
for (final DiskDef disk : disks) {
|
||||||
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM
|
if (disk.getDeviceType() == DiskDef.DeviceType.CDROM
|
||||||
&& (diskSeq == null || disk.getDiskLabel() == iso.getDiskLabel())) {
|
&& (diskSeq == null || disk.getDiskLabel().equals(iso.getDiskLabel()))) {
|
||||||
cleanupDisk(disk);
|
cleanupDisk(disk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4002,7 +4015,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||||
return stopVMInternal(conn, vmName, true);
|
return stopVMInternal(conn, vmName, true);
|
||||||
}
|
}
|
||||||
String ret = stopVMInternal(conn, vmName, false);
|
String ret = stopVMInternal(conn, vmName, false);
|
||||||
if (ret == Script.ERR_TIMEOUT) {
|
if (Script.ERR_TIMEOUT.equals(ret)) {
|
||||||
ret = stopVMInternal(conn, vmName, true);
|
ret = stopVMInternal(conn, vmName, true);
|
||||||
} else if (ret != null) {
|
} else if (ret != null) {
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -126,11 +126,10 @@ public class LibvirtDomainXMLParser {
|
||||||
}
|
}
|
||||||
def.defFileBasedDisk(diskFile, diskLabel, DiskDef.DiskBus.valueOf(bus.toUpperCase()), fmt);
|
def.defFileBasedDisk(diskFile, diskLabel, DiskDef.DiskBus.valueOf(bus.toUpperCase()), fmt);
|
||||||
} else if (device.equalsIgnoreCase("cdrom")) {
|
} else if (device.equalsIgnoreCase("cdrom")) {
|
||||||
def.defISODisk(diskFile, i+1, diskLabel);
|
def.defISODisk(diskFile, i+1, diskLabel, DiskDef.DiskType.FILE);
|
||||||
}
|
}
|
||||||
} else if (type.equalsIgnoreCase("block")) {
|
} else if (type.equalsIgnoreCase("block")) {
|
||||||
def.defBlockBasedDisk(diskDev, diskLabel,
|
parseDiskBlock(def, device, diskDev, diskLabel, bus, diskFile, i);
|
||||||
DiskDef.DiskBus.valueOf(bus.toUpperCase()));
|
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(diskCacheMode)) {
|
if (StringUtils.isNotBlank(diskCacheMode)) {
|
||||||
def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
|
def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
|
||||||
|
|
@ -449,6 +448,25 @@ public class LibvirtDomainXMLParser {
|
||||||
return node.getAttribute(attr);
|
return node.getAttribute(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the disk block part of the libvirt XML.
|
||||||
|
* @param def
|
||||||
|
* @param device
|
||||||
|
* @param diskDev
|
||||||
|
* @param diskLabel
|
||||||
|
* @param bus
|
||||||
|
* @param diskFile
|
||||||
|
* @param curDiskIndex
|
||||||
|
*/
|
||||||
|
private void parseDiskBlock(DiskDef def, String device, String diskDev, String diskLabel, String bus,
|
||||||
|
String diskFile, int curDiskIndex) {
|
||||||
|
if (device.equalsIgnoreCase("disk")) {
|
||||||
|
def.defBlockBasedDisk(diskDev, diskLabel, DiskDef.DiskBus.valueOf(bus.toUpperCase()));
|
||||||
|
} else if (device.equalsIgnoreCase("cdrom")) {
|
||||||
|
def.defISODisk(diskFile, curDiskIndex+1, diskLabel, DiskDef.DiskType.BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getVncPort() {
|
public Integer getVncPort() {
|
||||||
return vncPort;
|
return vncPort;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -833,8 +833,8 @@ public class LibvirtVMDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defISODisk(String volPath) {
|
public void defISODisk(String volPath, DiskType diskType) {
|
||||||
_diskType = DiskType.FILE;
|
_diskType = diskType;
|
||||||
_deviceType = DeviceType.CDROM;
|
_deviceType = DeviceType.CDROM;
|
||||||
_sourcePath = volPath;
|
_sourcePath = volPath;
|
||||||
_diskLabel = getDevLabel(3, DiskBus.IDE, true);
|
_diskLabel = getDevLabel(3, DiskBus.IDE, true);
|
||||||
|
|
@ -843,8 +843,8 @@ public class LibvirtVMDef {
|
||||||
_bus = DiskBus.IDE;
|
_bus = DiskBus.IDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defISODisk(String volPath, boolean isUefiEnabled) {
|
public void defISODisk(String volPath, boolean isUefiEnabled, DiskType diskType) {
|
||||||
_diskType = DiskType.FILE;
|
_diskType = diskType;
|
||||||
_deviceType = DeviceType.CDROM;
|
_deviceType = DeviceType.CDROM;
|
||||||
_sourcePath = volPath;
|
_sourcePath = volPath;
|
||||||
_bus = isUefiEnabled ? DiskBus.SATA : DiskBus.IDE;
|
_bus = isUefiEnabled ? DiskBus.SATA : DiskBus.IDE;
|
||||||
|
|
@ -853,18 +853,18 @@ public class LibvirtVMDef {
|
||||||
_diskCacheMode = DiskCacheMode.NONE;
|
_diskCacheMode = DiskCacheMode.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defISODisk(String volPath, Integer devId) {
|
public void defISODisk(String volPath, Integer devId, DiskType diskType) {
|
||||||
defISODisk(volPath, devId, null);
|
defISODisk(volPath, devId, null, diskType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defISODisk(String volPath, Integer devId, String diskLabel) {
|
public void defISODisk(String volPath, Integer devId, String diskLabel, DiskType diskType) {
|
||||||
if (devId == null && StringUtils.isBlank(diskLabel)) {
|
if (devId == null && StringUtils.isBlank(diskLabel)) {
|
||||||
s_logger.debug(String.format("No ID or label informed for volume [%s].", volPath));
|
s_logger.debug(String.format("No ID or label informed for volume [%s].", volPath));
|
||||||
defISODisk(volPath);
|
defISODisk(volPath, diskType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_diskType = DiskType.FILE;
|
_diskType = diskType;
|
||||||
_deviceType = DeviceType.CDROM;
|
_deviceType = DeviceType.CDROM;
|
||||||
_sourcePath = volPath;
|
_sourcePath = volPath;
|
||||||
|
|
||||||
|
|
@ -881,11 +881,11 @@ public class LibvirtVMDef {
|
||||||
_bus = DiskBus.IDE;
|
_bus = DiskBus.IDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void defISODisk(String volPath, Integer devId,boolean isSecure) {
|
public void defISODisk(String volPath, Integer devId, boolean isSecure, DiskType diskType) {
|
||||||
if (!isSecure) {
|
if (!isSecure) {
|
||||||
defISODisk(volPath, devId);
|
defISODisk(volPath, devId, diskType);
|
||||||
} else {
|
} else {
|
||||||
_diskType = DiskType.FILE;
|
_diskType = diskType;
|
||||||
_deviceType = DeviceType.CDROM;
|
_deviceType = DeviceType.CDROM;
|
||||||
_sourcePath = volPath;
|
_sourcePath = volPath;
|
||||||
_diskLabel = getDevLabel(devId, DiskBus.SATA, true);
|
_diskLabel = getDevLabel(devId, DiskBus.SATA, true);
|
||||||
|
|
|
||||||
|
|
@ -1114,11 +1114,12 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||||
storagePool = storagePoolMgr.getStoragePoolByURI(path);
|
storagePool = storagePoolMgr.getStoragePoolByURI(path);
|
||||||
}
|
}
|
||||||
final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name);
|
final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name);
|
||||||
|
final DiskDef.DiskType isoDiskType = LibvirtComputingResource.getDiskType(isoVol);
|
||||||
isoPath = isoVol.getPath();
|
isoPath = isoVol.getPath();
|
||||||
|
|
||||||
iso.defISODisk(isoPath, isUefiEnabled);
|
iso.defISODisk(isoPath, isUefiEnabled, isoDiskType);
|
||||||
} else {
|
} else {
|
||||||
iso.defISODisk(null, isUefiEnabled);
|
iso.defISODisk(null, isUefiEnabled, DiskDef.DiskType.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<DiskDef> disks = resource.getDisks(conn, vmName);
|
final List<DiskDef> disks = resource.getDisks(conn, vmName);
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||||
* Checks if downloaded template is extractable
|
* Checks if downloaded template is extractable
|
||||||
* @return true if it should be extracted, false if not
|
* @return true if it should be extracted, false if not
|
||||||
*/
|
*/
|
||||||
private boolean isTemplateExtractable(String templatePath) {
|
public static boolean isTemplateExtractable(String templatePath) {
|
||||||
String type = Script.runSimpleBashScript("file " + templatePath + " | awk -F' ' '{print $2}'");
|
String type = Script.runSimpleBashScript("file " + templatePath + " | awk -F' ' '{print $2}'");
|
||||||
return type.equalsIgnoreCase("bzip2") || type.equalsIgnoreCase("gzip") || type.equalsIgnoreCase("zip");
|
return type.equalsIgnoreCase("bzip2") || type.equalsIgnoreCase("gzip") || type.equalsIgnoreCase("zip");
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +182,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||||
* @param downloadedTemplateFile
|
* @param downloadedTemplateFile
|
||||||
* @param templateUuid
|
* @param templateUuid
|
||||||
*/
|
*/
|
||||||
private String getExtractCommandForDownloadedFile(String downloadedTemplateFile, String templateUuid) {
|
public static String getExtractCommandForDownloadedFile(String downloadedTemplateFile, String templateUuid) {
|
||||||
if (downloadedTemplateFile.endsWith(".zip")) {
|
if (downloadedTemplateFile.endsWith(".zip")) {
|
||||||
return "unzip -p " + downloadedTemplateFile + " | cat > " + templateUuid;
|
return "unzip -p " + downloadedTemplateFile + " | cat > " + templateUuid;
|
||||||
} else if (downloadedTemplateFile.endsWith(".bz2")) {
|
} else if (downloadedTemplateFile.endsWith(".bz2")) {
|
||||||
|
|
@ -197,7 +197,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||||
/**
|
/**
|
||||||
* Extract downloaded template into installPath, remove compressed file
|
* Extract downloaded template into installPath, remove compressed file
|
||||||
*/
|
*/
|
||||||
private void extractDownloadedTemplate(String downloadedTemplateFile, KVMStoragePool destPool, String destinationFile) {
|
public static void extractDownloadedTemplate(String downloadedTemplateFile, KVMStoragePool destPool, String destinationFile) {
|
||||||
String extractCommand = getExtractCommandForDownloadedFile(downloadedTemplateFile, destinationFile);
|
String extractCommand = getExtractCommandForDownloadedFile(downloadedTemplateFile, destinationFile);
|
||||||
Script.runSimpleBashScript(extractCommand);
|
Script.runSimpleBashScript(extractCommand);
|
||||||
Script.runSimpleBashScript("rm -f " + downloadedTemplateFile);
|
Script.runSimpleBashScript("rm -f " + downloadedTemplateFile);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Disable discard="unmap" for ide devices and qemu < 7.0
|
- Disable discard="unmap" for ide devices and qemu < 7.0
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=2029980
|
https://bugzilla.redhat.com/show_bug.cgi?id=2029980
|
||||||
|
|
||||||
|
## [2024-10-14]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for ISO direct download to primary storage
|
||||||
|
|
||||||
## [2024-10-04]
|
## [2024-10-04]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,13 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.utils.script.Script;
|
||||||
|
|
||||||
import org.apache.cloudstack.storage.datastore.util.LinstorUtil;
|
import org.apache.cloudstack.storage.datastore.util.LinstorUtil;
|
||||||
import org.apache.cloudstack.utils.qemu.QemuImg;
|
import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||||
|
|
@ -56,6 +58,8 @@ import com.linbit.linstor.api.model.StoragePool;
|
||||||
import com.linbit.linstor.api.model.Volume;
|
import com.linbit.linstor.api.model.Volume;
|
||||||
import com.linbit.linstor.api.model.VolumeDefinition;
|
import com.linbit.linstor.api.model.VolumeDefinition;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
@StorageAdaptorInfo(storagePoolType=Storage.StoragePoolType.Linstor)
|
@StorageAdaptorInfo(storagePoolType=Storage.StoragePoolType.Linstor)
|
||||||
public class LinstorStorageAdaptor implements StorageAdaptor {
|
public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||||
private static final Logger s_logger = Logger.getLogger(LinstorStorageAdaptor.class);
|
private static final Logger s_logger = Logger.getLogger(LinstorStorageAdaptor.class);
|
||||||
|
|
@ -563,13 +567,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||||
name, QemuImg.PhysicalDiskFormat.RAW, provisioningType, disk.getVirtualSize(), null);
|
name, QemuImg.PhysicalDiskFormat.RAW, provisioningType, disk.getVirtualSize(), null);
|
||||||
|
|
||||||
final DevelopersApi api = getLinstorAPI(destPools);
|
final DevelopersApi api = getLinstorAPI(destPools);
|
||||||
final String rscName = LinstorUtil.RSC_PREFIX + name;
|
applyAuxProps(api, name, disk.getDispName(), disk.getVmName());
|
||||||
try {
|
|
||||||
LinstorUtil.applyAuxProps(api, rscName, disk.getDispName(), disk.getVmName());
|
|
||||||
} catch (ApiException apiExc) {
|
|
||||||
s_logger.error(String.format("Error setting aux properties for %s", rscName));
|
|
||||||
logLinstorAnswers(apiExc.getApiCallRcList());
|
|
||||||
}
|
|
||||||
|
|
||||||
s_logger.debug(String.format("Linstor.copyPhysicalDisk: dstPath: %s", dstDisk.getPath()));
|
s_logger.debug(String.format("Linstor.copyPhysicalDisk: dstPath: %s", dstDisk.getPath()));
|
||||||
final QemuImgFile destFile = new QemuImgFile(dstDisk.getPath());
|
final QemuImgFile destFile = new QemuImgFile(dstDisk.getPath());
|
||||||
|
|
@ -620,13 +618,57 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fileExistsOrThrow(String templateFilePath) {
|
||||||
|
File sourceFile = new File(templateFilePath);
|
||||||
|
if (!sourceFile.exists()) {
|
||||||
|
throw new CloudRuntimeException("Direct download template file " + sourceFile +
|
||||||
|
" does not exist on this host");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFinalDirectDownloadPath(String templateFilePath, KVMStoragePool destPool) {
|
||||||
|
String finalSourcePath = templateFilePath;
|
||||||
|
if (LibvirtStorageAdaptor.isTemplateExtractable(templateFilePath)) {
|
||||||
|
finalSourcePath = templateFilePath.substring(0, templateFilePath.lastIndexOf('.'));
|
||||||
|
LibvirtStorageAdaptor.extractDownloadedTemplate(templateFilePath, destPool, finalSourcePath);
|
||||||
|
}
|
||||||
|
return finalSourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyAuxProps(DevelopersApi api, String csPath, String csName, String csVMName) {
|
||||||
|
final String rscName = getLinstorRscName(csPath);
|
||||||
|
try {
|
||||||
|
LinstorUtil.applyAuxProps(api, rscName, csName, csVMName);
|
||||||
|
} catch (ApiException apiExc) {
|
||||||
|
s_logger.error(String.format("Error setting aux properties for %s", rscName));
|
||||||
|
logLinstorAnswers(apiExc.getApiCallRcList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KVMPhysicalDisk createTemplateFromDirectDownloadFile(String templateFilePath, String destTemplatePath,
|
public KVMPhysicalDisk createTemplateFromDirectDownloadFile(String templateFilePath, String destTemplatePath,
|
||||||
KVMStoragePool destPool, Storage.ImageFormat format,
|
KVMStoragePool destPool, Storage.ImageFormat format,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
s_logger.debug("Linstor: createTemplateFromDirectDownloadFile");
|
s_logger.debug(String.format("Linstor: createTemplateFromDirectDownloadFile: %s/%s", templateFilePath, format));
|
||||||
return null;
|
fileExistsOrThrow(templateFilePath);
|
||||||
|
String name = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
String finalSourcePath = getFinalDirectDownloadPath(templateFilePath, destPool);
|
||||||
|
|
||||||
|
File finalSourceFile = new File(finalSourcePath);
|
||||||
|
final KVMPhysicalDisk dstDisk = destPool.createPhysicalDisk(
|
||||||
|
name, QemuImg.PhysicalDiskFormat.RAW, Storage.ProvisioningType.THIN, finalSourceFile.length(), null);
|
||||||
|
|
||||||
|
final DevelopersApi api = getLinstorAPI(destPool);
|
||||||
|
applyAuxProps(api, name, finalSourceFile.getName(), null);
|
||||||
|
|
||||||
|
Script.runSimpleBashScript(
|
||||||
|
String.format("dd if=\"%s\" of=\"%s\" bs=64k conv=nocreat,sparse oflag=direct",
|
||||||
|
finalSourcePath, dstDisk.getPath()));
|
||||||
|
|
||||||
|
Script.runSimpleBashScript("rm " + finalSourcePath);
|
||||||
|
return dstDisk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getCapacity(LinstorStoragePool pool) {
|
public long getCapacity(LinstorStoragePool pool) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue