You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by wi...@apache.org on 2013/02/26 17:29:33 UTC
git commit: refs/heads/qemu-img - kvm: Wrap qemu-img into it's own
util
Updated Branches:
refs/heads/qemu-img e1cb7927c -> 4d022483f (forced update)
kvm: Wrap qemu-img into it's own util
The KVM Agent used to run Script.runSimpleBashScript for various qemu-img
methods, but the output was not always checked properly.
This patch wraps qemu-img into it's own util to make integration more clean.
The goal is also to have more reliable executing since we can better check
if qemu-img did it's job.
Tests are also included to test the code.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/4d022483
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/4d022483
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/4d022483
Branch: refs/heads/qemu-img
Commit: 4d022483f2a57e8bfb49c6ac36663023be0ee3fe
Parents: 0b35f71
Author: Wido den Hollander <wi...@widodh.nl>
Authored: Tue Feb 5 23:05:55 2013 +0100
Committer: Wido den Hollander <wi...@widodh.nl>
Committed: Tue Feb 26 17:14:49 2013 +0100
----------------------------------------------------------------------
.../kvm/resource/LibvirtComputingResource.java | 32 +-
.../kvm/resource/LibvirtDomainXMLParser.java | 1 +
.../hypervisor/kvm/storage/KVMPhysicalDisk.java | 15 +-
.../hypervisor/kvm/storage/KVMStoragePool.java | 2 +-
.../kvm/storage/KVMStoragePoolManager.java | 9 +-
.../kvm/storage/LibvirtStorageAdaptor.java | 150 ++++---
.../hypervisor/kvm/storage/LibvirtStoragePool.java | 2 +-
.../hypervisor/kvm/storage/StorageAdaptor.java | 2 +-
utils/src/com/cloud/utils/script/Script.java | 21 +-
.../org/apache/cloudstack/utils/qemu/QemuImg.java | 352 +++++++++++++++
.../cloudstack/utils/qemu/QemuImgException.java | 25 +
.../apache/cloudstack/utils/qemu/QemuImgFile.java | 72 +++
.../cloudstack/utils/qemu/QemuImgFileTest.java | 60 +++
.../apache/cloudstack/utils/qemu/QemuImgTest.java | 287 ++++++++++++
14 files changed, 917 insertions(+), 113 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 99b8723..1094dc6 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -55,6 +55,10 @@ import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo;
@@ -188,7 +192,6 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.hostNicType;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.network.Networks.BroadcastDomainType;
@@ -1318,12 +1321,12 @@ ServerResource {
StoragePoolType poolType = pool.getType();
PhysicalDiskFormat volFormat = vol.getFormat();
- if(pool.getType() == StoragePoolType.CLVM && volFormat == KVMPhysicalDisk.PhysicalDiskFormat.RAW) {
+ if(pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) {
return "CLVM";
} else if ((poolType == StoragePoolType.NetworkFilesystem
|| poolType == StoragePoolType.SharedMountPoint
|| poolType == StoragePoolType.Filesystem)
- && volFormat == KVMPhysicalDisk.PhysicalDiskFormat.QCOW2 ) {
+ && volFormat == PhysicalDiskFormat.QCOW2 ) {
return "QCOW2";
}
return null;
@@ -2129,14 +2132,25 @@ ServerResource {
}
} else {
s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + cmd.getUniqueName());
- Script.runSimpleBashScript("qemu-img convert"
- + " -f raw -O qcow2 "
- + KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(),
+
+ QemuImgFile srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(),
primary.getSourcePort(),
primary.getAuthUserName(),
primary.getAuthSecret(),
- disk.getPath())
- + " " + tmpltPath + "/" + cmd.getUniqueName() + ".qcow2");
+ disk.getPath()));
+ srcFile.setFormat(PhysicalDiskFormat.RAW);
+
+ QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2");
+ destFile.setFormat(PhysicalDiskFormat.QCOW2);
+
+ QemuImg q = new QemuImg();
+ try {
+ q.convert(srcFile, destFile);
+ } catch (QemuImgException e) {
+ s_logger.error("Failed to create new template while converting "
+ + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
+ }
+
File templateProp = new File(tmpltPath + "/template.properties");
if (!templateProp.exists()) {
templateProp.createNewFile();
@@ -3181,7 +3195,7 @@ ServerResource {
if (!foundDisk) {
s_logger.debug("generating new patch disk for " + vmName + " since none was found");
- KVMPhysicalDisk disk = pool.createPhysicalDisk(patchName, KVMPhysicalDisk.PhysicalDiskFormat.RAW,
+ KVMPhysicalDisk disk = pool.createPhysicalDisk(patchName, PhysicalDiskFormat.RAW,
10L * 1024 * 1024);
} else {
s_logger.debug("found existing patch disk at " + patchDiskPath + " using it for " + vmName);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
index b622b6d..893dfa9 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
@@ -25,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
index 08f51a4..907c251 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
@@ -16,24 +16,13 @@
// under the License.
package com.cloud.hypervisor.kvm.storage;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
public class KVMPhysicalDisk {
private String path;
private String name;
private KVMStoragePool pool;
- public static enum PhysicalDiskFormat {
- RAW("raw"), QCOW2("qcow2");
- String format;
-
- private PhysicalDiskFormat(String format) {
- this.format = format;
- }
-
- public String toString() {
- return this.format;
- }
- }
-
public static String RBDStringBuilder(String monHost, int monPort,
String authUserName, String authSecret, String image) {
String rbdOpts;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
index 5437e7c..9ab1216 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
@@ -18,7 +18,7 @@ package com.cloud.hypervisor.kvm.storage;
import java.util.List;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import com.cloud.storage.Storage.StoragePoolType;
public interface KVMStoragePool {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
index c2bfad9..2a3b14e 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
@@ -23,10 +23,11 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.UUID;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
import com.cloud.hypervisor.kvm.resource.KVMHABase;
import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType;
import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -134,14 +135,14 @@ public class KVMStoragePoolManager {
// LibvirtStorageAdaptor-specific statement
if (destPool.getType() == StoragePoolType.RBD) {
return adaptor.createDiskFromTemplate(template, name,
- KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(), destPool);
+ PhysicalDiskFormat.RAW, template.getSize(), destPool);
} else if (destPool.getType() == StoragePoolType.CLVM) {
return adaptor.createDiskFromTemplate(template, name,
- KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(),
+ PhysicalDiskFormat.RAW, template.getSize(),
destPool);
} else {
return adaptor.createDiskFromTemplate(template, name,
- KVMPhysicalDisk.PhysicalDiskFormat.QCOW2,
+ PhysicalDiskFormat.QCOW2,
template.getSize(), destPool);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index d350ef9..eae2314 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -22,8 +22,14 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import java.util.Map;
+import java.util.HashMap;
import org.apache.log4j.Logger;
import org.apache.commons.codec.binary.Base64;
+import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import org.libvirt.Secret;
@@ -43,7 +49,6 @@ import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.poolType;
import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.authType;
import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef.volFormat;
import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeXMLParser;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.exception.InternalErrorException;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
@@ -411,11 +416,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
if (voldef.getFormat() == null) {
disk.setFormat(pool.getDefaultFormat());
} else if (pool.getType() == StoragePoolType.RBD) {
- disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW);
+ disk.setFormat(PhysicalDiskFormat.RAW);
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) {
- disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.QCOW2);
+ disk.setFormat(PhysicalDiskFormat.QCOW2);
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) {
- disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW);
+ disk.setFormat(PhysicalDiskFormat.RAW);
}
return disk;
} catch (LibvirtException e) {
@@ -586,50 +591,52 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
We then create a KVMPhysicalDisk object that we can return
*/
- if (destPool.getType() != StoragePoolType.RBD) {
- disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
-
- if (format == PhysicalDiskFormat.QCOW2) {
- Script.runSimpleBashScript("qemu-img create -f "
- + template.getFormat() + " -b " + template.getPath() + " "
- + disk.getPath());
- } else if (format == PhysicalDiskFormat.RAW) {
- Script.runSimpleBashScript("qemu-img convert -f "
- + template.getFormat() + " -O raw " + template.getPath()
- + " " + disk.getPath());
- }
- } else {
- disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
- disk.setFormat(format);
- disk.setSize(template.getVirtualSize());
- disk.setVirtualSize(disk.getSize());
-
- if (srcPool.getType() != StoragePoolType.RBD) {
- Script.runSimpleBashScript("qemu-img convert"
- + " -f " + template.getFormat()
- + " -O " + format
- + " " + template.getPath()
- + " " + KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
- destPool.getSourcePort(),
- destPool.getAuthUserName(),
- destPool.getAuthSecret(),
- disk.getPath()));
+ try {
+ if (destPool.getType() != StoragePoolType.RBD) {
+ disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
+
+ if (format == PhysicalDiskFormat.QCOW2) {
+ QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
+ QemuImgFile destFile = new QemuImgFile(disk.getPath());
+ QemuImg qemu = new QemuImg();
+ qemu.create(destFile, backingFile);
+ } else if (format == PhysicalDiskFormat.RAW) {
+ QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
+ QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
+ QemuImg qemu = new QemuImg();
+ qemu.convert(sourceFile, destFile);
+ }
} else {
- template.setFormat(PhysicalDiskFormat.RAW);
- Script.runSimpleBashScript("qemu-img convert"
- + " -f " + template.getFormat()
- + " -O " + format
- + " " + KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
- srcPool.getSourcePort(),
- srcPool.getAuthUserName(),
- srcPool.getAuthSecret(),
- template.getPath())
- + " " + KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
- destPool.getSourcePort(),
- destPool.getAuthUserName(),
- destPool.getAuthSecret(),
- disk.getPath()));
+ disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
+ disk.setFormat(format);
+ disk.setSize(template.getVirtualSize());
+ disk.setVirtualSize(disk.getSize());
+
+ QemuImg qemu = new QemuImg();
+ QemuImgFile srcFile;
+ QemuImgFile destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
+ destPool.getSourcePort(),
+ destPool.getAuthUserName(),
+ destPool.getAuthSecret(),
+ disk.getPath()));
+ destFile.setFormat(format);
+
+ if (srcPool.getType() != StoragePoolType.RBD) {
+ srcFile = new QemuImgFile(template.getPath(), template.getFormat());
+ } else {
+ template.setFormat(PhysicalDiskFormat.RAW);
+ srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
+ srcPool.getSourcePort(),
+ srcPool.getAuthUserName(),
+ srcPool.getAuthSecret(),
+ template.getPath()));
+ srcFile.setFormat(template.getFormat());
+ }
+ qemu.convert(srcFile, destFile);
}
+ } catch (QemuImgException e) {
+ s_logger.error("Failed to create " + disk.getPath() +
+ " due to a failed executing of qemu-img: " + e.getMessage());
}
return disk;
}
@@ -687,39 +694,54 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
PhysicalDiskFormat sourceFormat = disk.getFormat();
PhysicalDiskFormat destFormat = newDisk.getFormat();
- if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
- if (sourceFormat.equals(destFormat) &&
- Script.runSimpleBashScript("qemu-img info " + sourcePath + "|grep backing") == null) {
- Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
+ QemuImg qemu = new QemuImg();
+ QemuImgFile srcFile = null;
+ QemuImgFile destFile = null;
- } else {
- Script.runSimpleBashScript("qemu-img convert -f " + sourceFormat
- + " -O " + destFormat
- + " " + sourcePath
- + " " + destPath);
+ if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
+ srcFile = new QemuImgFile(sourcePath, sourceFormat);
+ try {
+ Map<String, String> info = qemu.info(srcFile);
+ String backingFile = info.get(new String("backing_file"));
+ if (sourceFormat.equals(destFormat) && backingFile == null) {
+ Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
+ } else {
+ destFile = new QemuImgFile(destPath, destFormat);
+ }
+ } catch (QemuImgException e) {
+ s_logger.error("Failed to fetch the information of file "
+ + srcFile.getFileName() + " the error was: " + e.getMessage());
}
} else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) {
- Script.runSimpleBashScript("qemu-img convert -f " + sourceFormat
- + " -O " + destFormat
- + " " + sourcePath
- + " " + KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
+ srcFile = new QemuImgFile(sourcePath, sourceFormat);
+ destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
destPool.getSourcePort(),
destPool.getAuthUserName(),
destPool.getAuthSecret(),
destPath));
+ destFile.setFormat(destFormat);
} else {
- Script.runSimpleBashScript("qemu-img convert -f " + sourceFormat
- + " -O " + destFormat
- + " " + KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
+ srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
srcPool.getSourcePort(),
srcPool.getAuthUserName(),
srcPool.getAuthSecret(),
- sourcePath)
- + " " + KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
+ sourcePath));
+ srcFile.setFormat(sourceFormat);
+ destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
destPool.getSourcePort(),
destPool.getAuthUserName(),
destPool.getAuthSecret(),
destPath));
+ destFile.setFormat(destFormat);
+ }
+
+ if (srcFile != null && destFile != null) {
+ try {
+ qemu.convert(srcFile, destFile);
+ } catch (QemuImgException e) {
+ s_logger.error("Failed to convert " + srcFile.getFileName() + " to "
+ + destFile.getFileName() + " the error was: " + e.getMessage());
+ }
}
return newDisk;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
index 32f8ce9..cba8aad 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
@@ -18,9 +18,9 @@ package com.cloud.hypervisor.kvm.storage;
import java.util.List;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.libvirt.StoragePool;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.storage.Storage.StoragePoolType;
public class LibvirtStoragePool implements KVMStoragePool {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
index 79c3b92..dd75677 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
@@ -18,7 +18,7 @@ package com.cloud.hypervisor.kvm.storage;
import java.util.List;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import com.cloud.storage.Storage.StoragePoolType;
public interface StorageAdaptor {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/src/com/cloud/utils/script/Script.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/script/Script.java b/utils/src/com/cloud/utils/script/Script.java
index cb25844..3632bf5 100755
--- a/utils/src/com/cloud/utils/script/Script.java
+++ b/utils/src/com/cloud/utils/script/Script.java
@@ -460,20 +460,7 @@ public class Script implements Callable<String> {
}
public static String runSimpleBashScript(String command) {
-
- Script s = new Script("/bin/bash");
- s.add("-c");
- s.add(command);
-
- OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
- if (s.execute(parser) != null)
- return null;
-
- String result = parser.getLine();
- if (result == null || result.trim().isEmpty())
- return null;
- else
- return result.trim();
+ return Script.runSimpleBashScript(command, 0);
}
public static String runSimpleBashScript(String command, int timeout) {
@@ -493,10 +480,4 @@ public class Script implements Callable<String> {
return result.trim();
}
- public static void main(String[] args) {
- String path = findScript(".", "try.sh");
- Script script = new Script(path, 5000, s_logger);
- script.execute();
- System.exit(1);
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/src/org/apache/cloudstack/utils/qemu/QemuImg.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/utils/qemu/QemuImg.java b/utils/src/org/apache/cloudstack/utils/qemu/QemuImg.java
new file mode 100644
index 0000000..26c1a61
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/utils/qemu/QemuImg.java
@@ -0,0 +1,352 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.qemu;
+
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
+
+import com.cloud.utils.script.Script;
+import com.cloud.utils.script.OutputInterpreter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+public class QemuImg {
+
+ /* The qemu-img binary. We expect this to be in $PATH */
+ public String _qemuImgPath = "qemu-img";
+
+ /* Shouldn't we have KVMPhysicalDisk and LibvirtVMDef read this? */
+ public static enum PhysicalDiskFormat {
+ RAW("raw"), QCOW2("qcow2"), VMDK("vmdk"), FILE("file"), RBD("rbd"), SHEEPDOG("sheepdog"), HTTP("http"), HTTPS("https");
+ String format;
+
+ private PhysicalDiskFormat(String format) {
+ this.format = format;
+ }
+
+ public String toString() {
+ return this.format;
+ }
+ }
+
+ public QemuImg() {
+
+ }
+
+ /**
+ * Create a QemuImg object
+ *
+ *
+ * @param qemuImgPath
+ * A alternative path to the qemu-img binary
+ * @return void
+ */
+ public QemuImg(String qemuImgPath) {
+ this._qemuImgPath = qemuImgPath;
+ }
+
+ /* These are all methods supported by the qemu-img tool */
+
+ /* Perform a consistency check on the disk image */
+ public void check(QemuImgFile file) {
+
+ }
+
+ /**
+ * Create a new image
+ *
+ * This method calls 'qemu-img create'
+ *
+ * @param file
+ * The file to create
+ * @param backingFile
+ * A backing file if used (for example with qcow2)
+ * @param options
+ * Options for the create. Takes a Map<String, String> with key value
+ * pairs which are passed on to qemu-img without validation.
+ * @return void
+ */
+ public void create(QemuImgFile file, QemuImgFile backingFile, Map<String, String> options) throws QemuImgException {
+ Script s = new Script(_qemuImgPath);
+ s.add("create");
+
+ if (options != null && !options.isEmpty()) {
+ s.add("-o");
+ String optionsStr = "";
+ for (Map.Entry<String, String> option : options.entrySet()) {
+ optionsStr += option.getKey() + "=" + option.getValue() + ",";
+ }
+ s.add(optionsStr);
+ }
+
+ /*
+ -b for a backing file does not show up in the docs, but it works.
+ Shouldn't this be -o backing_file=filename instead?
+ */
+ s.add("-f");
+ if (backingFile != null) {
+ s.add(backingFile.getFormat().toString());
+ s.add("-b");
+ s.add(backingFile.getFileName());
+ } else {
+ s.add(file.getFormat().toString());
+ }
+
+ s.add(file.getFileName());
+
+ if (backingFile == null) {
+ s.add(Long.toString(file.getSize()));
+ }
+ String result = s.execute();
+ if (result != null) {
+ throw new QemuImgException(result);
+ }
+ }
+
+ /**
+ * Create a new image
+ *
+ * This method calls 'qemu-img create'
+ *
+ * @param file
+ * The file to create
+ * @return void
+ */
+ public void create(QemuImgFile file) throws QemuImgException {
+ this.create(file, null, null);
+ }
+
+ /**
+ * Create a new image
+ *
+ * This method calls 'qemu-img create'
+ *
+ * @param file
+ * The file to create
+ * @param backingFile
+ * A backing file if used (for example with qcow2)
+ * @return void
+ */
+ public void create(QemuImgFile file, QemuImgFile backingFile) throws QemuImgException {
+ this.create(file, backingFile, null);
+ }
+
+ /**
+ * Create a new image
+ *
+ * This method calls 'qemu-img create'
+ *
+ * @param file
+ * The file to create
+ * @param options
+ * Options for the create. Takes a Map<String, String> with key value
+ * pairs which are passed on to qemu-img without validation.
+ * @return void
+ */
+ public void create(QemuImgFile file, Map<String, String> options) throws QemuImgException {
+ this.create(file, null, options);
+ }
+
+ /**
+ * Convert a image from source to destination
+ *
+ * This method calls 'qemu-img convert' and takes two objects
+ * as an argument.
+ *
+ *
+ * @param srcFile
+ * The source file
+ * @param destFile
+ * The destination file
+ * @param options
+ * Options for the convert. Takes a Map<String, String> with key value
+ * pairs which are passed on to qemu-img without validation.
+ * @return void
+ */
+ public void convert(QemuImgFile srcFile, QemuImgFile destFile, Map<String, String> options) throws QemuImgException {
+ Script s = new Script(_qemuImgPath);
+ s.add("convert");
+ s.add("-f");
+ s.add(srcFile.getFormat().toString());
+ s.add("-O");
+ s.add(destFile.getFormat().toString());
+
+ if (options != null && !options.isEmpty()) {
+ s.add("-o");
+ String optionsStr = "";
+ for (Map.Entry<String, String> option : options.entrySet()) {
+ optionsStr += option.getKey() + "=" + option.getValue() + ",";
+ }
+ s.add(optionsStr);
+ }
+
+ s.add(srcFile.getFileName());
+ s.add(destFile.getFileName());
+
+ String result = s.execute();
+ if (result != null) {
+ throw new QemuImgException(result);
+ }
+ }
+
+ /**
+ * Convert a image from source to destination
+ *
+ * This method calls 'qemu-img convert' and takes two objects
+ * as an argument.
+ *
+ *
+ * @param srcFile
+ * The source file
+ * @param destFile
+ * The destination file
+ * @return void
+ */
+ public void convert(QemuImgFile srcFile, QemuImgFile destFile) throws QemuImgException {
+ this.convert(srcFile, destFile, null);
+ }
+
+ /**
+ * Commit the changes recorded in the file in its base image.
+ *
+ * This method calls 'qemu-img commit' and takes one object as
+ * an argument
+ *
+ * @param file
+ * The file of which changes have to be committed
+ * @return void
+ */
+ public void commit(QemuImgFile file) throws QemuImgException {
+
+ }
+
+ /**
+ * Execute qemu-img info for the given file
+ *
+ * Qemu-img returns human readable output, but this method does it's best
+ * to turn that into machine readeable data.
+ *
+ * Spaces in keys are replaced by underscores (_).
+ * Sizes (virtual_size and disk_size) are returned in bytes
+ * Paths (image and backing_file) are the absolute path to the file
+ *
+ * @param file
+ * A QemuImgFile object containing the file to get the information from
+ * @return A HashMap with String key-value information as returned by 'qemu-img info'
+ */
+ public Map<String, String> info(QemuImgFile file) throws QemuImgException {
+ Script s = new Script(_qemuImgPath);
+ s.add("info");
+ s.add(file.getFileName());
+ OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+ String result = s.execute(parser);
+ if (result != null) {
+ throw new QemuImgException(result);
+ }
+
+ HashMap<String,String> info = new HashMap<String,String>();
+ String[] outputBuffer = parser.getLines().trim().split("\n");
+ for (int i = 0; i < outputBuffer.length; i++) {
+ String[] lineBuffer = outputBuffer[i].split(":", 2);
+ if (lineBuffer.length == 2) {
+ String key = lineBuffer[0].trim().replace(" ", "_");
+ String value = null;
+
+ if (key.equals("virtual_size")) {
+ value = lineBuffer[1].trim().replaceAll("^.*\\(([0-9]+).*$", "$1");
+ } else {
+ value = lineBuffer[1].trim();
+ }
+
+ info.put(key, value);
+ }
+ }
+ return info;
+ }
+
+ /* List, apply, create or delete snapshots in image */
+ public void snapshot() throws QemuImgException {
+
+ }
+
+ /* Changes the backing file of an image */
+ public void rebase() throws QemuImgException {
+
+ }
+
+ /**
+ * Resize an image
+ *
+ * This method simple calls 'qemu-img resize'.
+ * A negative size value will get prefixed with - and a positive with +
+ *
+ * Sizes are in bytes and will be passed on that way
+ *
+ * @param file
+ * The file to resize
+ * @param size
+ * The new size
+ * @param delta
+ * Flag if the new size is a delta
+ */
+ public void resize(QemuImgFile file, long size, boolean delta) throws QemuImgException {
+ String newSize = null;
+
+ if (size == 0) {
+ throw new QemuImgException("size should never be exactly zero");
+ }
+
+ if (delta) {
+ if (size > 0) {
+ newSize = "+" + Long.toString(size);
+ } else {
+ newSize = Long.toString(size);
+ }
+ } else {
+ if (size <= 0) {
+ throw new QemuImgException("size should not be negative if 'delta' is false!");
+ }
+ newSize = Long.toString(size);
+ }
+
+ Script s = new Script(_qemuImgPath);
+ s.add("resize");
+ s.add(file.getFileName());
+ s.add(newSize);
+ s.execute();
+ }
+
+ /**
+ * Resize an image
+ *
+ * This method simple calls 'qemu-img resize'.
+ * A negative size value will get prefixed with - and a positive with +
+ *
+ * Sizes are in bytes and will be passed on that way
+ *
+ * @param file
+ * The file to resize
+ * @param size
+ * The new size
+ */
+ public void resize(QemuImgFile file, long size) throws QemuImgException {
+ this.resize(file, size, false);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/utils/qemu/QemuImgException.java b/utils/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
new file mode 100644
index 0000000..082ebe4
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.qemu;
+
+public class QemuImgException extends Exception {
+
+ public QemuImgException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java b/utils/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
new file mode 100644
index 0000000..90d925d
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.qemu;
+
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
+public class QemuImgFile {
+
+ private long size = 0;
+ private String fileName;
+ private PhysicalDiskFormat format = PhysicalDiskFormat.RAW;
+
+ public QemuImgFile(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public QemuImgFile(String fileName, long size) {
+ this.fileName = fileName;
+ this.size = size;
+ }
+
+ public QemuImgFile(String fileName, long size, PhysicalDiskFormat format) {
+ this.fileName = fileName;
+ this.size = size;
+ this.format = format;
+ }
+
+ public QemuImgFile(String fileName, PhysicalDiskFormat format) {
+ this.fileName = fileName;
+ this.size = size;
+ this.format = format;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public void setFormat(PhysicalDiskFormat format) {
+ this.format = format;
+ }
+
+ public String getFileName() {
+ return this.fileName;
+ }
+
+ public long getSize() {
+ return this.size;
+ }
+
+ public PhysicalDiskFormat getFormat() {
+ return this.format;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
----------------------------------------------------------------------
diff --git a/utils/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java b/utils/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
new file mode 100644
index 0000000..761113f
--- /dev/null
+++ b/utils/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.qemu;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
+public class QemuImgFileTest {
+ @Test
+ public void testFileNameAtContructor() {
+ String filename = "/tmp/test-image.qcow2";
+ QemuImgFile file = new QemuImgFile(filename);
+ assertEquals(file.getFileName(), filename);
+ }
+
+ @Test
+ public void testFileNameAndSizeAtContructor() {
+ long size = 1024;
+ String filename = "/tmp/test-image.qcow2";
+ QemuImgFile file = new QemuImgFile(filename, size);
+ assertEquals(file.getFileName(), filename);
+ assertEquals(file.getSize(), size);
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testFileNameAndFormatAtContructor() {
+ PhysicalDiskFormat format = PhysicalDiskFormat.RAW;
+ String filename = "/tmp/test-image.qcow2";
+ QemuImgFile file = new QemuImgFile(filename, format);
+ assertEquals(file.getFileName(), filename);
+ assertEquals(file.getFormat(), format);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4d022483/utils/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
----------------------------------------------------------------------
diff --git a/utils/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/utils/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
new file mode 100644
index 0000000..22755eb
--- /dev/null
+++ b/utils/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
@@ -0,0 +1,287 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.utils.qemu;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.UUID;
+import java.io.File;
+
+public class QemuImgTest {
+
+ @Test
+ public void testCreateAndInfo() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ /* 10TB virtual_size */
+ long size = 10995116277760l;
+ QemuImgFile file = new QemuImgFile(filename, size, PhysicalDiskFormat.QCOW2);
+
+ QemuImg qemu = new QemuImg();
+ qemu.create(file);
+ Map<String, String> info = qemu.info(file);
+
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(size), Long.valueOf(infoSize));
+
+ String infoPath = info.get(new String("image"));
+ assertEquals(filename, infoPath);
+
+ File f = new File(filename);
+ f.delete();
+
+ }
+
+ @Test
+ public void testCreateAndInfoWithOptions() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ /* 10TB virtual_size */
+ long size = 10995116277760l;
+ QemuImgFile file = new QemuImgFile(filename, size, PhysicalDiskFormat.QCOW2);
+ String clusterSize = "131072";
+ Map<String, String> options = new HashMap<String, String>();
+
+ options.put("cluster_size", clusterSize);
+
+ QemuImg qemu = new QemuImg();
+ qemu.create(file, options);
+ Map<String, String> info = qemu.info(file);
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(size), Long.valueOf(infoSize));
+
+ String infoPath = info.get(new String("image"));
+ assertEquals(filename, infoPath);
+
+ String infoClusterSize = info.get(new String("cluster_size"));
+ assertEquals(clusterSize, infoClusterSize);
+
+ File f = new File(filename);
+ f.delete();
+
+ }
+
+ @Test
+ public void testCreateAndResize() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ long startSize = 20480;
+ long endSize = 40960;
+ QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
+
+ try {
+ QemuImg qemu = new QemuImg();
+ qemu.create(file);
+ qemu.resize(file, endSize);
+ Map<String, String> info = qemu.info(file);
+
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(endSize), Long.valueOf(infoSize));
+ } catch (QemuImgException e) {
+ fail(e.getMessage());
+ }
+
+ File f = new File(filename);
+ f.delete();
+
+ }
+
+ @Test
+ public void testCreateAndResizeDeltaPositive() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ long startSize = 20480;
+ long increment = 20480;
+ QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
+
+ try {
+ QemuImg qemu = new QemuImg();
+ qemu.create(file);
+ qemu.resize(file, increment, true);
+ Map<String, String> info = qemu.info(file);
+
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(startSize + increment), Long.valueOf(infoSize));
+ } catch (QemuImgException e) {
+ fail(e.getMessage());
+ }
+
+ File f = new File(filename);
+ f.delete();
+ }
+
+ @Test
+ public void testCreateAndResizeDeltaNegative() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ long startSize = 81920;
+ long increment = -40960;
+ QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
+
+ try {
+ QemuImg qemu = new QemuImg();
+ qemu.create(file);
+ qemu.resize(file, increment, true);
+ Map<String, String> info = qemu.info(file);
+
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(startSize + increment), Long.valueOf(infoSize));
+ } catch (QemuImgException e) {
+ fail(e.getMessage());
+ }
+
+ File f = new File(filename);
+ f.delete();
+ }
+
+ @Test(expected = QemuImgException.class)
+ public void testCreateAndResizeFail() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ long startSize = 20480;
+
+ /* Negative new size, expect failure */
+ long endSize = -1;
+ QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
+
+ QemuImg qemu = new QemuImg();
+ try {
+ qemu.create(file);
+ qemu.resize(file, endSize);
+ } finally {
+ File f = new File(filename);
+ f.delete();
+ }
+ }
+
+ @Test(expected = QemuImgException.class)
+ public void testCreateAndResizeZero() throws QemuImgException {
+ String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ long startSize = 20480;
+ QemuImgFile file = new QemuImgFile(filename, 20480, PhysicalDiskFormat.QCOW2);
+
+ QemuImg qemu = new QemuImg();
+ qemu.create(file);
+ qemu.resize(file, 0);
+
+ File f = new File(filename);
+ f.delete();
+
+ }
+
+ @Test
+ public void testCreateWithBackingFile() throws QemuImgException {
+ String firstFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
+ String secondFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ QemuImgFile firstFile = new QemuImgFile(firstFileName, 20480, PhysicalDiskFormat.QCOW2);
+ QemuImgFile secondFile = new QemuImgFile(secondFileName, PhysicalDiskFormat.QCOW2);
+
+ QemuImg qemu = new QemuImg();
+ qemu.create(firstFile);
+ qemu.create(secondFile, firstFile);
+
+ Map<String, String> info = qemu.info(secondFile);
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ String backingFile = info.get(new String("backing_file"));
+ if (backingFile == null) {
+ fail("The second file does not have a property backing_file! Create failed?");
+ }
+ }
+
+ @Test
+ public void testConvertBasic() throws QemuImgException {
+ long srcSize = 20480;
+ String srcFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
+ String destFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
+
+ QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize);
+ QemuImgFile destFile = new QemuImgFile(destFileName);
+
+ QemuImg qemu = new QemuImg();
+ qemu.create(srcFile);
+ qemu.convert(srcFile, destFile);
+ Map<String, String> info = qemu.info(destFile);
+ if (info == null) {
+ fail("We didn't get any information back from qemu-img");
+ }
+
+ File sf = new File(srcFileName);
+ sf.delete();
+
+ File df = new File(destFileName);
+ df.delete();
+
+ }
+
+ @Test
+ public void testConvertAdvanced() throws QemuImgException {
+ 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();
+ qemu.create(srcFile);
+ qemu.convert(srcFile, destFile);
+
+ Map<String, String> info = qemu.info(destFile);
+
+ PhysicalDiskFormat infoFormat = PhysicalDiskFormat.valueOf(info.get(new String("file_format")).toUpperCase());
+ assertEquals(destFormat, infoFormat);
+
+ Long infoSize = Long.parseLong(info.get(new String("virtual_size")));
+ assertEquals(Long.valueOf(srcSize), Long.valueOf(infoSize));
+
+ File sf = new File(srcFileName);
+ sf.delete();
+
+ File df = new File(destFileName);
+ df.delete();
+
+ }
+}
\ No newline at end of file