use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.
the class LibvirtComputingResource method getResizeScriptType.
public String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) {
final StoragePoolType poolType = pool.getType();
final PhysicalDiskFormat volFormat = vol.getFormat();
if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) {
return "CLVM";
} else if ((poolType == StoragePoolType.NetworkFilesystem || poolType == StoragePoolType.SharedMountPoint || poolType == StoragePoolType.Filesystem || poolType == StoragePoolType.Gluster) && volFormat == PhysicalDiskFormat.QCOW2) {
return "QCOW2";
} else if (poolType == StoragePoolType.Linstor) {
return RESIZE_NOTIFY_ONLY;
}
throw new CloudRuntimeException("Cannot determine resize type from pool type " + pool.getType());
}
use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.
the class QemuImgFileTest method testFileNameAndSizeAndFormatAtContructor.
@Test
public void testFileNameAndSizeAndFormatAtContructor() {
PhysicalDiskFormat format = PhysicalDiskFormat.RAW;
long size = 1024;
String filename = "/tmp/test-image.qcow2";
QemuImgFile file = new QemuImgFile(filename, size, format);
assertEquals(file.getFileName(), filename);
assertEquals(file.getSize(), size);
assertEquals(file.getFormat(), format);
}
use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.
the class QemuImgTest method testConvertAdvanced.
@Test
public void testConvertAdvanced() throws QemuImgException, LibvirtException {
long srcSize = 4019200;
String srcFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
String destFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
PhysicalDiskFormat srcFormat = PhysicalDiskFormat.RAW;
PhysicalDiskFormat destFormat = PhysicalDiskFormat.QCOW2;
QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize, srcFormat);
QemuImgFile destFile = new QemuImgFile(destFileName, destFormat);
QemuImg qemu = new QemuImg(0);
qemu.create(srcFile);
qemu.convert(srcFile, destFile);
Map<String, String> info = qemu.info(destFile);
PhysicalDiskFormat infoFormat = PhysicalDiskFormat.valueOf(info.get(QemuImg.FILE_FORMAT).toUpperCase());
assertEquals(destFormat, infoFormat);
Long infoSize = Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
assertEquals(Long.valueOf(srcSize), Long.valueOf(infoSize));
File sf = new File(srcFileName);
sf.delete();
File df = new File(destFileName);
df.delete();
}
use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.
the class LibvirtStorageAdaptor method createDiskFromSnapshot.
@Override
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool, int timeout) {
s_logger.info("Creating volume " + name + " from snapshot " + snapshotName + " in pool " + destPool.getUuid() + " (" + destPool.getType().toString() + ")");
PhysicalDiskFormat format = snapshot.getFormat();
long size = snapshot.getSize();
String destPath = destPool.getLocalPath().endsWith("/") ? destPool.getLocalPath() + name : destPool.getLocalPath() + "/" + name;
if (destPool.getType() == StoragePoolType.NetworkFilesystem) {
try {
if (format == PhysicalDiskFormat.QCOW2) {
QemuImg qemu = new QemuImg(timeout);
QemuImgFile destFile = new QemuImgFile(destPath, format);
if (size > snapshot.getVirtualSize()) {
destFile.setSize(size);
} else {
destFile.setSize(snapshot.getVirtualSize());
}
QemuImgFile srcFile = new QemuImgFile(snapshot.getPath(), snapshot.getFormat());
qemu.convert(srcFile, destFile, snapshotName);
}
} catch (QemuImgException | LibvirtException e) {
s_logger.error("Failed to create " + destPath + " due to a failed executing of qemu-img: " + e.getMessage());
}
}
return destPool.getPhysicalDisk(name);
}
use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.
the class LibvirtStorageAdaptor method copyPhysicalDisk.
/**
* This copies a volume from Primary Storage to Secondary Storage
*
* In theory it could also do it the other way around, but the current implementation
* in ManagementServerImpl shows that the destPool is always a Secondary Storage Pool
*/
@Override
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
/**
* With RBD you can't run qemu-img convert with an existing RBD image as destination
* qemu-img will exit with the error that the destination already exists.
* So for RBD we don't create the image, but let qemu-img do that for us.
*
* We then create a KVMPhysicalDisk object that we can return
*
* It is however very unlikely that the destPool will be RBD, since it isn't supported
* for Secondary Storage
*/
KVMStoragePool srcPool = disk.getPool();
PhysicalDiskFormat sourceFormat = disk.getFormat();
String sourcePath = disk.getPath();
KVMPhysicalDisk newDisk;
s_logger.debug("copyPhysicalDisk: disk size:" + toHumanReadableSize(disk.getSize()) + ", virtualsize:" + toHumanReadableSize(disk.getVirtualSize()) + " format:" + disk.getFormat());
if (destPool.getType() != StoragePoolType.RBD) {
if (disk.getFormat() == PhysicalDiskFormat.TAR) {
newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, Storage.ProvisioningType.THIN, disk.getVirtualSize());
} else {
newDisk = destPool.createPhysicalDisk(name, Storage.ProvisioningType.THIN, disk.getVirtualSize());
}
} else {
newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool);
newDisk.setFormat(PhysicalDiskFormat.RAW);
newDisk.setSize(disk.getVirtualSize());
newDisk.setVirtualSize(disk.getSize());
}
String destPath = newDisk.getPath();
PhysicalDiskFormat destFormat = newDisk.getFormat();
QemuImg qemu = new QemuImg(timeout);
QemuImgFile srcFile = null;
QemuImgFile destFile = null;
if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
if (sourceFormat == PhysicalDiskFormat.TAR && destFormat == PhysicalDiskFormat.DIR) {
// LXC template
Script.runSimpleBashScript("cp " + sourcePath + " " + destPath);
} else if (sourceFormat == PhysicalDiskFormat.TAR) {
Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
} else if (sourceFormat == PhysicalDiskFormat.DIR) {
Script.runSimpleBashScript("mkdir -p " + destPath);
Script.runSimpleBashScript("chmod 755 " + destPath);
Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
} else {
srcFile = new QemuImgFile(sourcePath, sourceFormat);
try {
Map<String, String> info = qemu.info(srcFile);
String backingFile = info.get(QemuImg.BACKING_FILE);
// qcow2 templates can just be copied into place
if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) {
String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
if (result != null) {
throw new CloudRuntimeException("Failed to create disk: " + result);
}
} else {
destFile = new QemuImgFile(destPath, destFormat);
try {
qemu.convert(srcFile, destFile);
Map<String, String> destInfo = qemu.info(destFile);
Long virtualSize = Long.parseLong(destInfo.get(QemuImg.VIRTUAL_SIZE));
newDisk.setVirtualSize(virtualSize);
newDisk.setSize(virtualSize);
} catch (QemuImgException | LibvirtException e) {
s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
newDisk = null;
}
}
} catch (QemuImgException | LibvirtException e) {
s_logger.error("Failed to fetch the information of file " + srcFile.getFileName() + " the error was: " + e.getMessage());
newDisk = null;
}
}
} else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) {
/**
* Using qemu-img we copy the QCOW2 disk to RAW (on RBD) directly.
* To do so it's mandatory that librbd on the system is at least 0.67.7 (Ceph Dumpling)
*/
s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2");
try {
srcFile = new QemuImgFile(sourcePath, sourceFormat);
String rbdDestPath = destPool.getSourceDir() + "/" + name;
String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), destPool.getAuthSecret(), rbdDestPath);
destFile = new QemuImgFile(rbdDestFile, destFormat);
s_logger.debug("Starting copy from source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
qemu.convert(srcFile, destFile);
s_logger.debug("Succesfully converted source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
/* We have to stat the RBD image to see how big it became afterwards */
Rados r = new Rados(destPool.getAuthUserName());
r.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
r.confSet("key", destPool.getAuthSecret());
r.confSet("client_mount_timeout", "30");
r.connect();
s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
IoCTX io = r.ioCtxCreate(destPool.getSourceDir());
Rbd rbd = new Rbd(io);
RbdImage image = rbd.open(name);
RbdImageInfo rbdInfo = image.stat();
newDisk.setSize(rbdInfo.size);
newDisk.setVirtualSize(rbdInfo.size);
s_logger.debug("After copy the resulting RBD image " + rbdDestPath + " is " + toHumanReadableSize(rbdInfo.size) + " bytes long");
rbd.close(image);
r.ioCtxDestroy(io);
} catch (QemuImgException | LibvirtException e) {
s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
newDisk = null;
} catch (RadosException e) {
s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
newDisk = null;
} catch (RbdException e) {
s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
newDisk = null;
}
} else {
/**
* We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
* it doesn't benefit us. It's better to keep the current code in place which works
*/
srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), sourcePath));
srcFile.setFormat(sourceFormat);
destFile = new QemuImgFile(destPath);
destFile.setFormat(destFormat);
try {
qemu.convert(srcFile, destFile);
} catch (QemuImgException | LibvirtException e) {
s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
newDisk = null;
}
}
if (newDisk == null) {
throw new CloudRuntimeException("Failed to copy " + disk.getPath() + " to " + name);
}
return newDisk;
}
Aggregations