You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2018/02/27 12:33:05 UTC
[cloudstack] branch master updated: CLOUDSTACK-10054:Volume
download times out in 3600 seconds (#2244)
This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/master by this push:
new bb607d0 CLOUDSTACK-10054:Volume download times out in 3600 seconds (#2244)
bb607d0 is described below
commit bb607d07a97476dc4fb934b3d75df6affba47086
Author: mrunalinikankariya <mr...@persistent.com>
AuthorDate: Tue Feb 27 18:03:00 2018 +0530
CLOUDSTACK-10054:Volume download times out in 3600 seconds (#2244)
---
.../com/cloud/storage/template/IsoProcessor.java | 5 ++
.../com/cloud/storage/template/OVAProcessor.java | 9 ++--
.../java/com/cloud/storage/template/Processor.java | 2 +
.../com/cloud/storage/template/QCOW2Processor.java | 7 ++-
.../cloud/storage/template/RawImageProcessor.java | 7 ++-
.../com/cloud/storage/template/TARProcessor.java | 5 ++
.../com/cloud/storage/template/VhdProcessor.java | 5 ++
.../com/cloud/storage/template/VmdkProcessor.java | 5 ++
.../command/TemplateOrVolumePostUploadCommand.java | 10 ++++
.../java/com/cloud/hypervisor/guru/VMwareGuru.java | 8 ++--
.../hypervisor/vmware/manager/VmwareManager.java | 3 ++
.../vmware/manager/VmwareManagerImpl.java | 5 +-
.../vmware/manager/VmwareStorageManager.java | 4 +-
.../vmware/manager/VmwareStorageManagerImpl.java | 34 +++++++------
.../VmwareSecondaryStorageResourceHandler.java | 7 ++-
.../VmwareStorageSubsystemCommandHandler.java | 12 +++--
.../com/cloud/storage/VolumeApiServiceImpl.java | 1 +
.../storage/resource/HttpUploadServerHandler.java | 6 ++-
.../resource/NfsSecondaryStorageResource.java | 7 ++-
.../storage/template/DownloadManagerImpl.java | 6 ++-
.../cloudstack/storage/template/UploadEntity.java | 9 ++++
.../main/java/com/cloud/utils/script/Script.java | 55 ++++++++++++----------
22 files changed, 148 insertions(+), 64 deletions(-)
diff --git a/core/src/main/java/com/cloud/storage/template/IsoProcessor.java b/core/src/main/java/com/cloud/storage/template/IsoProcessor.java
index 271818c..4cd2f1a 100644
--- a/core/src/main/java/com/cloud/storage/template/IsoProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/IsoProcessor.java
@@ -37,6 +37,11 @@ public class IsoProcessor extends AdapterBase implements Processor {
@Override
public FormatInfo process(String templatePath, ImageFormat format, String templateName) {
+ return process(templatePath, format, templateName, 0);
+ }
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) {
if (format != null) {
s_logger.debug("We don't handle conversion from " + format + " to ISO.");
return null;
diff --git a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
index 08087bf..f29efb4 100644
--- a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
@@ -42,11 +42,15 @@ import com.cloud.utils.script.Script;
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 {
+ return process(templatePath, format, templateName, 0);
+ }
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
if (format != null) {
if (s_logger.isInfoEnabled()) {
s_logger.info("We currently don't handle conversion from " + format + " to OVA.");
@@ -66,8 +70,7 @@ public class OVAProcessor extends AdapterBase implements Processor {
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);
+ Script command = new Script("tar", processTimeout, s_logger);
command.add("--no-same-owner");
command.add("--no-same-permissions");
command.add("-xf", templateFileFullPath);
diff --git a/core/src/main/java/com/cloud/storage/template/Processor.java b/core/src/main/java/com/cloud/storage/template/Processor.java
index ba57563..c8ee181 100644
--- a/core/src/main/java/com/cloud/storage/template/Processor.java
+++ b/core/src/main/java/com/cloud/storage/template/Processor.java
@@ -44,6 +44,8 @@ public interface Processor extends Adapter {
*/
FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException;
+ FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException;
+
public static class FormatInfo {
public ImageFormat format;
public long size;
diff --git a/core/src/main/java/com/cloud/storage/template/QCOW2Processor.java b/core/src/main/java/com/cloud/storage/template/QCOW2Processor.java
index 642d8d3..56ae078 100644
--- a/core/src/main/java/com/cloud/storage/template/QCOW2Processor.java
+++ b/core/src/main/java/com/cloud/storage/template/QCOW2Processor.java
@@ -40,8 +40,13 @@ public class QCOW2Processor extends AdapterBase implements Processor {
private StorageLayer _storage;
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ return process(templatePath, format, templateName, 0);
+ }
+
@Override
- public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
if (format != null) {
s_logger.debug("We currently don't handle conversion from " + format + " to QCOW2.");
return null;
diff --git a/core/src/main/java/com/cloud/storage/template/RawImageProcessor.java b/core/src/main/java/com/cloud/storage/template/RawImageProcessor.java
index 5645a31..5fbc626 100644
--- a/core/src/main/java/com/cloud/storage/template/RawImageProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/RawImageProcessor.java
@@ -45,8 +45,13 @@ public class RawImageProcessor extends AdapterBase implements Processor {
return true;
}
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ return process(templatePath, format, templateName, 0);
+ }
+
@Override
- public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
if (format != null) {
s_logger.debug("We currently don't handle conversion from " + format + " to raw image.");
return null;
diff --git a/core/src/main/java/com/cloud/storage/template/TARProcessor.java b/core/src/main/java/com/cloud/storage/template/TARProcessor.java
index dfd9a0a..51aeb23 100644
--- a/core/src/main/java/com/cloud/storage/template/TARProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/TARProcessor.java
@@ -35,6 +35,11 @@ public class TARProcessor extends AdapterBase implements Processor {
@Override
public FormatInfo process(String templatePath, ImageFormat format, String templateName) {
+ return process(templatePath, format, templateName, 0);
+ }
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) {
if (format != null) {
s_logger.debug("We currently don't handle conversion from " + format + " to TAR.");
return null;
diff --git a/core/src/main/java/com/cloud/storage/template/VhdProcessor.java b/core/src/main/java/com/cloud/storage/template/VhdProcessor.java
index cb13d06..baea7bf 100644
--- a/core/src/main/java/com/cloud/storage/template/VhdProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/VhdProcessor.java
@@ -58,6 +58,11 @@ public class VhdProcessor extends AdapterBase implements Processor {
@Override
public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ return process(templatePath, format, templateName, 0);
+ }
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
if (format != null) {
s_logger.debug("We currently don't handle conversion from " + format + " to VHD.");
return null;
diff --git a/core/src/main/java/com/cloud/storage/template/VmdkProcessor.java b/core/src/main/java/com/cloud/storage/template/VmdkProcessor.java
index eacabb9..ee50b27 100644
--- a/core/src/main/java/com/cloud/storage/template/VmdkProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/VmdkProcessor.java
@@ -44,6 +44,11 @@ public class VmdkProcessor extends AdapterBase implements Processor {
@Override
public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException {
+ return process(templatePath, format, templateName, 0);
+ }
+
+ @Override
+ public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
if (format != null) {
if (s_logger.isInfoEnabled()) {
s_logger.info("We currently don't handle conversion from " + format + " to VMDK.");
diff --git a/core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index 29fdd19..965d303 100644
--- a/core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -51,6 +51,8 @@ public class TemplateOrVolumePostUploadCommand {
private String defaultMaxAccountSecondaryStorage;
+ private long processTimeout;
+
private long accountId;
private Integer nfsVersion;
@@ -206,4 +208,12 @@ public class TemplateOrVolumePostUploadCommand {
public void setNfsVersion(Integer nfsVersion) {
this.nfsVersion = nfsVersion;
}
+
+ public void setProcessTimeout(long processTimeout) {
+ this.processTimeout = processTimeout;
+ }
+
+ public long getProcessTimeout() {
+ return processTimeout;
+ }
}
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
index d8076fd..81dfc33 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -32,6 +32,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -434,13 +435,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
@DB
public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
boolean needDelegation = false;
-
if (cmd instanceof StorageSubSystemCommand) {
Boolean fullCloneEnabled = VmwareFullClone.value();
StorageSubSystemCommand c = (StorageSubSystemCommand)cmd;
c.setExecuteInSequence(fullCloneEnabled);
}
-
+ if (cmd instanceof DownloadCommand) {
+ cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
+ }
//NOTE: the hostid can be a hypervisor host, or a ssvm agent. For copycommand, if it's for volume upload, the hypervisor
//type is empty, so we need to check the format of volume at first.
if (cmd instanceof CopyCommand) {
@@ -514,11 +516,11 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
cmd.setContextParam("noderuninfo", String.format("%d-%d", _clusterMgr.getManagementNodeId(), _clusterMgr.getCurrentRunId()));
cmd.setContextParam("vCenterSessionTimeout", String.valueOf(_vmwareMgr.getVcenterSessionTimeout()));
+ cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
if (cmd instanceof BackupSnapshotCommand || cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand || cmd instanceof CopyVolumeCommand || cmd instanceof CopyCommand ||
cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand || cmd instanceof CreateVolumeFromSnapshotCommand) {
-
String workerName = _vmwareMgr.composeWorkerName();
long checkPointId = 1;
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java
index 4a4d2ea..efdbc72 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java
@@ -42,6 +42,9 @@ public interface VmwareManager {
static final ConfigKey<String> s_vmwareSearchExcludeFolder = new ConfigKey<String>("Advanced", String.class, "vmware.search.exclude.folders", null,
"Comma seperated list of Datastore Folders to exclude from VMWare search", true, ConfigKey.Scope.Global);
+ static final ConfigKey<Integer> s_vmwareOVAPackageTimeout = new ConfigKey<Integer>(Integer.class, "vmware.package.ova.timeout", "Advanced", "3600",
+ "Vmware script timeout for ova packaging process", true, ConfigKey.Scope.Global, 1000);
+
String composeWorkerName();
String getSystemVMIsoFileNameOnDatastore();
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index b7149ab..3cf0c00 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -136,6 +136,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
private static final long SECONDS_PER_MINUTE = 60;
+
private int _timeout;
private String _instance;
@@ -204,7 +205,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
private int _additionalPortRangeSize;
private int _routerExtraPublicNics = 2;
private int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
-
private String _rootDiskController = DiskControllerType.ide.toString();
private final String _dataDiskController = DiskControllerType.osdefault.toString();
@@ -229,9 +229,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
@Override
public ConfigKey<?>[] getConfigKeys() {
- return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder};
+ return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout};
}
-
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
s_logger.info("Configure VmwareManagerImpl, manager name: " + name);
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
index f78f370..e7cd919 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
@@ -51,7 +51,7 @@ public interface VmwareStorageManager {
boolean execute(VmwareHostService hostService, CreateEntityDownloadURLCommand cmd);
- public void createOva(String path, String name);
+ public void createOva(String path, String name, int archiveTimeout);
- public String createOvaForTemplate(TemplateObjectTO template);
+ public String createOvaForTemplate(TemplateObjectTO template, int archiveTimeout);
}
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index a22410f..b6f207a 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -98,28 +98,32 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
@Override
public boolean execute(VmwareHostService hostService, CreateEntityDownloadURLCommand cmd) {
DataTO data = cmd.getData();
+ int timeout = NumbersUtil.parseInt(cmd.getContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key()),
+ Integer.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.defaultValue()) * VmwareManager.s_vmwareOVAPackageTimeout.multiplier());
if (data == null) {
return false;
}
String newPath = null;
if (data.getObjectType() == DataObjectType.VOLUME) {
- newPath = createOvaForVolume((VolumeObjectTO)data);
+ newPath = createOvaForVolume((VolumeObjectTO)data, timeout);
} else if (data.getObjectType() == DataObjectType.TEMPLATE) {
- newPath = createOvaForTemplate((TemplateObjectTO)data);
+ newPath = createOvaForTemplate((TemplateObjectTO)data, timeout);
}
if (newPath != null) {
cmd.setInstallPath(newPath);
+ return true;
}
- return true;
+ return false;
+
}
@Override
- public void createOva(String path, String name) {
+ public void createOva(String path, String name, int archiveTimeout) {
Script commandSync = new Script(true, "sync", 0, s_logger);
commandSync.execute();
- Script command = new Script(false, "tar", 0, s_logger);
+ Script command = new Script(false, "tar", archiveTimeout, s_logger);
command.setWorkDir(path);
command.add("-cf", name + ".ova");
command.add(name + ".ovf"); // OVF file should be the first file in OVA archive
@@ -155,7 +159,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
}
@Override
- public String createOvaForTemplate(TemplateObjectTO template) {
+ public String createOvaForTemplate(TemplateObjectTO template, int archiveTimeout) {
DataStoreTO storeTO = template.getDataStore();
if (!(storeTO instanceof NfsTO)) {
s_logger.debug("Can only handle NFS storage, while creating OVA from template");
@@ -173,7 +177,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
s_logger.debug("OVA file found at: " + installFullPath);
} else {
if (new File(installFullPath + ".meta").exists()) {
- createOVAFromMetafile(installFullPath + ".meta");
+ createOVAFromMetafile(installFullPath + ".meta", archiveTimeout);
} else {
String msg = "Unable to find OVA or OVA MetaFile to prepare template.";
s_logger.error(msg);
@@ -190,7 +194,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
//Fang: new command added;
// Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
- public String createOvaForVolume(VolumeObjectTO volume) {
+ public String createOvaForVolume(VolumeObjectTO volume, int archiveTimeout) {
DataStoreTO storeTO = volume.getDataStore();
if (!(storeTO instanceof NfsTO)) {
s_logger.debug("can only handle nfs storage, when create ova from volume");
@@ -215,15 +219,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
} else {
Script commandSync = new Script(true, "sync", 0, s_logger);
commandSync.execute();
-
- Script command = new Script(false, "tar", 0, s_logger);
+ Script command = new Script(false, "tar", archiveTimeout, s_logger);
command.setWorkDir(installFullPath);
command.add("-cf", volumeUuid + ".ova");
command.add(volumeUuid + ".ovf"); // OVF file should be the first file in OVA archive
command.add(volumeUuid + "-disk0.vmdk");
- command.execute();
- return volumePath;
+ String result = command.execute();
+ if (result != Script.ERR_TIMEOUT) {
+ return volumePath;
+ }
+
}
} catch (Throwable e) {
s_logger.info("Exception for createVolumeOVA");
@@ -1046,7 +1052,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
// here we use a method to return the ovf and vmdk file names; Another way to do it:
// create a new class, and like TemplateLocation.java and create templateOvfInfo.java to handle it;
- private String createOVAFromMetafile(String metafileName) throws Exception {
+ private String createOVAFromMetafile(String metafileName, int archiveTimeout) throws Exception {
File ova_metafile = new File(metafileName);
Properties props = null;
String ovaFileName = "";
@@ -1080,7 +1086,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
s_logger.info("ova: " + ovaFileName + ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + ".");
Script commandSync = new Script(true, "sync", 0, s_logger);
commandSync.execute();
- Script command = new Script(false, "tar", 0, s_logger);
+ Script command = new Script(false, "tar", archiveTimeout, s_logger);
command.setWorkDir(exportDir); // Fang: pass this in to the method?
command.add("-cf", ovaFileName);
command.add(ovfFileName); // OVF file should be the first file in OVA archive
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index d0d5964..ff00f55 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -145,8 +145,11 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
}
protected Answer execute(CreateEntityDownloadURLCommand cmd) {
- _storageMgr.execute(this, cmd);
- return _resource.defaultAction(cmd);
+ boolean success = _storageMgr.execute(this, cmd);
+ if (success) {
+ return _resource.defaultAction(cmd);
+ }
+ return new Answer(cmd, false, "Failed to download");
}
private Answer execute(PrimaryStorageDownloadCommand cmd) {
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
index fc19972..02ae2fe 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
@@ -21,6 +21,8 @@ package com.cloud.storage.resource;
import java.io.File;
import java.util.EnumMap;
+import com.cloud.hypervisor.vmware.manager.VmwareManager;
+import com.cloud.utils.NumbersUtil;
import org.apache.log4j.Logger;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand;
@@ -95,6 +97,8 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
DataTO destData = cmd.getDestTO();
DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore();
+ int timeout = NumbersUtil.parseInt(cmd.getContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key()),
+ Integer.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.defaultValue()) * VmwareManager.s_vmwareOVAPackageTimeout.multiplier());
//if copied between s3 and nfs cache, go to resource
boolean needDelegation = false;
if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
@@ -112,11 +116,11 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
String path = vol.getPath();
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
- storageManager.createOva(parentPath + File.separator + path, name);
+ storageManager.createOva(parentPath + File.separator + path, name, timeout);
vol.setPath(path + File.separator + name + ".ova");
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
// sync template from NFS cache to S3 in NFS migration to S3 case
- storageManager.createOvaForTemplate((TemplateObjectTO)srcData);
+ storageManager.createOvaForTemplate((TemplateObjectTO)srcData, timeout);
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT) {
// pack ova first
// sync snapshot from NFS cache to S3 in NFS migration to S3 case
@@ -126,7 +130,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
String snapDir = path.substring(0, index);
- storageManager.createOva(parentPath + File.separator + snapDir, name);
+ storageManager.createOva(parentPath + File.separator + snapDir, name, timeout);
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
//create template from snapshot on src at first, then copy it to s3
TemplateObjectTO cacheTemplate = (TemplateObjectTO)destData;
@@ -169,7 +173,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
String dir = path.substring(0, index);
- storageManager.createOva(parentPath + File.separator + dir, name);
+ storageManager.createOva(parentPath + File.separator + dir, name, timeout);
newSnapshot.setPath(newSnapshot.getPath() + ".ova");
newSnapshot.setDataStore(cmd.getCacheTO().getDataStore());
CopyCommand newCmd = new CopyCommand(newSnapshot, destData, cmd.getWait(), cmd.executeInSequence());
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index bea9b4a..69dfd1d 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -367,6 +367,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
dataObject.getDataStore().getRole().toString());
command.setLocalPath(volumeStore.getLocalDownloadPath());
//using the existing max upload size configuration
+ command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
command.setAccountId(vol.getAccountId());
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 7a22b20..ea4e75d 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -87,6 +87,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
private static final String HEADER_HOST = "X-Forwarded-Host";
+ private static long processTimeout;
+
public HttpUploadServerHandler(NfsSecondaryStorageResource storageResource) {
this.storageResource = storageResource;
}
@@ -152,7 +154,6 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
Map<String, List<String>> uriAttributes = decoderQuery.parameters();
uuid = uriAttributes.get("uuid").get(0);
logger.info("URI: uuid=" + uuid);
-
UploadEntity uploadEntity = null;
try {
// Validate the request here
@@ -175,6 +176,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
}
//set the base directory to download the file
DiskFileUpload.baseDirectory = uploadEntity.getInstallPathPrefix();
+ this.processTimeout = uploadEntity.getProcessTimeout();
logger.info("base directory: " + DiskFileUpload.baseDirectory);
try {
//initialize the decoder
@@ -243,7 +245,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
storageResource.updateStateMapWithError(uuid, errorString);
return HttpResponseStatus.BAD_REQUEST;
}
- String status = storageResource.postUpload(uuid, fileUpload.getFile().getName());
+ String status = storageResource.postUpload(uuid, fileUpload.getFile().getName(), processTimeout);
if (status != null) {
responseContent.append(status);
storageResource.updateStateMapWithError(uuid, status);
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 93d8c27..1f81f6a 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -251,6 +251,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
protected String createTemplateFromSnapshotXenScript;
private HashMap<String, UploadEntity> uploadEntityStateMap = new HashMap<String, UploadEntity>();
private String _ssvmPSK = null;
+ private long processTimeout;
public void setParentPath(String path) {
_parent = path;
@@ -3345,6 +3346,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
throw new InvalidParameterValueException(errorMessage);
} else {
uuid = cmd.getEntityUUID();
+ processTimeout = cmd.getProcessTimeout();
if (isOneTimePostUrlUsed(cmd)) {
uploadEntity = uploadEntityStateMap.get(uuid);
StringBuilder errorMessage = new StringBuilder("The one time post url is already used");
@@ -3366,6 +3368,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
uploadEntity.setMetaDataPopulated(true);
uploadEntity.setResourceType(UploadEntity.ResourceType.valueOf(cmd.getType()));
+ uploadEntity.setProcessTimeout(processTimeout);
uploadEntity.setFormat(Storage.ImageFormat.valueOf(cmd.getImageFormat()));
//relative path with out ssvm mount info.
uploadEntity.setTemplatePath(absolutePath);
@@ -3447,7 +3450,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return (int)Math.ceil(sizeInBytes * 1.0d / (1024 * 1024 * 1024));
}
- public String postUpload(String uuid, String filename) {
+ public String postUpload(String uuid, String filename, long processTimeout) {
UploadEntity uploadEntity = uploadEntityStateMap.get(uuid);
int installTimeoutPerGig = 180 * 60 * 1000;
@@ -3552,7 +3555,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
for (Processor processor : processors.values()) {
FormatInfo info = null;
try {
- info = processor.process(resourcePath, null, templateName);
+ info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
} catch (InternalErrorException e) {
s_logger.error("Template process exception ", e);
return e.toString();
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index 5fa13a3..2ace37f 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -90,7 +90,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
private String _name;
StorageLayer _storage;
public Map<String, Processor> _processors;
-
+ private long _processTimeout;
private Integer _nfsVersion;
public class Completion implements DownloadCompleteCallback {
@@ -459,7 +459,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
FormatInfo info = null;
try {
- info = processor.process(resourcePath, null, templateName);
+ info = processor.process(resourcePath, null, templateName, this._processTimeout);
} catch (InternalErrorException e) {
s_logger.error("Template process exception ", e);
return e.toString();
@@ -677,6 +677,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
@Override
public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
+ int timeout = NumbersUtil.parseInt(cmd.getContextParam("vmware.package.ova.timeout"), 3600000);
+ this._processTimeout = timeout;
ResourceType resourceType = cmd.getResourceType();
if (cmd instanceof DownloadProgressCommand) {
return handleDownloadProgressCmd(resource, (DownloadProgressCommand)cmd);
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java
index d851143..031a163 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java
@@ -34,6 +34,7 @@ public class UploadEntity {
private int maxSizeInGB;
private String description;
private long contentLength;
+ private long processTimeout;
public static enum ResourceType {
VOLUME, TEMPLATE
@@ -60,6 +61,14 @@ public class UploadEntity {
this.entityId=entityId;
}
+ public void setProcessTimeout(long processTimeout) {
+ this.processTimeout = processTimeout;
+ }
+
+ public long getProcessTimeout() {
+ return processTimeout;
+ }
+
public UploadEntity(){
}
diff --git a/utils/src/main/java/com/cloud/utils/script/Script.java b/utils/src/main/java/com/cloud/utils/script/Script.java
index 01f18bd..7087395 100644
--- a/utils/src/main/java/com/cloud/utils/script/Script.java
+++ b/utils/src/main/java/com/cloud/utils/script/Script.java
@@ -37,7 +37,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.apache.cloudstack.utils.security.KeyStoreUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.joda.time.Duration;
@@ -203,7 +202,7 @@ public class Script implements Callable<String> {
String[] command = _command.toArray(new String[_command.size()]);
if (_logger.isDebugEnabled()) {
- _logger.debug("Executing: " + buildCommandLine(command).split(KeyStoreUtils.defaultKeystoreFile)[0]);
+ _logger.debug("Executing: " + buildCommandLine(command));
}
try {
@@ -233,18 +232,23 @@ public class Script implements Callable<String> {
}
while (true) {
+ _logger.debug("Executing while with timeout : " + _timeout);
try {
- if (_process.waitFor() == 0) {
- _logger.debug("Execution is successful.");
- if (interpreter != null) {
- return interpreter.drain() ? task.getResult() : interpreter.interpret(ir);
- } else {
- // null return exitValue apparently
- return String.valueOf(_process.exitValue());
+ //process execution completed within timeout period
+ if (_process.waitFor(_timeout, TimeUnit.MILLISECONDS)) {
+ //process completed successfully
+ if (_process.exitValue() == 0) {
+ _logger.debug("Execution is successful.");
+ if (interpreter != null) {
+ return interpreter.drain() ? task.getResult() : interpreter.interpret(ir);
+ } else {
+ // null return exitValue apparently
+ return String.valueOf(_process.exitValue());
+ }
+ } else { //process failed
+ break;
}
- } else {
- break;
- }
+ } //timeout
} catch (InterruptedException e) {
if (!_isTimeOut) {
/*
@@ -254,24 +258,25 @@ public class Script implements Callable<String> {
_logger.debug("We are interrupted but it's not a timeout, just continue");
continue;
}
-
- TimedOutLogger log = new TimedOutLogger(_process);
- Task timedoutTask = new Task(log, ir);
-
- timedoutTask.run();
- if (!_passwordCommand) {
- _logger.warn("Timed out: " + buildCommandLine(command) + ". Output is: " + timedoutTask.getResult());
- } else {
- _logger.warn("Timed out: " + buildCommandLine(command));
- }
-
- return ERR_TIMEOUT;
} finally {
if (future != null) {
future.cancel(false);
}
Thread.interrupted();
}
+
+ //timeout without completing the process
+ TimedOutLogger log = new TimedOutLogger(_process);
+ Task timedoutTask = new Task(log, ir);
+
+ timedoutTask.run();
+ if (!_passwordCommand) {
+ _logger.warn("Timed out: " + buildCommandLine(command) + ". Output is: " + timedoutTask.getResult());
+ } else {
+ _logger.warn("Timed out: " + buildCommandLine(command));
+ }
+
+ return ERR_TIMEOUT;
}
_logger.debug("Exit value is " + _process.exitValue());
@@ -300,7 +305,7 @@ public class Script implements Callable<String> {
IOUtils.closeQuietly(_process.getErrorStream());
IOUtils.closeQuietly(_process.getOutputStream());
IOUtils.closeQuietly(_process.getInputStream());
- _process.destroy();
+ _process.destroyForcibly();
}
}
}
--
To stop receiving notification emails like this one, please contact
dahn@apache.org.