cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edi...@apache.org
Subject git commit: updated refs/heads/master to ea0daea
Date Mon, 01 Apr 2013 23:38:24 GMT
Updated Branches:
  refs/heads/master aa79ccf98 -> ea0daeaee


CLOUDSTACK-1158: Wrap qemu-img into it's own util
Signed-off-by: Edison Su <sudison@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ea0daeae
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ea0daeae
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ea0daeae

Branch: refs/heads/master
Commit: ea0daeaee3f0c2d29821674a836e655fa844fb07
Parents: aa79ccf
Author: Wido den Hollander <wido@widodh.nl>
Authored: Mon Apr 1 16:37:18 2013 -0700
Committer: Edison Su <sudison@gmail.com>
Committed: Mon Apr 1 16:37:58 2013 -0700

----------------------------------------------------------------------
 plugins/hypervisors/kvm/pom.xml                    |   10 +
 .../kvm/resource/LibvirtComputingResource.java     |   30 +-
 .../kvm/resource/LibvirtDomainXMLParser.java       |    1 +
 .../hypervisor/kvm/storage/KVMPhysicalDisk.java    |   14 +-
 .../hypervisor/kvm/storage/KVMStoragePool.java     |    2 +-
 .../kvm/storage/KVMStoragePoolManager.java         |   13 +-
 .../kvm/storage/LibvirtStorageAdaptor.java         |  187 +++++----
 .../hypervisor/kvm/storage/LibvirtStoragePool.java |    2 +-
 .../hypervisor/kvm/storage/StorageAdaptor.java     |    2 +-
 .../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     |   62 +++
 .../apache/cloudstack/utils/qemu/QemuImgTest.java  |  289 ++++++++++++
 utils/src/com/cloud/utils/script/Script.java       |   21 +-
 15 files changed, 949 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml
index 013a58d..3a1ba3a 100644
--- a/plugins/hypervisors/kvm/pom.xml
+++ b/plugins/hypervisors/kvm/pom.xml
@@ -67,6 +67,16 @@
             </execution>
           </executions>
         </plugin>
+        <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.14</version>
+        <configuration>
+          <excludes>
+            <exclude>**/Qemu*.java</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea0daeae/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 d30e8f8..526107f 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
@@ -57,6 +57,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;
@@ -193,7 +197,6 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef;
 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;
@@ -1418,12 +1421,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;
@@ -2230,14 +2233,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();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea0daeae/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 61a75ba..403ed37 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/cloudstack/blob/ea0daeae/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 f359713..7f088fa 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
@@ -15,25 +15,13 @@
 // specific language governing permissions and limitations
 // 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"), TAR("tar"), DIR("dir");
-        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/cloudstack/blob/ea0daeae/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 d32a6fd..a1721e1 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/cloudstack/blob/ea0daeae/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 f6db3f1..f5719ba 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,18 +135,18 @@ 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 if (template.getFormat() == KVMPhysicalDisk.PhysicalDiskFormat.DIR) {
+        } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
             return adaptor.createDiskFromTemplate(template, name,
-                    KVMPhysicalDisk.PhysicalDiskFormat.DIR,
+                    PhysicalDiskFormat.DIR,
                     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/cloudstack/blob/ea0daeae/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 cee2aae..8f58719 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;
@@ -399,11 +404,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
                     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) {
@@ -647,57 +652,57 @@ 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 (template.getFormat() == PhysicalDiskFormat.TAR) {
-                Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath());
-            } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
-                Script.runSimpleBashScript("mkdir -p " + disk.getPath());
-                Script.runSimpleBashScript("chmod 755 " + disk.getPath());
-                Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath());
-            } else 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 (template.getFormat() == PhysicalDiskFormat.TAR) {
+                    Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath());
+                } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
+                    Script.runSimpleBashScript("mkdir -p " + disk.getPath());
+                    Script.runSimpleBashScript("chmod 755 " + disk.getPath());
+                    Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath());
+                } else 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;
     }
@@ -759,49 +764,65 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         PhysicalDiskFormat sourceFormat = disk.getFormat();
         PhysicalDiskFormat destFormat = newDisk.getFormat();
 
+        QemuImg qemu = new QemuImg();
+        QemuImgFile srcFile = null;
+        QemuImgFile destFile = null;
+
         if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
             if (sourceFormat == PhysicalDiskFormat.TAR) {
                 Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath);
-
             } else if (sourceFormat == PhysicalDiskFormat.DIR) {
                 Script.runSimpleBashScript("mkdir -p " + destPath);
                 Script.runSimpleBashScript("chmod 755 " + destPath);
                 Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath);
-
-            } else if (sourceFormat.equals(destFormat) &&
-                Script.runSimpleBashScript("qemu-img info " + sourcePath + "|grep backing") == null) {
-                Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
-
             } else {
-                Script.runSimpleBashScript("qemu-img convert -f " + sourceFormat
-                    + " -O " + destFormat
-                    + " " + sourcePath
-                    + " " + destPath);
+                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(),
-                                                destPool.getSourcePort(),
-                                                destPool.getAuthUserName(),
-                                                destPool.getAuthSecret(),
-                                                destPath));
+            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(),
-                                                srcPool.getSourcePort(),
-                                                srcPool.getAuthUserName(),
-                                                srcPool.getAuthSecret(),
-                                                sourcePath)
-                    + " " + KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                                                destPool.getSourcePort(),
-                                                destPool.getAuthUserName(),
-                                                destPool.getAuthSecret(),
-                                                destPath));
+            srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
+                    srcPool.getSourcePort(),
+                    srcPool.getAuthUserName(),
+                    srcPool.getAuthSecret(),
+                    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/cloudstack/blob/ea0daeae/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 1396097..2ce5175 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/cloudstack/blob/ea0daeae/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/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java
new file mode 100644
index 0000000..4ed8593
--- /dev/null
+++ b/plugins/hypervisors/kvm/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"), TAR("tar"), DIR("dir");
+        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/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgException.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
new file mode 100644
index 0000000..082ebe4
--- /dev/null
+++ b/plugins/hypervisors/kvm/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/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
new file mode 100644
index 0000000..90d925d
--- /dev/null
+++ b/plugins/hypervisors/kvm/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/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
new file mode 100644
index 0000000..9fe057f
--- /dev/null
+++ b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
@@ -0,0 +1,62 @@
+// 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.Ignore;
+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;
+
+@Ignore
+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/cloudstack/blob/ea0daeae/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
new file mode 100644
index 0000000..9c6ac8b
--- /dev/null
+++ b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
@@ -0,0 +1,289 @@
+// 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.Ignore;
+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;
+
+@Ignore
+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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea0daeae/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);
-    }
 }


Mime
View raw message