You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ml...@apache.org on 2013/12/17 20:17:39 UTC
git commit: updated refs/heads/master to 95364a4
Updated Branches:
refs/heads/master 7e4407d3d -> 95364a402
CLOUDSTACK-5531
Initial support for vhd, raw, vmdk image formats on KVM. Tested all formats with local and CLVM.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/95364a40
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/95364a40
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/95364a40
Branch: refs/heads/master
Commit: 95364a40225460c03fcec2eed1cbb4bc5e4a3e56
Parents: 7e4407d
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Mon Dec 16 14:32:38 2013 -0700
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Mon Dec 16 14:32:51 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/storage/Storage.java | 2 +
.../cloud/storage/template/OVAProcessor.java | 158 +++++++++++++++++++
.../cloud/storage/template/VmdkProcessor.java | 95 ++++-------
.../kvm/storage/KVMStorageProcessor.java | 1 +
.../kvm/storage/LibvirtStorageAdaptor.java | 4 +-
.../apache/cloudstack/utils/qemu/QemuImg.java | 7 +-
.../manager/VmwareStorageManagerImpl.java | 10 +-
.../resource/VmwareStorageProcessor.java | 10 +-
.../template/HypervisorTemplateAdapter.java | 57 +++++--
.../resource/NfsSecondaryStorageResource.java | 16 +-
.../storage/template/DownloadManagerImpl.java | 13 +-
ui/scripts/templates.js | 12 ++
12 files changed, 289 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/api/src/com/cloud/storage/Storage.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java
index f1868a7..2175c9b 100755
--- a/api/src/com/cloud/storage/Storage.java
+++ b/api/src/com/cloud/storage/Storage.java
@@ -28,6 +28,8 @@ public class Storage {
OVA(true, true, true, "ova"),
VHDX(true, true, true, "vhdx"),
BAREMETAL(false, false, false, "BAREMETAL"),
+ VMDK(true, true, false, "vmdk"),
+ VDI(true, true, false, "vdi"),
TAR(false, false, false, "tar");
private final boolean thinProvisioned;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/core/src/com/cloud/storage/template/OVAProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/OVAProcessor.java b/core/src/com/cloud/storage/template/OVAProcessor.java
new file mode 100644
index 0000000..0db3bb0
--- /dev/null
+++ b/core/src/com/cloud/storage/template/OVAProcessor.java
@@ -0,0 +1,158 @@
+// 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
+// with 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 com.cloud.storage.template;
+
+import java.io.File;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.script.Script;
+
+@Local(value = Processor.class)
+public class OVAProcessor extends AdapterBase implements Processor {
+ private static final Logger s_logger = Logger.getLogger(OVAProcessor.class);
+
+ StorageLayer _storage;
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ if (format != null) {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("We currently don't handle conversion from " + format + " to OVA.");
+ }
+ return null;
+ }
+
+ s_logger.info("Template processing. templatePath: " + templatePath + ", templateName: " + templateName);
+ String templateFilePath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
+ if (!_storage.exists(templateFilePath)) {
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Unable to find the vmware template file: " + templateFilePath);
+ }
+ return null;
+ }
+
+ s_logger.info("Template processing - untar OVA package. templatePath: " + templatePath + ", templateName: " + templateName);
+ String templateFileFullPath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
+ File templateFile = new File(templateFileFullPath);
+
+ Script command = new Script("tar", 0, s_logger);
+ command.add("--no-same-owner");
+ command.add("-xf", templateFileFullPath);
+ command.setWorkDir(templateFile.getParent());
+ String result = command.execute();
+ if (result != null) {
+ s_logger.info("failed to untar OVA package due to " + result + ". templatePath: " + templatePath + ", templateName: " + templateName);
+ return null;
+ }
+
+ FormatInfo info = new FormatInfo();
+ info.format = ImageFormat.OVA;
+ info.filename = templateName + "." + ImageFormat.OVA.getFileExtension();
+ info.size = _storage.getSize(templateFilePath);
+ info.virtualSize = getTemplateVirtualSize(templatePath, info.filename);
+
+ // delete original OVA file
+ // templateFile.delete();
+ return info;
+ }
+
+ @Override
+ public Long getVirtualSize(File file) {
+ try {
+ long size = getTemplateVirtualSize(file.getParent(), file.getName());
+ return size;
+ } catch (Exception e) {
+
+ }
+ return file.length();
+ }
+
+ public long getTemplateVirtualSize(String templatePath, String templateName) throws InternalErrorException {
+ // get the virtual size from the OVF file meta data
+ long virtualSize = 0;
+ String templateFileFullPath = templatePath.endsWith(File.separator) ? templatePath : templatePath + File.separator;
+ templateFileFullPath += templateName.endsWith(ImageFormat.OVA.getFileExtension()) ? templateName : templateName + "." + ImageFormat.OVA.getFileExtension();
+ String ovfFileName = getOVFFilePath(templateFileFullPath);
+ if (ovfFileName == null) {
+ String msg = "Unable to locate OVF file in template package directory: " + templatePath;
+ s_logger.error(msg);
+ throw new InternalErrorException(msg);
+ }
+ try {
+ Document ovfDoc = null;
+ ovfDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(ovfFileName));
+ Element disk = (Element)ovfDoc.getElementsByTagName("Disk").item(0);
+ virtualSize = Long.parseLong(disk.getAttribute("ovf:capacity"));
+ String allocationUnits = disk.getAttribute("ovf:capacityAllocationUnits");
+ if ((virtualSize != 0) && (allocationUnits != null)) {
+ long units = 1;
+ if (allocationUnits.equalsIgnoreCase("KB") || allocationUnits.equalsIgnoreCase("KiloBytes") || allocationUnits.equalsIgnoreCase("byte * 2^10")) {
+ units = 1024;
+ } else if (allocationUnits.equalsIgnoreCase("MB") || allocationUnits.equalsIgnoreCase("MegaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^20")) {
+ units = 1024 * 1024;
+ } else if (allocationUnits.equalsIgnoreCase("GB") || allocationUnits.equalsIgnoreCase("GigaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^30")) {
+ units = 1024 * 1024 * 1024;
+ }
+ virtualSize = virtualSize * units;
+ } else {
+ throw new InternalErrorException("Failed to read capacity and capacityAllocationUnits from the OVF file: " + ovfFileName);
+ }
+ return virtualSize;
+ } catch (Exception e) {
+ String msg = "Unable to parse OVF XML document to get the virtual disk size due to" + e;
+ s_logger.error(msg);
+ throw new InternalErrorException(msg);
+ }
+ }
+
+ private String getOVFFilePath(String srcOVAFileName) {
+ File file = new File(srcOVAFileName);
+ assert (_storage != null);
+ String[] files = _storage.listFiles(file.getParent());
+ if (files != null) {
+ for (String fileName : files) {
+ if (fileName.toLowerCase().endsWith(".ovf")) {
+ File ovfFile = new File(fileName);
+ return file.getParent() + File.separator + ovfFile.getName();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+ if (_storage == null) {
+ throw new ConfigurationException("Unable to get storage implementation");
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/core/src/com/cloud/storage/template/VmdkProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/VmdkProcessor.java b/core/src/com/cloud/storage/template/VmdkProcessor.java
index be20143..2c08447 100644
--- a/core/src/com/cloud/storage/template/VmdkProcessor.java
+++ b/core/src/com/cloud/storage/template/VmdkProcessor.java
@@ -16,22 +16,24 @@
// under the License.
package com.cloud.storage.template;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
-import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
import com.cloud.exception.InternalErrorException;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.script.Script;
@Local(value = Processor.class)
public class VmdkProcessor extends AdapterBase implements Processor {
@@ -49,7 +51,7 @@ public class VmdkProcessor extends AdapterBase implements Processor {
}
s_logger.info("Template processing. templatePath: " + templatePath + ", templateName: " + templateName);
- String templateFilePath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
+ String templateFilePath = templatePath + File.separator + templateName + "." + ImageFormat.VMDK.getFileExtension();
if (!_storage.exists(templateFilePath)) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Unable to find the vmware template file: " + templateFilePath);
@@ -57,28 +59,12 @@ public class VmdkProcessor extends AdapterBase implements Processor {
return null;
}
- s_logger.info("Template processing - untar OVA package. templatePath: " + templatePath + ", templateName: " + templateName);
- String templateFileFullPath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
- File templateFile = new File(templateFileFullPath);
-
- Script command = new Script("tar", 0, s_logger);
- command.add("--no-same-owner");
- command.add("-xf", templateFileFullPath);
- command.setWorkDir(templateFile.getParent());
- String result = command.execute();
- if (result != null) {
- s_logger.info("failed to untar OVA package due to " + result + ". templatePath: " + templatePath + ", templateName: " + templateName);
- return null;
- }
-
FormatInfo info = new FormatInfo();
- info.format = ImageFormat.OVA;
- info.filename = templateName + "." + ImageFormat.OVA.getFileExtension();
+ info.format = ImageFormat.VMDK;
+ info.filename = templateName + "." + ImageFormat.VMDK.getFileExtension();
info.size = _storage.getSize(templateFilePath);
info.virtualSize = getTemplateVirtualSize(templatePath, info.filename);
- // delete original OVA file
- // templateFile.delete();
return info;
}
@@ -94,56 +80,37 @@ public class VmdkProcessor extends AdapterBase implements Processor {
}
public long getTemplateVirtualSize(String templatePath, String templateName) throws InternalErrorException {
- // get the virtual size from the OVF file meta data
long virtualSize = 0;
String templateFileFullPath = templatePath.endsWith(File.separator) ? templatePath : templatePath + File.separator;
- templateFileFullPath += templateName.endsWith(ImageFormat.OVA.getFileExtension()) ? templateName : templateName + "." + ImageFormat.OVA.getFileExtension();
- String ovfFileName = getOVFFilePath(templateFileFullPath);
- if (ovfFileName == null) {
- String msg = "Unable to locate OVF file in template package directory: " + templatePath;
- s_logger.error(msg);
- throw new InternalErrorException(msg);
- }
+ templateFileFullPath += templateName.endsWith(ImageFormat.VMDK.getFileExtension()) ? templateName : templateName + "." + ImageFormat.VMDK.getFileExtension();
+ String vmdkHeader = "";
+
try {
- Document ovfDoc = null;
- ovfDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(ovfFileName));
- Element disk = (Element)ovfDoc.getElementsByTagName("Disk").item(0);
- virtualSize = Long.parseLong(disk.getAttribute("ovf:capacity"));
- String allocationUnits = disk.getAttribute("ovf:capacityAllocationUnits");
- if ((virtualSize != 0) && (allocationUnits != null)) {
- long units = 1;
- if (allocationUnits.equalsIgnoreCase("KB") || allocationUnits.equalsIgnoreCase("KiloBytes") || allocationUnits.equalsIgnoreCase("byte * 2^10")) {
- units = 1024;
- } else if (allocationUnits.equalsIgnoreCase("MB") || allocationUnits.equalsIgnoreCase("MegaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^20")) {
- units = 1024 * 1024;
- } else if (allocationUnits.equalsIgnoreCase("GB") || allocationUnits.equalsIgnoreCase("GigaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^30")) {
- units = 1024 * 1024 * 1024;
+ FileReader fileReader = new FileReader(templateFileFullPath);
+ BufferedReader bufferedReader = new BufferedReader(fileReader);
+ Pattern regex = Pattern.compile("(RW|RDONLY|NOACCESS) (\\d+) (FLAT|SPARSE|ZERO|VMFS|VMFSSPARSE|VMFSDRM|VMFSRAW)");
+ String line = null;
+ while((line = bufferedReader.readLine()) != null) {
+ Matcher m = regex.matcher(line);
+ if (m.find( )) {
+ long sectors = Long.parseLong(m.group(2));
+ virtualSize = sectors * 512;
+ break;
}
- virtualSize = virtualSize * units;
- } else {
- throw new InternalErrorException("Failed to read capacity and capacityAllocationUnits from the OVF file: " + ovfFileName);
}
- return virtualSize;
- } catch (Exception e) {
- String msg = "Unable to parse OVF XML document to get the virtual disk size due to" + e;
+ bufferedReader.close();
+ } catch(FileNotFoundException ex) {
+ String msg = "Unable to open file '" + templateFileFullPath + "' " + ex.toString();
+ s_logger.error(msg);
+ throw new InternalErrorException(msg);
+ } catch(IOException ex) {
+ String msg = "Unable read open file '" + templateFileFullPath + "' " + ex.toString();
s_logger.error(msg);
throw new InternalErrorException(msg);
}
- }
- private String getOVFFilePath(String srcOVAFileName) {
- File file = new File(srcOVAFileName);
- assert (_storage != null);
- String[] files = _storage.listFiles(file.getParent());
- if (files != null) {
- for (String fileName : files) {
- if (fileName.toLowerCase().endsWith(".ovf")) {
- File ovfFile = new File(fileName);
- return file.getParent() + File.separator + ovfFile.getName();
- }
- }
- }
- return null;
+ s_logger.debug("vmdk file had size="+virtualSize);
+ return virtualSize;
}
@Override
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index d854ca5..7d5d335 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -189,6 +189,7 @@ public class KVMStorageProcessor implements StorageProcessor {
}
/* Copy volume to primary storage */
+ s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
KVMPhysicalDisk primaryVol = null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/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 82d0f8d..f910813 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
@@ -978,6 +978,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
String sourcePath = disk.getPath();
KVMPhysicalDisk newDisk;
+ s_logger.debug("copyPhysicalDisk: disk size:" + disk.getSize() + ", virtualsize:" + disk.getVirtualSize()+" format:"+disk.getFormat());
if (destPool.getType() != StoragePoolType.RBD) {
if (disk.getFormat() == PhysicalDiskFormat.TAR) {
newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, disk.getVirtualSize());
@@ -1015,7 +1016,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
try {
Map<String, String> info = qemu.info(srcFile);
String backingFile = info.get(new String("backing_file"));
- if (sourceFormat.equals(destFormat) && backingFile == null) {
+ // qcow2 templates can just be copied into place
+ if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) {
String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
if (result != null) {
throw new CloudRuntimeException("Failed to create disk: " + result);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/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
index 8c23f1e..a948ca1 100644
--- a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java
+++ b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java
@@ -184,8 +184,9 @@ public class QemuImg {
public void convert(QemuImgFile srcFile, QemuImgFile destFile, Map<String, String> options) throws QemuImgException {
Script s = new Script(_qemuImgPath, timeout);
s.add("convert");
- s.add("-f");
- s.add(srcFile.getFormat().toString());
+ // autodetect source format. Sometime int he future we may teach KVMPhysicalDisk about more formats, then we can explicitly pass them if necessary
+ //s.add("-f");
+ //s.add(srcFile.getFormat().toString());
s.add("-O");
s.add(destFile.getFormat().toString());
@@ -350,4 +351,4 @@ public class QemuImg {
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/95364a40/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 040a4cf..cd3fe73 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -80,7 +80,7 @@ import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.Volume;
-import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.storage.template.OVAProcessor;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
@@ -649,10 +649,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, true, false);
long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
- VmdkProcessor processor = new VmdkProcessor();
+ OVAProcessor processor = new OVAProcessor();
Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, _storage);
- processor.configure("VMDK Processor", params);
+ processor.configure("OVA Processor", params);
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
@@ -771,11 +771,11 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
}
long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
- VmdkProcessor processor = new VmdkProcessor();
+ OVAProcessor processor = new OVAProcessor();
// long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, _storage);
- processor.configure("VMDK Processor", params);
+ processor.configure("OVA Processor", params);
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index b55dbec..abb6733 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -78,7 +78,7 @@ import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.Volume;
-import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.storage.template.OVAProcessor;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.script.Script;
@@ -617,10 +617,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, true, false);
long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
- VmdkProcessor processor = new VmdkProcessor();
+ OVAProcessor processor = new OVAProcessor();
Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, _storage);
- processor.configure("VMDK Processor", params);
+ processor.configure("OVA Processor", params);
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
@@ -841,11 +841,11 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
- VmdkProcessor processor = new VmdkProcessor();
+ OVAProcessor processor = new OVAProcessor();
// long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, _storage);
- processor.configure("VMDK Processor", params);
+ processor.configure("OVA Processor", params);
long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index 74d1ac8..25e79db 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -151,21 +151,54 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
(!url.toLowerCase().endsWith("qcow2.bz2")) && (!url.toLowerCase().endsWith("qcow2.gz")) && (!url.toLowerCase().endsWith("ova")) &&
(!url.toLowerCase().endsWith("ova.zip")) && (!url.toLowerCase().endsWith("ova.bz2")) && (!url.toLowerCase().endsWith("ova.gz")) &&
(!url.toLowerCase().endsWith("tar")) && (!url.toLowerCase().endsWith("tar.zip")) && (!url.toLowerCase().endsWith("tar.bz2")) &&
- (!url.toLowerCase().endsWith("tar.gz")) && (!url.toLowerCase().endsWith("img")) && (!url.toLowerCase().endsWith("raw"))) {
+ (!url.toLowerCase().endsWith("tar.gz")) && (!url.toLowerCase().endsWith("vmdk")) && (!url.toLowerCase().endsWith("vmdk.gz")) &&
+ (!url.toLowerCase().endsWith("vmdk.zip")) && (!url.toLowerCase().endsWith("vmdk.bz2")) && (!url.toLowerCase().endsWith("img")) &&
+ (!url.toLowerCase().endsWith("img.gz")) && (!url.toLowerCase().endsWith("img.zip")) && (!url.toLowerCase().endsWith("img.bz2")) &&
+ (!url.toLowerCase().endsWith("raw")) && (!url.toLowerCase().endsWith("raw.gz")) && (!url.toLowerCase().endsWith("raw.bz2")) &&
+ (!url.toLowerCase().endsWith("raw.zip"))) {
throw new InvalidParameterValueException("Please specify a valid " + format.toLowerCase());
}
- if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith("vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase()
- .endsWith("vhd.gz"))) ||
- (format.equalsIgnoreCase("vhdx") && (!url.toLowerCase().endsWith("vhdx") && !url.toLowerCase().endsWith("vhdx.zip") &&
- !url.toLowerCase().endsWith("vhdx.bz2") && !url.toLowerCase()
- .endsWith("vhdx.gz"))) ||
- (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith("qcow2") && !url.toLowerCase().endsWith("qcow2.zip") &&
- !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz"))) ||
- (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith("ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase()
- .endsWith("ova.gz"))) ||
- (format.equalsIgnoreCase("tar") && (!url.toLowerCase().endsWith("tar") && !url.toLowerCase().endsWith("tar.zip") && !url.toLowerCase().endsWith("tar.bz2") && !url.toLowerCase()
- .endsWith("tar.gz"))) || (format.equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith("img") && !url.toLowerCase().endsWith("raw")))) {
+ if ((format.equalsIgnoreCase("vhd")
+ && (!url.toLowerCase().endsWith("vhd")
+ && !url.toLowerCase().endsWith("vhd.zip")
+ && !url.toLowerCase().endsWith("vhd.bz2")
+ && !url.toLowerCase().endsWith("vhd.gz")))
+ || (format.equalsIgnoreCase("vhdx")
+ && (!url.toLowerCase().endsWith("vhdx")
+ && !url.toLowerCase().endsWith("vhdx.zip")
+ && !url.toLowerCase().endsWith("vhdx.bz2")
+ && !url.toLowerCase().endsWith("vhdx.gz")))
+ || (format.equalsIgnoreCase("qcow2")
+ && (!url.toLowerCase().endsWith("qcow2")
+ && !url.toLowerCase().endsWith("qcow2.zip")
+ && !url.toLowerCase().endsWith("qcow2.bz2")
+ && !url.toLowerCase().endsWith("qcow2.gz")))
+ || (format.equalsIgnoreCase("ova")
+ && (!url.toLowerCase().endsWith("ova")
+ && !url.toLowerCase().endsWith("ova.zip")
+ && !url.toLowerCase().endsWith("ova.bz2")
+ && !url.toLowerCase().endsWith("ova.gz")))
+ || (format.equalsIgnoreCase("tar")
+ && (!url.toLowerCase().endsWith("tar")
+ && !url.toLowerCase().endsWith("tar.zip")
+ && !url.toLowerCase().endsWith("tar.bz2")
+ && !url.toLowerCase().endsWith("tar.gz")))
+ || (format.equalsIgnoreCase("raw")
+ && (!url.toLowerCase().endsWith("img")
+ && !url.toLowerCase().endsWith("img.zip")
+ && !url.toLowerCase().endsWith("img.bz2")
+ && !url.toLowerCase().endsWith("img.gz")
+ && !url.toLowerCase().endsWith("raw")
+ && !url.toLowerCase().endsWith("raw.bz2")
+ && !url.toLowerCase().endsWith("raw.zip")
+ && !url.toLowerCase().endsWith("raw.gz")))
+ || (format.equalsIgnoreCase("vmdk")
+ && (!url.toLowerCase().endsWith("vmdk")
+ && !url.toLowerCase().endsWith("vmdk.zip")
+ && !url.toLowerCase().endsWith("vmdk.bz2")
+ && !url.toLowerCase().endsWith("vmdk.gz")))
+ ) {
throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase());
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 7c1b9c8..00c1aac 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -125,6 +125,7 @@ import com.cloud.storage.template.RawImageProcessor;
import com.cloud.storage.template.TemplateLocation;
import com.cloud.storage.template.TemplateProp;
import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.OVAProcessor;
import com.cloud.storage.template.VmdkProcessor;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.S3Utils;
@@ -771,6 +772,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
if (ext != null) {
if (ext.equalsIgnoreCase("vhd")) {
return ImageFormat.VHD;
+ } else if (ext.equalsIgnoreCase("vhdx")) {
+ return ImageFormat.VHDX;
} else if (ext.equalsIgnoreCase("qcow2")) {
return ImageFormat.QCOW2;
} else if (ext.equalsIgnoreCase("ova")) {
@@ -779,6 +782,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return ImageFormat.TAR;
} else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
return ImageFormat.RAW;
+ } else if (ext.equalsIgnoreCase("vmdk")) {
+ return ImageFormat.VMDK;
+ } else if (ext.equalsIgnoreCase("vdi")) {
+ return ImageFormat.VDI;
}
}
@@ -794,11 +801,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
} else if (format == ImageFormat.QCOW2) {
processor = new QCOW2Processor();
} else if (format == ImageFormat.OVA) {
- processor = new VmdkProcessor();
+ processor = new OVAProcessor();
} else if (format == ImageFormat.VHD) {
processor = new VhdProcessor();
} else if (format == ImageFormat.RAW) {
processor = new RawImageProcessor();
+ } else if (format == ImageFormat.VMDK) {
+ processor = new VmdkProcessor();
}
if (processor == null) {
@@ -840,7 +849,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
if (!srcFile.exists()) {
srcFile = _storage.getFile(templatePath + ".ova");
if (!srcFile.exists()) {
- return new CopyCmdAnswer("Can't find src file:" + templatePath);
+ srcFile = _storage.getFile(templatePath + ".vmdk");
+ if (!srcFile.exists()) {
+ return new CopyCmdAnswer("Can't find src file:" + templatePath);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index c01537c..84daf27 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -75,6 +75,7 @@ import com.cloud.storage.template.TemplateDownloader.Status;
import com.cloud.storage.template.TemplateLocation;
import com.cloud.storage.template.TemplateProp;
import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.OVAProcessor;
import com.cloud.storage.template.VmdkProcessor;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
@@ -840,8 +841,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
if ((tInfo.getSize() == tInfo.getPhysicalSize()) && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
try {
- Processor processor = _processors.get("VMDK Processor");
- VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
+ Processor processor = _processors.get("OVA Processor");
+ OVAProcessor vmdkProcessor = (OVAProcessor)processor;
long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.getInstallPath().substring(tInfo.getInstallPath().lastIndexOf(File.separator) + 1));
tInfo.setSize(vSize);
loc.updateVirtualSize(vSize);
@@ -897,8 +898,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
if ((vInfo.getSize() == vInfo.getPhysicalSize()) && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
try {
- Processor processor = _processors.get("VMDK Processor");
- VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
+ Processor processor = _processors.get("OVA Processor");
+ OVAProcessor vmdkProcessor = (OVAProcessor)processor;
long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.getInstallPath().substring(vInfo.getInstallPath().lastIndexOf(File.separator) + 1));
vInfo.setSize(vSize);
loc.updateVirtualSize(vSize);
@@ -1052,6 +1053,10 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
processor.configure("QCOW2 Processor", params);
_processors.put("QCOW2 Processor", processor);
+ processor = new OVAProcessor();
+ processor.configure("OVA Processor", params);
+ _processors.put("OVA Processor", processor);
+
processor = new VmdkProcessor();
processor.configure("VMDK Processor", params);
_processors.put("VMDK Processor", processor);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/95364a40/ui/scripts/templates.js
----------------------------------------------------------------------
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index bcceb89..3854db7 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -361,6 +361,18 @@
id: 'QCOW2',
description: 'QCOW2'
});
+ items.push({
+ id: 'RAW',
+ description: 'RAW'
+ });
+ items.push({
+ id: 'VHD',
+ description: 'VHD'
+ });
+ items.push({
+ id: 'VMDK',
+ description: 'VMDK'
+ });
} else if (args.hypervisor == "BareMetal") {
//formatSelect.append("<option value='BareMetal'>BareMetal</option>");
items.push({