mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-1158: Wrap qemu-img into it's own util
Signed-off-by: Edison Su <sudison@gmail.com>
This commit is contained in:
parent
aa79ccf985
commit
ea0daeaee3
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user