You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2015/04/29 07:43:45 UTC

[01/50] git commit: updated refs/heads/master to 0b83559

Repository: cloudstack
Updated Branches:
  refs/heads/master 07c30895b -> 0b8355920


volume upload: Use volume/template UUID instead of ID in UploadStatusCommand


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

Branch: refs/heads/master
Commit: d19ea5226a995435848cb8f64ae41af34e8a9655
Parents: 58f2fb1
Author: Koushik Das <ko...@apache.org>
Authored: Wed Feb 4 18:35:12 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Feb 17 12:31:40 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/storage/command/UploadStatusCommand.java   | 10 +++++-----
 .../com/cloud/storage/ImageStoreUploadMonitorImpl.java    |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d19ea522/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java b/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java
index bad821e..9e6b76e 100644
--- a/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java
@@ -26,19 +26,19 @@ public class UploadStatusCommand extends Command {
         Volume,
         Template
     }
-    private long entityId;
+    private String entityUuid;
     private EntityType entityType;
 
     protected UploadStatusCommand() {
     }
 
-    public UploadStatusCommand(long entityId, EntityType entityType) {
-        this.entityId = entityId;
+    public UploadStatusCommand(String entityUuid, EntityType entityType) {
+        this.entityUuid = entityUuid;
         this.entityType = entityType;
     }
 
-    public long getEntityId() {
-        return entityId;
+    public String getEntityUuid() {
+        return entityUuid;
     }
 
     public EntityType getEntityType() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d19ea522/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 6a27f29..d87fe60 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -190,7 +190,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                     continue;
                 }
                 Host host = _hostDao.findById(ep.getId());
-                UploadStatusCommand cmd = new UploadStatusCommand(volume.getId(), EntityType.Volume);
+                UploadStatusCommand cmd = new UploadStatusCommand(volume.getUuid(), EntityType.Volume);
                 if (host != null && host.getManagementServerId() != null) {
                     if (_nodeId == host.getManagementServerId().longValue()) {
                         Answer answer = null;
@@ -227,7 +227,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                     continue;
                 }
                 Host host = _hostDao.findById(ep.getId());
-                UploadStatusCommand cmd = new UploadStatusCommand(template.getId(), EntityType.Template);
+                UploadStatusCommand cmd = new UploadStatusCommand(template.getUuid(), EntityType.Template);
                 if (host != null && host.getManagementServerId() != null) {
                     if (_nodeId == host.getManagementServerId().longValue()) {
                         Answer answer = null;


[12/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: Volume resource count is incremented even for failed and abandoned volumes
Added logic to clean up abandoned and failed volume uploads. This is done as part of storage GC.


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

Branch: refs/heads/master
Commit: 1dae3a4a137989a12b52e66b876df6373533c47b
Parents: db7964f
Author: Koushik Das <ko...@apache.org>
Authored: Wed Mar 11 16:24:03 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Wed Mar 11 16:24:03 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/StorageManagerImpl.java   | 100 +++++++++++++------
 1 file changed, 69 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1dae3a4a/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index 1184320..fb51ff5 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -43,7 +43,6 @@ import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
@@ -59,6 +58,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
 import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
@@ -71,6 +71,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@@ -108,6 +109,7 @@ import com.cloud.cluster.ClusterManagerListener;
 import com.cloud.cluster.ManagementServerHost;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.ClusterDao;
@@ -150,6 +152,7 @@ import com.cloud.storage.listener.VolumeStateListener;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
 import com.cloud.user.dao.UserDao;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
@@ -193,6 +196,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
     @Inject
     protected VolumeDao _volsDao;
     @Inject
+    private VolumeDataStoreDao _volumeDataStoreDao;
+    @Inject
     protected HostDao _hostDao;
     @Inject
     protected SnapshotDao _snapshotDao;
@@ -245,10 +250,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
     @Inject
     ManagementServer _msServer;
     @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
     VolumeService volService;
     @Inject
     VolumeDataFactory volFactory;
@@ -266,6 +267,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
     private TemplateService _imageSrv;
     @Inject
     EndPointSelector _epSelector;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
 
     protected List<StoragePoolDiscoverer> _discoverers;
 
@@ -563,7 +566,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                 }
             }
 
-            DataStoreProvider provider = dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
+            DataStoreProvider provider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
             DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
             if (pool == null) {
                 Map<String, Object> params = new HashMap<String, Object>();
@@ -580,7 +583,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
 
                 store = lifeCycle.initialize(params);
             } else {
-                store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+                store = _dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
             }
 
             HostScope scope = new HostScope(host.getId(), host.getClusterId(), host.getDataCenterId());
@@ -590,17 +593,17 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
             throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e);
         }
 
-        return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
+        return _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
     }
 
     @Override
     public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException,
     ResourceUnavailableException {
         String providerName = cmd.getStorageProviderName();
-        DataStoreProvider storeProvider = dataStoreProviderMgr.getDataStoreProvider(providerName);
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
 
         if (storeProvider == null) {
-            storeProvider = dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
+            storeProvider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
             if (storeProvider == null) {
                 throw new InvalidParameterValueException("can't find storage provider: " + providerName);
             }
@@ -695,7 +698,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
             throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
         }
 
-        return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
     }
 
     private Map<String, String> extractApiParamAsMap(Map ds) {
@@ -786,7 +789,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
 
         if (updatedCapacityBytes != null || updatedCapacityIops != null) {
             StoragePoolVO storagePool = _storagePoolDao.findById(id);
-            DataStoreProvider dataStoreProvider = dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName());
+            DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName());
             DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle();
 
             if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) {
@@ -811,7 +814,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
             _storagePoolDao.updateCapacityIops(id, capacityIops);
         }
 
-        return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
     }
 
     @Override
@@ -875,19 +878,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         _storagePoolDao.releaseFromLockTable(lock.getId());
         s_logger.trace("Released lock for storage pool " + id);
 
-        DataStoreProvider storeProvider = dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
-        DataStore store = dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary);
+        DataStore store = _dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary);
         return lifeCycle.deleteDataStore(store);
     }
 
     @Override
     public void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException {
-        StoragePool pool = (StoragePool)dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
+        StoragePool pool = (StoragePool)_dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
         assert (pool.isShared()) : "Now, did you actually read the name of this method?";
         s_logger.debug("Adding pool " + pool.getName() + " to  host " + hostId);
 
-        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
         HypervisorHostListener listener = hostListeners.get(provider.getName());
         listener.hostConnect(hostId, pool.getId());
     }
@@ -1059,11 +1062,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                     List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed();
                     for (VolumeVO vol : vols) {
                         try {
-
                             volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));
-
                         } catch (Exception e) {
-                            s_logger.warn("Unable to destroy " + vol.getId(), e);
+                            s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
                         }
                     }
 
@@ -1077,10 +1078,47 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                             }
                             _snapshotDao.expunge(snapshotVO.getId());
                         } catch (Exception e) {
-                            s_logger.warn("Unable to destroy " + snapshotVO.getId(), e);
+                            s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
                         }
                     }
 
+                    // destroy uploaded volumes in UploadAbandoned/UploadError state
+                    List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
+                    for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
+                        VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
+                        if (volume == null) {
+                            s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
+                            continue;
+                        }
+                        try {
+                            DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
+                            EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
+                            if (ep == null) {
+                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
+                                continue;
+                            }
+                            Host host = _hostDao.findById(ep.getId());
+                            if (host != null && host.getManagementServerId() != null) {
+                                if (_serverId == host.getManagementServerId().longValue()) {
+                                    if (!volService.destroyVolume(volume.getId())) {
+                                        s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid());
+                                        continue;
+                                    }
+                                    // decrement volume resource count
+                                    _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
+                                    // expunge volume from secondary if volume is on image store
+                                    VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
+                                    if (volOnSecondary != null) {
+                                        s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
+                                        AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
+                                        future.get();
+                                    }
+                                }
+                            }
+                        } catch (Throwable th) {
+                            s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
+                        }
+                    }
                 } finally {
                     scanLock.unlock();
                 }
@@ -1139,7 +1177,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         // so here we don't need to issue DeleteCommand to resource anymore, only need to remove db entry.
         try {
             // Cleanup templates in template_store_ref
-            List<DataStore> imageStores = dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
+            List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
             for (DataStore store : imageStores) {
                 try {
                     long storeId = store.getId();
@@ -1236,12 +1274,12 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                     primaryStorage.getStatus().toString());
         }
 
-        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
         lifeCycle.maintain(store);
 
-        return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
     }
 
     @Override
@@ -1263,12 +1301,12 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                     primaryStorage.getStatus().toString(), primaryStorageId);
         }
 
-        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
         lifeCycle.cancelMaintain(store);
 
-        return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
     }
 
 
@@ -1396,7 +1434,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
 
     @Override
     public PrimaryDataStoreInfo getStoragePool(long id) {
-        return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(id, DataStoreRole.Primary);
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(id, DataStoreRole.Primary);
     }
 
     @Override
@@ -1784,9 +1822,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
 
                 _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
 
-                DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(store.getProviderName());
+                DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(store.getProviderName());
                 DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-                DataStore secStore = dataStoreMgr.getDataStore(storeId, DataStoreRole.Image);
+                DataStore secStore = _dataStoreMgr.getDataStore(storeId, DataStoreRole.Image);
                 lifeCycle.migrateToObjectStore(secStore);
                 // update store_role in template_store_ref and snapshot_store_ref to ImageCache
                 _templateStoreDao.updateStoreRoleToCachce(storeId);


[48/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: added account level secondary storage resource limit checks


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

Branch: refs/heads/master
Commit: 75ae90b0730b632127cba01f9a4fdeb3ad16e86a
Parents: 0525e47
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Apr 23 17:18:31 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Apr 24 15:48:44 2015 +0530

----------------------------------------------------------------------
 .../TemplateOrVolumePostUploadCommand.java      | 20 ++++++++
 .../com/cloud/storage/VolumeApiServiceImpl.java |  2 +
 .../template/HypervisorTemplateAdapter.java     |  2 +
 .../resource/NfsSecondaryStorageResource.java   | 48 ++++++++++++++++++++
 4 files changed, 72 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75ae90b0/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index 0a5f1d6..5d1e56b 100644
--- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -49,6 +49,10 @@ public class TemplateOrVolumePostUploadCommand {
 
     String description;
 
+    private String defaultMaxAccountSecondaryStorage;
+
+    private long accountId;
+
     public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
             String dataToRole) {
         this.entityId = entityId;
@@ -176,4 +180,20 @@ public class TemplateOrVolumePostUploadCommand {
     public void setDescription(String description) {
         this.description = description;
     }
+
+    public void setDefaultMaxAccountSecondaryStorage(String defaultMaxAccountSecondaryStorage) {
+        this.defaultMaxAccountSecondaryStorage = defaultMaxAccountSecondaryStorage;
+    }
+
+    public String getDefaultMaxAccountSecondaryStorage() {
+        return defaultMaxAccountSecondaryStorage;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    public long getAccountId() {
+        return accountId;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75ae90b0/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d7000f7..7e12284 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -339,6 +339,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
                 command.setLocalPath(volumeStore.getLocalDownloadPath());
                 //using the existing max upload size configuration
                 command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
+                command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
+                command.setAccountId(vol.getAccountId());
                 Gson gson = new GsonBuilder().create();
                 String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
                 response.setMetadata(metadata);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75ae90b0/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 265bc12..38a145b 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -270,6 +270,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
                             templateOnStore.getDataStore().getRole().toString());
                     //using the existing max template size configuration
                     payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
+                    payload.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
+                    payload.setAccountId(template.getAccountId());
                     payload.setRemoteEndPoint(ep.getPublicAddr());
                     payload.setRequiresHvm(template.requiresHvm());
                     payload.setDescription(template.getDisplayText());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75ae90b0/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 1cd69fc..bedd5c1 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -48,6 +48,7 @@ import javax.naming.ConfigurationException;
 
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.storage.Storage;
+import com.cloud.storage.template.TemplateConstants;
 import com.cloud.utils.EncryptionUtil;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -2633,6 +2634,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 updateStateMapWithError(uuid, errorMessage);
                 throw new InvalidParameterValueException(errorMessage);
             }
+            checkSecondaryStorageResourceLimit(cmd, contentLengthInGB);
             try {
                 String absolutePath = cmd.getAbsolutePath();
                 uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
@@ -2663,6 +2665,52 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         return uploadEntity;
     }
 
+    private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
+        String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator;
+        long accountId = cmd.getAccountId();
+
+        long accountTemplateDirSize = 0;
+        File accountTemplateDir = new File(rootDir + getTemplatePathForAccount(accountId));
+        if(accountTemplateDir.exists()) {
+            FileUtils.sizeOfDirectory(accountTemplateDir);
+        }
+        long accountVolumeDirSize = 0;
+        File accountVolumeDir = new File(rootDir + getVolumePathForAccount(accountId));
+        if(accountVolumeDir.exists()) {
+            accountVolumeDirSize = FileUtils.sizeOfDirectory(accountVolumeDir);
+        }
+        long accountSnapshotDirSize = 0;
+        File accountSnapshotDir = new File(rootDir + getSnapshotPathForAccount(accountId));
+        if(accountSnapshotDir.exists()) {
+            accountSnapshotDirSize = FileUtils.sizeOfDirectory(accountSnapshotDir);
+        }
+        s_logger.debug("accountTemplateDirSize: " + accountTemplateDirSize + " accountSnapshotDirSize: " +accountSnapshotDirSize + " accountVolumeDirSize: " +
+                           accountVolumeDirSize);
+
+        int accountDirSizeInGB = getSizeInGB(accountTemplateDirSize + accountSnapshotDirSize + accountVolumeDirSize);
+        int defaultMaxAccountSecondaryStorageInGB = Integer.parseInt(cmd.getDefaultMaxAccountSecondaryStorage());
+
+        if ((accountDirSizeInGB + contentLengthInGB) > defaultMaxAccountSecondaryStorageInGB) {
+            s_logger.error("accountDirSizeInGb: " + accountDirSizeInGB + " defaultMaxAccountSecondaryStorageInGB: " + defaultMaxAccountSecondaryStorageInGB + " contentLengthInGB:"
+                    + contentLengthInGB);
+            String errorMessage = "Maximum number of resources of type secondary_storage for account has exceeded";
+            updateStateMapWithError(cmd.getEntityUUID(), errorMessage);
+            throw new InvalidParameterValueException(errorMessage);
+        }
+    }
+
+    private String getVolumePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + accountId;
+    }
+
+    private String getTemplatePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + accountId;
+    }
+
+    private String getSnapshotPathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId;
+    }
+
     private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
         String uuid = cmd.getEntityUUID();
         String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();


[39/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Returning template/volume download percent in UploadStatusAnswer

Also updating the store ref entries on receiving the answer.


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

Branch: refs/heads/master
Commit: ce823a3a2639f4272b96facd1ee08b26ad461681
Parents: 7c2c9b4
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Apr 9 15:24:39 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Thu Apr 9 15:38:58 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/storage/command/UploadStatusAnswer.java      | 9 +++++++++
 .../src/com/cloud/storage/ImageStoreUploadMonitorImpl.java  | 6 ++++++
 .../storage/resource/NfsSecondaryStorageResource.java       | 8 +++++++-
 .../apache/cloudstack/storage/template/UploadEntity.java    | 9 +++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce823a3a/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java b/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
index a5ef53b..1825b5a 100644
--- a/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
+++ b/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
@@ -30,6 +30,7 @@ public class UploadStatusAnswer extends Answer {
     private long virtualSize = 0;
     private long physicalSize = 0;
     private String installPath = null;
+    private int downloadPercent = 0;
 
     protected UploadStatusAnswer() {
     }
@@ -76,4 +77,12 @@ public class UploadStatusAnswer extends Answer {
     public void setInstallPath(String installPath) {
         this.installPath = installPath;
     }
+
+    public int getDownloadPercent() {
+        return downloadPercent;
+    }
+
+    public void setDownloadPercent(int downloadPercent) {
+        this.downloadPercent = downloadPercent;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce823a3a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 7841ad9..01bda4f 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -293,6 +293,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                         case IN_PROGRESS:
                             if (tmpVolume.getState() == Volume.State.NotUploaded) {
                                 tmpVolumeDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS);
+                                tmpVolumeDataStore.setDownloadPercent(answer.getDownloadPercent());
                                 stateMachine.transitTo(tmpVolume, Event.UploadRequested, null, _volumeDao);
                             } else if (tmpVolume.getState() == Volume.State.UploadInProgress) { // check for timeout
                                 if (System.currentTimeMillis() - tmpVolumeDataStore.getCreated().getTime() > _uploadOperationTimeout) {
@@ -301,6 +302,8 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                                     if (s_logger.isDebugEnabled()) {
                                         s_logger.debug("Volume " + tmpVolume.getUuid() + " failed to upload due to operation timed out");
                                     }
+                                } else {
+                                    tmpVolumeDataStore.setDownloadPercent(answer.getDownloadPercent());
                                 }
                             }
                             break;
@@ -364,6 +367,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             if (tmpTemplate.getState() == VirtualMachineTemplate.State.NotUploaded) {
                                 tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS);
                                 stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.UploadRequested, null, _templateDao);
+                                tmpTemplateDataStore.setDownloadPercent(answer.getDownloadPercent());
                             } else if (tmpTemplate.getState() == VirtualMachineTemplate.State.UploadInProgress) { // check for timeout
                                 if (System.currentTimeMillis() - tmpTemplateDataStore.getCreated().getTime() > _uploadOperationTimeout) {
                                     tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
@@ -371,6 +375,8 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                                     if (s_logger.isDebugEnabled()) {
                                         s_logger.debug("Template " + tmpTemplate.getUuid() + " failed to upload due to operation timed out");
                                     }
+                                } else {
+                                    tmpTemplateDataStore.setDownloadPercent(answer.getDownloadPercent());
                                 }
                             }
                             break;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce823a3a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 1571f50..4644785 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -1689,10 +1689,15 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 answer.setVirtualSize(uploadEntity.getVirtualSize());
                 answer.setInstallPath(uploadEntity.getTmpltPath());
                 answer.setPhysicalSize(uploadEntity.getPhysicalSize());
+                answer.setDownloadPercent(100);
                 uploadEntityStateMap.remove(entityUuid);
                 return answer;
             } else if (uploadEntity.getUploadState() == UploadEntity.Status.IN_PROGRESS) {
-                return new UploadStatusAnswer(cmd, UploadStatus.IN_PROGRESS);
+                UploadStatusAnswer answer =  new UploadStatusAnswer(cmd, UploadStatus.IN_PROGRESS);
+                long downloadedSize = FileUtils.sizeOfDirectory(new File(uploadEntity.getInstallPathPrefix()));
+                int downloadPercent = (int) (100 * downloadedSize / uploadEntity.getContentLength());
+                answer.setDownloadPercent(Math.min(downloadPercent, 100));
+                return answer;
             }
         }
         return new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN);
@@ -2637,6 +2642,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 uploadEntity.setChksum(cmd.getChecksum());
                 uploadEntity.setMaxSizeInGB(maxSizeInGB);
                 uploadEntity.setDescription(cmd.getDescription());
+                uploadEntity.setContentLength(contentLength);
                 // create a install dir
                 if (!_storage.exists(installPathPrefix)) {
                     _storage.mkdir(installPathPrefix);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce823a3a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
index e9444c2..d851143 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
@@ -33,6 +33,7 @@ public class UploadEntity {
     private long physicalSize;
     private int maxSizeInGB;
     private String description;
+    private long contentLength;
 
     public static enum ResourceType {
         VOLUME, TEMPLATE
@@ -189,4 +190,12 @@ public class UploadEntity {
     public void setDescription(String description) {
         this.description = description;
     }
+
+    public long getContentLength() {
+        return contentLength;
+    }
+
+    public void setContentLength(long contentLength) {
+        this.contentLength = contentLength;
+    }
 }


[15/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Added global config validation test


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

Branch: refs/heads/master
Commit: aad9b8a51fa55709eb588d8bdea7bcd88cb0bdb8
Parents: 8840d90
Author: sailajamada <sa...@citrix.com>
Authored: Thu Mar 12 16:57:48 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Mar 12 16:57:48 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_volumes.py            | 49 +++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad9b8a5/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 8f6d8bb..1b6b4d1 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -203,6 +203,36 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return(getuploadparamsresponce)
 
+    def validate_max_vol_size(self,up_vol,volumestate):
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=up_vol.id
+                )
+        self.assertNotEqual(
+                    list_volume_response,
+                    None,
+                    "Check if volume exists in ListVolumes"
+                )
+
+        self.assertEqual(
+                    list_volume_response[0].state,
+                    volumestate,
+                    "Check volume state in ListVolumes"
+                )
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='storage.max.volume.upload.size'
+                                     )
+
+        max_size = int(config[0].value)
+
+        if int(list_volume_response[0].size) > max_size:
+            self.fail("Global Config storage.max.volume.upload.size is not considered with Browser Based Upload volumes")
+
+
+
     def browse_upload_volume_with_md5(self):
         cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
         cmd.zoneid = self.zone.id
@@ -1407,7 +1437,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 15:  Recover destroyed VM which has Uploaded volumes attached========================= ")
 
             self.recover_destroyed_vm(vm4details)
-            self.destroy_vm(vm4details)
+            self.expunge_vm(vm4details)
 
             self.deletevolume(newvolumetodestoy_VM.id)
 
@@ -1434,6 +1464,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 19:  Create template from Backup Snapshot of attached uploaded volume========================= ")
             self.volume_snapshot_template(snapshotdetails)
 
+            self.detach_volume(vm6details,browseup_vol6.id)
             self.deletevolume(browseup_vol6.id)
             self.expunge_vm(vm6details)
 
@@ -1523,6 +1554,22 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         return
 
 
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_03_Browser_Upload_Volume_Global_Config_TPath(self):
+        """
+        Test Browser_Upload_Volume_Global_Config limits 
+        """
+        try:
+            
+            self.debug("========================= Test 1 Validate Storage.max.upload.size ========================= ")
+            globalconfig_browse_up_vol=self.browse_upload_volume()
+            self.validate_max_vol_size(globalconfig_browse_up_vol,"Uploaded")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
     @classmethod
     def tearDownClass(self):
         try:


[34/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Merge branch 'volume-upload' of https://git-wip-us.apache.org/repos/asf/cloudstack into volume-upload


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

Branch: refs/heads/master
Commit: 3d6318e539bb8bb967a01b5413538c7357e29ff0
Parents: 736f704 878b43b
Author: sailajamada <sa...@citrix.com>
Authored: Thu Apr 2 09:32:40 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Apr 2 09:32:40 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/storage/resource/NfsSecondaryStorageResource.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------



[32/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: removed hardcoded vhd for Image format check.


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

Branch: refs/heads/master
Commit: 878b43bc64bf3070babc4a62f4c5c74f9cbb0b38
Parents: eac8d4b
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Mar 30 17:52:43 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Mar 30 17:56:59 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/storage/resource/NfsSecondaryStorageResource.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/878b43bc/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 8ccbcb6..1571f50 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2666,13 +2666,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
 
         String uploadedFileExtension = FilenameUtils.getExtension(filename);
-        String userSelectedFormat= "vhd";
+        String userSelectedFormat= uploadEntity.getFormat().toString();
         if(uploadedFileExtension.equals("zip") || uploadedFileExtension.equals("bz2") || uploadedFileExtension.equals("gz")) {
             userSelectedFormat += "." + uploadedFileExtension;
         }
         String formatError = ImageStoreUtil.checkTemplateFormat(fileSavedTempLocation, userSelectedFormat);
         if(StringUtils.isNotBlank(formatError)) {
-            String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + uploadEntity.getFormat() + ". Received: " + formatError;
+            String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + userSelectedFormat + ". Received: " + formatError;
             s_logger.error(errorString);
             return errorString;
         }


[50/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Merge branch 'volume-upload' into master

This closes #206


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

Branch: refs/heads/master
Commit: 0b8355920ed858c21f57ebedbf3e8dbe3283b671
Parents: 07c3089 faaa136
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Wed Apr 29 09:36:00 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Wed Apr 29 11:12:53 2015 +0530

----------------------------------------------------------------------
 agent/pom.xml                                   |    1 +
 api/src/com/cloud/storage/Volume.java           |   24 +-
 api/src/com/cloud/storage/VolumeApiService.java |    6 +
 .../com/cloud/template/TemplateApiService.java  |    5 +
 .../cloud/template/VirtualMachineTemplate.java  |   42 +-
 .../api/AbstractGetUploadParamsCmd.java         |   89 +
 .../org/apache/cloudstack/api/ApiConstants.java |    2 +
 .../template/GetUploadParamsForTemplateCmd.java |  183 ++
 .../volume/GetUploadParamsForVolumeCmd.java     |   83 +
 .../api/response/GetUploadParamsResponse.java   |   84 +
 client/tomcatconf/commands.properties.in        |    4 +
 core/pom.xml                                    |   14 -
 .../cloud/agent/api/SecStorageSetupCommand.java |    8 +
 .../template/HttpTemplateDownloader.java        |    4 +-
 .../TemplateOrVolumePostUploadCommand.java      |  199 ++
 .../storage/command/UploadStatusAnswer.java     |   88 +
 .../storage/command/UploadStatusCommand.java    |   53 +
 .../subsystem/api/storage/VolumeService.java    |    3 +
 .../src/com/cloud/storage/VMTemplateVO.java     |    3 +
 .../com/cloud/storage/dao/VMTemplateDao.java    |    4 +-
 .../cloud/storage/dao/VMTemplateDaoImpl.java    |   72 +
 .../datastore/db/TemplateDataStoreDao.java      |    3 +
 .../datastore/db/VolumeDataStoreDao.java        |    3 +
 .../storage/image/TemplateServiceImpl.java      |   60 +-
 .../storage/image/store/TemplateObject.java     |   20 +-
 .../datastore/ObjectInDataStoreManagerImpl.java |    2 +
 .../storage/image/TemplateEntityImpl.java       |   17 +
 .../image/db/TemplateDataStoreDaoImpl.java      |   22 +-
 .../image/db/VolumeDataStoreDaoImpl.java        |   28 +-
 .../storage/volume/VolumeServiceImpl.java       |   63 +-
 framework/db/pom.xml                            |    1 +
 framework/jobs/pom.xml                          |    1 +
 framework/spring/module/pom.xml                 |    1 +
 .../manager/BareMetalTemplateAdapter.java       |   10 +-
 plugins/hypervisors/kvm/pom.xml                 |    1 +
 .../cloud/agent/manager/MockStorageManager.java |    5 +
 .../agent/manager/MockStorageManagerImpl.java   |    9 +-
 .../agent/manager/SimulatorManagerImpl.java     |    3 +
 pom.xml                                         |    2 +-
 server/pom.xml                                  |    2 +
 .../spring-server-core-managers-context.xml     |    1 +
 .../com/cloud/api/query/QueryManagerImpl.java   |    2 +-
 .../api/query/dao/TemplateJoinDaoImpl.java      |    4 +-
 server/src/com/cloud/configuration/Config.java  |    4 +-
 .../cloud/server/ConfigurationServerImpl.java   |   44 +-
 .../com/cloud/server/ManagementServerImpl.java  |    5 +-
 .../cloud/storage/ImageStoreUploadMonitor.java  |   27 +
 .../storage/ImageStoreUploadMonitorImpl.java    |  436 +++
 .../com/cloud/storage/StorageManagerImpl.java   |  154 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java |  145 +-
 .../template/HypervisorTemplateAdapter.java     |  102 +-
 .../src/com/cloud/template/TemplateAdapter.java |    7 +
 .../com/cloud/template/TemplateAdapterBase.java |   39 +-
 .../com/cloud/template/TemplateManagerImpl.java |   72 +-
 services/iam/server/pom.xml                     |    1 +
 .../SecondaryStorageManagerImpl.java            |    4 +
 services/secondary-storage/server/pom.xml       |    7 +
 .../resource/HttpUploadServerHandler.java       |  295 ++
 .../resource/NfsSecondaryStorageResource.java   |  433 ++-
 .../storage/template/DownloadManager.java       |    3 +
 .../storage/template/DownloadManagerImpl.java   |    7 +-
 .../storage/template/UploadEntity.java          |  201 ++
 .../debian/config/etc/init.d/cloud-early-config |   30 +
 systemvm/scripts/config_ssl.sh                  |   24 +
 .../component/test_browse_templates.py          | 1684 +++++++++++
 .../component/test_browse_volumes.py            | 2686 ++++++++++++++++++
 test/pom.xml                                    |    5 -
 tools/marvin/marvin/config/test_data.py         |   34 +-
 ui/scripts/storage.js                           |  194 +-
 ui/scripts/templates.js                         |  327 ++-
 ui/scripts/ui/dialog.js                         |  141 +-
 utils/pom.xml                                   |   14 +-
 utils/src/com/cloud/utils/EncryptionUtil.java   |   69 +
 .../utils/imagestore/ImageStoreUtil.java        |  110 +
 .../utils/template/TemplateUtils.java           |   97 -
 .../utils/imagestore/ImageStoreUtilTest.java    |   38 +
 76 files changed, 8363 insertions(+), 307 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/api/src/com/cloud/storage/Volume.java
----------------------------------------------------------------------
diff --cc api/src/com/cloud/storage/Volume.java
index f0c7000,b7a5eeb..9f5f502
mode 100644,100755..100644
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/api/src/com/cloud/storage/VolumeApiService.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/api/src/com/cloud/template/TemplateApiService.java
----------------------------------------------------------------------
diff --cc api/src/com/cloud/template/TemplateApiService.java
index 9a2e215,43177fc..43177fc
mode 100644,100755..100644
--- a/api/src/com/cloud/template/TemplateApiService.java
+++ b/api/src/com/cloud/template/TemplateApiService.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/api/src/com/cloud/template/VirtualMachineTemplate.java
----------------------------------------------------------------------
diff --cc api/src/com/cloud/template/VirtualMachineTemplate.java
index 599212b,54d61a4..54d61a4
mode 100644,100755..100644
--- a/api/src/com/cloud/template/VirtualMachineTemplate.java
+++ b/api/src/com/cloud/template/VirtualMachineTemplate.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --cc api/src/org/apache/cloudstack/api/ApiConstants.java
index 4ab10fa,54604f3..2b64258
mode 100644,100755..100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@@ -616,10 -614,7 +617,11 @@@ public class ApiConstants 
      public static final String REGION_LEVEL_VPC = "regionlevelvpc";
      public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
      public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
+     public static final String METADATA = "metadata";
 +    public static final String PHYSICAL_SIZE = "physicalsize";
 +    public static final String OVM3_POOL = "ovm3pool";
 +    public static final String OVM3_CLUSTER = "ovm3cluster";
 +    public static final String OVM3_VIP = "ovm3vip";
  
      public enum HostDetails {
          all, capacity, events, stats, min;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/schema/src/com/cloud/storage/VMTemplateVO.java
----------------------------------------------------------------------
diff --cc engine/schema/src/com/cloud/storage/VMTemplateVO.java
index d44de22,dd2b35a..dd2b35a
mode 100644,100755..100644
--- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java
+++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
----------------------------------------------------------------------
diff --cc engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
index 2b815d8,a3adffc..a3adffc
mode 100644,100755..100644
--- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
----------------------------------------------------------------------
diff --cc engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
index 401a4a2,90196a8..90196a8
mode 100644,100755..100644
--- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
----------------------------------------------------------------------
diff --cc engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
index c5ca5b9,197caa7..473959b
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
@@@ -166,7 -165,7 +165,7 @@@ public class TemplateObject implements 
      }
  
      @Override
-     public void processEvent(Event event) {
 -    public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event) {
++    public void processEvent(ObjectInDataStoreStateMachine.Event event) {
          try {
              objectInStoreMgr.update(this, event);
          } catch (NoTransitionException e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --cc engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 3a52c83,436c462..a2fd656
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@@ -26,8 -26,8 +26,9 @@@ import java.util.Map
  
  import javax.inject.Inject;
  
 +import com.cloud.offering.DiskOffering;
  import com.cloud.storage.RegisterVolumePayload;
+ import com.cloud.utils.Pair;
  import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
  import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
  import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@@@ -1226,18 -1224,25 +1227,31 @@@ public class VolumeServiceImpl implemen
          return future;
      }
  
+     @Override
+     public Pair<EndPoint,DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store) {
+ 
+         EndPoint ep = _epSelector.select(store);
+         if (ep == null) {
+             String errorMessage = "There is no secondary storage VM for image store " + store.getName();
+             s_logger.warn(errorMessage);
+             throw new CloudRuntimeException(errorMessage);
+         }
+         DataObject volumeOnStore = store.create(volume);
+         return new Pair<>(ep,volumeOnStore);
+     }
+ 
      protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
          CreateCmdResult result = callback.getResult();
 +        VolumeObject vo = (VolumeObject)context.volume;
          try {
 -            VolumeObject vo = (VolumeObject)context.volume;
              if (result.isFailed()) {
                  vo.processEvent(Event.OperationFailed);
 +                // delete the volume entry from volumes table in case of failure
 +                VolumeVO vol = volDao.findById(vo.getId());
 +                if (vol != null) {
 +                    volDao.remove(vo.getId());
 +                }
 +
              } else {
                  vo.processEvent(Event.OperationSuccessed, result.getAnswer());
  
@@@ -1385,13 -1385,12 +1399,13 @@@
                          return;
                      }
  
 -                    List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listUploadedVolumesByStoreId(storeId);
 +                    // find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
 +                    List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
                      List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
                      for (VolumeDataStoreVO volumeStore : dbVolumes) {
 -                        VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId());
 +                        VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
                          if (volume == null) {
-                             s_logger.warn("Volume_store_ref shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId +
+                             s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId +
                                      ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
                              volumeStore.setDestroyed(true);
                              _volumeStoreDao.update(volumeStore.getId(), volumeStore);
@@@ -1434,9 -1436,14 +1451,14 @@@
                                  if (volume.getSize() == 0) {
                                      // Set volume size in volumes table
                                      volume.setSize(volInfo.getSize());
 -                                    _volumeDao.update(volumeStore.getVolumeId(), volume);
 +                                    volDao.update(volumeStore.getVolumeId(), volume);
                                  }
  
+                                 if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
+                                     VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                                     volObj.processEvent(Event.OperationSuccessed);
+                                 }
+ 
                                  if (volInfo.getSize() > 0) {
                                      try {
                                          _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
@@@ -1456,8 -1472,8 +1487,7 @@@
                          }
                          // Volume is not on secondary but we should download.
                          if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
-                             s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId +
-                                     ", will request download to start/resume shortly");
+                             s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
 -                            toBeDownloaded.add(volumeStore);
                          }
                      }
  

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
----------------------------------------------------------------------
diff --cc plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
index 1be3439,17dab00..17dab00
mode 100644,100755..100644
--- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/plugins/hypervisors/kvm/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
----------------------------------------------------------------------
diff --cc plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
index 46ddd95,27be6f8..bd7e9e8
--- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
@@@ -31,8 -35,7 +31,9 @@@ import org.apache.cloudstack.storage.co
  import org.apache.cloudstack.storage.command.DownloadCommand;
  import org.apache.cloudstack.storage.command.DownloadProgressCommand;
  import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+ import org.apache.cloudstack.storage.command.UploadStatusCommand;
 +import org.apache.log4j.Logger;
 +import org.springframework.stereotype.Component;
  
  import com.cloud.agent.api.Answer;
  import com.cloud.agent.api.AttachIsoCommand;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index 175394c,6f7bd34..0c55e33
--- a/pom.xml
+++ b/pom.xml
@@@ -57,21 -53,20 +57,21 @@@
      <cs.junit.version>4.11</cs.junit.version>
      <cs.hamcrest.version>1.3</cs.hamcrest.version>
      <cs.bcprov.version>1.46</cs.bcprov.version>
 -    <cs.jsch.version>0.1.42</cs.jsch.version>
 -    <cs.jpa.version>2.0.0</cs.jpa.version>
 -    <cs.jasypt.version>1.9.0</cs.jasypt.version>
 -    <cs.trilead.version>build213-svnkit-1.3-patch</cs.trilead.version>
 -    <cs.ehcache.version>2.6.6</cs.ehcache.version>
 +    <cs.jsch.version>0.1.51</cs.jsch.version>
 +    <cs.jpa.version>2.1.0</cs.jpa.version>
 +    <cs.jasypt.version>1.9.2</cs.jasypt.version>
 +    <cs.trilead.version>1.0.0-build217</cs.trilead.version>
 +    <cs.ehcache.version>2.6.9</cs.ehcache.version>
      <cs.gson.version>1.7.2</cs.gson.version>
 -    <cs.guava.version>14.0-rc1</cs.guava.version>
 +    <cs.guava.version>18.0</cs.guava.version>
      <cs.xapi.version>6.2.0-3.1</cs.xapi.version>
      <cs.httpclient.version>4.3.6</cs.httpclient.version>
-     <cs.httpcore.version>4.3.3</cs.httpcore.version>
+     <cs.httpcore.version>4.4</cs.httpcore.version>
 -    <cs.mysql.version>5.1.21</cs.mysql.version>
 -    <cs.xstream.version>1.3.1</cs.xstream.version>
 +    <cs.commons-httpclient.version>3.1</cs.commons-httpclient.version>
 +    <cs.mysql.version>5.1.34</cs.mysql.version>
 +    <cs.xstream.version>1.4.7</cs.xstream.version>
      <cs.xmlrpc.version>3.1.3</cs.xmlrpc.version>
 -    <cs.mail.version>1.4</cs.mail.version>
 +    <cs.mail.version>1.4.7</cs.mail.version>
      <cs.axis.version>1.4</cs.axis.version>
      <cs.axis2.version>1.5.6</cs.axis2.version>
      <cs.rampart.version>1.5.1</cs.rampart.version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/configuration/Config.java
index e48e0b3,4d6fb53..1d0a387
mode 100644,100755..100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/server/ConfigurationServerImpl.java
index 157ea03,d12bd6b..a28d984
mode 100644,100755..100644
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/server/ManagementServerImpl.java
index 1723c1e,66fa52a..a187d4e
mode 100644,100755..100644
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@@ -39,8 -37,9 +39,10 @@@ import javax.crypto.spec.SecretKeySpec
  import javax.inject.Inject;
  import javax.naming.ConfigurationException;
  
 +import org.apache.cloudstack.api.command.admin.usage.RemoveRawUsageRecordsCmd;
  import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
+ import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
+ import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
  import org.apache.commons.codec.binary.Base64;
  import org.apache.log4j.Logger;
  import org.apache.cloudstack.acl.ControlledEntity;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/StorageManagerImpl.java
index 2a46592,91e4047..f31095b
mode 100644,100755..100644
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@@ -41,10 -41,8 +41,9 @@@ import javax.ejb.Local
  import javax.inject.Inject;
  import javax.naming.ConfigurationException;
  
 +import com.cloud.hypervisor.Hypervisor;
  import org.apache.log4j.Logger;
  import org.springframework.stereotype.Component;
- 
  import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
  import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
  import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
@@@ -269,7 -270,7 +272,9 @@@ public class StorageManagerImpl extend
      @Inject
      EndPointSelector _epSelector;
      @Inject
 +    private DiskOfferingDao _diskOfferingDao;
++    @Inject
+     ResourceLimitService _resourceLimitMgr;
  
      protected List<StoragePoolDiscoverer> _discoverers;
  
@@@ -588,15 -585,11 +593,15 @@@
  
                  store = lifeCycle.initialize(params);
              } else {
-                 store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+                 store = _dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
              }
  
 -            HostScope scope = new HostScope(host.getId(), host.getClusterId(), host.getDataCenterId());
 -            lifeCycle.attachHost(store, scope, pInfo);
 +            pool = _storagePoolDao.findById(store.getId());
 +            if (pool.getStatus() != StoragePoolStatus.Maintenance && pool.getStatus() != StoragePoolStatus.Removed) {
 +                HostScope scope = new HostScope(host.getId(), host.getClusterId(), host.getDataCenterId());
 +                lifeCycle.attachHost(store, scope, pInfo);
 +            }
 +
          } catch (Exception e) {
              s_logger.warn("Unable to setup the local storage pool for " + host, e);
              throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/VolumeApiServiceImpl.java
index dbae194,7e12284..7a450e7
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@@ -291,22 -375,24 +384,26 @@@ public class VolumeApiServiceImpl exten
              throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
          }
  
-         if (url.toLowerCase().contains("file://")) {
-             throw new InvalidParameterValueException("File:// type urls are currently unsupported");
-         }
- 
-         ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
-         if (imgfmt == null) {
-             throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
-         }
- 
-         UriUtils.validateUrl(format, url);
- 
+         //validating the url only when url is not null. url can be null incase of form based post upload
+         if (url != null ) {
+             if( url.toLowerCase().contains("file://")) {
+                 throw new InvalidParameterValueException("File:// type urls are currently unsupported");
+             }
+             UriUtils.validateUrl(format, url);
 +        // check URL existence
 +        UriUtils.checkUrlExistence(url);
+             // Check that the resource limit for secondary storage won't be exceeded
+             _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+         } else {
+             _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage);
+         }
  
-         // Check that the resource limit for secondary storage won't be exceeded
-         _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+         try {
+             ImageFormat.valueOf(format.toUpperCase());
+         } catch (IllegalArgumentException e) {
+             s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
+             throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+         }
  
          // Check that the the disk offering specified is valid
          if (diskOfferingId != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/HypervisorTemplateAdapter.java
index e58edb9,38a145b..369262b
mode 100644,100755..100644
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/template/TemplateAdapter.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateAdapter.java
index a85e337,4ed0a81..4ed0a81
mode 100644,100755..100644
--- a/server/src/com/cloud/template/TemplateAdapter.java
+++ b/server/src/com/cloud/template/TemplateAdapter.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/template/TemplateAdapterBase.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateAdapterBase.java
index 92383a0,c5d0c5b..c5d0c5b
mode 100644,100755..100644
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/com/cloud/template/TemplateAdapterBase.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateManagerImpl.java
index c322b12,af35dd8..1135518
mode 100644,100755..100644
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --cc services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
index 8d4454f,79a1486..6abb421
mode 100644,100755..100644
--- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --cc services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 1b3dc83,bedd5c1..6565187
mode 100644,100755..100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --cc services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index 9678b6b,25c0887..25c0887
mode 100644,100755..100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/systemvm/scripts/config_ssl.sh
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/ui/scripts/storage.js
----------------------------------------------------------------------
diff --cc ui/scripts/storage.js
index 1773c27,68e3ec1..7f210bd
--- a/ui/scripts/storage.js
+++ b/ui/scripts/storage.js
@@@ -322,45 -328,37 +329,68 @@@
                                                  data: items
                                              });
                                          }
 +
-                                     },
-                                     url: {
-                                         label: 'label.url',
-                                         docID: 'helpUploadVolumeURL',
-                                         validation: {
-                                             required: true
+                                     },                                      
+                                     diskOffering: {
+                                         label: 'Custom Disk Offering',
+                                         docID: 'helpVolumeDiskOffering',
+                                         select: function(args) {
+                                         	var diskofferingObjs;
+                                         	$.ajax({
+                                                 url: createURL("listDiskOfferings"),
+                                                 dataType: "json",
+                                                 async: false,
+                                                 success: function(json) {
+                                                     diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
+                                                     var items = [{
+                                                     	id: '',
+                                                         description: ''
+                                                     }];
+                                                     $(diskofferingObjs).each(function() {
+                                                     	if (this.iscustomized == true) {                                                    	
+ 	                                                        items.push({
+ 	                                                            id: this.id,
+ 	                                                            description: this.displaytext
+ 	                                                        });
+                                                     	}
+                                                     });
+                                                     args.response.success({
+                                                         data: items
+                                                     });
+                                                 }
+                                             });
                                          }
-                                     },                                                                         
+                                     },                                    
 +                                    diskOffering: {
 +                                        label: 'Custom Disk Offering',
 +                                        docID: 'helpVolumeDiskOffering',
 +                                        select: function(args) {
 +                                        	var diskofferingObjs;
 +                                        	$.ajax({
 +                                                url: createURL("listDiskOfferings"),
 +                                                dataType: "json",
 +                                                async: false,
 +                                                success: function(json) {
 +                                                    diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
 +                                                    var items = [{
 +                                                    	id: '',
 +                                                        description: ''
 +                                                    }];
 +                                                    $(diskofferingObjs).each(function() {
 +                                                    	if (this.iscustomized == true) {                                                    	
 +	                                                        items.push({
 +	                                                            id: this.id,
 +	                                                            description: this.displaytext
 +	                                                        });
 +                                                    	}
 +                                                    });
 +                                                    args.response.success({
 +                                                        data: items
 +                                                    });
 +                                                }
 +                                            });
 +                                        }
 +                                    },      
                                      checksum: {
                                          docID: 'helpUploadVolumeChecksum',
                                          label: 'label.md5.checksum'

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/ui/scripts/templates.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/ui/scripts/ui/dialog.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b835592/utils/pom.xml
----------------------------------------------------------------------


[20/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: added validation for file formats

merged TemplateUtils and ImageStoreUtil to a singe ImageStoreUtil
also added a unittest for ImageStoreUtil


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

Branch: refs/heads/master
Commit: 018023c1ef7fc5216a607e40811ff20f185d295c
Parents: d5dffb5
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Mar 19 11:54:51 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Mar 20 16:25:13 2015 +0530

----------------------------------------------------------------------
 .../template/HttpTemplateDownloader.java        |   4 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java |   2 +-
 .../com/cloud/template/TemplateManagerImpl.java |   2 +-
 .../resource/HttpUploadServerHandler.java       |  10 ++
 .../resource/NfsSecondaryStorageResource.java   |  14 +++
 utils/src/com/cloud/utils/ImageStoreUtil.java   |  39 -------
 .../utils/imagestore/ImageStoreUtil.java        | 110 +++++++++++++++++++
 .../utils/template/TemplateUtils.java           |  97 ----------------
 .../utils/imagestore/ImageStoreUtilTest.java    |  38 +++++++
 9 files changed, 176 insertions(+), 140 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
index 5644af4..632a809 100644
--- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
+++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
@@ -28,6 +28,7 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Date;
 
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
 import org.apache.commons.httpclient.Credentials;
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.HttpClient;
@@ -45,7 +46,6 @@ import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.cloudstack.utils.template.TemplateUtils;
 
 import com.cloud.agent.api.storage.Proxy;
 import com.cloud.storage.StorageLayer;
@@ -259,7 +259,7 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te
                         } catch (URISyntaxException e) {
                             s_logger.warn("Invalid download url: " + getDownloadUrl() + ", This should not happen since we have validated the url before!!");
                         }
-                        String unsupportedFormat = TemplateUtils.checkTemplateFormat(file.getAbsolutePath(), uripath);
+                        String unsupportedFormat = ImageStoreUtil.checkTemplateFormat(file.getAbsolutePath(), uripath);
                             if (unsupportedFormat == null || !unsupportedFormat.isEmpty()) {
                                  try {
                                      request.abort();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 567a742..4ff7686 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -29,7 +29,6 @@ import java.util.concurrent.ExecutionException;
 import javax.inject.Inject;
 
 import com.cloud.utils.EncryptionUtil;
-import com.cloud.utils.ImageStoreUtil;
 import com.cloud.utils.db.TransactionCallbackWithException;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -39,6 +38,7 @@ import org.apache.cloudstack.api.response.GetUploadParamsResponse;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
 import org.apache.log4j.Logger;
 import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
 import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 9747ad0..10ff77f 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -35,13 +35,13 @@ import javax.naming.ConfigurationException;
 
 import com.cloud.storage.ImageStoreUploadMonitorImpl;
 import com.cloud.utils.EncryptionUtil;
-import com.cloud.utils.ImageStoreUtil;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
 import org.apache.cloudstack.api.response.GetUploadParamsResponse;
 import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 44a2b60..4a3fa86 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -28,6 +28,8 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.cloudstack.storage.template.UploadEntity;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 
 import com.cloud.exception.InvalidParameterValueException;
@@ -228,6 +230,14 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                         FileUpload fileUpload = (FileUpload) data;
                         if (fileUpload.isCompleted()) {
                             fileReceived = true;
+                            String format = ImageStoreUtil.checkTemplateFormat(fileUpload.getFile().getAbsolutePath(), fileUpload.getFilename());
+                            if(StringUtils.isNotBlank(format)) {
+                                String errorString = "File type mismatch between the sent file and the actual content. Received: " + format;
+                                logger.error(errorString);
+                                responseContent.append(errorString);
+                                storageResource.updateStateMapWithError(uuid, errorString);
+                                return HttpResponseStatus.BAD_REQUEST;
+                            }
                             String status = storageResource.postUpload(uuid, fileUpload.getFile().getName());
                             if (status != null) {
                                 responseContent.append(status);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index f67015c..8ccbcb6 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -66,8 +66,10 @@ import io.netty.handler.logging.LogLevel;
 import io.netty.handler.logging.LoggingHandler;
 import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
 import org.apache.cloudstack.storage.template.UploadEntity;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -2663,6 +2665,18 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
 
         String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
 
+        String uploadedFileExtension = FilenameUtils.getExtension(filename);
+        String userSelectedFormat= "vhd";
+        if(uploadedFileExtension.equals("zip") || uploadedFileExtension.equals("bz2") || uploadedFileExtension.equals("gz")) {
+            userSelectedFormat += "." + uploadedFileExtension;
+        }
+        String formatError = ImageStoreUtil.checkTemplateFormat(fileSavedTempLocation, userSelectedFormat);
+        if(StringUtils.isNotBlank(formatError)) {
+            String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + uploadEntity.getFormat() + ". Received: " + formatError;
+            s_logger.error(errorString);
+            return errorString;
+        }
+
         int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
         int maxSize = uploadEntity.getMaxSizeInGB();
         if(imgSizeGigs > maxSize) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/utils/src/com/cloud/utils/ImageStoreUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/ImageStoreUtil.java b/utils/src/com/cloud/utils/ImageStoreUtil.java
deleted file mode 100644
index 52f1324..0000000
--- a/utils/src/com/cloud/utils/ImageStoreUtil.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.utils;
-
-import org.apache.log4j.Logger;
-
-public class ImageStoreUtil {
-    public static final Logger s_logger = Logger.getLogger(ImageStoreUtil.class.getName());
-
-    public static String generatePostUploadUrl(String ssvmUrlDomain, String ipAddress, String uuid) {
-        String hostname = ipAddress;
-
-        //if ssvm url domain is present, use it to construct hostname in the format 1-2-3-4.domain
-        // if the domain name is not present, ssl validation fails and has to be ignored
-        if(StringUtils.isNotBlank(ssvmUrlDomain)) {
-            hostname = ipAddress.replace(".", "-");
-            hostname = hostname + ssvmUrlDomain.substring(1);
-        }
-
-        //only https works with postupload and url format is fixed
-        return "https://" + hostname + "/upload/" + uuid;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java b/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java
new file mode 100644
index 0000000..ed13360
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java
@@ -0,0 +1,110 @@
+/*
+ * 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 org.apache.cloudstack.utils.imagestore;
+
+import com.cloud.utils.script.Script;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+public class ImageStoreUtil {
+    public static final Logger s_logger = Logger.getLogger(ImageStoreUtil.class.getName());
+
+    public static String generatePostUploadUrl(String ssvmUrlDomain, String ipAddress, String uuid) {
+        String hostname = ipAddress;
+
+        //if ssvm url domain is present, use it to construct hostname in the format 1-2-3-4.domain
+        // if the domain name is not present, ssl validation fails and has to be ignored
+        if(StringUtils.isNotBlank(ssvmUrlDomain)) {
+            hostname = ipAddress.replace(".", "-");
+            hostname = hostname + ssvmUrlDomain.substring(1);
+        }
+
+        //only https works with postupload and url format is fixed
+        return "https://" + hostname + "/upload/" + uuid;
+    }
+
+    // given a path, returns empty if path is supported image, and the file type if unsupported
+    // this is meant to catch things like accidental upload of ASCII text .vmdk descriptor
+    public static String checkTemplateFormat(String path, String uripath) {
+        // note 'path' was generated by us so it should be safe on the cmdline, be wary of 'url'
+        String command = "file ";
+        if (isCompressedExtension(uripath)) {
+            command = "file -z ";
+        }
+        String output = Script.runSimpleBashScript(command + path + " | cut -d: -f2", 60000);
+
+        // vmdk
+        if ((output.contains("VMware") || output.contains("data")) && isCorrectExtension(uripath, "vmdk")) {
+            s_logger.debug("File at path " + path + " looks like a vmware image :" + output);
+            return "";
+        }
+        // raw
+        if ((output.contains("x86 boot") || output.contains("data")) && (isCorrectExtension(uripath, "raw") || isCorrectExtension(uripath, "img"))) {
+            s_logger.debug("File at path " + path + " looks like a raw image :" + output);
+            return "";
+        }
+        // qcow2
+        if (output.contains("QEMU QCOW") && isCorrectExtension(uripath, "qcow2")) {
+            s_logger.debug("File at path " + path + " looks like QCOW2 : " + output);
+            return "";
+        }
+        // vhd
+        if (output.contains("Microsoft Disk Image") && (isCorrectExtension(uripath, "vhd") || isCorrectExtension(uripath, "vhdx"))) {
+            s_logger.debug("File at path " + path + " looks like vhd : " + output);
+            return "";
+        }
+        // ova
+        if (output.contains("POSIX tar") && isCorrectExtension(uripath, "ova")) {
+            s_logger.debug("File at path " + path + " looks like ova : " + output);
+            return "";
+        }
+
+        //lxc
+        if (output.contains("POSIX tar") && isCorrectExtension(uripath, "tar")) {
+            s_logger.debug("File at path " + path + " looks like just tar : " + output);
+            return "";
+        }
+
+        if (output.contains("ISO 9660") && isCorrectExtension(uripath, "iso")) {
+            s_logger.debug("File at path " + path + " looks like an iso : " + output);
+            return "";
+        }
+        return output;
+    }
+
+    private static boolean isCorrectExtension(String path, String ext) {
+        if (path.toLowerCase().endsWith(ext)
+            || path.toLowerCase().endsWith(ext + ".gz")
+            || path.toLowerCase().endsWith(ext + ".bz2")
+            || path.toLowerCase().endsWith(ext + ".zip")) {
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean isCompressedExtension(String path) {
+        if (path.toLowerCase().endsWith(".gz")
+            || path.toLowerCase().endsWith(".bz2")
+            || path.toLowerCase().endsWith(".zip")) {
+            return true;
+        }
+        return false;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java b/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java
deleted file mode 100644
index 53aa911..0000000
--- a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// 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 org.apache.cloudstack.utils.template;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.script.Script;
-
-public class TemplateUtils {
-    public static final Logger s_logger = Logger.getLogger(TemplateUtils.class.getName());
-
-    // given a path, returns empty if path is supported image, and the file type if unsupported
-    // this is meant to catch things like accidental upload of ASCII text .vmdk descriptor
-    public static String checkTemplateFormat(String path, String uripath) {
-        // note 'path' was generated by us so it should be safe on the cmdline, be wary of 'url'
-        String command = "file ";
-        if (isCompressedExtension(uripath)) {
-            command = "file -z ";
-        }
-        String output = Script.runSimpleBashScript(command + path + " | cut -d: -f2", 60000);
-
-        // vmdk
-        if ((output.contains("VMware") || output.contains("data")) && isCorrectExtension(uripath, "vmdk")) {
-            s_logger.debug("File at path " + path + " looks like a vmware image :" + output);
-            return "";
-        }
-        // raw
-        if ((output.contains("x86 boot") || output.contains("data")) && (isCorrectExtension(uripath, "raw") || isCorrectExtension(uripath, "img"))) {
-            s_logger.debug("File at path " + path + " looks like a raw image :" + output);
-            return "";
-        }
-        // qcow2
-        if (output.contains("QEMU QCOW") && isCorrectExtension(uripath, "qcow2")) {
-            s_logger.debug("File at path " + path + " looks like QCOW2 : " + output);
-            return "";
-        }
-        // vhd
-        if (output.contains("Microsoft Disk Image") && (isCorrectExtension(uripath, "vhd") || isCorrectExtension(uripath, "vhdx"))) {
-            s_logger.debug("File at path " + path + " looks like vhd : " + output);
-            return "";
-        }
-        // ova
-        if (output.contains("POSIX tar") && isCorrectExtension(uripath, "ova")) {
-            s_logger.debug("File at path " + path + " looks like ova : " + output);
-            return "";
-        }
-
-        //lxc
-        if (output.contains("POSIX tar") && isCorrectExtension(uripath, "tar")) {
-            s_logger.debug("File at path " + path + " looks like just tar : " + output);
-            return "";
-        }
-
-        if (output.contains("ISO 9660") && isCorrectExtension(uripath, "iso")) {
-            s_logger.debug("File at path " + path + " looks like an iso : " + output);
-            return "";
-        }
-        return output;
-    }
-
-    public static boolean isCorrectExtension(String path, String ext) {
-        if (path.toLowerCase().endsWith(ext)
-            || path.toLowerCase().endsWith(ext + ".gz")
-            || path.toLowerCase().endsWith(ext + ".bz2")
-            || path.toLowerCase().endsWith(ext + ".zip")) {
-            return true;
-        }
-        return false;
-    }
-
-    public static boolean isCompressedExtension(String path) {
-        if (path.toLowerCase().endsWith(".gz")
-            || path.toLowerCase().endsWith(".bz2")
-            || path.toLowerCase().endsWith(".zip")) {
-            return true;
-        }
-        return false;
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/018023c1/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java
----------------------------------------------------------------------
diff --git a/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java b/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java
new file mode 100644
index 0000000..e1b5578
--- /dev/null
+++ b/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java
@@ -0,0 +1,38 @@
+package org.apache.cloudstack.utils.imagestore;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.UUID;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ImageStoreUtilTest {
+
+    @Test
+    public void testgeneratePostUploadUrl() throws MalformedURLException {
+        String ssvmdomain = "*.realhostip.com";
+        String ipAddress = "10.147.28.14";
+        String uuid = UUID.randomUUID().toString();
+
+        //ssvm domain is not set
+        String url = ImageStoreUtil.generatePostUploadUrl(null, ipAddress, uuid);
+        assertPostUploadUrl(url, ipAddress, uuid);
+
+        //ssvm domain is set to empty value
+        url = ImageStoreUtil.generatePostUploadUrl("", ipAddress, uuid);
+        assertPostUploadUrl(url, ipAddress, uuid);
+
+        //ssvm domain is set to a valid value
+        url = ImageStoreUtil.generatePostUploadUrl(ssvmdomain, ipAddress, uuid);
+        assertPostUploadUrl(url, ipAddress.replace(".", "-") + ssvmdomain.substring(1), uuid);
+    }
+
+    private void assertPostUploadUrl(String urlStr, String domain, String uuid) throws MalformedURLException {
+        URL url = new URL(urlStr);
+        Assert.assertNotNull(url);
+        Assert.assertEquals(url.getHost(), domain);
+        Assert.assertEquals(url.getPath(), "/upload/" + uuid);
+    }
+
+}
\ No newline at end of file


[08/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Added Browser Based Upload Volume Test configurations into Testdata file


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

Branch: refs/heads/master
Commit: c65dad47ebba8337b2016997b4685230111902a9
Parents: fa7ef95
Author: sailajamada <sa...@citrix.com>
Authored: Wed Mar 4 09:52:11 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Wed Mar 4 09:52:11 2015 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/config/test_data.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c65dad47/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 2f97d5f..a9f1959 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -860,6 +860,27 @@ test_data = {
         "http://10.147.28.7/templates/393d3550-05ef-330f-9b8c-745b0e699759.vhd",
         "checksum": "",
     },
+    "browser_upload_volume": {
+          "VHD": {
+        "diskname": "XenUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
+        "checksum": "",
+                },
+          "OVA": {
+        "diskname": "VMwareUploadVol",
+        "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
+        "checksum": "",
+                },
+          "QCOW2": {
+        "diskname": "KVMUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
+        "checksum": "",
+                },
+    'browser_resized_disk_offering': {
+        "displaytext": "Resizeddisk",
+        "name": "Resizeddisk",
+        "disksize": 3
+    },
     "recurring_snapshot": {
         "maxsnaps": 2,
         "timezone": "US/Arizona",


[26/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: Templates in uploaded error state are also accounted in resource limits which leads to failure during template upload even though there aren't any active ones
Fixed the storage GC thread to clean up templates in error/abandoned states.


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

Branch: refs/heads/master
Commit: c62ce3eecb01bda070129143a170ceb63e0f23b9
Parents: e864b93
Author: Koushik Das <ko...@apache.org>
Authored: Tue Mar 24 09:21:42 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Tue Mar 24 09:21:42 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/StorageManagerImpl.java   | 58 +++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c62ce3ee/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index fb51ff5..91e4047 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -70,6 +70,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@@ -150,6 +151,7 @@ import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.listener.StoragePoolMonitor;
 import com.cloud.storage.listener.VolumeStateListener;
 import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
@@ -1082,7 +1084,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                         }
                     }
 
-                    // destroy uploaded volumes in UploadAbandoned/UploadError state
+                    // destroy uploaded volumes in abandoned/error state
                     List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
                     for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
                         VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
@@ -1111,7 +1113,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                                     if (volOnSecondary != null) {
                                         s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
                                         AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
-                                        future.get();
+                                        VolumeApiResult result = future.get();
+                                        if (!result.isSuccess()) {
+                                            s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
+                                        }
                                     }
                                 }
                             }
@@ -1119,6 +1124,55 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                             s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
                         }
                     }
+
+                    // destroy uploaded templates in abandoned/error state
+                    List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
+                    for (TemplateDataStoreVO templateDataStore : templateDataStores) {
+                        VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
+                        if (template == null) {
+                            s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
+                            continue;
+                        }
+                        try {
+                            DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
+                            EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
+                            if (ep == null) {
+                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
+                                continue;
+                            }
+                            Host host = _hostDao.findById(ep.getId());
+                            if (host != null && host.getManagementServerId() != null) {
+                                if (_serverId == host.getManagementServerId().longValue()) {
+                                    AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
+                                    TemplateApiResult result = future.get();
+                                    if (!result.isSuccess()) {
+                                        s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
+                                        continue;
+                                    }
+                                    // remove from template_zone_ref
+                                    List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity)dataStore).getDataCenterId(), template.getId());
+                                    if (templateZones != null) {
+                                        for (VMTemplateZoneVO templateZone : templateZones) {
+                                            _vmTemplateZoneDao.remove(templateZone.getId());
+                                        }
+                                    }
+                                    // mark all the occurrences of this template in the given store as destroyed
+                                    _templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
+                                    // find all eligible image stores for this template
+                                    List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
+                                    if (imageStores == null || imageStores.size() == 0) {
+                                        template.setState(VirtualMachineTemplate.State.Inactive);
+                                        _templateDao.update(template.getId(), template);
+
+                                        // decrement template resource count
+                                        _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
+                                    }
+                                }
+                            }
+                        } catch (Throwable th) {
+                            s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
+                        }
+                    }
                 } finally {
                     scanLock.unlock();
                 }


[03/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: Size is listed as zero for uploaded volumes
Updating the virtual size for template/volume when upload is completed.


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

Branch: refs/heads/master
Commit: dc870b5114a0bf864cc4477cc800e6b09a9e3299
Parents: 075c841
Author: Koushik Das <ko...@apache.org>
Authored: Thu Feb 19 17:11:51 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Thu Feb 19 17:13:47 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/ImageStoreUploadMonitorImpl.java    | 10 ++++++++++
 1 file changed, 10 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/dc870b51/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index b2cc5d9..bbc650f 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -280,7 +280,12 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             tmpVolumeDataStore.setPhysicalSize(answer.getPhysicalSize());
                             tmpVolumeDataStore.setSize(answer.getVirtualSize());
                             tmpVolumeDataStore.setDownloadPercent(100);
+
+                            VolumeVO volumeUpdate = _volumeDao.createForUpdate();
+                            volumeUpdate.setSize(answer.getVirtualSize());
+                            _volumeDao.update(tmpVolume.getId(), volumeUpdate);
                             stateMachine.transitTo(tmpVolume, Event.OperationSucceeded, null, _volumeDao);
+
                             if (s_logger.isDebugEnabled()) {
                                 s_logger.debug("Volume " + tmpVolume.getUuid() + " uploaded successfully");
                             }
@@ -344,7 +349,12 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             tmpTemplateDataStore.setPhysicalSize(answer.getPhysicalSize());
                             tmpTemplateDataStore.setSize(answer.getVirtualSize());
                             tmpTemplateDataStore.setDownloadPercent(100);
+
+                            VMTemplateVO templateUpdate = _templateDao.createForUpdate();
+                            templateUpdate.setSize(answer.getVirtualSize());
+                            _templateDao.update(tmpTemplate.getId(), templateUpdate);
                             stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
+
                             if (s_logger.isDebugEnabled()) {
                                 s_logger.debug("Template " + tmpTemplate.getUuid() + " uploaded successfully");
                             }


[40/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: disabled all zones during template upload


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

Branch: refs/heads/master
Commit: 5c152e5f3a8abf7385cbc8c65ddcb000bc11a560
Parents: ce823a3
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Apr 13 14:40:28 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Apr 13 14:43:12 2015 +0530

----------------------------------------------------------------------
 .../template/GetUploadParamsForTemplateCmd.java | 10 ++++-
 ui/scripts/templates.js                         | 47 +++++---------------
 2 files changed, 21 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5c152e5f/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
index d1dc468..248e892 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
@@ -22,7 +22,6 @@ import java.net.MalformedURLException;
 import java.util.Collection;
 import java.util.Map;
 
-import com.cloud.exception.ResourceAllocationException;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.AbstractGetUploadParamsCmd;
 import org.apache.cloudstack.api.ApiConstants;
@@ -34,6 +33,8 @@ import org.apache.cloudstack.api.response.GuestOSResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.log4j.Logger;
 
+import com.cloud.exception.ResourceAllocationException;
+
 @APICommand(name = "getUploadParamsForTemplate", description = "upload an existing template into the CloudStack cloud. ", responseObject = GetUploadParamsResponse.class, since =
     "4.6.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
 public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
@@ -149,6 +150,7 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
 
     @Override
     public void execute() throws ServerApiException {
+        validateRequest();
         try {
             GetUploadParamsResponse response = _templateService.registerTemplateForPostUpload(this);
             response.setResponseName(getCommandName());
@@ -159,6 +161,12 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
         }
     }
 
+    private void validateRequest() {
+        if (getZoneId() <= 0) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "invalid zoneid");
+        }
+    }
+
     @Override
     public String getCommandName() {
         return s_name;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5c152e5f/ui/scripts/templates.js
----------------------------------------------------------------------
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index c060a0c..5d6c013 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -691,41 +691,18 @@
                                         label: 'label.zone',
                                         docID: 'helpRegisterTemplateZone',
                                         select: function(args) {
-                                            if (g_regionsecondaryenabled == true) {
-                                                args.response.success({
-                                                    data: [{
-                                                        id: -1,
-                                                        description: "All Zones"
-                                                    }]
-                                                });
-                                            } else {
-                                                $.ajax({
-                                                    url: createURL("listZones&available=true"),
-                                                    dataType: "json",
-                                                    async: true,
-                                                    success: function(json) {
-                                                        var zoneObjs = [];
-                                                        var items = json.listzonesresponse.zone;
-                                                        if (items != null) {
-                                                            for (var i = 0; i < items.length; i++) {
-                                                                zoneObjs.push({
-                                                                    id: items[i].id,
-                                                                    description: items[i].name
-                                                                });
-                                                            }
-                                                        }
-                                                        if (isAdmin() && !(cloudStack.context.projects && cloudStack.context.projects[0])) {
-                                                            zoneObjs.unshift({
-                                                                id: -1,
-                                                                description: "All Zones"
-                                                            });
-                                                        }
-                                                        args.response.success({
-                                                            data: zoneObjs
-                                                        });
-                                                    }
-                                                });
-                                            }
+                                            $.ajax({
+                                                url: createURL("listZones&available=true"),
+                                                dataType: "json",
+                                                async: true,
+                                                success: function(json) {
+                                                    var zoneObjs = json.listzonesresponse.zone;
+                                                    args.response.success({
+                                                        descriptionField: 'name',
+                                                        data: zoneObjs
+                                                    });
+                                                }
+                                            });
                                         }
                                     },
 


[35/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Browser Based Volume additional test scenarios


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

Branch: refs/heads/master
Commit: 651f8c9339de27857feafc3571f636a6ca93d5a4
Parents: 3d6318e
Author: sailajamada <sa...@citrix.com>
Authored: Sat Apr 4 20:31:27 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Sat Apr 4 20:31:27 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_volumes.py            | 170 ++++++++++++++++---
 1 file changed, 150 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/651f8c93/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 929cea8..b2b7caf 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -145,29 +145,35 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def validate_uploaded_volume(self,up_volid,volumestate):
 
-        config = Configurations.list(
+        config1 = Configurations.list(
                                      self.apiclient,
                                      name='upload.operation.timeout'
                                      )
 
-        uploadtimeout = int(config[0].value)
-        time.sleep(uploadtimeout*60)
+        config2 = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.monitornsving.interval'
+                                     )
+
+        uploadtimeout = int(config1[0].value)
+        monitoringinterval=int(config2[0].value)
+
+        time.sleep((uploadtimeout*60)+monitoringinterval)
 
         list_volume_response = Volume.list(
                     self.apiclient,
                     id=up_volid
                 )
-        self.assertNotEqual(
-                    list_volume_response,
-                    None,
-                    "Check if volume exists in ListVolumes"
-                )
+        if list_volume_response is None:
+            self.debug("Volume got deleted after timeout")
+            return
 
         self.assertEqual(
                     list_volume_response[0].state,
                     volumestate,
                     "Check volume state in ListVolumes"
                 )
+        return
 
     def browse_upload_volume(self):
         cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
@@ -718,11 +724,19 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                                             id=volumeid,
                                             type='DATADISK'
                                             )
+        self.debug(list_volume_response)
+
         self.assertEqual(
-                        list_volume_response,
-                        None,
-                        "Check if volume exists in ListVolumes"
-                    )
+                            isinstance(list_volume_response, list),
+                            True,
+                            "Check VOLUME is deleted from list Volumes"
+                        )
+        self.assertEqual(
+                            list_volume_response,
+                            None,
+                            "Check VOLUME is deleted from list Volumes"
+                        )
+
         return
 
     def download_volume(self,volumeid):
@@ -1682,6 +1696,50 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
 
+
+
+    def uploadwithimagestoreid(self):
+
+        sscmd=listImageStores.listImageStoresCmd()
+        sscmd.zoneid=self.zone.id
+        sscmdresponse=self.apiclient.listImageStores(sscmd)
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.imagestoreuuid=sscmdresponse[0].id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        self.globalurl=getuploadparamsresponce.postURL
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
     def uploadwithsamedisplaytext(self,voldetails):
 
 
@@ -1789,6 +1847,44 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
 
+
+
+    def posturlwithdeletedvolume(self,getuploadparamsresponce):
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'UploadAbandoned')
+
+        cmd = deleteVolume.deleteVolumeCmd()
+        cmd.id = getuploadparamsresponce.id
+
+        self.apiclient.deleteVolume(cmd)
+
+        success = False
+
+        url=self.extuploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code ==200: 
+            return("FAIL")
+        return("PASS")
+
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
     def test_01_Browser_volume_Life_cycle_tpath(self):
         """
@@ -2068,10 +2164,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 33 Upload Volume with custom offering id=========================")
             self.uploadwithcustomoffering()
 
-
-            self.debug("========================= Test 34 Upload Volume with tampered post URL=========================")
-            invaliduploadvolume=self.invalidposturl()
-
         except Exception as e:
             self.fail("Exception occurred  : %s" % e)
         return
@@ -2083,7 +2175,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         """
         try:
 
-            self.debug("========================= Test 35 Upload volume with Multiple SSVM=========================")
+            self.debug("========================= Test 34 Upload volume with Multiple SSVM=========================")
 
             testresult=self.uploadvolwithmultissvm()
             if testresult==0:
@@ -2103,7 +2195,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         """
 
         try:
-            self.debug("========================= Test 36 Upload volume with extended file extenstions=========================")
+            self.debug("========================= Test 35 Upload volume with extended file extenstions=========================")
             if self.uploadvolumeformat=="OVA":
                  raise unittest.SkipTest("This test is need not be executed on VMWARE")
             self.uploadwithextendedfileextentions()
@@ -2118,7 +2210,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         """
         Test Browser_Upload_Volume_Storage_Cleanup_Config_Validation
         """
-        self.debug("========================= Test 37 Validate storage.cleanup.enabled and storage.cleanup.interval ========================= ")
+        self.debug("========================= Test 36 Validate storage.cleanup.enabled and storage.cleanup.interval ========================= ")
         config1 = Configurations.list(
                                      self.apiclient,
                                      name='storage.cleanup.enabled'
@@ -2151,7 +2243,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         Test Browser_Upload_Volume_Negative_Scenarios
         """
         try:
-            self.debug("========================= Test 34 Upload Volume with tampered post URL=========================")
+            self.debug("========================= Test 37 Upload Volume with tampered post URL=========================")
             invaliduploadvolume=self.invalidposturl()
 
         except Exception as e:
@@ -2165,3 +2257,41 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
         return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_09_Browser_Upload_Volume_PostURL_with_Deleted_Uploadvolume_Details(self):
+        """
+        Test Browser_Upload_Volume_PostURL_with_Deleted_Uploadvolume_Details
+        """
+        self.debug("========================= Test 38 PostURL_with_Deleted_Upload_Abondaned volume details=========================")
+        browse_up_vol=self.onlyupload()
+        res=self.posturlwithdeletedvolume(browse_up_vol)
+
+        if res=="FAIL":
+            self.fail("Verify - PostURL_with_Deleted_Uploadvolume_Details ")
+
+        return
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_10_Browser_Upload_Volume_API_with_imagepoolid(self):
+        """
+        Test Browser_Upload_Volume_API_with_imagepoolid
+        """
+        self.debug("========================= Test 39 Test Browser_Upload_Volume_API_with_imagepoolid=========================")
+        self.uploadwithimagestoreid()
+
+        return
+
+    @classmethod
+    def tearDownClass(self):
+        try:
+            self.apiclient = super(TestBrowseUploadVolume,self).getClsTestClient().getApiClient()
+            cleanup_resources(self.apiclient, self._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+


[22/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Merge branch 'volume-upload' of https://git-wip-us.apache.org/repos/asf/cloudstack into volume-upload


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

Branch: refs/heads/master
Commit: 48078289f5942f5c5ecc7338a82272e0df95c93f
Parents: f22bd7a 018023c
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 23 09:59:58 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 23 09:59:58 2015 +0530

----------------------------------------------------------------------
 .../template/GetUploadParamsForTemplateCmd.java |   3 +
 .../template/HttpTemplateDownloader.java        |   4 +-
 .../TemplateOrVolumePostUploadCommand.java      |  10 ++
 .../com/cloud/storage/VolumeApiServiceImpl.java |   4 +-
 .../template/HypervisorTemplateAdapter.java     |   3 +-
 .../com/cloud/template/TemplateManagerImpl.java |   2 +-
 .../resource/HttpUploadServerHandler.java       |  49 +++++++--
 .../resource/NfsSecondaryStorageResource.java   |  38 +++++--
 .../storage/template/UploadEntity.java          |   9 ++
 utils/src/com/cloud/utils/ImageStoreUtil.java   |  39 -------
 .../utils/imagestore/ImageStoreUtil.java        | 110 +++++++++++++++++++
 .../utils/template/TemplateUtils.java           |  97 ----------------
 .../utils/imagestore/ImageStoreUtilTest.java    |  38 +++++++
 13 files changed, 241 insertions(+), 165 deletions(-)
----------------------------------------------------------------------



[07/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Automated Script To Validate Browser Based Volume LifeCycle Test Scenarios


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

Branch: refs/heads/master
Commit: fa7ef95817241b56952293aeec916bc7ca2f0490
Parents: b16520b
Author: sailajamada <sa...@citrix.com>
Authored: Wed Mar 4 09:16:43 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Wed Mar 4 09:16:43 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_volumes.py            | 819 +++++++++++++++++++
 1 file changed, 819 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa7ef958/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
new file mode 100644
index 0000000..0de20e2
--- /dev/null
+++ b/test/integration/component/test_browse_volumes.py
@@ -0,0 +1,819 @@
+# 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.
+""" P1 tests for Browser Based Upload Volumes
+"""
+# Import Local Modules
+
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.lib.utils import cleanup_resources, validateList
+from marvin.lib.base import (Account,
+                             ServiceOffering,
+                             VirtualMachine,
+                             Volume,
+                             Host,
+                             Iso,
+                             Configurations,
+                             DiskOffering,
+                             Domain,
+                             StoragePool)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               get_pod,list_hosts)
+from marvin.codes import PASS,FAILED
+
+from marvin.sshClient import SshClient
+
+import requests
+
+import time
+
+import wget
+
+import random
+
+import string
+
+
+class TestBrowseUploadVolume(cloudstackTestCase):
+
+    """
+    Testing Browse Upload Volume Feature
+    """
+    @classmethod
+    def setUpClass(cls):
+
+        cls.testClient = super(TestBrowseUploadVolume, cls).getClsTestClient()
+        cls.testdata = cls.testClient.getParsedTestDataConfig()
+        cls.apiclient = cls.testClient.getApiClient()
+        cls._cleanup = []
+        cls.cleanup = []
+        cls.uploadvolumeformat="VHD"
+
+        hosts = list_hosts(
+            cls.apiclient,
+            type="Routing"
+        )
+
+        if hosts is None:
+            raise unittest.SkipTest(
+                "There are no hypervisor's available.Check listhosts response")
+        for hypervisorhost in hosts :
+                 if hypervisorhost.hypervisor == "XenServer":
+                     cls.uploadvolumeformat="VHD"
+                     break
+                 elif hypervisorhost.hypervisor== "VMware":
+                     cls.uploadvolumeformat="OVA"
+                     break
+                 elif hypervisorhost.hypervisor=="KVM":
+                     cls.uploadvolumeformat="QCOW2"
+                     break
+                 else:
+                     break
+
+        cls.uploadurl=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["url"]
+        cls.volname=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["diskname"]
+        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
+        cls.domain = get_domain(cls.apiclient)
+        cls.pod = get_pod(cls.apiclient, cls.zone.id)
+
+        cls.account = Account.create(
+            cls.apiclient,
+            cls.testdata["account"],
+            domainid=cls.domain.id
+        )
+
+        cls.template = get_template(
+            cls.apiclient,
+            cls.zone.id)
+
+        if cls.template == FAILED:
+                raise unittest.SkipTest(
+                    "Check for default cent OS template readiness ")
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.testdata["service_offering"]
+        )
+        cls.disk_offering = DiskOffering.create(
+            cls.apiclient,
+            cls.testdata["browser_upload_volume"]["browser_resized_disk_offering"],
+            custom=True
+        )
+        cls._cleanup = [
+            cls.account,
+            cls.service_offering,
+            cls.disk_offering
+        ]
+
+
+
+    def validate_uploaded_volume(self,up_volid,volumestate):
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=up_volid
+                )
+        self.assertNotEqual(
+                    list_volume_response,
+                    None,
+                    "Check if volume exists in ListVolumes"
+                )
+
+        self.assertEqual(
+                    list_volume_response[0].state,
+                    volumestate,
+                    "Check volume state in ListVolumes"
+                )
+
+    def browse_upload_volume(self):
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+        return(getuploadparamsresponce)
+
+
+    def validate_vm(self,vmdetails,vmstate):
+
+        time.sleep(120 )
+        vm_response = VirtualMachine.list(
+                self.apiclient,
+                id=vmdetails.id,
+            )
+        self.assertEqual(
+                isinstance(vm_response, list),
+                True,
+                "Check list VM response for valid list"
+            )
+
+            # Verify VM response to check whether VM deployment was successful
+        self.assertNotEqual(
+                len(vm_response),
+                0,
+                "Check VMs available in List VMs response"
+            )
+
+        deployedvm = vm_response[0]
+        self.assertEqual(
+                deployedvm.state,
+                vmstate,
+                "Check the state of VM"
+            )
+
+    def deploy_vm(self):
+            virtual_machine = VirtualMachine.create(
+                                                    self.apiclient,
+                                                    self.testdata["virtual_machine"],
+                                                    templateid=self.template.id,
+                                                    zoneid=self.zone.id,
+                                                    accountid=self.account.name,
+                                                    domainid=self.account.domainid,
+                                                    serviceofferingid=self.service_offering.id,
+                                                )
+            self.validate_vm(virtual_machine,'Running')
+            return(virtual_machine)
+
+    def attach_volume(self,vmlist,volid):
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=volid
+                )
+        print list_volume_response[0]
+        vmlist.attach_volume(
+                    self.apiclient,
+                    list_volume_response[0]
+                )
+        list_volume_response = Volume.list(
+                self.apiclient,
+                virtualmachineid=vmlist.id,
+                type='DATADISK',
+                listall=True
+            )
+        self.assertNotEqual(
+                list_volume_response,
+                None,
+                "Check if volume exists in ListVolumes")
+        self.assertEqual(
+                isinstance(list_volume_response, list),
+                True,
+                "Check list volumes response for valid list")
+        self.validate_uploaded_volume(volid,'Ready')
+
+
+    def reboot_vm(self,vmdetails):
+        vmdetails.reboot(self.apiclient)
+        self.validate_vm(vmdetails,'Running')
+
+    def stop_vm(self,vmdetails):
+        vmdetails.stop(self.apiclient)
+        self.validate_vm(vmdetails,'Stopped')
+
+    def start_vm(self,vmdetails):
+        vmdetails.start(self.apiclient)
+        self.validate_vm(vmdetails,'Running')
+
+    def vmoperations(self,vmdetails):
+        self.reboot_vm(vmdetails)
+
+        self.stop_vm(vmdetails)
+
+        self.start_vm(vmdetails)
+
+
+    def detach_volume(self,vmdetails,volid):
+        """Detach a Volume attached to a VM
+        """
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=volid
+                )
+        print list_volume_response[0]
+        vmdetails.detach_volume(self.apiclient,list_volume_response[0])
+
+        # Sleep to ensure the current state will reflected in other calls
+        time.sleep(self.testdata["sleep"])
+
+        list_volume_response = Volume.list(
+            self.apiclient,
+            id=volid
+        )
+        self.assertNotEqual(
+            list_volume_response,
+            None,
+            "Check if volume exists in ListVolumes"
+        )
+        self.assertEqual(
+            isinstance(list_volume_response, list),
+            True,
+            "Check list volumes response for valid list"
+        )
+        volume = list_volume_response[0]
+        self.assertEqual(
+            volume.virtualmachineid,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+
+        self.assertEqual(
+            volume.vmname,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+        return
+
+
+    def restore_vm(self,vmdetails):
+        #TODO: SIMENH: add another test the data on the restored VM.
+        """Test recover Virtual Machine
+        """
+
+        #cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
+        cmd = restoreVirtualMachine.restoreVirtualMachineCmd()
+        cmd.virtualmachineid = vmdetails.id
+        self.apiclient.recoverVirtualMachine(cmd)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Running",
+                            "Check virtual machine is in Running state"
+                        )
+
+        return
+
+    def deletevolume(self,volumeid):
+        """Delete a Volume attached to a VM
+        """
+
+        cmd = deleteVolume.deleteVolumeCmd()
+        cmd.id = volumeid
+        self.apiclient.deleteVolume(cmd)
+
+        list_volume_response = Volume.list(
+                                            self.apiclient,
+                                            id=volumeid,
+                                            type='DATADISK'
+                                            )
+        self.assertEqual(
+                        list_volume_response,
+                        None,
+                        "Check if volume exists in ListVolumes"
+                    )
+        return
+
+
+    def download_volume(self,volumeid):
+
+        cmd = extractVolume.extractVolumeCmd()
+        cmd.id = volumeid
+        cmd.mode = "HTTP_DOWNLOAD"
+        cmd.zoneid = self.zone.id
+        extract_vol = self.apiclient.extractVolume(cmd)
+
+        try:
+            formatted_url = urllib.unquote_plus(extract_vol.url)
+            self.debug("Attempting to download volume at url %s" % formatted_url)
+            response = urllib.urlopen(formatted_url)
+            self.debug("response from volume url %s" % response.getcode())
+            fd, path = tempfile.mkstemp()
+            self.debug("Saving volume %s to path %s" %(volumeid, path))
+            os.close(fd)
+            with open(path, 'wb') as fd:
+                fd.write(response.read())
+            self.debug("Saved volume successfully")
+        except Exception:
+            self.fail(
+                "Extract Volume Failed with invalid URL %s (vol id: %s)" \
+                % (extract_vol.url, volumeid)
+            )
+
+
+
+    def resize_fail(self,volumeid):
+
+        cmd                = resizeVolume.resizeVolumeCmd()
+        cmd.id             = volumeid
+        cmd.diskofferingid = self.disk_offering.id
+        success            = False
+        try:
+            self.apiclient.resizeVolume(cmd)
+        except Exception as ex:
+            if "Volume should be in ready or allocated state before attempting a resize" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "ResizeVolume - verify Uploaded State volume is handled appropriately")
+
+
+    def resize_volume(self,volumeid):
+
+        """Test resize a volume"""
+
+        self.testdata["browser_upload_volume"]["browser_resized_disk_offering"]["disksize"] = 20
+
+        disk_offering_20_GB = DiskOffering.create(
+                                    self.apiclient,
+                                    self.testdata["browser_upload_volume"]["browser_resized_disk_offering"]
+                                    )
+        self.cleanup.append(disk_offering_20_GB)
+
+        cmd= resizeVolume.resizeVolumeCmd()
+        cmd.id= volumeid
+        cmd.diskofferingid = disk_offering_20_GB.id
+
+        self.apiclient.resizeVolume(cmd)
+
+        count = 0
+        success = False
+        while count < 3:
+            list_volume_response = Volume.list(
+                                                self.apiclient,
+                                                id=volumeid,
+                                                type='DATADISK'
+                                                )
+            for vol in list_volume_response:
+                if vol.id == volumeid and int(vol.size) == (int(disk_offering_20_GB.disksize) * (1024** 3)) and vol.state == 'Ready':
+                    success = True
+            if success:
+                break
+            else:
+                time.sleep(10)
+                count += 1
+
+        self.assertEqual(
+                         success,
+                         True,
+                         "Check if the data volume resized appropriately"
+                         )
+
+        return
+
+
+    def destroy_vm(self,vmdetails):
+
+        vmdetails.delete(self.apiclient, expunge=False)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Destroyed",
+                            "Check virtual machine is in destroyed state"
+                        )
+        return
+
+
+    def recover_destroyed_vm(self,vmdetails):
+
+        cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
+        cmd.id = vmdetails.id
+        self.apiclient.recoverVirtualMachine(cmd)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Stopped",
+                            "Check virtual machine is in Stopped state"
+                        )
+
+        return
+
+    def volume_snapshot(self):
+        """
+        @summary: Test to verify creation of snapshot from volume
+        and creation of template, volume from snapshot
+        """
+
+        list_volumes = Volume.list(
+            self.apiclient,
+            id=volumedetails.id
+        )
+        # Creating Snapshot from volume
+        snapshot_created = Snapshot.create(
+            self.userapiclient,
+            volumedetails.id,
+        )
+
+        self.assertIsNotNone(snapshot_created, "Snapshot not created")
+
+        self.cleanup.append(snapshot_created)
+
+        # Creating expected and actual values dictionaries
+        expected_dict = {
+            "id": volumedetails.id,
+            "intervaltype": "MANUAL",
+            "snapshottype": "MANUAL",
+            "volumetype": list_volumes[0].type,
+            "domain": self.domain.id
+        }
+        actual_dict = {
+            "id": snapshot_created.volumeid,
+            "intervaltype": snapshot_created.intervaltype,
+            "snapshottype": snapshot_created.snapshottype,
+            "volumetype": snapshot_created.volumetype,
+            "domain": snapshot_created.domainid,
+        }
+        status = self.__verify_values(
+            expected_dict,
+            actual_dict
+        )
+        self.assertEqual(
+            True,
+            status,
+            "Snapshot created from Volume details are not as expected"
+        )
+        return(snapshot_created)
+
+    def volume_snapshot_volume(self,snapshot_created):
+
+        # Creating Volume from snapshot
+        cmd = createVolume.createVolumeCmd()
+        cmd.name = "-".join([self.testdata["volume"]
+                             ["diskname"], random_gen()])
+        cmd.snapshotid = snapshot_created.id
+
+        volume_from_snapshot = Volume(
+            self.apiclient.createVolume(cmd).__dict__)
+
+        self.assertIsNotNone(
+            volume_from_snapshot,
+            "Volume creation failed from snapshot"
+        )
+
+
+        # Creating expected and actual values dictionaries
+        expected_dict = {
+            "snapshotid": snapshot_created.id,
+            "volumetype": snapshot_created.volumetype,
+            "size": self.disk_offering.disksize,
+            "accounr": self.account.name,
+            "domain": self.domain.id,
+            "storagetype": self.storagetype,
+            "zone": self.zone.id
+        }
+        actual_dict = {
+            "snapshotid": volume_from_snapshot.snapshotid,
+            "volumetype": volume_from_snapshot.type,
+            "size": volume_from_snapshot.size / (1024 * 1024 * 1024),
+            "accounr": volume_from_snapshot.account,
+            "domain": volume_from_snapshot.domainid,
+            "storagetype": volume_from_snapshot.storagetype,
+            "zone": volume_from_snapshot.zoneid,
+        }
+        status = self.__verify_values(
+            expected_dict,
+            actual_dict
+        )
+        self.assertEqual(
+            True,
+            status,
+            "Volume created from Snapshot details are not as expected"
+        )
+        return
+
+    def volume_snapshost_template(self,snapshot_created):
+        # Creating Template from Snapshot
+        list_templates_before = Template.list(
+            self.apiclient,
+            templatefilter='self')
+
+        if list_templates_before is None:
+            templates_before_size = 0
+        else:
+            templates_before_size = len(list_templates_before)
+
+        cmd = createTemplate.createTemplateCmd()
+        cmd.name = self.testdata["ostype"]
+        cmd.displaytext = self.testdata["ostype"]
+        cmd.ostypeid = self.template.ostypeid
+        cmd.snapshotid = snapshot_created.id
+        cmd.ispublic = False
+        cmd.passwordenabled = False
+
+        template_from_snapshot = Template(
+            self.apiclient.createTemplate(cmd).__dict__)
+
+        self.assertIsNotNone(
+            template_from_snapshot,
+            "Template creation failed from snapshot"
+        )
+
+        self.cleanup.append(template_from_snapshot)
+
+        # Creating expected and actual values dictionaries
+        expected_dict = {
+            "name": self.services["ostype"],
+            "ostypeid": self.template.ostypeid,
+            "type": "USER",
+            "zone": self.zone.id,
+            "domain": self.domain.id,
+            "account": self.account.name,
+            "passwordenabled": False,
+            "ispublic": False,
+            "size": self.disk_offering.disksize
+        }
+        actual_dict = {
+            "name": template_from_snapshot.name,
+            "ostypeid": template_from_snapshot.ostypeid,
+            "type": template_from_snapshot.templatetype,
+            "zone": template_from_snapshot.zoneid,
+            "domain": template_from_snapshot.domainid,
+            "account": template_from_snapshot.account,
+            "passwordenabled": template_from_snapshot.passwordenabled,
+            "ispublic": template_from_snapshot.ispublic,
+            "size": template_from_snapshot.size / (1024 * 1024 * 1024)
+        }
+        status = self.__verify_values(
+            expected_dict,
+            actual_dict
+        )
+        self.assertEqual(
+            True,
+            status,
+            "Template created from Snapshot details are not as expected"
+        )
+
+        list_templates_after = Template.list(
+            self.userapiclient,
+            templatefilter='self')
+
+        self.assertEquals(
+            templates_before_size + 1,
+            len(list_templates_after),
+            "Template creation failed from snapshot"
+        )
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_01_Browser_volume_Life_cycle_tpath(self):
+        """
+        Test Browser_volume_Life_cycle - This includes upload volume,attach to a VM, write data ,Stop ,Start, Reboot,Reset  of a VM, detach,attach back to the VM, delete volumes  
+        """
+        try:
+
+            self.debug("========================= Test 1: Upload Browser based volume and validate ========================= ")
+            browseup_vol=self.browse_upload_volume()
+
+            self.debug("========================= Test 2: Deploy a VM , Attach Uploaded Browser based volume and validate VM Operations========================= ")
+
+            vm1details=self.deploy_vm()
+
+            self.attach_volume(vm1details,browseup_vol.id)
+
+            self.vmoperations(vm1details)
+
+            self.debug("========================= Test 3: Restore VM with Uploaded volume attached========================= ")
+
+            self.restore_vm(vm1details)
+
+            self.debug("========================= Test 4: Detach Uploaded volume and validation of VM operations after detach========================= ")
+
+            self.detach_volume(vm1details,browseup_vol.id)
+
+            self.vmoperations(vm1details)
+
+            self.debug("========================= Test 5: Deploy New VM,Attach the detached Uploaded volume and validate VM operations after attach========================= ")
+
+            vm2details=self.deploy_vm()
+
+            self.attach_volume(vm2details,browseup_vol.id)
+
+            self.vmoperations(vm2details)
+
+            self.debug("========================= Test 6: Detach Uploaded volume and resize detached uploaded volume========================= ")
+
+            self.detach_volume(vm2details,browseup_vol.id)
+
+            self.resize_volume(browseup_vol.id)
+
+            self.debug("========================= Test 7: Attach resized uploaded volume and validate VM operations========================= ")
+
+            self.attach_volume(vm2details,browseup_vol.id)
+
+            self.vmoperations(vm2details)
+
+            self.debug("========================= Test 8: Try resizing uploaded state volume and validate the error scenario========================= ")
+
+            browseup_vol2=self.browse_upload_volume()
+
+            self.resize_fail(browseup_vol2.id)
+
+            self.debug("========================= Test 9: Attach multiple uploaded volumes to a VM and validate VM operations========================= ")
+
+            browseup_vol3=self.browse_upload_volume()
+
+            self.attach_volume(vm2details,browseup_vol2.id)
+
+            self.attach_volume(vm2details,browseup_vol3.id)
+
+            self.vmoperations(vm2details)
+
+            self.debug("========================= Test 10:  Detach and delete uploaded volume========================= ")
+
+            self.detach_volume(vm2details,browseup_vol2.id)
+
+            self.deletevolume(browseup_vol2.id)
+
+            self.debug("========================= Test 11:  Detach and download uploaded volume========================= ")
+
+            self.detach_volume(vm2details,browseup_vol3.id)
+
+            self.download_volume(browseup_vol3.id)
+
+            self.debug("========================= Test 12:  Delete detached uploaded volume========================= ")
+
+            self.detach_volume(vm2details,browseup_vol3.id)
+
+            self.deletevolume(browseup_vol3.id)
+
+ 
+            self.debug("========================= Test 13:  Delete Uploaded State volume========================= ")
+
+            browseup_vol4=self.browse_upload_volume()
+
+            self.deletevolume(browseup_vol4.id)
+
+            self.debug("========================= Test 14:  Destroy VM which has Uploaded volumes attached========================= ")
+
+            vm4details=self.deploy_vm()
+            self.attach_volume(vm4details,browseup_vol4.id)
+
+            self.destroy_vm(vm4details)
+
+            self.debug("========================= Test 15:  Recover destroyed VM which has Uploaded volumes attached========================= ")
+
+            self.recover_destroyed_vm(vm4details)
+
+            self.debug("========================= Test 16:  Delete attached Uploaded volume which is in ready state========================= ")
+
+            browseup_vol5=self.browse_upload_volume()
+            self.attach_volume(vm4details,browseup_vol5.id)
+            self.deletevolume(browseup_vol5.id)
+
+            self.debug("========================= Test 17:  Create Volume Backup Snapshot uploaded volume attached to the VM========================= ")
+
+            browseup_vol6=self.browse_upload_volume()
+
+            self.attach_volume(vm2details,browseup_vol6.id)
+
+            snapshotdetails=self.volume_snapshot(browseup_vol6.id)
+
+            self.debug("========================= Test 18:  Create Volume from Backup Snapshot of attached uploaded volume========================= ")
+
+            self.volume_snapshot_volume(snapshotdetails)
+
+            self.debug("========================= Test 19:  Create template from Backup Snapshot of attached uploaded volume========================= ")
+            self.volume_snapshot_template(snapshotdetails)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @classmethod
+    def tearDownClass(self):
+        try:
+            self.apiclient = super(TestBrowseUploadVolume,self).getClsTestClient().getApiClient()
+            cleanup_resources(self.apiclient, self._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return


[24/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Browser Based Template Automation Changes


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

Branch: refs/heads/master
Commit: 5c06f2bbd415a05c749412906e78074955ea34aa
Parents: 4807828
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 23 15:19:17 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 23 15:19:17 2015 +0530

----------------------------------------------------------------------
 test/integration/component/test_browse_templates.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5c06f2bb/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
index 3df5139..c1acf3c 100644
--- a/test/integration/component/test_browse_templates.py
+++ b/test/integration/component/test_browse_templates.py
@@ -1262,7 +1262,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
             print browseup_template
-            #self.delete_template(browseup_template)
+            self.delete_template(browseup_template)
 
             self.debug("========================= Test 10:  Upload Multiple templates========================= ")
 
@@ -1274,7 +1274,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
-    def xtest_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self):
+    def test_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self):
         """
         Test SSVM_Life_Cycle_With_Browser_template_TPath 
         """


[16/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: Restart of MS leads to loss of browser uploaded templates

on restart of management server, template sync runs. It checks for
templates in ssvm using the uniquename. If it doesnt find any, cleans
the directory. In case of uploaded templates, these are getting saved
using name instead on uniquename and hence template sync cant find them
and does cleanup. Using uniquename in template.properties now.


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

Branch: refs/heads/master
Commit: 3de5d9db5fa0b3196a00784ffc2c04b998f64de2
Parents: aad9b8a
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Mar 16 12:41:58 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Mar 16 12:45:24 2015 +0530

----------------------------------------------------------------------
 .../command/TemplateOrVolumePostUploadCommand.java        | 10 ++++++++++
 .../src/com/cloud/template/HypervisorTemplateAdapter.java |  3 ++-
 .../storage/resource/NfsSecondaryStorageResource.java     |  7 ++++---
 .../apache/cloudstack/storage/template/UploadEntity.java  |  9 +++++++++
 4 files changed, 25 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3de5d9db/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index cc9df71..0a5f1d6 100644
--- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -47,6 +47,8 @@ public class TemplateOrVolumePostUploadCommand {
 
     String maxUploadSize;
 
+    String description;
+
     public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
             String dataToRole) {
         this.entityId = entityId;
@@ -166,4 +168,12 @@ public class TemplateOrVolumePostUploadCommand {
     public void setMaxUploadSize(String maxUploadSize) {
         this.maxUploadSize = maxUploadSize;
     }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3de5d9db/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 0cb48fc..1ad2135 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -258,12 +258,13 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             }
 
             TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl.getChecksum(), tmpl
-                    .getType().toString(), template.getName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(), templateOnStore.getDataStore().getRole()
+                    .getType().toString(), template.getUniqueName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(), templateOnStore.getDataStore().getRole()
                     .toString());
             //using the existing max template size configuration
             payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
             payload.setRemoteEndPoint(ep.getPublicAddr());
             payload.setRequiresHvm(template.requiresHvm());
+            payload.setDescription(template.getDisplayText());
             payloads.add(payload);
         }
         _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3de5d9db/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 236498c..d10242c 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2634,6 +2634,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 uploadEntity.setHvm(cmd.getRequiresHvm());
                 uploadEntity.setChksum(cmd.getChecksum());
                 uploadEntity.setMaxSizeInGB(maxSizeInGB);
+                uploadEntity.setDescription(cmd.getDescription());
                 // create a install dir
                 if (!_storage.exists(installPathPrefix)) {
                     _storage.mkdir(installPathPrefix);
@@ -2677,9 +2678,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         Script scr = new Script(getScriptLocation(resourceType), timeout, s_logger);
         scr.add("-s", Integer.toString(imgSizeGigs));
         scr.add("-S", Long.toString(UploadEntity.s_maxTemplateSize));
-        //if (uploadEntity.getDescription() != null && dnld.getDescription().length() > 1) {
-        //    scr.add("-d", dnld.getDescription());
-        //}
+        if (uploadEntity.getDescription() != null && uploadEntity.getDescription().length() > 1) {
+            scr.add("-d", uploadEntity.getDescription());
+        }
         if (uploadEntity.isHvm()) {
             scr.add("-h");
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3de5d9db/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
index 15a6ef2..e9444c2 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
@@ -32,6 +32,7 @@ public class UploadEntity {
     private String chksum;
     private long physicalSize;
     private int maxSizeInGB;
+    private String description;
 
     public static enum ResourceType {
         VOLUME, TEMPLATE
@@ -180,4 +181,12 @@ public class UploadEntity {
     public void setMaxSizeInGB(int maxSizeInGB) {
         this.maxSizeInGB = maxSizeInGB;
     }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
 }


[23/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
wrapped create template in db transaction

Template entry created in DB even though GetUpload* API fails with "No
ssvm present" error


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

Branch: refs/heads/master
Commit: c32a6695dc9fe0d6c1f06e0d6f670d4e8cea5ab4
Parents: 4807828
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Mar 23 11:15:02 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Mar 23 11:19:21 2015 +0530

----------------------------------------------------------------------
 .../template/HypervisorTemplateAdapter.java     | 120 ++++++++++---------
 1 file changed, 65 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c32a6695/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 1ad2135..265bc12 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -27,6 +27,9 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 
 import com.cloud.configuration.Config;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
 import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -201,74 +204,81 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
     }
 
     @Override
-    public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile) {
+    public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(final TemplateProfile profile) {
         // persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync.
-        VMTemplateVO template = persistTemplate(profile, State.NotUploaded);
+        return Transaction.execute(new TransactionCallback<List<TemplateOrVolumePostUploadCommand>>() {
 
-        if (template == null) {
-            throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate());
-        }
+            @Override
+            public List<TemplateOrVolumePostUploadCommand> doInTransaction(TransactionStatus status) {
 
-        // find all eligible image stores for this zone scope
-        List<DataStore> imageStores = storeMgr.getImageStoresByScope(new ZoneScope(profile.getZoneId()));
-        if (imageStores == null || imageStores.size() == 0) {
-            throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
-        }
+                VMTemplateVO template = persistTemplate(profile, State.NotUploaded);
 
-        List<TemplateOrVolumePostUploadCommand> payloads = new LinkedList<>();
-        Set<Long> zoneSet = new HashSet<Long>();
-        Collections.shuffle(imageStores); // For private templates choose a random store. TODO - Have a better algorithm based on size, no. of objects, load etc.
-        for (DataStore imageStore : imageStores) {
-            // skip data stores for a disabled zone
-            Long zoneId = imageStore.getScope().getScopeId();
-            if (zoneId != null) {
-                DataCenterVO zone = _dcDao.findById(zoneId);
-                if (zone == null) {
-                    s_logger.warn("Unable to find zone by id " + zoneId + ", so skip downloading template to its image store " + imageStore.getId());
-                    continue;
+                if (template == null) {
+                    throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate());
                 }
 
-                // Check if zone is disabled
-                if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
-                    s_logger.info("Zone " + zoneId + " is disabled, so skip downloading template to its image store " + imageStore.getId());
-                    continue;
+                // find all eligible image stores for this zone scope
+                List<DataStore> imageStores = storeMgr.getImageStoresByScope(new ZoneScope(profile.getZoneId()));
+                if (imageStores == null || imageStores.size() == 0) {
+                    throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
                 }
 
-                // We want to download private template to one of the image store in a zone
-                if (isPrivateTemplate(template) && zoneSet.contains(zoneId)) {
-                    continue;
-                } else {
-                    zoneSet.add(zoneId);
-                }
+                List<TemplateOrVolumePostUploadCommand> payloads = new LinkedList<>();
+                Set<Long> zoneSet = new HashSet<Long>();
+                Collections.shuffle(imageStores); // For private templates choose a random store. TODO - Have a better algorithm based on size, no. of objects, load etc.
+                for (DataStore imageStore : imageStores) {
+                    // skip data stores for a disabled zone
+                    Long zoneId = imageStore.getScope().getScopeId();
+                    if (zoneId != null) {
+                        DataCenterVO zone = _dcDao.findById(zoneId);
+                        if (zone == null) {
+                            s_logger.warn("Unable to find zone by id " + zoneId + ", so skip downloading template to its image store " + imageStore.getId());
+                            continue;
+                        }
 
-            }
+                        // Check if zone is disabled
+                        if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
+                            s_logger.info("Zone " + zoneId + " is disabled, so skip downloading template to its image store " + imageStore.getId());
+                            continue;
+                        }
 
-            TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
-            //imageService.createTemplateAsync(tmpl, imageStore, caller);
+                        // We want to download private template to one of the image store in a zone
+                        if (isPrivateTemplate(template) && zoneSet.contains(zoneId)) {
+                            continue;
+                        } else {
+                            zoneSet.add(zoneId);
+                        }
 
-            // persist template_store_ref entry
-            DataObject templateOnStore = imageStore.create(tmpl);
-            // update template_store_ref and template state
+                    }
 
-            EndPoint ep = _epSelector.select(templateOnStore);
-            if (ep == null) {
-                String errMsg = "There is no secondary storage VM for downloading template to image store " + imageStore.getName();
-                s_logger.warn(errMsg);
-                throw new CloudRuntimeException(errMsg);
-            }
+                    TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
+                    //imageService.createTemplateAsync(tmpl, imageStore, caller);
 
-            TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl.getChecksum(), tmpl
-                    .getType().toString(), template.getUniqueName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(), templateOnStore.getDataStore().getRole()
-                    .toString());
-            //using the existing max template size configuration
-            payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
-            payload.setRemoteEndPoint(ep.getPublicAddr());
-            payload.setRequiresHvm(template.requiresHvm());
-            payload.setDescription(template.getDisplayText());
-            payloads.add(payload);
-        }
-        _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
-        return payloads;
+                    // persist template_store_ref entry
+                    DataObject templateOnStore = imageStore.create(tmpl);
+                    // update template_store_ref and template state
+
+                    EndPoint ep = _epSelector.select(templateOnStore);
+                    if (ep == null) {
+                        String errMsg = "There is no secondary storage VM for downloading template to image store " + imageStore.getName();
+                        s_logger.warn(errMsg);
+                        throw new CloudRuntimeException(errMsg);
+                    }
+
+                    TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl
+                            .getChecksum(), tmpl.getType().toString(), template.getUniqueName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(),
+                            templateOnStore.getDataStore().getRole().toString());
+                    //using the existing max template size configuration
+                    payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
+                    payload.setRemoteEndPoint(ep.getPublicAddr());
+                    payload.setRequiresHvm(template.requiresHvm());
+                    payload.setDescription(template.getDisplayText());
+                    payloads.add(payload);
+                }
+                _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
+                return payloads;
+            }
+        });
     }
 
     private boolean isPrivateTemplate(VMTemplateVO template){


[33/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Automation script changes with additional cases


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

Branch: refs/heads/master
Commit: 736f7042f33446b0c4b73c2f10e50d2f21f3edd0
Parents: eac8d4b
Author: sailajamada <sa...@citrix.com>
Authored: Thu Apr 2 09:31:34 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Apr 2 09:31:34 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_templates.py          |  51 +-
 .../component/test_browse_volumes.py            | 646 ++++++++++++++++++-
 tools/marvin/marvin/config/test_data.py         |  12 +
 3 files changed, 650 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/736f7042/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
index c1acf3c..d469446 100644
--- a/test/integration/component/test_browse_templates.py
+++ b/test/integration/component/test_browse_templates.py
@@ -81,13 +81,12 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                      break
                  else:
                      break
-
-        cls.uploadurl=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["url"]
-        cls.templatename=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["templatename"]
-        cls.md5sum=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["checksum"]
-        cls.templatedisplaytext=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["displaytext"]
-        cls.templatehypervisor=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["hypervisor"]
-        cls.templateostypeid=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["ostypeid"]
+        cls.uploadurl=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["url"]
+        cls.templatename=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["templatename"]
+        cls.md5sum=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["checksum"]
+        cls.templatedisplaytext=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["displaytext"]
+        cls.templatehypervisor=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["hypervisor"]
+        cls.templateostypeid=cls.testdata["configurableData"]["browser_upload_template"][cls.uploadtemplateformat]["ostypeid"]
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.domain = get_domain(cls.apiclient)
         cls.pod = get_pod(cls.apiclient, cls.zone.id)
@@ -111,7 +110,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         )
         cls.disk_offering = DiskOffering.create(
             cls.apiclient,
-            cls.testdata["browser_upload_volume"]["browser_resized_disk_offering"],
+            cls.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"],
             custom=True
         )
         cls._cleanup = [
@@ -145,6 +144,14 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def validate_uploaded_template(self,up_templateid,templatestate):
 
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.operation.timeout'
+                                     )
+
+        uploadtimeout = int(config[0].value)
+        time.sleep(uploadtimeout*60)
+
         list_template_response = Template.list(
                     self.apiclient,
                     id=up_templateid,
@@ -174,7 +181,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
         cmd.hypervisor=self.templatehypervisor
         cmd.ostypeid=self.templateostypeid
-        cmd.isdynamicallyscalable="false"
+        #cmd.isdynamicallyscalable="false"
         #cmd.type="template"
         getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
 
@@ -204,7 +211,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
 
         results = requests.post(posturl,files=files,headers=headers,verify=False)
-        time.sleep(600)
 
         print results.status_code
         if results.status_code !=200: 
@@ -1121,24 +1127,21 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def delete_template(self,templatedetails):
 
-        print templatedetails
+        self.debug(templatedetails)
         list_template_response = Template.list(
                                     self.apiclient,
                                     templatefilter="all",
                                     id=templatedetails.id,
                                     zoneid=self.zone.id)
-        print list_template_response
+        self.debug(list_template_response[0])
+
         self.assertEqual(
-                        isinstance(list_template_response, list),
+                        isinstance(list_template_response[0], list),
                         True,
                         "Check for list template response return valid list"
                         )
 
-        self.assertNotEqual(
-                            len(list_template_response),
-                            0,
-                            "Check template available in List Templates"
-                        )
+
         template_response = list_template_response[0]
 
         self.assertEqual(
@@ -1220,7 +1223,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             vm1details=self.deploy_vm(browseup_template)
 
-            #vm1details=self.deploy_vm(self.template)
+            vm1details=self.deploy_vm(self.template)
 
             self.vmoperations(vm1details)
 
@@ -1230,8 +1233,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.attach_data_volume(cvolume, vm1details)
             self.vmoperations(vm1details)
 
-
-
             self.debug("========================= Test 4: Restore VM created with Uploaded template========================= ")
 
             self.restore_vm(vm1details)
@@ -1250,7 +1251,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.debug("========================= Test 7:  Destroy VM ========================= ")
 
-            #vm2details=self.deploy_vm(self.template)
+            vm2details=self.deploy_vm(self.template)
 
             vm2details=self.deploy_vm(browseup_template)
             self.destroy_vm(vm2details)
@@ -1260,9 +1261,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.recover_destroyed_vm(vm2details)
             self.expunge_vm(vm2details)
 
-            self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
-            print browseup_template
-            self.delete_template(browseup_template)
+            #self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
+            #self.debug(browseup_template)
+            #self.delete_template(browseup_template)
 
             self.debug("========================= Test 10:  Upload Multiple templates========================= ")
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/736f7042/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 9067e2f..929cea8 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -60,6 +60,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         cls.cleanup = []
         cls.uploadvolumeformat="VHD"
         cls.storagetype = 'shared'
+        cls.globalurl="http://url"
 
         hosts = list_hosts(
             cls.apiclient,
@@ -89,6 +90,8 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         cls.domain = get_domain(cls.apiclient)
         cls.pod = get_pod(cls.apiclient, cls.zone.id)
 
+        if cls.uploadvolumeformat=="QCOW2" or cls.uploadvolumeformat=="VHD": 
+                cls.extuploadurl=cls.testdata["configurableData"]["browser_upload_volume_extended"][cls.uploadvolumeformat]["url"]
         cls.account = Account.create(
             cls.apiclient,
             cls.testdata["account"],
@@ -142,6 +145,14 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def validate_uploaded_volume(self,up_volid,volumestate):
 
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.operation.timeout'
+                                     )
+
+        uploadtimeout = int(config[0].value)
+        time.sleep(uploadtimeout*60)
+
         list_volume_response = Volume.list(
                     self.apiclient,
                     id=up_volid
@@ -171,6 +182,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         posturl=getuploadparamsresponce.postURL
         metadata=getuploadparamsresponce.metadata
         expiredata=getuploadparamsresponce.expires
+        self.globalurl=getuploadparamsresponce.postURL
         #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
         url=self.uploadurl
 
@@ -182,18 +194,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                     f.write(chunk)
                     f.flush()
 
-        #uploadfile='rajani-thin-volume.vhd'
-
-        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
-
-        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
-
         files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
 
         headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
 
         results = requests.post(posturl,files=files,headers=headers,verify=False)
-        time.sleep(60)
 
         print results.status_code
         if results.status_code !=200: 
@@ -203,6 +208,177 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return(getuploadparamsresponce)
 
+    def onlyupload(self):
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+        return(getuploadparamsresponce)
+
+
+
+    def invalidupload(self):
+
+        success= False
+        try:
+            cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+            cmd.zoneid = self.zone.id
+            cmd.format = "invalidformat"
+            cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+            cmd.account=self.account.name
+            cmd.domainid=self.domain.id
+            getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        except Exception as ex:
+            if "No enum constant com.cloud.storage.Storage.ImageFormat" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Verify - Upload volume with invalid format is handled")
+
+        return
+
+
+    def invalidposturl(self):
+
+        success= False
+        try:
+            cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+            cmd.zoneid = self.zone.id
+            cmd.format = self.uploadvolumeformat
+            cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+            cmd.account=self.account.name
+            cmd.domainid=self.domain.id
+            getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+
+            signt=getuploadparamsresponce.signature
+            posturl="http://invalidposturl/2999834."+self.uploadvolumeformat
+            metadata=getuploadparamsresponce.metadata
+            expiredata=getuploadparamsresponce.expires
+            #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+            url=self.uploadurl
+
+            uploadfile = url.split('/')[-1]
+            r = requests.get(url, stream=True)
+            with open(uploadfile, 'wb') as f:
+                for chunk in r.iter_content(chunk_size=1024): 
+                    if chunk: # filter out keep-alive new chunks
+                        f.write(chunk)
+                        f.flush()
+
+            files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+            headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+            results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+            self.debug(results.status_code) 
+            if results.status_code !=200: 
+                self.fail("Upload is not fine")
+
+            self.validate_uploaded_volume(getuploadparamsresponce.id,'UploadedAbandoned')
+
+        except Exception as ex:
+                if "Max retries exceeded with url" in str(ex):
+                    success = True
+
+        self.assertEqual(
+                                 success,
+                                 True,
+                                 "Verify - Tampered Post URL is handled")
+
+        return(getuploadparamsresponce)
+
+
+    def reuse_url(self):
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=self.globalurl
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        url=self.uploadurl
+        time.sleep(300)
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+                for chunk in r.iter_content(chunk_size=1024): 
+                    if chunk: # filter out keep-alive new chunks
+                        f.write(chunk)
+                        f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code == 200: 
+                self.fail("Upload URL is allowed to reuse")
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.operation.timeout'
+                                     )
+
+        uploadtimeout = int(config[0].value)
+        time.sleep(uploadtimeout*60)
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'UploadAbandoned')
+        return
+
+    def validate_storage_cleanup(self,invalidpostvolume,cleanup_interval):
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=invalidpostvolume.id
+                )
+        self.assertNotEqual(
+                    list_volume_response,
+                    None,
+                    "Check if volume exists in ListVolumes"
+                )
+
+        config1 = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.operation.timeout'
+                                     )
+        config2 = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.monitoring.interval'
+                                     )
+        uploadtimeout = int(config1[0].value)
+        monitorinterval=int(config2[0].value)
+
+        if cleanup_interval >= ((uploadtimeout*60)+monitorinterval):
+            time.sleep(cleanup_interval)
+        else:
+            time.sleep(((uploadtimeout*60)+monitorinterval))
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=invalidpostvolume.id
+                )
+        self.assertEqual(
+                    list_volume_response,
+                    None,
+                    "Storage Cleanup - Verify UploadAbandoned volumes are deleted"
+                )
+
+
     def validate_max_vol_size(self,up_vol,volumestate):
 
         list_volume_response = Volume.list(
@@ -280,6 +456,52 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return(getuploadparamsresponce)
 
+    def browse_upload_volume_with_invalid_md5(self):
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.checksum="xxxxxxxx"
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+        return(getuploadparamsresponce)
+
     def validate_vm(self,vmdetails,vmstate):
 
         time.sleep(120 )
@@ -348,6 +570,25 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         self.validate_uploaded_volume(volid,'Ready')
 
 
+    def attach_deleted_volume(self,vmlist,volume):
+
+        success= False
+        try:
+            vmlist.attach_volume(
+                    self.apiclient,
+                    volume
+                )
+        except Exception as ex:
+            if "Please specify a volume with the valid type: DATADISK" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Attaching the Deleted Volume is handled appropriately not to get attached the deleted uploaded volume")
+
+        return
+
+
     def reboot_vm(self,vmdetails):
         vmdetails.reboot(self.apiclient)
         self.validate_vm(vmdetails,'Running')
@@ -509,8 +750,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                 % (extract_vol.url, volumeid)
             )
 
-
-
     def resize_fail(self,volumeid):
 
         cmd                = resizeVolume.resizeVolumeCmd()
@@ -795,30 +1034,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             "Volume creation failed from snapshot"
         )
 
-        # Creating expected and actual values dictionaries
-        #expected_dict = {
-            #"snapshotid": snapshot_created.id,
-            #"volumetype": snapshot_created.volumetype,
-           # "size": self.disk_offering.disksize,
-          #  "storagetype": self.storagetype,
-         #   "zone": self.zone.id
-        #}
-        #actual_dict = {
-         #   "snapshotid": volume_from_snapshot.snapshotid,
-         #   "volumetype": volume_from_snapshot.type,
-          #  "size": volume_from_snapshot.size / (1024 * 1024 * 1024),
-           # "storagetype": volume_from_snapshot.storagetype,
-            #"zone": volume_from_snapshot.zoneid,
-        #}
-        #status = self.__verify_values(
-         #   expected_dict,
-          #  actual_dict
-        #)
-        #self.assertEqual(
-         #   True,
-          #  status,
-           # "Volume created from Snapshot details are not as expected"
-        #)
         return
 
     def volume_snapshot_template(self,snapshot_created):
@@ -1337,6 +1552,243 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
+
+
+    def uploadvol(self,getuploadparamsresponce):
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        success = False
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=getuploadparamsresponce.id
+                )
+        self.debug("======================Before SSVM Reboot==================")
+
+        self.reboot_ssvm()
+        self.debug("======================After SSVM Reboot==================")
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='upload.operation.timeout'
+                                     )
+
+        uploadtimeout = int(config[0].value)
+        time.sleep(uploadtimeout*60)
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'UploadAbandoned')
+
+        return()
+
+
+
+    def uploadvolwithssvmreboot(self,getuploadparamsresponce):
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+
+        self.debug("======================Before SSVM Reboot==================")
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=getuploadparamsresponce.id
+                )
+
+        self.debug(list_volume_response[0])
+        self.reboot_ssvm()
+
+        success = False
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=getuploadparamsresponce.id
+                )
+
+        self.debug("======================Upload After SSVM Reboot==================")
+        self.debug(list_volume_response[0])
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+        return()
+
+    def uploadwithcustomoffering(self):
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.diskofferingid=self.disk_offering.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        self.globalurl=getuploadparamsresponce.postURL
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+    def uploadwithsamedisplaytext(self,voldetails):
+
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=voldetails.id
+                )
+
+        success=True
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=list_volume_response[0].name
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+        list_volume_response1 = Volume.list(
+                  self.apiclient,
+                    id=getuploadparamsresponce.id
+                )
+        if list_volume_response1[0].name==voldetails.name:
+           success=False
+
+        self.assertEqual(
+                success,
+                False,
+                "Verify: Upload Multiple volumes with same name is handled")
+
+        return
+
+    def uploadvolwithmultissvm(self):
+
+        ssvmhosts = list_hosts(
+            self.apiclient,
+            type="SecondaryStorageVM"
+        )
+        self.debug("Total SSVMs are:")
+        self.debug(len(ssvmhosts))
+
+        if len(ssvmhosts)==1:
+            return(1)
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='secstorage.session.max'
+                                     )
+
+        multissvmvalue = int(config[0].value)
+        if multissvmvalue !=1:
+            return(0)
+
+        browseup_vol=self.browse_upload_volume()
+
+        vm1details=self.deploy_vm()
+
+        self.attach_volume(vm1details,browseup_vol.id)
+
+        self.vmoperations(vm1details)
+
+        self.destroy_vm(vm1details)
+
+        self.detach_volume(vm1details,browseup_vol.id)
+
+        self.deletevolume(browseup_vol.id)
+
+        return(2)
+
+
+    def uploadwithextendedfileextentions(self):
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.diskofferingid=self.disk_offering.id
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.extuploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
     def test_01_Browser_volume_Life_cycle_tpath(self):
         """
@@ -1570,15 +2022,141 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         """
         try:
             
-            self.debug("========================= Test 1 Validate Storage.max.upload.size ========================= ")
+            self.debug("========================= Test 26 Validate Storage.max.upload.size ========================= ")
             globalconfig_browse_up_vol=self.browse_upload_volume()
             self.validate_max_vol_size(globalconfig_browse_up_vol,"Uploaded")
 
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_04_Browser_Upload_Volume_Negative_Scenarios_TPath(self):
+        """
+        Test Browser_Upload_Volume_Negative_Scenarios
+        """
+        try:
+            self.debug("========================= Test 27 Reuse the POST URL after expiry time========================= ")
+            reuse_browse_up_vol=self.browse_upload_volume()
+            self.reuse_url()
+            self.deletevolume(reuse_browse_up_vol.id)
+
+            self.debug("========================= Test 28 Reboot SSVM before upload is completed=========================")
+            browse_up_vol=self.onlyupload()
+            self.uploadvol(browse_up_vol)
+            self.deletevolume(browse_up_vol.id)
+
+            self.debug("========================= Test 29 Reboot SSVM after getting the upload volume params and before initiating the upload=========================")
+            browse_up_vol=self.onlyupload()
+            self.uploadvolwithssvmreboot(browse_up_vol)
+            self.deletevolume(browse_up_vol.id)
+
+            self.debug("========================= Test 30 Attach Deleted Volume=========================")
+            deleted_browse_up_vol=self.browse_upload_volume()
+            self.deletevolume(deleted_browse_up_vol.id)
+            deletedvm1details=self.deploy_vm()
+            self.attach_deleted_volume(deletedvm1details, deleted_browse_up_vol)
+
+            self.debug("========================= Test 31 Upload Volume with Invalid Format=========================")
+            self.invalidupload()
+
+            self.debug("========================= Test 32 Upload Mutliple Volumes with same display text=========================")
+            samedisplaytext_browse_up_vol=self.browse_upload_volume()
+            self.uploadwithsamedisplaytext(samedisplaytext_browse_up_vol)
+
+            self.debug("========================= Test 33 Upload Volume with custom offering id=========================")
+            self.uploadwithcustomoffering()
+
+
+            self.debug("========================= Test 34 Upload Volume with tampered post URL=========================")
+            invaliduploadvolume=self.invalidposturl()
+
         except Exception as e:
             self.fail("Exception occurred  : %s" % e)
         return
 
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_05_Browser_Upload_Volume_MultiSSVM_Scenarios_TPath(self):
+        """
+        Test Browser_Upload_Volume_MultiSSVM_Scenarios
+        """
+        try:
+
+            self.debug("========================= Test 35 Upload volume with Multiple SSVM=========================")
+
+            testresult=self.uploadvolwithmultissvm()
+            if testresult==0:
+                raise unittest.SkipTest("secstorage.session.max global config is not set to 1 which means Multiple SSVM's are not present")
+            elif testresult==1:
+                raise unittest.SkipTest("only one SSVM is present")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_06_Browser_Upload_Volume_with_extended_file_extenstions(self):
+        """
+        Test Browser_Upload_Volume_with_extended_file_extenstions
+        """
+
+        try:
+            self.debug("========================= Test 36 Upload volume with extended file extenstions=========================")
+            if self.uploadvolumeformat=="OVA":
+                 raise unittest.SkipTest("This test is need not be executed on VMWARE")
+            self.uploadwithextendedfileextentions()
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
 
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_07_Browser_Upload_Volume_Storage_Cleanup_Config_Validation(self):
+        """
+        Test Browser_Upload_Volume_Storage_Cleanup_Config_Validation
+        """
+        self.debug("========================= Test 37 Validate storage.cleanup.enabled and storage.cleanup.interval ========================= ")
+        config1 = Configurations.list(
+                                     self.apiclient,
+                                     name='storage.cleanup.enabled'
+                                     )
+
+        config2 = Configurations.list(
+                                     self.apiclient,
+                                     name='storage.cleanup.interval'
+                                     )
+
+        cleanup_enabled=config1[0].value
+        cleanup_interval = int(config2[0].value)
+
+        if cleanup_enabled=="false":
+                raise unittest.SkipTest("storage.cleanup.enabled is not set to true")
+
+        if cleanup_interval>600:
+                raise unittest.SkipTest("storage.cleanup.interval is set to wait for more than 10 mins before cleanup. Please reduce the interval to less than 10 mins")
+
+        invaliduploadvolume=self.invalidposturl()
+
+        self.validate_storage_cleanup(invaliduploadvolume,cleanup_interval)
+
+        return
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_08_Browser_Upload_Volume_TamperedPostURL(self):
+        """
+        Test Browser_Upload_Volume_Negative_Scenarios
+        """
+        try:
+            self.debug("========================= Test 34 Upload Volume with tampered post URL=========================")
+            invaliduploadvolume=self.invalidposturl()
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
     @classmethod
     def tearDownClass(self):
         try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/736f7042/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 48053eb..5bbe4f2 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -1530,6 +1530,18 @@ test_data = {
         "disksize": 3,
     }
 },
+    "browser_upload_volume_extended":{
+          "VHD": {
+        "diskname": "XenUploadVol",
+        "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
+        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
+                },
+          "QCOW2": {
+        "diskname": "KVMUploadVol",
+        "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
+        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
+                },
+},
     "browser_upload_template": {
           "VHD": {
         "templatename": "XenUploadtemplate",


[45/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Bug-Id: CS-39350 Able to upload Volume greater than the Resource limit defined for Primary Storage.

Reviewed-By: Harikrishna Patnala <ha...@citrix.com>


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

Branch: refs/heads/master
Commit: f172fbef8aa2170efd63458cbcefc12652c5f2bc
Parents: a7e511c
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Apr 20 12:57:31 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Apr 20 13:01:19 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java | 6 ++++++
 server/src/com/cloud/storage/VolumeApiServiceImpl.java        | 2 --
 2 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f172fbef/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 01bda4f..84b33d2 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -26,6 +26,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.configuration.Resource;
+import com.cloud.user.ResourceLimitService;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
@@ -92,6 +94,8 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
     private EndPointSelector _epSelector;
     @Inject
     private DataStoreManager storeMgr;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
 
     private long _nodeId;
     private ScheduledExecutorService _executor = null;
@@ -285,6 +289,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             volumeUpdate.setSize(answer.getVirtualSize());
                             _volumeDao.update(tmpVolume.getId(), volumeUpdate);
                             stateMachine.transitTo(tmpVolume, Event.OperationSucceeded, null, _volumeDao);
+                            _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), Resource.ResourceType.secondary_storage, answer.getVirtualSize());
 
                             if (s_logger.isDebugEnabled()) {
                                 s_logger.debug("Volume " + tmpVolume.getUuid() + " uploaded successfully");
@@ -358,6 +363,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             templateUpdate.setSize(answer.getVirtualSize());
                             _templateDao.update(tmpTemplate.getId(), templateUpdate);
                             stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
+                            _resourceLimitMgr.incrementResourceCount(template.getAccountId(), Resource.ResourceType.secondary_storage, answer.getVirtualSize());
 
                             if (s_logger.isDebugEnabled()) {
                                 s_logger.debug("Template " + tmpTemplate.getUuid() + " uploaded successfully");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f172fbef/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 2022dde..d7000f7 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -456,8 +456,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
                 //url can be null incase of postupload
                 if(url!=null) {
                     _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
-                } else {
-                    _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage);
                 }
 
                 return volume;


[14/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Modified few lines


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

Branch: refs/heads/master
Commit: 8840d90ea8e4c11c28c1844ea3af00c32ced1a98
Parents: 47a22e0
Author: sailajamada <sa...@citrix.com>
Authored: Thu Mar 12 09:02:46 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Mar 12 09:02:46 2015 +0530

----------------------------------------------------------------------
 test/integration/component/test_browse_volumes.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8840d90e/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 4018cc6..8f6d8bb 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -1462,7 +1462,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
-    def xtest_02_SSVM_Life_Cycle_With_Browser_Volume_TPath(self):
+    def test_02_SSVM_Life_Cycle_With_Browser_Volume_TPath(self):
         """
         Test SSVM_Life_Cycle_With_Browser_Volume_TPath - This includes SSVM life cycle followed by Browser volume upload operations
         """


[19/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: added  md5 checksum validation

also fixed the issue wherein the successful uploads where also moving to
error state as the channelinactive is called after the end of successful
upload as well.
added a fileuploaded boolean to check when the channel is inactive.


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

Branch: refs/heads/master
Commit: d5dffb5dc9ba43b0595bad08e096526050b9e1a7
Parents: 6b8b4b9
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Wed Mar 18 12:17:15 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Wed Mar 18 12:20:51 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/VolumeApiServiceImpl.java |  2 +-
 .../resource/HttpUploadServerHandler.java       | 38 ++++++++++++--------
 .../resource/NfsSecondaryStorageResource.java   | 15 ++++----
 3 files changed, 32 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d2c1c69..567a742 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -333,7 +333,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
                   * encoded metadata using the post upload config key
                   */
                 TemplateOrVolumePostUploadCommand command =
-                    new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), volumeStore.getChecksum(), vol.getType().toString(),
+                    new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(),
                                                           vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(),
                                                           dataObject.getDataStore().getRole().toString());
                 command.setLocalPath(volumeStore.getLocalDownloadPath());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 0caee32..44a2b60 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -75,6 +75,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
 
     private String uuid;
 
+    private boolean fileReceived = false;
+
     private static final String HEADER_SIGNATURE = "X-signature";
 
     private static final String HEADER_METADATA = "X-metadata";
@@ -92,13 +94,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
         if (decoder != null) {
             decoder.cleanFiles();
         }
+        fileReceived = false;
     }
 
     @Override
     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        String message = "file receive failed or connection closed prematurely.";
-        logger.error(message);
-        storageResource.updateStateMapWithError(uuid, message);
+        if (!fileReceived) {
+            String message = "file receive failed or connection closed prematurely.";
+            logger.error(message);
+            storageResource.updateStateMapWithError(uuid, message);
+        }
     }
 
     @Override
@@ -198,15 +203,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     return;
                 }
                 if (chunk instanceof LastHttpContent) {
-                    try {
-                        readFileUploadData();
-                        writeResponse(ctx.channel(), HttpResponseStatus.OK);
-                        reset();
-                    } catch (InvalidParameterValueException e) {
-                        logger.error("error during the file install.", e);
-                        responseContent.append("\n").append(e.getMessage());
-                        writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
-                    }
+                    writeResponse(ctx.channel(), readFileUploadData());
+                    reset();
                 }
             }
         }
@@ -220,7 +218,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
         decoder = null;
     }
 
-    private void readFileUploadData() throws IOException {
+    private HttpResponseStatus readFileUploadData() throws IOException {
         while (decoder.hasNext()) {
             InterfaceHttpData data = decoder.next();
             if (data != null) {
@@ -229,8 +227,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     if (data.getHttpDataType() == HttpDataType.FileUpload) {
                         FileUpload fileUpload = (FileUpload) data;
                         if (fileUpload.isCompleted()) {
-                            responseContent.append("upload successful.");
-                            storageResource.postUpload(uuid, fileUpload.getFile().getName());
+                            fileReceived = true;
+                            String status = storageResource.postUpload(uuid, fileUpload.getFile().getName());
+                            if (status != null) {
+                                responseContent.append(status);
+                                storageResource.updateStateMapWithError(uuid, status);
+                                return HttpResponseStatus.INTERNAL_SERVER_ERROR;
+                            } else {
+                                responseContent.append("upload successful.");
+                                return HttpResponseStatus.OK;
+                            }
                         }
                     }
                 } finally {
@@ -238,6 +244,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                 }
             }
         }
+        responseContent.append("received entity is not a file");
+        return HttpResponseStatus.UNPROCESSABLE_ENTITY;
     }
 
     private void writeResponse(Channel channel, HttpResponseStatus statusCode) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 1bce4a0..f67015c 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2662,16 +2662,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         UploadEntity.ResourceType resourceType = uploadEntity.getResourceType();
 
         String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
-        //String checkSum = computeCheckSum(originalTemplate);
-        //if (checkSum == null) {
-        //  s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!");
-        //}
-        //dnld.setCheckSum(checkSum);
 
         int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
         int maxSize = uploadEntity.getMaxSizeInGB();
         if(imgSizeGigs > maxSize) {
-            throw new InvalidParameterValueException("Maximum file upload size exceeded. Physical file size: "+imgSizeGigs+"GB. Maximum allowed size: "+maxSize+"GB.");
+            String errorMessage = "Maximum file upload size exceeded. Physical file size: " + imgSizeGigs + "GB. Maximum allowed size: " + maxSize + "GB.";
+            s_logger.error(errorMessage);
+            return errorMessage;
         }
         imgSizeGigs++; // add one just in case
         long timeout = (long)imgSizeGigs * installTimeoutPerGig;
@@ -2684,6 +2681,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         if (uploadEntity.isHvm()) {
             scr.add("-h");
         }
+        String checkSum = uploadEntity.getChksum();
+        if (StringUtils.isNotBlank(checkSum)) {
+            scr.add("-c", checkSum);
+        }
 
         // add options common to ISO and template
         String extension = uploadEntity.getFormat().getFileExtension();
@@ -2734,7 +2735,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         } catch (IOException e) {
             s_logger.warn("Something is wrong with template location " + resourcePath, e);
             loc.purge();
-            return "Unable to download due to " + e.getMessage();
+            return "Unable to upload due to " + e.getMessage();
         }
 
         Map<String, Processor> processors = _dlMgr.getProcessors();


[44/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Added file exists check for onetime post url

also, fixed an issue where in the upload was going to error state in
case of parallel call to the same post url


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

Branch: refs/heads/master
Commit: a7e511c1a30c974038ebd5683f112631e5abb6da
Parents: 4f35d36
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Fri Apr 17 18:03:13 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Apr 17 18:08:23 2015 +0530

----------------------------------------------------------------------
 .../storage/resource/HttpUploadServerHandler.java     | 13 +++++++++----
 .../storage/resource/NfsSecondaryStorageResource.java | 14 ++++++++++++--
 2 files changed, 21 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7e511c1/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 4a3fa86..05e5fe4 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -77,7 +77,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
 
     private String uuid;
 
-    private boolean fileReceived = false;
+    private boolean requestProcessed = false;
 
     private static final String HEADER_SIGNATURE = "X-signature";
 
@@ -96,12 +96,12 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
         if (decoder != null) {
             decoder.cleanFiles();
         }
-        fileReceived = false;
+        requestProcessed = false;
     }
 
     @Override
     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        if (!fileReceived) {
+        if (!requestProcessed) {
             String message = "file receive failed or connection closed prematurely.";
             logger.error(message);
             storageResource.updateStateMapWithError(uuid, message);
@@ -163,12 +163,14 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     logger.error("post request validation failed", ex);
                     responseContent.append(ex.getMessage());
                     writeResponse(ctx.channel(), HttpResponseStatus.BAD_REQUEST);
+                    requestProcessed = true;
                     return;
                 }
                 if (uploadEntity == null) {
                     logger.error("Unable to create upload entity. An exception occurred.");
                     responseContent.append("Internal Server Error");
                     writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
+                    requestProcessed = true;
                     return;
                 }
                 //set the base directory to download the file
@@ -181,12 +183,14 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     logger.error("exception while initialising the decoder", e);
                     responseContent.append(e.getMessage());
                     writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
+                    requestProcessed = true;
                     return;
                 }
             } else {
                 logger.warn("received a get request");
                 responseContent.append("only post requests are allowed");
                 writeResponse(ctx.channel(), HttpResponseStatus.BAD_REQUEST);
+                requestProcessed = true;
                 return;
             }
 
@@ -202,6 +206,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     logger.error("data decoding exception", e);
                     responseContent.append(e.getMessage());
                     writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
+                    requestProcessed = true;
                     return;
                 }
                 if (chunk instanceof LastHttpContent) {
@@ -229,7 +234,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     if (data.getHttpDataType() == HttpDataType.FileUpload) {
                         FileUpload fileUpload = (FileUpload) data;
                         if (fileUpload.isCompleted()) {
-                            fileReceived = true;
+                            requestProcessed = true;
                             String format = ImageStoreUtil.checkTemplateFormat(fileUpload.getFile().getAbsolutePath(), fileUpload.getFilename());
                             if(StringUtils.isNotBlank(format)) {
                                 String errorString = "File type mismatch between the sent file and the actual content. Received: " + format;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7e511c1/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 4644785..7cfaa9c 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2617,9 +2617,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             throw new InvalidParameterValueException("unable to decode and deserialize metadata");
         } else {
             uuid = cmd.getEntityUUID();
-            if (uploadEntityStateMap.containsKey(uuid)) {
+            if (isOneTimePostUrlUsed(cmd)) {
                 uploadEntity = uploadEntityStateMap.get(uuid);
-                throw new InvalidParameterValueException("The one time post url is already used and the upload is in " + uploadEntity.getUploadState() + " state.");
+                StringBuilder errorMessage = new StringBuilder("The one time post url is already used");
+                if (uploadEntity != null) {
+                    errorMessage.append(" and the upload is in ").append(uploadEntity.getUploadState()).append(" state.");
+                }
+                throw new InvalidParameterValueException(errorMessage.toString());
             }
             int maxSizeInGB = Integer.valueOf(cmd.getMaxUploadSize());
             int contentLengthInGB = getSizeInGB(contentLength);
@@ -2657,6 +2661,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         return uploadEntity;
     }
 
+    private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
+        String uuid = cmd.getEntityUUID();
+        String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();
+        return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
+    }
+
     private int getSizeInGB(long sizeInBytes) {
         return (int)Math.ceil(sizeInBytes * 1.0d / (1024 * 1024 * 1024));
     }


[04/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: fixed the UI after the change to move params to header.

Signed-off-by: Rajani Karuturi <ra...@gmail.com>


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

Branch: refs/heads/master
Commit: da1d8f9dce524db33d61ce8427e288aa753478a2
Parents: dc870b5
Author: ramamurtis <ra...@citrix.com>
Authored: Fri Feb 20 16:19:54 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Feb 27 17:40:06 2015 +0530

----------------------------------------------------------------------
 .../debian/config/etc/init.d/cloud-early-config |  10 ++
 systemvm/scripts/config_ssl.sh                  |   9 ++
 ui/scripts/storage.js                           |  27 ++--
 ui/scripts/templates.js                         |  44 ++----
 ui/scripts/ui/dialog.js                         | 157 +++++++++++--------
 5 files changed, 136 insertions(+), 111 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/da1d8f9d/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
index 0edd11e..5b98a0c 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -1159,9 +1159,11 @@ setup_secstorage() {
   log_it "setting up apache2 for post upload of volume/template"
   a2enmod proxy
   a2enmod proxy_http
+  a2enmod headers
 
   SSL_FILE="/etc/apache2/sites-available/default-ssl"
   PATTERN="RewriteRule ^\/upload\/(.*)"
+  CORS_PATTERN="Header set Access-Control-Allow-Origin"
   if [ -f $SSL_FILE ]; then
     if grep -q "$PATTERN" $SSL_FILE ; then
       log_it "rewrite rules already exist in file $SSL_FILE"
@@ -1172,6 +1174,14 @@ setup_secstorage() {
         sed -i -e "s/<\/VirtualHost>/RewriteCond %{REQUEST_METHOD} =POST \n&/" $SSL_FILE
         sed -i -e "s/<\/VirtualHost>/RewriteRule ^\/upload\/(.*) http:\/\/127.0.0.1:8210\/upload?uuid=\$1 [P,L] \n&/" $SSL_FILE
     fi
+    if grep -q "$CORS_PATTERN" $SSL_FILE ; then
+      log_it "cors rules already exist in file $SSL_FILE"
+    else
+        log_it "adding cors rules to file: $SSL_FILE"
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Origin \"*\" \n&/" $SSL_FILE
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Methods \"POST, OPTIONS\" \n&/" $SSL_FILE
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Headers \"x-requested-with, Content-Type, origin, authorization, accept, client-security-token, x-signature, x-metadata, x-expires\" \n&/" $SSL_FILE
+    fi
   fi
 
   service apache2 restart

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/da1d8f9d/systemvm/scripts/config_ssl.sh
----------------------------------------------------------------------
diff --git a/systemvm/scripts/config_ssl.sh b/systemvm/scripts/config_ssl.sh
index 8022b78..cd8059c 100755
--- a/systemvm/scripts/config_ssl.sh
+++ b/systemvm/scripts/config_ssl.sh
@@ -61,6 +61,7 @@ config_apache2_conf() {
 
   SSL_FILE="/etc/apache2/sites-available/default-ssl"
   PATTERN="RewriteRule ^\/upload\/(.*)"
+  CORS_PATTERN="Header set Access-Control-Allow-Origin"
   if [ -f $SSL_FILE ]; then
     if grep -q "$PATTERN" $SSL_FILE ; then
       echo "rewrite rules already exist in file $SSL_FILE"
@@ -71,6 +72,14 @@ config_apache2_conf() {
         sed -i -e "s/<\/VirtualHost>/RewriteCond %{REQUEST_METHOD} =POST \n&/" $SSL_FILE
         sed -i -e "s/<\/VirtualHost>/RewriteRule ^\/upload\/(.*) http:\/\/127.0.0.1:8210\/upload?uuid=\$1 [P,L] \n&/" $SSL_FILE
     fi
+    if grep -q "$CORS_PATTERN" $SSL_FILE ; then
+      echo "cors rules already exist in file $SSL_FILE"
+    else
+        echo "adding cors rules to file: $SSL_FILE"
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Origin \"*\" \n&/" $SSL_FILE
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Methods \"POST, OPTIONS\" \n&/" $SSL_FILE
+        sed -i -e "s/<\/VirtualHost>/Header always set Access-Control-Allow-Headers \"x-requested-with, Content-Type, origin, authorization, accept, client-security-token, x-signature, x-metadata, x-expires\" \n&/" $SSL_FILE
+    fi
   fi
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/da1d8f9d/ui/scripts/storage.js
----------------------------------------------------------------------
diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js
index 3ca19b3..68e3ec1 100644
--- a/ui/scripts/storage.js
+++ b/ui/scripts/storage.js
@@ -454,28 +454,25 @@
 
                                                 args.response.success({
                                                     url: uploadparams.postURL,
+                                                    ajaxPost: true,
                                                     data: {
-                                                        signature: uploadparams.signature,
-                                                        expires: uploadparams.expires,
-                                                        metadata: uploadparams.metadata
+                                                        'X-signature': uploadparams.signature,
+                                                        'X-expires': uploadparams.expires,
+                                                        'X-metadata': uploadparams.metadata
                                                     }
                                                 });
-                                                
-                                                cloudStack.dialog.notice({
-                                                    message: "This volume file has been uploaded. Please check its status at Stroage menu > Volumes > " + args.data.name + " > Status field."
-                                                });
                                             }
                                         });
                                     },
                                     postUpload: function(args) {
-                                        console.log("postUpload() is hit");
-                                        // Called when upload is done to do 
-                                        // verification checks;
-                                        // i.e., poll the server to verify successful upload
-                                        //
-                                        // success() will close the dialog and call standard action
-                                        // error() will keep dialog open if user wants to re-submit
-                                        args.response.success();
+                                        if(args.error) {
+                                            args.response.error(args.errorMsg);
+                                        } else {
+                                            cloudStack.dialog.notice({
+                                                message: "This volume file has been uploaded. Please check its status at Stroage menu > Volumes > " + args.data.name + " > Status field."
+                                            });
+                                            args.response.success();
+                                        }
                                     }
                                 },                                
                                 fields: {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/da1d8f9d/ui/scripts/templates.js
----------------------------------------------------------------------
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index 4fe0944..c060a0c 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -636,48 +636,30 @@
                                             data: data,
                                             async: false,
                                             success: function(json) {                                                
-                                                /*                        						
-												{
-												    "postuploadtemplateresponse": {
-												        "getuploadparams": {
-												            "id": "d5bdaf23-dcb9-4eef-9b94-81870490f457",
-												            "postURL": "https://10.223.67.4/upload/d5bdaf23-dcb9-4eef-9b94-81870490f457",
-												            "metadata": "7jCvmzKuMBStM/qEjx9HjSAISd+f3VAUqC9CkYmq92O+SznYov415LUndZ4KuLAtGNY37VeePs8X+0oyaVSj+cjD+KKoBJuynjBJViAQQYKT/amcOdrkloBA4DgNEAn16p32Z2qI4+Ky1ecDAtg1vkYNoz9ReaKbehM3n5MIFPonhnYBEmbVSZkCIbVbJeh+vmYs9Y3SHtcG+0gWiU06YQ4KGl7Wc03wp3wusAlj7+L+fEBha54Rx+C7aS6UPZgm8/+atUUric6xiGMsx603NUElcLWE+gQ7PTimsIr6ySvcmc3D0n6JK6A7bc72sfPrHEbnNPD+5+qXJsBcXPLtEAG2WwduarwZ",
-												            "timeout": "2015-01-20T01:01:02.548Z",
-												            "signature": "NLXv5YsNuUn7NKC+ZP5JtSM26MY="
-												        }
-												    }
-												}
-                                                */
-
-                                                var uploadparams = json.postuploadtemplateresponse.getuploadparams; //son.postuploadtemplateresponse.getuploadparams is an object, not an array of object.
+                                                var uploadparams = json.postuploadtemplateresponse.getuploadparams;
                                                 var templateId = uploadparams.id;
                                                
                                                 args.response.success({
                                                     url: uploadparams.postURL,
+                                                    ajaxPost: true,
                                                     data: {
-                                                        signature: uploadparams.signature,
-                                                        expires: uploadparams.timeout,
-                                                        metadata: uploadparams.metadata
+                                                        'X-signature': uploadparams.signature,
+                                                        'X-expires': uploadparams.expires,
+                                                        'X-metadata': uploadparams.metadata
                                                     }
                                                 });   
-                                                   
-                                                cloudStack.dialog.notice({ 
-                                                	message: "This template file has been uploaded. Please check its status at Templates menu > " + args.data.name + " > Zones tab > click a zone > Status field and Ready field."
-                                                });
-                                                
                                             }
                                         });                                        
                                     },
                                     postUpload: function(args) {
-                                        console.log("postUpload() is hit");
-                                        // Called when upload is done to do 
-                                        // verification checks;
-                                        // i.e., poll the server to verify successful upload
-                                        //
-                                        // success() will close the dialog and call standard action
-                                        // error() will keep dialog open if user wants to re-submit
-                                        args.response.success();
+                                        if(args.error) {
+                                            args.response.error(args.errorMsg);
+                                        } else {
+                                            cloudStack.dialog.notice({
+                                                message: "This template file has been uploaded. Please check its status at Templates menu > " + args.data.name + " > Zones tab > click a zone > Status field and Ready field."
+                                            });
+                                            args.response.success();
+                                        }
                                     }
                                 },
                                 fields: {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/da1d8f9d/ui/scripts/ui/dialog.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js
index 86703d5..38d248d 100644
--- a/ui/scripts/ui/dialog.js
+++ b/ui/scripts/ui/dialog.js
@@ -690,76 +690,103 @@
                         context: args.context,
                         response: {
                             success: function(successArgs) {
-                                //
-                                // Move file field into iframe; keep visible for consistency
-                                //
-                                var $uploadFrame = $('<iframe>');
-                                var $frameForm = $('<form>').attr({
-                                    method: 'POST',
-                                    action: successArgs.url,
-                                    enctype: 'multipart/form-data'
-                                });
                                 var $file = $form.find('input[type=file]');
-                                var $field = $file.closest('.form-item .value');
-                                
-                                // Add additional passed data
-                                $.map(successArgs.data, function(v, k) {
-                                    var $hidden = $('<input>').attr({
-                                        type: 'hidden',
-                                        name: k,
-                                        value: v
+                                var postUploadArgs = {
+                                    $form: $form,
+                                    data: data,
+                                    context: args.context,
+                                    response: {
+                                        success: function() {
+                                            args.after({
+                                                data: data,
+                                                ref: args.ref, // For backwards compatibility; use context
+                                                context: args.context,
+                                                $form: $form
+                                            });
+
+                                            $('div.overlay').remove();
+                                            $form.find('.loading-overlay').remove();
+                                            $('div.loading-overlay').remove();
+
+                                            $('.tooltip-box').remove();
+                                            $formContainer.remove();
+                                            $(this).dialog('destroy');
+
+                                            $('.hovered-elem').hide();
+                                        },
+                                        error: function(msg) {
+                                            $('div.overlay').remove();
+                                            $form.find('.loading-overlay').remove();
+                                            $('div.loading-overlay').remove();
+
+                                            cloudStack.dialog.error({ message: msg });
+                                        }
+                                    }
+                                };
+                                var postUploadArgsWithStatus = $.extend(true, {}, postUploadArgs);
+
+                                if(successArgs.ajaxPost) {
+                                    var request = new FormData();
+                                    request.append('file', $file.prop("files")[0]);
+                                    $.ajax({
+                                            type: 'POST',
+                                            url: successArgs.url,
+                                            data: request,
+                                            dataType : 'html',
+                                            processData: false,
+                                            contentType: false,
+                                            headers: successArgs.data,
+                                            success: function(r) {
+                                                postUploadArgsWithStatus.error = false;
+                                                args.form.fileUpload.postUpload(postUploadArgsWithStatus);
+                                            },
+                                            error: function(r) {
+                                                postUploadArgsWithStatus.error = true;
+                                                postUploadArgsWithStatus.errorMsg = r.responseText;
+                                                args.form.fileUpload.postUpload(postUploadArgsWithStatus);
+                                            }
+                                        });
+                                } else {
+                                    //
+                                    // Move file field into iframe; keep visible for consistency
+                                    //
+                                    var $uploadFrame = $('<iframe>');
+                                    var $frameForm = $('<form>').attr({
+                                        method: 'POST',
+                                        action: successArgs.url,
+                                        enctype: 'multipart/form-data'
                                     });
+                                    var $field = $file.closest('.form-item .value');
+
+                                    // Add additional passed data
+                                    $.map(successArgs.data, function(v, k) {
+                                        var $hidden = $('<input>').attr({
+                                            type: 'hidden',
+                                            name: k,
+                                            value: v
+                                        });
 
-                                    $hidden.appendTo($frameForm);
-                                });                                
-                                
-                                console.log("The following object is a hidden HTML form that will submit local file with hidden field signature/expires/metadata:");
-                                console.log($frameForm);                                
-                                
-                                $uploadFrame.css({ width: $field.outerWidth(), height: $field.height() }).show();
-                                $frameForm.append($file);
-                                $field.append($uploadFrame);
-                                $uploadFrame.contents().find('html body').append($frameForm);
-                                $frameForm.submit(function() {
-                                	console.log("callback() in $frameForm.submit(callback(){}) is triggered");
-                                    $uploadFrame.load(function() {
-                                    	console.log("callback() in $uploadFrame.load(callback(){}) is triggered");
-                                        args.form.fileUpload.postUpload({
-                                            $form: $form,
-                                            formData: data,
-                                            context: args.context,
-                                            response: {
-                                                success: function() {
-                                                    args.after({
-                                                        data: data,
-                                                        ref: args.ref, // For backwards compatibility; use context
-                                                        context: args.context,
-                                                        $form: $form
-                                                    });
-
-                                                    $('div.overlay').remove();
-                                                    $form.find('.loading-overlay').remove();
-                                                    $('div.loading-overlay').remove();
-                                                    
-                                                    $('.tooltip-box').remove();
-                                                    $formContainer.remove();
-                                                    $(this).dialog('destroy');
-
-                                                    $('.hovered-elem').hide();
-                                                },
-                                                error: function(msg) {
-                                                	$('div.overlay').remove();
-                                                    $form.find('.loading-overlay').remove();
-                                                    $('div.loading-overlay').remove();
-                                                    
-                                                    cloudStack.dialog.error({ message: msg });
-                                                }
-                                            }
+                                        $hidden.appendTo($frameForm);
+
+                                    });
+
+                                    console.log("The following object is a hidden HTML form that will submit local file with hidden field signature/expires/metadata:");
+                                    console.log($frameForm);
+
+                                    $uploadFrame.css({ width: $field.outerWidth(), height: $field.height() }).show();
+                                    $frameForm.append($file);
+                                    $field.append($uploadFrame);
+                                    $uploadFrame.contents().find('html body').append($frameForm);
+                                    $frameForm.submit(function() {
+                                        console.log("callback() in $frameForm.submit(callback(){}) is triggered");
+                                        $uploadFrame.load(function() {
+                                            console.log("callback() in $uploadFrame.load(callback(){}) is triggered");
+                                            args.form.fileUpload.postUpload(postUploadArgs);
                                         });
+                                        return true;
                                     });
-                                    return true;
-                                });
-                                $frameForm.submit();
+                                    $frameForm.submit();
+                                }
                             },
                             error: function(msg) {
                                 cloudStack.dialog.error({ message: msg });


[25/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Merge branch 'volume-upload' of https://git-wip-us.apache.org/repos/asf/cloudstack into volume-upload


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

Branch: refs/heads/master
Commit: e864b93a231dcef028731da0951bda91519f7dac
Parents: 5c06f2b c32a669
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 23 15:20:27 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 23 15:20:27 2015 +0530

----------------------------------------------------------------------
 .../template/HypervisorTemplateAdapter.java     | 120 ++++++++++---------
 1 file changed, 65 insertions(+), 55 deletions(-)
----------------------------------------------------------------------



[28/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Updated Browser Based Volume Automation Script changes


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

Branch: refs/heads/master
Commit: 98306c356ad0e54da87725899309d8d00ab48e91
Parents: 5643d51
Author: sailajamada <sa...@citrix.com>
Authored: Thu Mar 26 10:12:15 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Mar 26 10:12:15 2015 +0530

----------------------------------------------------------------------
 test/integration/component/test_browse_volumes.py | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/98306c35/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 1b6b4d1..ddc8517 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -227,8 +227,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                                      )
 
         max_size = int(config[0].value)
-
-        if int(list_volume_response[0].size) > max_size:
+        self.debug(max_size)
+        self.debug(int(list_volume_response[0].size)/(1024*1024*1024))
+        if (int(list_volume_response[0].size)/(1024*1024*1024)) > max_size:
             self.fail("Global Config storage.max.volume.upload.size is not considered with Browser Based Upload volumes")
 
 
@@ -730,6 +731,14 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         and creation of template, volume from snapshot
         """
 
+        if self.uploadvolumeformat=="QCOW2":
+            config = Configurations.list(
+                                     self.apiclient,
+                                     name='kvm.snapshot.enabled'
+                                     )
+            kvmsnapshotenabled = config[0].value
+            if kvmsnapshotenabled == "false":
+                self.fail("Please enable kvm.snapshot.enable global config")
         list_volumes = Volume.list(
             self.apiclient,
             id=volumedetails.id


[38/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Additional automated test paths for browser based templates


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

Branch: refs/heads/master
Commit: 7c2c9b4e4742f8f0cf034108b289390e71ccb63f
Parents: 55ee1ec
Author: sailajamada <sa...@citrix.com>
Authored: Wed Apr 8 09:08:33 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Wed Apr 8 09:08:33 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_templates.py          | 261 ++++++++++++++++++-
 1 file changed, 260 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7c2c9b4e/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
index 594df5d..2cacdb6 100644
--- a/test/integration/component/test_browse_templates.py
+++ b/test/integration/component/test_browse_templates.py
@@ -113,14 +113,20 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             cls.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"],
             custom=True
         )
+        cls.project = Project.create(
+                                 cls.apiclient,
+                                 cls.testdata["project"],
+                                 account=cls.account.name,
+                                 domainid=cls.account.domainid
+                                 )
         cls._cleanup = [
+            cls.project,
             cls.account,
             cls.service_offering,
             cls.disk_offering
         ]
 
 
-
     def __verify_values(self, expected_vals, actual_vals):
 
         return_flag = True
@@ -171,6 +177,33 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                 )
         return
 
+
+
+    def gettemplatelimts(self):
+
+        totalresoucelist=Account.list(
+                                      self.apiclient,
+                                      id=self.account.id
+                                      )
+        totaltemplates=totalresoucelist[0].templatetotal
+
+        return(totaltemplates)
+
+
+    def getstoragelimts(self,rtype):
+
+        cmd=updateResourceCount.updateResourceCountCmd()
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.resourcetype=rtype
+
+        responce=self.apiclient.updateResourceCount(cmd)
+
+        totalstorage=responce[0].resourcecount
+
+        return(totalstorage)
+
+
     def browse_upload_template(self):
         cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
         cmd.zoneid = self.zone.id
@@ -221,6 +254,101 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         return(getuploadparamsresponce)
 
 
+    def browse_upload_template_with_out_zoneid(self):
+
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+        cmd.ostypeid=self.templateostypeid
+
+        success= False
+        try:
+            getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+        except Exception as ex:
+            if "Invalid Parameter" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Upload Template - verify upload Template API request is handled without mandatory params - zoneid ")
+
+        return
+
+
+    def browse_upload_template_with_out_ostypeid(self):
+
+
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+
+        success= False
+        try:
+            getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+        except Exception as ex:
+            if "Invalid Parameter" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Upload Template - verify upload template API request is handled without mandatory params - ostypeid")
+
+        return
+
+
+    def browse_upload_template_with_projectid(self,projectid):
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+        cmd.ostypeid=self.templateostypeid
+        cmd.projectid=projectid
+        #cmd.isdynamicallyscalable="false"
+        #cmd.type="template"
+        getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_template(getuploadparamsresponce.id,'Download Complete',self.zone.id)
+
+        return(getuploadparamsresponce)
+
     def browse_upload_template_multiplezones(self,lzones):
 
         cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
@@ -1415,6 +1543,137 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.fail("Exception occurred  : %s" % e)
         return
 
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_05_Browser_Upload_Template_with_all_API_parameters(self):
+        """
+        Test Browser_Upload_Template with all API parameters
+        """
+        try:
+
+            self.debug("========================= Test 16 & 17 Upload template with account name and domainid========================")
+
+            browseup_template1=self.browse_upload_template()
+
+            self.debug("========================= Test 18 Upload template with project id========================")
+            browseup_template2=self.browse_upload_template_with_projectid(self.project.id)
+
+            self.debug("========================= Test 19 Upload template with out mandatory param zone id ========================")
+
+            browseup_vol2=self.browse_upload_template_with_out_zoneid()
+
+            self.debug("========================= Test 20 Upload template with out mandatory param ostypeid ========================")
+
+            browseup_vol3=self.browse_upload_template_with_out_ostypeid()
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_06_Browser_Upload_template_resource_limits(self):
+        """
+        Test Browser Upload Template Resource limits
+        """
+        try:
+
+            self.debug("========================= Test 21 Upload Template and verify Template limits========================")
+            initialtemplatelimit=self.gettemplatelimts()
+            browseup_template1=self.browse_upload_template()
+            afteruploadtemplatelimit=self.gettemplatelimts()
+
+            if int(afteruploadtemplatelimit)!=(int(initialtemplatelimit)+1):
+                self.fail("Volume Resouce Count is not updated")
+
+            self.delete_template(browseup_template1.id)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_07_Browser_Upload_template_secondary_storage_resource_limits(self):
+        """
+        Test Browser_Upload_Template Secondary Storage Resource limits
+        """
+        try:
+
+            self.debug("========================= Test 22 Upload template and verify secondary storage limits========================")
+
+            initialsecondarystoragelimit=self.getstoragelimts(11)
+            browseup_template1=self.browse_upload_template()
+
+            tmpldetails=Template.list(
+                                      self.apiclient,
+                                      id=browseup_template1.id,
+                                     templatefilter="all",
+                                     zoneid=self.zone.id)
+
+
+            afteruploadsecondarystoragelimit=self.getstoragelimts(11)
+
+            if afteruploadsecondarystoragelimit!=(initialsecondarystoragelimit+tmpldetails[0].size):
+                self.fail("Secondary Storage Resouce Count is not updated")
+
+            self.delete_template(browseup_template1.id)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_08_Browser_Upload_template_resource_limits_after_deletion(self):
+        """
+        Test Browser_Upload_Template Resource limits after template deletion
+        """
+        try:
+            self.debug("========================= Test 23 Delete Upload template and verify template limits========================")
+            browseup_template1=self.browse_upload_template()
+            initialtemplatelimit=self.gettemplatelimts()
+
+            self.delete_template(browseup_template1)
+            aftertemplatelimit=self.gettemplatelimts()
+
+            if afteruploadtemplatlimit!=(initialtemplatelimit-1):
+                self.fail("Template Resource Count is not updated after deletion")
+
+        except Exception as e:
+            self.fail("Exceptione occurred  : %s" % e)
+        return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_09_Browser_Upload_Volume_secondary_storage_resource_limits_after_deletion(self):
+        """
+        Test Browser_Upload_Template Secondary Storage Resource limits after template deletion
+        """
+        try:
+            self.debug("========================= Test 24 Delete Upload template and verify secondary storage limits========================")
+
+            browseup_template1=self.browse_upload_template()
+
+            tmpldetails=Template.list(
+                                      self.apiclient,
+                                      id=browseup_template1.id,
+                                     templatefilter="all",
+                                     zoneid=self.zone.id)
+
+            initialuploadprimarystoragelimit=self.getstoragelimts(11)
+            self.delete_template(browseup_template1)
+
+            afteruploadprimarystoragelimit=self.getstoragelimts(11)
+
+            if afteruploadprimarystoragelimit!=(initialprimarystoragelimit-tempdetails[0].size):
+                self.fail("Secondary Storage Resource Count is not updated after deletion")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
     @classmethod
     def tearDownClass(self):
         try:


[49/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Throwing an exception incase the template service couldnt register template.


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

Branch: refs/heads/master
Commit: faaa1365a3e9f8729967f85701befa43a45bdcb6
Parents: 75ae90b
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Mon Apr 27 15:00:35 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Mon Apr 27 15:12:09 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/template/TemplateManagerImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/faaa1365/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 10ff77f..af35dd8 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -384,7 +384,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
             return response;
         } else {
-            return null;
+            throw new CloudRuntimeException("Unable to register template.");
         }
     }
 


[17/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Fixed NPE with getUploadParamsForTemplate API call

if isdynamicallyscalable optional parameter is not specified, its trying
to cast null to Boolean and throws NPE


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

Branch: refs/heads/master
Commit: 7d1ca8a55c352ad2186dad47a6cdd3eea59e9e23
Parents: 3de5d9d
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Tue Mar 17 09:45:01 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Mar 17 10:35:48 2015 +0530

----------------------------------------------------------------------
 .../api/command/user/template/GetUploadParamsForTemplateCmd.java  | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7d1ca8a5/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
index 79f920f..d1dc468 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
@@ -109,6 +109,9 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
     }
 
     public Boolean isDynamicallyScalable() {
+        if (isDynamicallyScalable == null) {
+            return Boolean.FALSE;
+        }
         return isDynamicallyScalable;
     }
 


[05/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: Volume entry created in DB even though GetUpload* API fails with "No ssvm present" error

Signed-off-by: Rajani Karuturi <ra...@gmail.com>


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

Branch: refs/heads/master
Commit: dd1a8da9775f3348bc664550270d7a0e99199e5b
Parents: da1d8f9
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Feb 26 15:13:52 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Feb 27 17:42:32 2015 +0530

----------------------------------------------------------------------
 .../com/cloud/storage/VolumeApiServiceImpl.java | 100 ++++++++++---------
 1 file changed, 54 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/dd1a8da9/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 62f7710..9840096 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -30,6 +30,7 @@ import javax.inject.Inject;
 
 import com.cloud.utils.EncryptionUtil;
 import com.cloud.utils.ImageStoreUtil;
+import com.cloud.utils.db.TransactionCallbackWithException;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
@@ -276,70 +277,77 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     }
 
     @Override
-    @DB
     @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true)
-    public GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException {
+    public GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException {
         Account caller = CallContext.current().getCallingAccount();
         long ownerId = cmd.getEntityOwnerId();
-        Account owner = _entityMgr.findById(Account.class, ownerId);
-        Long zoneId = cmd.getZoneId();
-        String volumeName = cmd.getName();
+        final Account owner = _entityMgr.findById(Account.class, ownerId);
+        final Long zoneId = cmd.getZoneId();
+        final String volumeName = cmd.getName();
         String format = cmd.getFormat();
-        Long diskOfferingId = cmd.getDiskOfferingId();
+        final Long diskOfferingId = cmd.getDiskOfferingId();
         String imageStoreUuid = cmd.getImageStoreUuid();
-        DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
+        final DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
 
         validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId);
 
-        VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, cmd.getFormat(), diskOfferingId, Volume.State.NotUploaded);
-
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-
-        RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), cmd.getFormat());
-        vol.addPayload(payload);
+        return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
+            @Override
+            public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws MalformedURLException {
 
-        Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
-        EndPoint ep = pair.first();
-        DataObject dataObject = pair.second();
+                VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, cmd.getFormat(), diskOfferingId, Volume.State.NotUploaded);
 
+                VolumeInfo vol = volFactory.getVolume(volume.getId());
 
-        GetUploadParamsResponse response = new GetUploadParamsResponse();
+                RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), cmd.getFormat());
+                vol.addPayload(payload);
 
-        String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
+                Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
+                EndPoint ep = pair.first();
+                DataObject dataObject = pair.second();
 
-        String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid());
-        response.setPostURL(new URL(url));
 
-        // set the post url, this is used in the monitoring thread to determine the SSVM
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
-        if (volumeStore != null) {
-            volumeStore.setExtractUrl(url);
-            _volumeStoreDao.persist(volumeStore);
-        }
+                GetUploadParamsResponse response = new GetUploadParamsResponse();
 
-        response.setId(UUID.fromString(vol.getUuid()));
+                String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
 
-        int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
-        DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
-        String expires = currentDateTime.plusMinutes(timeout).toString();
-        response.setTimeout(expires);
+                String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid());
+                response.setPostURL(new URL(url));
 
-        String key = _configDao.getValue(Config.SSVMPSK.key());
-         /*
-          * encoded metadata using the post upload config key
-          */
-        TemplateOrVolumePostUploadCommand command = new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), volumeStore.getChecksum(), vol
-                .getType().toString(), vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString());
-        command.setLocalPath(volumeStore.getLocalDownloadPath());
-        Gson gson = new GsonBuilder().create();
-        String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
-        response.setMetadata(metadata);
+                // set the post url, this is used in the monitoring thread to determine the SSVM
+                VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
+                if (volumeStore != null) {
+                    volumeStore.setExtractUrl(url);
+                    _volumeStoreDao.persist(volumeStore);
+                }
 
-        /*
-         * signature calculated on the url, expiry, metadata.
-         */
-        response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
-        return response;
+                response.setId(UUID.fromString(vol.getUuid()));
+
+                int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
+                DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
+                String expires = currentDateTime.plusMinutes(timeout).toString();
+                response.setTimeout(expires);
+
+                String key = _configDao.getValue(Config.SSVMPSK.key());
+                 /*
+                  * encoded metadata using the post upload config key
+                  */
+                TemplateOrVolumePostUploadCommand command =
+                    new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), volumeStore.getChecksum(), vol.getType().toString(),
+                                                          vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(),
+                                                          dataObject.getDataStore().getRole().toString());
+                command.setLocalPath(volumeStore.getLocalDownloadPath());
+                Gson gson = new GsonBuilder().create();
+                String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
+                response.setMetadata(metadata);
+
+                /*
+                 * signature calculated on the url, expiry, metadata.
+                 */
+                response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
+                return response;
+            }
+        });
     }
 
     private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url,


[41/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: cannot delete a volume in NotUploaded state
Volume deletion is not allowed in NotUploaded or UploadInProgress states, added validation in delete volume API for same


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

Branch: refs/heads/master
Commit: 4338bea07003e7bcdd5a9565f1b203708f75b11f
Parents: 5c152e5
Author: Koushik Das <ko...@apache.org>
Authored: Tue Apr 14 16:08:54 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Tue Apr 14 16:08:54 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/storage/VolumeApiServiceImpl.java | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4338bea0/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 4ff7686..533f6fa 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -1169,11 +1169,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         VolumeVO volume = _volsDao.findById(volumeId);
         if (volume == null) {
-            throw new InvalidParameterValueException("Unable to aquire volume with ID: " + volumeId);
+            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
         }
 
         if (!_snapshotMgr.canOperateOnVolume(volume)) {
-            throw new InvalidParameterValueException("There are snapshot creating on it, Unable to delete the volume");
+            throw new InvalidParameterValueException("There are snapshot operations in progress on the volume, unable to delete it");
         }
 
         _accountMgr.checkAccess(caller, null, true, volume);
@@ -1189,6 +1189,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             }
         }
 
+        if (volume.getState() == Volume.State.NotUploaded || volume.getState() == Volume.State.UploadInProgress) {
+            throw new InvalidParameterValueException("The volume is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
+        }
+
         try {
             if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunging) {
                 Long instanceId = volume.getInstanceId();


[47/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: refactored some error messages


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

Branch: refs/heads/master
Commit: 0525e4763b7fa991535cea662ed53a41493c427c
Parents: bc399b9
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Tue Apr 7 16:26:38 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Fri Apr 24 15:45:29 2015 +0530

----------------------------------------------------------------------
 .../storage/resource/NfsSecondaryStorageResource.java     | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0525e476/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 7cfaa9c..1cd69fc 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2613,8 +2613,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         TemplateOrVolumePostUploadCommand cmd = getTemplateOrVolumePostUploadCmd(metadata);
         UploadEntity uploadEntity = null;
         if(cmd == null ){
-            updateStateMapWithError(uuid,"unable decode and deserialize metadata.");
-            throw new InvalidParameterValueException("unable to decode and deserialize metadata");
+            String errorMessage = "unable decode and deserialize metadata.";
+            updateStateMapWithError(uuid, errorMessage);
+            throw new InvalidParameterValueException(errorMessage);
         } else {
             uuid = cmd.getEntityUUID();
             if (isOneTimePostUrlUsed(cmd)) {
@@ -2628,8 +2629,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             int maxSizeInGB = Integer.valueOf(cmd.getMaxUploadSize());
             int contentLengthInGB = getSizeInGB(contentLength);
             if (contentLengthInGB > maxSizeInGB) {
-                throw new InvalidParameterValueException("Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " +
-                                                             maxSizeInGB + "GB.");
+                String errorMessage = "Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " + maxSizeInGB + "GB.";
+                updateStateMapWithError(uuid, errorMessage);
+                throw new InvalidParameterValueException(errorMessage);
             }
             try {
                 String absolutePath = cmd.getAbsolutePath();


[13/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: Unable to download template which has been uploaded via POST URL
During upload, POST url is saved in template_store_ref DB table. Now during download, same url is incorrectly returned back.
Fixed the code to cleanup POST url from DB on successful template upload.


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

Branch: refs/heads/master
Commit: 47a22e0594b3ecd4d11827912be5245cea65a009
Parents: 1dae3a4
Author: Koushik Das <ko...@apache.org>
Authored: Wed Mar 11 17:55:04 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Wed Mar 11 17:55:04 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/47a22e05/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index bbc650f..7841ad9 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -349,6 +349,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             tmpTemplateDataStore.setPhysicalSize(answer.getPhysicalSize());
                             tmpTemplateDataStore.setSize(answer.getVirtualSize());
                             tmpTemplateDataStore.setDownloadPercent(100);
+                            tmpTemplateDataStore.setExtractUrl(null);
 
                             VMTemplateVO templateUpdate = _templateDao.createForUpdate();
                             templateUpdate.setSize(answer.getVirtualSize());


[09/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Modified Browser Volume Test


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

Branch: refs/heads/master
Commit: f22760a9ad5717a87fd7afa99bbbbe5917d9905e
Parents: c65dad4
Author: sailajamada <sa...@citrix.com>
Authored: Sun Mar 8 20:07:54 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Sun Mar 8 20:07:54 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_volumes.py            | 757 +++++++++++++++++--
 1 file changed, 683 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f22760a9/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 0de20e2..5f5c611 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -18,38 +18,31 @@
 """
 # Import Local Modules
 
+import marvin
 from nose.plugins.attrib import attr
-from marvin.cloudstackTestCase import *
+from marvin.cloudstackTestCase import cloudstackTestCase, unittest
 from marvin.cloudstackAPI import *
-from marvin.lib.utils import cleanup_resources, validateList
-from marvin.lib.base import (Account,
-                             ServiceOffering,
-                             VirtualMachine,
-                             Volume,
-                             Host,
-                             Iso,
-                             Configurations,
-                             DiskOffering,
-                             Domain,
-                             StoragePool)
-from marvin.lib.common import (get_domain,
-                               get_zone,
-                               get_template,
-                               get_pod,list_hosts)
-from marvin.codes import PASS,FAILED
+from marvin.lib.utils import *
+from marvin.lib.base import *
+from marvin.lib.common import *
+from marvin.codes import PASS,FAILED,SUCCESS,XEN_SERVER
 
 from marvin.sshClient import SshClient
 
 import requests
 
-import time
-
 import wget
 
 import random
 
 import string
 
+import telnetlib
+import os
+import urllib
+import time
+import tempfile
+_multiprocess_shared_ = True
 
 class TestBrowseUploadVolume(cloudstackTestCase):
 
@@ -58,13 +51,15 @@ class TestBrowseUploadVolume(cloudstackTestCase):
     """
     @classmethod
     def setUpClass(cls):
-
-        cls.testClient = super(TestBrowseUploadVolume, cls).getClsTestClient()
+        cls.testClient = super(TestBrowseUploadVolume,cls).getClsTestClient()
+        #print cls.testClient.getParsedTestDataConfig()
         cls.testdata = cls.testClient.getParsedTestDataConfig()
         cls.apiclient = cls.testClient.getApiClient()
+        cls.hypervisor = cls.testClient.getHypervisorInfo()
         cls._cleanup = []
         cls.cleanup = []
         cls.uploadvolumeformat="VHD"
+        cls.storagetype = 'shared'
 
         hosts = list_hosts(
             cls.apiclient,
@@ -89,6 +84,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         cls.uploadurl=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["url"]
         cls.volname=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["diskname"]
+        cls.md5sum=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["checksum"]
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.domain = get_domain(cls.apiclient)
         cls.pod = get_pod(cls.apiclient, cls.zone.id)
@@ -107,7 +103,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                 raise unittest.SkipTest(
                     "Check for default cent OS template readiness ")
         cls.service_offering = ServiceOffering.create(
-            cls.apiclient,
+            cls.apiclient, 
             cls.testdata["service_offering"]
         )
         cls.disk_offering = DiskOffering.create(
@@ -123,6 +119,27 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
 
+    def __verify_values(self, expected_vals, actual_vals):
+
+        return_flag = True
+
+        if len(expected_vals) != len(actual_vals):
+            return False
+
+        keys = expected_vals.keys()
+        for i in range(0, len(expected_vals)):
+            exp_val = expected_vals[keys[i]]
+            act_val = actual_vals[keys[i]]
+            if exp_val == act_val:
+                return_flag = return_flag and True
+            else:
+                return_flag = return_flag and False
+                self.debug(
+                    "expected Value: %s, is not matching with actual value:\
+                    %s" %
+                    (exp_val, act_val))
+        return return_flag
+
     def validate_uploaded_volume(self,up_volid,volumestate):
 
         list_volume_response = Volume.list(
@@ -186,6 +203,51 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return(getuploadparamsresponce)
 
+    def browse_upload_volume_with_md5(self):
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.checksum=self.md5sum
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+        return(getuploadparamsresponce)
 
     def validate_vm(self,vmdetails,vmstate):
 
@@ -351,12 +413,32 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
+    def deletevolume_fail(self,volumeid):
+        """Delete a Volume attached to a VM
+        """
+
+        cmd = deleteVolume.deleteVolumeCmd()
+        cmd.id = volumeid
+        success= False
+        try:
+            self.apiclient.deleteVolume(cmd)
+        except Exception as ex:
+            if "Please specify a volume that is not attached to any VM" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "DeleteVolume - verify Ready State volume (attached to a VM) is handled appropriately not to get deleted ")
+
+        return
+
     def deletevolume(self,volumeid):
         """Delete a Volume attached to a VM
         """
 
         cmd = deleteVolume.deleteVolumeCmd()
         cmd.id = volumeid
+
         self.apiclient.deleteVolume(cmd)
 
         list_volume_response = Volume.list(
@@ -371,7 +453,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                     )
         return
 
-
     def download_volume(self,volumeid):
 
         cmd = extractVolume.extractVolumeCmd()
@@ -518,7 +599,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
-    def volume_snapshot(self):
+    def volume_snapshot(self,volumedetails):
         """
         @summary: Test to verify creation of snapshot from volume
         and creation of template, volume from snapshot
@@ -530,7 +611,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         )
         # Creating Snapshot from volume
         snapshot_created = Snapshot.create(
-            self.userapiclient,
+            self.apiclient,
             volumedetails.id,
         )
 
@@ -580,38 +661,33 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             "Volume creation failed from snapshot"
         )
 
-
         # Creating expected and actual values dictionaries
-        expected_dict = {
-            "snapshotid": snapshot_created.id,
-            "volumetype": snapshot_created.volumetype,
-            "size": self.disk_offering.disksize,
-            "accounr": self.account.name,
-            "domain": self.domain.id,
-            "storagetype": self.storagetype,
-            "zone": self.zone.id
-        }
-        actual_dict = {
-            "snapshotid": volume_from_snapshot.snapshotid,
-            "volumetype": volume_from_snapshot.type,
-            "size": volume_from_snapshot.size / (1024 * 1024 * 1024),
-            "accounr": volume_from_snapshot.account,
-            "domain": volume_from_snapshot.domainid,
-            "storagetype": volume_from_snapshot.storagetype,
-            "zone": volume_from_snapshot.zoneid,
-        }
-        status = self.__verify_values(
-            expected_dict,
-            actual_dict
-        )
-        self.assertEqual(
-            True,
-            status,
-            "Volume created from Snapshot details are not as expected"
-        )
+        #expected_dict = {
+            #"snapshotid": snapshot_created.id,
+            #"volumetype": snapshot_created.volumetype,
+           # "size": self.disk_offering.disksize,
+          #  "storagetype": self.storagetype,
+         #   "zone": self.zone.id
+        #}
+        #actual_dict = {
+         #   "snapshotid": volume_from_snapshot.snapshotid,
+         #   "volumetype": volume_from_snapshot.type,
+          #  "size": volume_from_snapshot.size / (1024 * 1024 * 1024),
+           # "storagetype": volume_from_snapshot.storagetype,
+            #"zone": volume_from_snapshot.zoneid,
+        #}
+        #status = self.__verify_values(
+         #   expected_dict,
+          #  actual_dict
+        #)
+        #self.assertEqual(
+         #   True,
+          #  status,
+           # "Volume created from Snapshot details are not as expected"
+        #)
         return
 
-    def volume_snapshost_template(self,snapshot_created):
+    def volume_snapshot_template(self,snapshot_created):
         # Creating Template from Snapshot
         list_templates_before = Template.list(
             self.apiclient,
@@ -642,12 +718,10 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         # Creating expected and actual values dictionaries
         expected_dict = {
-            "name": self.services["ostype"],
+            "name": self.testdata["ostype"],
             "ostypeid": self.template.ostypeid,
             "type": "USER",
             "zone": self.zone.id,
-            "domain": self.domain.id,
-            "account": self.account.name,
             "passwordenabled": False,
             "ispublic": False,
             "size": self.disk_offering.disksize
@@ -657,8 +731,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             "ostypeid": template_from_snapshot.ostypeid,
             "type": template_from_snapshot.templatetype,
             "zone": template_from_snapshot.zoneid,
-            "domain": template_from_snapshot.domainid,
-            "account": template_from_snapshot.account,
             "passwordenabled": template_from_snapshot.passwordenabled,
             "ispublic": template_from_snapshot.ispublic,
             "size": template_from_snapshot.size / (1024 * 1024 * 1024)
@@ -667,14 +739,14 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             expected_dict,
             actual_dict
         )
-        self.assertEqual(
-            True,
-            status,
-            "Template created from Snapshot details are not as expected"
-        )
+        #self.assertEqual(
+         #   True,
+          #  status,
+           # "Template created from Snapshot details are not as expected"
+        #)
 
         list_templates_after = Template.list(
-            self.userapiclient,
+            self.apiclient,
             templatefilter='self')
 
         self.assertEquals(
@@ -684,6 +756,453 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         )
         return
 
+
+    def waitForSystemVMAgent(self, vmname):
+        timeout = self.testdata["timeout"]
+
+        while True:
+            list_host_response = list_hosts(
+                                                 self.apiclient,
+                                                 name=vmname
+                                                )
+
+            if list_host_response and list_host_response[0].state == 'Up':
+                break
+
+            if timeout == 0:
+                raise Exception("Timed out waiting for SSVM agent to be Up")
+
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+
+    def ssvm_internals(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        self.debug("Running SSVM check script")
+
+        if self.hypervisor.lower() in ('vmware', 'hyperv'):
+            #SSH into SSVMs is done via management server for Vmware and Hyper-V
+            result = get_process_status(
+                                self.apiclient.connection.mgtSvr,
+                                22,
+                                self.apiclient.connection.user,
+                                self.apiclient.connection.passwd,
+                                ssvm.privateip,
+                                "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL",
+                                hypervisor=self.hypervisor
+                                )
+        else:
+            try:
+                host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
+                result = get_process_status(
+                                    host.ipaddress,
+                                    22,
+                                    host.user,
+                                    host.passwd,
+                                    ssvm.linklocalip,
+                                    "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL"
+                                )
+            except KeyError:
+                self.skipTest("Marvin configuration has no host credentials to check router services")
+        res = str(result)
+        self.debug("SSVM script output: %s" % res)
+
+        self.assertEqual(
+                            res.count("ERROR"),
+                            1,
+                            "Check for Errors in tests"
+                        )
+
+        self.assertEqual(
+                            res.count("WARNING"),
+                            1,
+                            "Check for warnings in tests"
+                        )
+
+        #Check status of cloud service
+        if self.hypervisor.lower() in ('vmware', 'hyperv'):
+            #SSH into SSVMs is done via management server for Vmware and Hyper-V
+            result = get_process_status(
+                                self.apiclient.connection.mgtSvr,
+                                22,
+                                self.apiclient.connection.user,
+                                self.apiclient.connection.passwd,
+                                ssvm.privateip,
+                                "service cloud status",
+                                hypervisor=self.hypervisor
+                                )
+        else:
+            try:
+                host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
+                result = get_process_status(
+                                    host.ipaddress,
+                                    22,
+                                    host.user,
+                                    host.passwd,
+                                    ssvm.linklocalip,
+                                    "service cloud status"
+                                    )
+            except KeyError:
+                self.skipTest("Marvin configuration has no host credentials to check router services")
+        res = str(result)
+        self.debug("Cloud Process status: %s" % res)
+        # cloud.com service (type=secstorage) is running: process id: 2346
+        self.assertEqual(
+                            res.count("is running"),
+                            1,
+                            "Check cloud service is running or not"
+                        )
+        return
+
+    def list_sec_storage_vm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        #Verify SSVM response
+        self.assertNotEqual(
+                            len(list_ssvm_response),
+                            0,
+                            "Check list System VMs response"
+                        )
+
+        list_zones_response = list_zones(self.apiclient)
+        
+        self.assertEqual(
+                            isinstance(list_zones_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.debug("Number of zones: %s" % len(list_zones_response))
+        self.debug("Number of SSVMs: %s" % len(list_ssvm_response))
+        # Number of Sec storage VMs = No of Zones
+        self.assertEqual(
+                            len(list_ssvm_response),
+                            len(list_zones_response),
+                            "Check number of SSVMs with number of zones"
+                        )
+        #For each secondary storage VM check private IP,
+        #public IP, link local IP and DNS
+        for ssvm in list_ssvm_response:
+
+            self.debug("SSVM state: %s" % ssvm.state)
+            self.assertEqual(
+                            ssvm.state,
+                            'Running',
+                            "Check whether state of SSVM is running"
+                        )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'privateip'),
+                            True,
+                            "Check whether SSVM has private IP field"
+                            )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'linklocalip'),
+                            True,
+                            "Check whether SSVM has link local IP field"
+                            )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'publicip'),
+                            True,
+                            "Check whether SSVM has public IP field"
+                            )
+
+            #Fetch corresponding ip ranges information from listVlanIpRanges
+            ipranges_response = list_vlan_ipranges(
+                                                   self.apiclient,
+                                                   zoneid=ssvm.zoneid
+                                                   )
+            self.assertEqual(
+                            isinstance(ipranges_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+            iprange = ipranges_response[0]
+            
+            #Fetch corresponding Physical Network of SSVM's Zone
+            listphyntwk = PhysicalNetwork.list(
+                            self.apiclient,
+                            zoneid=ssvm.zoneid
+                            )
+            
+            # Execute the following assertion in all zones except EIP-ELB Zones
+            if not (self.zone.networktype.lower() == 'basic' and isinstance(NetScaler.list(self.apiclient,physicalnetworkid=listphyntwk[0].id), list) is True):
+                self.assertEqual(
+                            ssvm.gateway,
+                            iprange.gateway,
+                            "Check gateway with that of corresponding ip range"
+                            )
+
+            #Fetch corresponding zone information from listZones
+            zone_response = list_zones(
+                                       self.apiclient,
+                                       id=ssvm.zoneid
+                                       )
+            self.assertEqual(
+                            isinstance(zone_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+            self.assertEqual(
+                            ssvm.dns1,
+                            zone_response[0].dns1,
+                            "Check DNS1 with that of corresponding zone"
+                            )
+
+            self.assertEqual(
+                            ssvm.dns2,
+                            zone_response[0].dns2,
+                            "Check DNS2 with that of corresponding zone"
+                            )
+        return
+
+    def stop_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        self.debug("Stopping SSVM: %s" % ssvm.id)
+        cmd = stopSystemVm.stopSystemVmCmd()
+        cmd.id = ssvm.id
+        self.apiclient.stopSystemVm(cmd)
+        
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        id=ssvm.id
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+        
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm_response = list_ssvm_response[0]
+        self.debug("SSVM state after debug: %s" % ssvm_response.state)
+        self.assertEqual(
+                        ssvm_response.state,
+                        'Running',
+                        "Check whether SSVM is running or not"
+                        )
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        # Call above tests to ensure SSVM is properly running
+        self.list_sec_storage_vm()
+
+
+    def reboot_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+    
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        
+        ssvm_response = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm_response.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        #Store the public & private IP values before reboot
+        old_public_ip = ssvm_response.publicip
+        old_private_ip = ssvm_response.privateip
+
+        self.debug("Rebooting SSVM: %s" % ssvm_response.id)
+        cmd = rebootSystemVm.rebootSystemVmCmd()
+        cmd.id = ssvm_response.id
+        self.apiclient.rebootSystemVm(cmd)
+
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        id=ssvm_response.id
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+        ssvm_response = list_ssvm_response[0]
+        self.debug("SSVM State: %s" % ssvm_response.state)
+        self.assertEqual(
+                        'Running',
+                        str(ssvm_response.state),
+                        "Check whether CPVM is running or not"
+                        )
+
+        self.assertEqual(
+                    ssvm_response.publicip,
+                    old_public_ip,
+                    "Check Public IP after reboot with that of before reboot"
+                    )
+
+        self.assertEqual(
+                    ssvm_response.privateip,
+                    old_private_ip,
+                    "Check Private IP after reboot with that of before reboot"
+                    )
+
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        return
+
+    def destroy_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm_response = list_ssvm_response[0]
+
+        old_name = ssvm_response.name
+
+        self.debug("Destroying SSVM: %s" % ssvm_response.id)
+        cmd = destroySystemVm.destroySystemVmCmd()
+        cmd.id = ssvm_response.id
+        self.apiclient.destroySystemVm(cmd)
+
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        zoneid=self.zone.id,
+                                        systemvmtype='secondarystoragevm'
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+        ssvm_response = list_ssvm_response[0]
+
+        # Verify Name, Public IP, Private IP and Link local IP
+        # for newly created SSVM
+        self.assertNotEqual(
+                        ssvm_response.name,
+                        old_name,
+                        "Check SSVM new name with name of destroyed SSVM"
+                        )
+        self.assertEqual(
+                        hasattr(ssvm_response, 'privateip'),
+                        True,
+                        "Check whether SSVM has private IP field"
+                        )
+
+        self.assertEqual(
+                        hasattr(ssvm_response, 'linklocalip'),
+                        True,
+                        "Check whether SSVM has link local IP field"
+                        )
+
+        self.assertEqual(
+                        hasattr(ssvm_response, 'publicip'),
+                        True,
+                        "Check whether SSVM has public IP field"
+                        )
+        
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        return
+
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
     def test_01_Browser_volume_Life_cycle_tpath(self):
         """
@@ -762,11 +1281,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.debug("========================= Test 12:  Delete detached uploaded volume========================= ")
 
-            self.detach_volume(vm2details,browseup_vol3.id)
-
             self.deletevolume(browseup_vol3.id)
 
- 
+
             self.debug("========================= Test 13:  Delete Uploaded State volume========================= ")
 
             browseup_vol4=self.browse_upload_volume()
@@ -776,27 +1293,35 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 14:  Destroy VM which has Uploaded volumes attached========================= ")
 
             vm4details=self.deploy_vm()
-            self.attach_volume(vm4details,browseup_vol4.id)
+
+            newvolumetodestoy_VM=self.browse_upload_volume()
+
+            self.attach_volume(vm4details,newvolumetodestoy_VM.id)
 
             self.destroy_vm(vm4details)
 
             self.debug("========================= Test 15:  Recover destroyed VM which has Uploaded volumes attached========================= ")
 
             self.recover_destroyed_vm(vm4details)
+            self.destroy_vm(vm4details)
+
+            self.deletevolume(newvolumetodestoy_VM.id)
 
-            self.debug("========================= Test 16:  Delete attached Uploaded volume which is in ready state========================= ")
+            self.debug("========================= Test 16:  Delete attached Uploaded volume which is in ready state and it should not be allowed to delete========================= ")
 
+            vm5details=self.deploy_vm()
             browseup_vol5=self.browse_upload_volume()
-            self.attach_volume(vm4details,browseup_vol5.id)
-            self.deletevolume(browseup_vol5.id)
+            self.attach_volume(vm5details,browseup_vol5.id)
+            self.deletevolume_fail(browseup_vol5.id)
 
             self.debug("========================= Test 17:  Create Volume Backup Snapshot uploaded volume attached to the VM========================= ")
 
+            vm6details=self.deploy_vm()
             browseup_vol6=self.browse_upload_volume()
 
-            self.attach_volume(vm2details,browseup_vol6.id)
+            self.attach_volume(vm6details,browseup_vol6.id)
 
-            snapshotdetails=self.volume_snapshot(browseup_vol6.id)
+            snapshotdetails=self.volume_snapshot(browseup_vol6)
 
             self.debug("========================= Test 18:  Create Volume from Backup Snapshot of attached uploaded volume========================= ")
 
@@ -805,10 +1330,94 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 19:  Create template from Backup Snapshot of attached uploaded volume========================= ")
             self.volume_snapshot_template(snapshotdetails)
 
+            self.deletevolume(browseup_vol6.id)
+
+            self.debug("========================= Test 20: Upload Browser based volume with checksum and validate ========================= ")
+            browseup_vol_withchecksum=self.browse_upload_volume_with_md5()
+
+            self.debug("========================= Test 21: Deploy a VM , Attach Uploaded Browser based volume with checksum and validate VM Operations========================= ")
+
+            vm7details=self.deploy_vm()
+
+            self.attach_volume(vm7details,browseup_vol_withchecksum.id)
+
+            self.debug("========================= Test 22: Detach Uploaded volume with checksum and validation of VM operations after detach========================= ")
+
+            self.detach_volume(vm7details,browseup_vol_withchecksum.id)
+            self.deletevolume(browseup_vol_withchecksum.id)
+
+            self.vmoperations(vm7details)
+
+            self.destroy_vm(vm7details)
+
+
         except Exception as e:
             self.fail("Exception occurred  : %s" % e)
         return
 
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_02_SSVM_Life_Cycle_With_Browser_Volume_TPath(self):
+        """
+        Test SSVM_Life_Cycle_With_Browser_Volume_TPath - This includes SSVM life cycle followed by Browser volume upload operations
+        """
+        try:
+            
+            self.debug("========================= Test 23: Stop and Start SSVM and Perform Browser based volume validations ========================= ")
+
+            self.stop_ssvm()
+            ssvm1browseup_vol=self.browse_upload_volume()
+
+            ssvm1vm1details=self.deploy_vm()
+
+            self.attach_volume(ssvm1vm1details,ssvm1browseup_vol.id)
+
+            self.vmoperations(ssvm1vm1details)
+
+            self.detach_volume(ssvm1vm1details,ssvm1browseup_vol.id)
+
+            self.deletevolume(ssvm1browseup_vol.id)
+            self.destroy_vm(ssvm1vm1details)
+
+            self.debug("========================= Test 24: Reboot SSVM and Perform Browser based volume validations ========================= ")
+
+            self.reboot_ssvm()
+            ssvm2browseup_vol=self.browse_upload_volume()
+
+            ssvm2vm1details=self.deploy_vm()
+
+            self.attach_volume(ssvm2vm1details,ssvm2browseup_vol.id)
+
+            self.vmoperations(ssvm2vm1details)
+
+            self.detach_volume(ssvm2vm1details,ssvm2browseup_vol.id)
+
+            self.deletevolume(ssvm2browseup_vol.id)
+
+            self.destroy_vm(ssvm2vm1details)
+
+            self.debug("========================= Test 25: Reboot SSVM and Perform Browser based volume validations ========================= ")
+
+            self.destroy_ssvm()
+            ssvm3browseup_vol=self.browse_upload_volume()
+
+            ssvm3vm1details=self.deploy_vm()
+
+            self.attach_volume(ssvm3vm1details,ssvm3browseup_vol.id)
+
+            self.vmoperations(ssvm3vm1details)
+
+            self.detach_volume(ssvm3vm1details,ssvm3browseup_vol.id)
+
+            self.deletevolume(ssvm3browseup_vol.id)
+
+            self.destroy_vm(ssvm3vm1details)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
     @classmethod
     def tearDownClass(self):
         try:


[37/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Additional automated test paths of browser based volume


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

Branch: refs/heads/master
Commit: 55ee1ecd8443b92bc8b0ab9634383edcb2ac3b6a
Parents: 0d06dbd
Author: sailajamada <sa...@citrix.com>
Authored: Wed Apr 8 08:06:34 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Wed Apr 8 08:06:34 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_volumes.py            | 489 +++++++++++++++++--
 1 file changed, 439 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/55ee1ecd/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index b2b7caf..edd13e7 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -114,7 +114,14 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             cls.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"],
             custom=True
         )
+        cls.project = Project.create(
+                                 cls.apiclient,
+                                 cls.testdata["project"],
+                                 account=cls.account.name,
+                                 domainid=cls.account.domainid
+                                 )
         cls._cleanup = [
+            cls.project,
             cls.account,
             cls.service_offering,
             cls.disk_offering
@@ -152,7 +159,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         config2 = Configurations.list(
                                      self.apiclient,
-                                     name='upload.monitornsving.interval'
+                                     name='upload.monitoring.interval'
                                      )
 
         uploadtimeout = int(config1[0].value)
@@ -175,6 +182,92 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                 )
         return
 
+
+    def browse_upload_volume_with_projectid(self,projectid):
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.projectid=projectid
+        getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_volume(getuploadparamsresponce.id,'Uploaded')
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    projectid=projectid
+                )
+        if list_volume_response[0].id==getuploadparamsresponce.id:
+            return(getuploadparamsresponce)
+        else:
+            self.fail("Volume is not listed with projectid")
+
+
+    def browse_upload_volume_with_out_zoneid(self):
+
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.format = self.uploadvolumeformat
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        success= False
+        try:
+            getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+        except Exception as ex:
+            if "Invalid Parameter" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Upload Volume - verify upload volume API request is handled without mandatory params - zoneid ")
+
+        return
+
+
+    def browse_upload_volume_with_out_format(self):
+
+
+        cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
+        cmd.zoneid = self.zone.id
+        cmd.name=self.volname+self.account.name+(random.choice(string.ascii_uppercase))
+        success= False
+        try:
+            getuploadparamsresponce=self.apiclient.getUploadParamsForVolume(cmd)
+        except Exception as ex:
+            if "Invalid Parameter" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Upload Volume - verify upload volume API request is handled without mandatory params - format")
+
+        return
+
     def browse_upload_volume(self):
         cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd()
         cmd.zoneid = self.zone.id
@@ -710,35 +803,15 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
-    def deletevolume(self,volumeid):
+    def delete_volume(self,volumeid):
         """Delete a Volume attached to a VM
         """
 
         cmd = deleteVolume.deleteVolumeCmd()
-        cmd.id = volumeid
+        cmd.id =volumeid
 
         self.apiclient.deleteVolume(cmd)
 
-        list_volume_response = Volume.list(
-                                            self.apiclient,
-                                            id=volumeid,
-                                            type='DATADISK'
-                                            )
-        self.debug(list_volume_response)
-
-        self.assertEqual(
-                            isinstance(list_volume_response, list),
-                            True,
-                            "Check VOLUME is deleted from list Volumes"
-                        )
-        self.assertEqual(
-                            list_volume_response,
-                            None,
-                            "Check VOLUME is deleted from list Volumes"
-                        )
-
-        return
-
     def download_volume(self,volumeid):
 
         cmd = extractVolume.extractVolumeCmd()
@@ -785,11 +858,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         """Test resize a volume"""
 
-        self.testdata["browser_upload_volume"]["browser_resized_disk_offering"]["disksize"] = 20
+        self.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"]["disksize"] = 20
 
         disk_offering_20_GB = DiskOffering.create(
                                     self.apiclient,
-                                    self.testdata["browser_upload_volume"]["browser_resized_disk_offering"]
+                                    self.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"]
                                     )
         self.cleanup.append(disk_offering_20_GB)
 
@@ -1803,7 +1876,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         self.detach_volume(vm1details,browseup_vol.id)
 
-        self.deletevolume(browseup_vol.id)
+        cmd=deleteVolume.deleteVolumeCmd()
+        cmd.id=browseup_vol.id
+        self.apiclient.deleteVolume(cmd)
 
         return(2)
 
@@ -1860,7 +1935,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         cmd = deleteVolume.deleteVolumeCmd()
         cmd.id = getuploadparamsresponce.id
 
-        self.apiclient.deleteVolume(cmd)
+        self.apiclient.delete_volume(cmd)
 
         success = False
 
@@ -1885,6 +1960,69 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             return("FAIL")
         return("PASS")
 
+    def volume_migration(self,browseup_vol,vm1details):
+        
+        pools = StoragePool.list(
+            self.apiclient,
+            zoneid=self.zone.id
+        )
+        if not pools:
+            self.skipTest(
+                "No suitable storage pools found for volume migration.\
+                        Skipping")
+        self.assertEqual(
+            validateList(pools)[0],
+            PASS,
+            "invalid pool response from findStoragePoolsForMigration")
+        pool = pools[0]
+
+        try:
+            if vm1details is None:
+                Volume.migrate(
+                               self.apiclient,
+                               volumeid=browseup_vol.id,
+                               storageid=pool.id,
+                               livemigrate='false'
+                               )
+            else:
+                Volume.migrate(
+                               self.apiclient,
+                               volumeid=browseup_vol.id,
+                               storageid=pool.id,
+                               livemigrate='true'
+            )
+
+        except Exception as e:
+            self.fail("Volume migration failed with error %s" % e)
+
+        return
+
+
+    def getvolumelimts(self):
+
+        totalresoucelist=Account.list(
+                                      self.apiclient,
+                                      id=self.account.id
+                                      )
+        totalvolumes=totalresoucelist[0].volumetotal
+
+        return(totalvolumes)
+
+
+    def getstoragelimts(self,rtype):
+
+        cmd=updateResourceCount.updateResourceCountCmd()
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.resourcetype=rtype
+
+        responce=self.apiclient.updateResourceCount(cmd)
+
+        totalstorage=responce[0].resourcecount
+
+        return(totalstorage)
+
+
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
     def test_01_Browser_volume_Life_cycle_tpath(self):
         """
@@ -1936,7 +2074,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.vmoperations(vm2details)
             self.detach_volume(vm2details,browseup_vol.id)
 
-            self.deletevolume(browseup_vol.id)
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol.id
+            self.apiclient.deleteVolume(cmd)
 
             self.debug("========================= Test 8: Try resizing uploaded state volume and validate the error scenario========================= ")
 
@@ -1958,7 +2098,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.detach_volume(vm2details,browseup_vol2.id)
 
-            self.deletevolume(browseup_vol2.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol2.id
+            self.apiclient.deleteVolume(cmd)
+
 
             self.debug("========================= Test 11:  Detach and download uploaded volume========================= ")
 
@@ -1969,7 +2113,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 12:  Delete detached uploaded volume========================= ")
 
 
-            self.deletevolume(browseup_vol3.id)
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol3.id
+            self.apiclient.deleteVolume(cmd)
 
             self.debug("========================= Deletion of UnUsed VM's after test is complete========================= ")
 
@@ -1979,7 +2125,10 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             browseup_vol4=self.browse_upload_volume()
 
-            self.deletevolume(browseup_vol4.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol4.id
+            self.apiclient.deleteVolume(cmd)
 
             self.debug("========================= Test 14:  Destroy VM which has Uploaded volumes attached========================= ")
 
@@ -1996,7 +2145,10 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.recover_destroyed_vm(vm4details)
             self.expunge_vm(vm4details)
 
-            self.deletevolume(newvolumetodestoy_VM.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=newvolumetodestoy_VM.id
+            self.apiclient.deleteVolume(cmd)
 
             self.debug("========================= Test 16:  Delete attached Uploaded volume which is in ready state and it should not be allowed to delete========================= ")
 
@@ -2022,7 +2174,12 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.volume_snapshot_template(snapshotdetails)
 
             self.detach_volume(vm6details,browseup_vol6.id)
-            self.deletevolume(browseup_vol6.id)
+
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol6.id
+            self.apiclient.deleteVolume(cmd)
+
             self.expunge_vm(vm6details)
 
             self.debug("========================= Test 20: Upload Browser based volume with checksum and validate ========================= ")
@@ -2037,7 +2194,13 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 22: Detach Uploaded volume with checksum and validation of VM operations after detach========================= ")
 
             self.detach_volume(vm7details,browseup_vol_withchecksum.id)
-            self.deletevolume(browseup_vol_withchecksum.id)
+
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol_withchecksum.id
+
+            self.apiclient.deleteVolume(cmd)
+
 
             self.vmoperations(vm7details)
 
@@ -2069,7 +2232,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.detach_volume(ssvm1vm1details,ssvm1browseup_vol.id)
 
-            self.deletevolume(ssvm1browseup_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=ssvm1browseup_vol.id
+            self.apiclient.deleteVolume(cmd)
+
             self.expunge_vm(ssvm1vm1details)
 
             self.debug("========================= Test 24: Reboot SSVM and Perform Browser based volume validations ========================= ")
@@ -2085,7 +2252,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.detach_volume(ssvm2vm1details,ssvm2browseup_vol.id)
 
-            self.deletevolume(ssvm2browseup_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=ssvm2browseup_vol.id
+            self.apiclient.deleteVolume(cmd)
+
 
             self.expunge_vm(ssvm2vm1details)
 
@@ -2102,7 +2273,11 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.detach_volume(ssvm3vm1details,ssvm3browseup_vol.id)
 
-            self.deletevolume(ssvm3browseup_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=ssvm3browseup_vol.id
+            self.apiclient.deleteVolume(cmd)
+
 
             self.expunge_vm(ssvm3vm1details)
 
@@ -2136,21 +2311,38 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.debug("========================= Test 27 Reuse the POST URL after expiry time========================= ")
             reuse_browse_up_vol=self.browse_upload_volume()
             self.reuse_url()
-            self.deletevolume(reuse_browse_up_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=reuse_browse_up_vol.id
+            self.apiclient.deleteVolume(cmd)
+
 
             self.debug("========================= Test 28 Reboot SSVM before upload is completed=========================")
             browse_up_vol=self.onlyupload()
             self.uploadvol(browse_up_vol)
-            self.deletevolume(browse_up_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browse_up_vol.id
+            self.apiclient.deleteVolume(cmd)
+
 
             self.debug("========================= Test 29 Reboot SSVM after getting the upload volume params and before initiating the upload=========================")
             browse_up_vol=self.onlyupload()
             self.uploadvolwithssvmreboot(browse_up_vol)
-            self.deletevolume(browse_up_vol.id)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=reuse_browse_up_vol.id
+            self.apiclient.deleteVolume(cmd)
 
             self.debug("========================= Test 30 Attach Deleted Volume=========================")
             deleted_browse_up_vol=self.browse_upload_volume()
-            self.deletevolume(deleted_browse_up_vol.id)
+
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=deleted_browse_up_vol.id
+            self.apiclient.deleteVolume(cmd)
+
+
             deletedvm1details=self.deploy_vm()
             self.attach_deleted_volume(deletedvm1details, deleted_browse_up_vol)
 
@@ -2249,15 +2441,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         except Exception as e:
             self.fail("Exception occurred  : %s" % e)
         return
-    @classmethod
-    def tearDownClass(self):
-        try:
-            self.apiclient = super(TestBrowseUploadVolume,self).getClsTestClient().getApiClient()
-            cleanup_resources(self.apiclient, self._cleanup)
-        except Exception as e:
-            raise Exception("Warning: Exception during cleanup : %s" % e)
-        return
-
 
 
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
@@ -2285,6 +2468,212 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_11_migrate_upload_volume(self):
+        """
+        Test Browser_Upload_Volume_migrate_upload_volume
+        """
+        self.debug("========================= Test 40 Test Browser_Upload_Volume_Migration=========================")
+
+        browseup_vol=self.browse_upload_volume()
+        vm1details=self.deploy_vm()
+        self.attach_volume(vm1details,browseup_vol.id)
+        self.volume_migration(browseup_vol, vm1details)
+        self.debug("========================= Test 41 Test VM Operations after Browser_Upload_Volume_Migration=========================")
+        self.vmoperations(vm1details)
+
+        self.debug("========================= Test 42 Detach Browser_Upload_Volume after Migration and attach to a new VM=========================")
+        self.detach_volume(vm1details,browseup_vol.id)
+        vm2details=self.deploy_vm()
+        self.attach_volume(vm2details,browseup_vol.id)
+        self.vmoperations(vm2details)
+
+        self.debug("========================= Test 43 Detach Browser_Upload_Volume and Migrate to another storage=========================")
+
+        self.detach_volume(vm2details,browseup_vol.id)
+        self.volume_migration(browseup_vol, "None")
+
+        self.debug("========================= Test 44 Attach detached Browser_Upload_Volume after Migration =========================")
+
+        self.attach_volume(vm2details,browseup_vol.id)
+        self.vmoperations(vm2details)
+
+        self.debug("========================= Test 45 Detach  ,Resize,Attach  Browser_Upload_Volume after Migration =========================")
+
+        self.detach_volume(vm2details,browseup_vol.id)
+        self.resize_volume(browseup_vol.id)
+        self.attach_volume(vm2details,browseup_vol.id)
+        self.vmoperations(vm2details)
+
+        self.detach_volume(vm2details,browseup_vol.id)
+
+        self.cleanup.append(browseup_vol)
+        self.cleanup.append(vm2details)
+        self.cleanup.append(vm1details)
+        return
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_12_Browser_Upload_Volume_with_all_API_parameters(self):
+        """
+        Test Browser_Upload_Volumewith all API parameters
+        """
+        try:
+
+            self.debug("========================= Test 46 & 47 Upload volume with account name and domainid========================")
+
+            browseup_vol1=self.browse_upload_volume()
+
+            self.debug("========================= Test 48 Upload volume with projectid========================")
+            browseup_vol2=self.browse_upload_volume_with_projectid(self.project.id)
+
+            self.debug("========================= Test 49 Upload volume with out mandatory param zone id ========================")
+
+            browseup_vol2=self.browse_upload_volume_with_out_zoneid()
+
+
+            self.debug("========================= Test 50 Upload volume with out mandatory param format ========================")
+
+            browseup_vol3=self.browse_upload_volume_with_out_format()
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_13_Browser_Upload_Volume_volume_resource_limits(self):
+        """
+        Test Browser_Upload_Volume Volume Resource limits
+        """
+        try:
+
+            self.debug("========================= Test 51 Upload volume and verify volume limits========================")
+            initialvolumelimit=self.getvolumelimts()
+            browseup_vol1=self.browse_upload_volume()
+            afteruploadvolumelimit=self.getvolumelimts()
+
+            if int(afteruploadvolumelimit)!=(int(initialvolumelimit)+1):
+                self.fail("Volume Resouce Count is not updated")
+
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=deleted_browse_up_vol1.id
+            self.apiclient.deleteVolume(cmd)
+
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_14_Browser_Upload_Volume_secondary_storage_resource_limits(self):
+        """
+        Test Browser_Upload_Volume Secondary Storage Resource limits
+        """
+        try:
+
+            self.debug("========================= Test 52 Upload volume and verify secondary storage limits========================")
+
+            initialsecondarystoragelimit=self.getstoragelimts(11)
+            browseup_vol1=self.browse_upload_volume()
+            volumedetails=Volume.list(
+                                      self.apiclient,
+                                      id=browseup_vol1.id)
+            afteruploadsecondarystoragelimit=self.getstoragelimts(11)
+
+            if afteruploadsecondarystoragelimit!=(initialsecondarystoragelimit+volumedetails[0].size):
+                self.fail("Secondary Storage Resouce Count is not updated")
+
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=deleted_browse_up_vol1.id
+            self.apiclient.deleteVolume(cmd)
+
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_15_Browser_Upload_Volume_primary_storage_resource_limits(self):
+        """
+        Test Browser_Upload_Volume Primary Storage Resource limits
+        """
+        try:
+
+            self.debug("========================= Test 53 Attach Upload volume and verify primary storage limits========================")
+
+            initialprimarystoragelimit=self.getstoragelimts(10)
+            browseup_vol1=self.browse_upload_volume()
+            volumedetails=Volume.list(
+                                      self.apiclient,
+                                      id=browseup_vol1.id)
+            afteruploadprimarystoragelimit=self.getstoragelimts(10)
+
+            if afteruploadprimarystoragelimit!=(initialprimarystoragelimit+volumedetails[0].size):
+                self.fail("Primary Storage Resource Count is not updated")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_16_Browser_Upload_volume_resource_limits_after_deletion(self):
+        """
+        Test Browser_Upload_Volume resource_limits_after_deletion
+        """
+        try:
+            self.debug("========================= Test 54 Delete Upload volume and verify volume limits========================")
+            browseup_vol1=self.browse_upload_volume()
+            initialvolumelimit=self.getvolumelimts()
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol1.id
+            self.apiclient.deleteVolume(cmd)
+
+            aftervolumelimit=self.getvolumelimts()
+
+            if aftervolumelimit!=(initialvolumelimit-1):
+                self.fail("Volume Resource Count is not updated after deletion")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_17_Browser_Upload_Volume_secondary_storage_resource_limits_after_deletion(self):
+        """
+        Test Browser_Upload_Volume secondary_storage_resource_limits_after_deletion
+        """
+        try:
+            self.debug("========================= Test 55 Delete Upload volume and secondary storage limits========================")
+
+            browseup_vol1=self.browse_upload_volume()
+
+            volumedetails=Volume.list(
+                                      self.apiclient,
+                                      id=browseup_vol1.id)
+
+            initialuploadsecondarystoragelimit=self.getstoragelimts(11)
+
+            cmd=deleteVolume.deleteVolumeCmd()
+            cmd.id=browseup_vol1.id
+            self.apiclient.deleteVolume(cmd)
+
+            afteruploadsecondarystoragelimit=self.getstoragelimts(11)
+
+            if afteruploadsecondarystoragelimit!=(initialuploadsecondarystoragelimit-volumedetails[0].size):
+                self.fail("Secondary Storage Resouce Count is not updated after deletion")
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
     @classmethod
     def tearDownClass(self):
         try:


[06/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: added max size check for temaplte/volume post upload

used the existing configuration variables max.template.iso.size and
storage.max.volume.upload.size for templates and volumes respectively.


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

Branch: refs/heads/master
Commit: b16520bcecf5066259f9ee44c653fbb60847c18b
Parents: dd1a8da
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Tue Mar 3 17:22:40 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Mar 3 17:27:40 2015 +0530

----------------------------------------------------------------------
 .../TemplateOrVolumePostUploadCommand.java      | 10 +++++++
 .../com/cloud/storage/VolumeApiServiceImpl.java |  2 ++
 .../template/HypervisorTemplateAdapter.java     |  3 ++
 .../resource/HttpUploadServerHandler.java       | 22 +++++++++++----
 .../resource/NfsSecondaryStorageResource.java   | 29 ++++++++++++++++----
 .../storage/template/UploadEntity.java          |  7 +++++
 6 files changed, 63 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index 8872798..cc9df71 100644
--- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -45,6 +45,8 @@ public class TemplateOrVolumePostUploadCommand {
 
     String remoteEndPoint;
 
+    String maxUploadSize;
+
     public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
             String dataToRole) {
         this.entityId = entityId;
@@ -156,4 +158,12 @@ public class TemplateOrVolumePostUploadCommand {
     public void setName(String name) {
         this.name = name;
     }
+
+    public String getMaxUploadSize() {
+        return maxUploadSize;
+    }
+
+    public void setMaxUploadSize(String maxUploadSize) {
+        this.maxUploadSize = maxUploadSize;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 9840096..d2c1c69 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -337,6 +337,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
                                                           vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(),
                                                           dataObject.getDataStore().getRole().toString());
                 command.setLocalPath(volumeStore.getLocalDownloadPath());
+                //using the existing max upload size configuration
+                command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
                 Gson gson = new GsonBuilder().create();
                 String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
                 response.setMetadata(metadata);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/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 6d81047..0cb48fc 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutionException;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import com.cloud.configuration.Config;
 import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -259,6 +260,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl.getChecksum(), tmpl
                     .getType().toString(), template.getName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(), templateOnStore.getDataStore().getRole()
                     .toString());
+            //using the existing max template size configuration
+            payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
             payload.setRemoteEndPoint(ep.getPublicAddr());
             payload.setRequiresHvm(template.requiresHvm());
             payloads.add(payload);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 0c95707..7a17ef1 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -108,6 +108,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                 String expires = null;
                 String metadata = null;
                 String hostname = null;
+                long contentLength = 0;
+
                 for (Entry<String, String> entry : request.headers()) {
                     switch (entry.getKey()) {
                         case HEADER_SIGNATURE:
@@ -122,12 +124,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                         case HEADER_HOST:
                             hostname = entry.getValue();
                             break;
+                        case HttpHeaders.Names.CONTENT_LENGTH:
+                            contentLength = Long.valueOf(entry.getValue());
+                            break;
                     }
                 }
                 logger.info("HEADER: signature=" + signature);
                 logger.info("HEADER: metadata=" + metadata);
                 logger.info("HEADER: expires=" + expires);
                 logger.info("HEADER: hostname=" + hostname);
+                logger.info("HEADER: Content-Length=" + contentLength);
                 QueryStringDecoder decoderQuery = new QueryStringDecoder(uri);
                 Map<String, List<String>> uriAttributes = decoderQuery.parameters();
                 uuid = uriAttributes.get("uuid").get(0);
@@ -136,9 +142,9 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                 UploadEntity uploadEntity = null;
                 try {
                     // Validate the request here
-                    storageResource.validatePostUploadRequest(signature, metadata, expires, hostname, uuid);
+                    storageResource.validatePostUploadRequest(signature, metadata, expires, hostname, contentLength, uuid);
                     //create an upload entity. This will fail if entity already exists.
-                    uploadEntity = storageResource.createUploadEntity(uuid, metadata);
+                    uploadEntity = storageResource.createUploadEntity(uuid, metadata, contentLength);
                 } catch (InvalidParameterValueException ex) {
                     logger.error("post request validation failed", ex);
                     responseContent.append(ex.getMessage());
@@ -185,9 +191,15 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
                     return;
                 }
                 if (chunk instanceof LastHttpContent) {
-                    readFileUploadData();
-                    writeResponse(ctx.channel(), HttpResponseStatus.OK);
-                    reset();
+                    try {
+                        readFileUploadData();
+                        writeResponse(ctx.channel(), HttpResponseStatus.OK);
+                        reset();
+                    } catch (InvalidParameterValueException e) {
+                        logger.error("error during the file install.", e);
+                        responseContent.append("\n").append(e.getMessage());
+                        writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
+                    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index f80572a..236498c 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2602,7 +2602,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         return Script.findScript(scriptsDir, scriptname);
     }
 
-    public UploadEntity createUploadEntity(String uuid, String metadata) {
+    public UploadEntity createUploadEntity(String uuid, String metadata, long contentLength) {
         TemplateOrVolumePostUploadCommand cmd = getTemplateOrVolumePostUploadCmd(metadata);
         UploadEntity uploadEntity = null;
         if(cmd == null ){
@@ -2610,10 +2610,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             throw new InvalidParameterValueException("unable to decode and deserialize metadata");
         } else {
             uuid = cmd.getEntityUUID();
-            if(uploadEntityStateMap.containsKey(uuid)) {
+            if (uploadEntityStateMap.containsKey(uuid)) {
                 uploadEntity = uploadEntityStateMap.get(uuid);
                 throw new InvalidParameterValueException("The one time post url is already used and the upload is in " + uploadEntity.getUploadState() + " state.");
             }
+            int maxSizeInGB = Integer.valueOf(cmd.getMaxUploadSize());
+            int contentLengthInGB = getSizeInGB(contentLength);
+            if (contentLengthInGB > maxSizeInGB) {
+                throw new InvalidParameterValueException("Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " +
+                                                             maxSizeInGB + "GB.");
+            }
             try {
                 String absolutePath = cmd.getAbsolutePath();
                 uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
@@ -2627,6 +2633,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 uploadEntity.setInstallPathPrefix(installPathPrefix);
                 uploadEntity.setHvm(cmd.getRequiresHvm());
                 uploadEntity.setChksum(cmd.getChecksum());
+                uploadEntity.setMaxSizeInGB(maxSizeInGB);
                 // create a install dir
                 if (!_storage.exists(installPathPrefix)) {
                     _storage.mkdir(installPathPrefix);
@@ -2634,13 +2641,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 uploadEntityStateMap.put(uuid, uploadEntity);
             } catch (Exception e) {
                 //upload entity will be null incase an exception occurs and the handler will not proceed.
-                s_logger.debug("exception occured while creating upload entity " + e);
+                s_logger.error("exception occurred while creating upload entity ", e);
                 updateStateMapWithError(uuid, e.getMessage());
             }
         }
         return uploadEntity;
     }
 
+    private int getSizeInGB(long sizeInBytes) {
+        return (int)Math.ceil(sizeInBytes * 1.0d / (1024 * 1024 * 1024));
+    }
 
     public String postUpload(String uuid, String filename) {
         UploadEntity uploadEntity = uploadEntityStateMap.get(uuid);
@@ -2657,7 +2667,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         //}
         //dnld.setCheckSum(checkSum);
 
-        int imgSizeGigs = (int)Math.ceil(_storage.getSize(fileSavedTempLocation) * 1.0d / (1024 * 1024 * 1024));
+        int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
+        int maxSize = uploadEntity.getMaxSizeInGB();
+        if(imgSizeGigs > maxSize) {
+            throw new InvalidParameterValueException("Maximum file upload size exceeded. Physical file size: "+imgSizeGigs+"GB. Maximum allowed size: "+maxSize+"GB.");
+        }
         imgSizeGigs++; // add one just in case
         long timeout = (long)imgSizeGigs * installTimeoutPerGig;
         Script scr = new Script(getScriptLocation(resourceType), timeout, s_logger);
@@ -2771,13 +2785,18 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         uploadEntityStateMap.put(uuid, uploadEntity);
     }
 
-    public void validatePostUploadRequest(String signature, String metadata, String timeout, String hostname, String uuid) throws InvalidParameterValueException{
+    public void validatePostUploadRequest(String signature, String metadata, String timeout, String hostname,long contentLength, String uuid) throws InvalidParameterValueException{
         // check none of the params are empty
         if(StringUtils.isEmpty(signature) || StringUtils.isEmpty(metadata) || StringUtils.isEmpty(timeout)) {
             updateStateMapWithError(uuid,"signature, metadata and expires are compulsory fields.");
             throw new InvalidParameterValueException("signature, metadata and expires are compulsory fields.");
         }
 
+        //check that contentLength exists and is greater than zero
+        if (contentLength <= 0) {
+            throw new InvalidParameterValueException("content length is not set in the request or has invalid value.");
+        }
+
         //validate signature
         String fullUrl = "https://" + hostname + "/upload/" + uuid;
         String computedSignature = EncryptionUtil.generateSignature(metadata + fullUrl + timeout, getPostUploadPSK());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b16520bc/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
index 46ace7c..15a6ef2 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
@@ -31,6 +31,7 @@ public class UploadEntity {
     private long entityId;
     private String chksum;
     private long physicalSize;
+    private int maxSizeInGB;
 
     public static enum ResourceType {
         VOLUME, TEMPLATE
@@ -172,5 +173,11 @@ public class UploadEntity {
         return physicalSize;
     }
 
+    public int getMaxSizeInGB() {
+        return maxSizeInGB;
+    }
 
+    public void setMaxSizeInGB(int maxSizeInGB) {
+        this.maxSizeInGB = maxSizeInGB;
+    }
 }


[21/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Browser Basesd Test Template changes


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

Branch: refs/heads/master
Commit: f22bd7a79e1af15d22d3ea3f9cb01ee807d0e38c
Parents: aad9b8a
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 23 09:58:02 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 23 09:58:02 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_templates.py          | 46 ++++++++++++--------
 1 file changed, 27 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f22bd7a7/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
index 9b1eda0..3df5139 100644
--- a/test/integration/component/test_browse_templates.py
+++ b/test/integration/component/test_browse_templates.py
@@ -147,19 +147,22 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         list_template_response = Template.list(
                     self.apiclient,
-                    id=up_templateid
-                )
+                    id=up_templateid,
+                    templatefilter="all",
+                    zoneid=self.zone.id)
+
         self.assertNotEqual(
-                    list_volume_response,
+                    list_template_response,
                     None,
                     "Check if template exists in ListTemplates"
                 )
 
         self.assertEqual(
-                    list_template_response[0].state,
+                    list_template_response[0].status,
                     templatestate,
-                    "Check template state in List templates"
+                    "Check template status in List templates"
                 )
+        return
 
     def browse_upload_template(self):
         cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
@@ -171,6 +174,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
         cmd.hypervisor=self.templatehypervisor
         cmd.ostypeid=self.templateostypeid
+        cmd.isdynamicallyscalable="false"
         #cmd.type="template"
         getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
 
@@ -200,13 +204,13 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
 
         results = requests.post(posturl,files=files,headers=headers,verify=False)
-        time.sleep(60)
+        time.sleep(600)
 
         print results.status_code
         if results.status_code !=200: 
             self.fail("Upload is not fine")
 
-        self.validate_uploaded_template(getuploadparamsresponce.id,'Uploaded')
+        self.validate_uploaded_template(getuploadparamsresponce.id,'Download Complete')
 
         return(getuploadparamsresponce)
 
@@ -262,9 +266,13 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         templ1=self.uploadtemplate()
         templ2=self.uploadtemplate()
         templ3=self.uploadtemplate()
-        self.validate_uploaded_template(templ1.id,'Uploaded')
-        self.validate_uploaded_template(templ2.id,'Uploaded')
-        self.validate_uploaded_template(templ3.id,'Uploaded')
+        time.sleep(600)
+        self.validate_uploaded_template(templ1.id,'Download Complete')
+        self.validate_uploaded_template(templ2.id,'Download Complete')
+        self.validate_uploaded_template(templ3.id,'Download Complete')
+        self.delete_template(templ1)
+        self.delete_template(templ2)
+        self.delete_template(templ3)
         return
 
     def validate_vm(self,vmdetails,vmstate):
@@ -1113,12 +1121,13 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def delete_template(self,templatedetails):
 
+        print templatedetails
         list_template_response = Template.list(
                                     self.apiclient,
-                                    templatefilter=\
-                                    self.testdata["template"]["templatefilter"],
+                                    templatefilter="all",
                                     id=templatedetails.id,
                                     zoneid=self.zone.id)
+        print list_template_response
         self.assertEqual(
                         isinstance(list_template_response, list),
                         True,
@@ -1139,15 +1148,13 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                             (template_response.id, templatedetails.id)
                         )
 
-        self.debug("Deleting template: %s" % self.template)
-        # Delete the template
+                # Delete the template
         templatedetails.delete(self.apiclient)
         self.debug("Delete template: %s successful" % templatedetails)
 
         list_template_response = Template.list(
                                     self.apiclient,
-                                    templatefilter=\
-                                    self.services["template"]["templatefilter"],
+                                    templatefilter="all",
                                     id=templatedetails.id,
                                     zoneid=self.zone.id
                                     )
@@ -1254,8 +1261,8 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.expunge_vm(vm2details)
 
             self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
-
-            self.delete_template(browseup_template)
+            print browseup_template
+            #self.delete_template(browseup_template)
 
             self.debug("========================= Test 10:  Upload Multiple templates========================= ")
 
@@ -1267,7 +1274,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
-    def test_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self):
+    def xtest_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self):
         """
         Test SSVM_Life_Cycle_With_Browser_template_TPath 
         """
@@ -1314,6 +1321,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         return
 
 
+
     @classmethod
     def tearDownClass(self):
         try:


[46/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume-upload: If SSVM is destroyed and started, then partially uploaded volumes/templates remain in
inconsistent state (NotUploaded or UploadInProgress) and doesn't transition to any terminal
state (Uploaded, Uploaded). As a result these volumes/templates cannot be removed. Fix is to handle such
volume/template entries correctly.


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

Branch: refs/heads/master
Commit: bc399b981f6b9bd7a5471820632e104f6077f7d6
Parents: f172fbe
Author: Koushik Das <ko...@apache.org>
Authored: Wed Apr 22 19:28:51 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Wed Apr 22 19:28:51 2015 +0530

----------------------------------------------------------------------
 .../storage/image/TemplateServiceImpl.java      | 60 +++++++++++++-------
 .../datastore/ObjectInDataStoreManagerImpl.java |  1 +
 .../storage/volume/VolumeServiceImpl.java       | 51 ++++++++++-------
 .../storage/ImageStoreUploadMonitorImpl.java    |  2 +
 4 files changed, 76 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc399b98/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
index c15cda0..f6dc33e 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -29,7 +29,6 @@ import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
@@ -87,12 +86,15 @@ import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.template.TemplateConstants;
 import com.cloud.storage.template.TemplateProp;
 import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
 
 @Component
 public class TemplateServiceImpl implements TemplateService {
@@ -315,6 +317,7 @@ public class TemplateServiceImpl implements TemplateService {
 
                     toBeDownloaded.addAll(allTemplates);
 
+                    final StateMachine2<VirtualMachineTemplate.State, VirtualMachineTemplate.Event, VirtualMachineTemplate> stateMachine = VirtualMachineTemplate.State.getStateMachine();
                     for (VMTemplateVO tmplt : allTemplates) {
                         String uniqueName = tmplt.getUniqueName();
                         TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
@@ -330,18 +333,23 @@ public class TemplateServiceImpl implements TemplateService {
                                     tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
                                     String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
                                     tmpltStore.setErrorString(msg);
-                                    s_logger.info("msg");
-                                    if (tmplt.getUrl() == null) {
-                                        msg =
-                                                "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() +
-                                                "is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
+                                    s_logger.info(msg);
+                                    if (tmplt.getState() == VirtualMachineTemplate.State.NotUploaded || tmplt.getState() == VirtualMachineTemplate.State.UploadInProgress) {
+                                        s_logger.info("Template Sync found " + uniqueName + " on image store " + storeId + " uploaded using SSVM as corrupted, marking it as failed");
+                                        tmpltStore.setState(State.Failed);
+                                        try {
+                                            stateMachine.transitTo(tmplt, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
+                                        } catch (NoTransitionException e) {
+                                            s_logger.error("Unexpected state transition exception for template " + tmplt.getName() + ". Details: " + e.getMessage());
+                                        }
+                                    } else if (tmplt.getUrl() == null) {
+                                        msg = "Private template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + " is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
                                         s_logger.warn(msg);
                                     } else {
                                         s_logger.info("Removing template_store_ref entry for corrupted template " + tmplt.getName());
                                         _vmTemplateStoreDao.remove(tmpltStore.getId());
                                         toBeDownloaded.add(tmplt);
                                     }
-
                                 } else {
                                     tmpltStore.setDownloadPercent(100);
                                     tmpltStore.setDownloadState(Status.DOWNLOADED);
@@ -355,6 +363,14 @@ public class TemplateServiceImpl implements TemplateService {
                                     tmlpt.setSize(tmpltInfo.getSize());
                                     _templateDao.update(tmplt.getId(), tmlpt);
 
+                                    if (tmplt.getState() == VirtualMachineTemplate.State.NotUploaded || tmplt.getState() == VirtualMachineTemplate.State.UploadInProgress) {
+                                        try {
+                                            stateMachine.transitTo(tmplt, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
+                                        } catch (NoTransitionException e) {
+                                            s_logger.error("Unexpected state transition exception for template " + tmplt.getName() + ". Details: " + e.getMessage());
+                                        }
+                                    }
+
                                     // Skipping limit checks for SYSTEM Account and for the templates created from volumes or snapshots
                                     // which already got checked and incremented during createTemplate API call.
                                     if (tmpltInfo.getSize() > 0 && tmplt.getAccountId() != Account.ACCOUNT_ID_SYSTEM && tmplt.getUrl() != null) {
@@ -374,9 +390,7 @@ public class TemplateServiceImpl implements TemplateService {
                                 }
                                 _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
                             } else {
-                                tmpltStore =
-                                        new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(),
-                                                tmplt.getUrl());
+                                tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
                                 tmpltStore.setSize(tmpltInfo.getSize());
                                 tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
                                 tmpltStore.setDataStoreRole(store.getRole());
@@ -387,18 +401,28 @@ public class TemplateServiceImpl implements TemplateService {
                                 tmlpt.setSize(tmpltInfo.getSize());
                                 _templateDao.update(tmplt.getId(), tmlpt);
                                 associateTemplateToZone(tmplt.getId(), zoneId);
-
+                            }
+                        } else if (tmplt.getState() == VirtualMachineTemplate.State.NotUploaded || tmplt.getState() == VirtualMachineTemplate.State.UploadInProgress) {
+                            s_logger.info("Template Sync did not find " + uniqueName + " on image store " + storeId + " uploaded using SSVM, marking it as failed");
+                            toBeDownloaded.remove(tmplt);
+                            tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                            String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
+                            tmpltStore.setErrorString(msg);
+                            tmpltStore.setState(State.Failed);
+                            _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
+                            try {
+                                stateMachine.transitTo(tmplt, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
+                            } catch (NoTransitionException e) {
+                                s_logger.error("Unexpected state transition exception for template " + tmplt.getName() + ". Details: " + e.getMessage());
                             }
                         } else {
-                            s_logger.info("Template Sync did not find " + uniqueName + " on image store " + storeId +
-                                    ", may request download based on available hypervisor types");
+                            s_logger.info("Template Sync did not find " + uniqueName + " on image store " + storeId + ", may request download based on available hypervisor types");
                             if (tmpltStore != null) {
                                 if (_storeMgr.isRegionStore(store) && tmpltStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED
                                         && tmpltStore.getState() == State.Ready
                                         && tmpltStore.getInstallPath() == null) {
                                     s_logger.info("Keep fake entry in template store table for migration of previous NFS to object store");
-                                }
-                                else {
+                                } else {
                                     s_logger.info("Removing leftover template " + uniqueName + " entry from template store table");
                                     // remove those leftover entries
                                     _vmTemplateStoreDao.remove(tmpltStore.getId());
@@ -422,7 +446,7 @@ public class TemplateServiceImpl implements TemplateService {
                         availHypers.add(HypervisorType.None); // bug 9809: resume ISO
                         // download.
                         for (VMTemplateVO tmplt : toBeDownloaded) {
-                            if (tmplt.getUrl() == null) { // If url is null we can't
+                            if (tmplt.getUrl() == null) { // If url is null, skip downloading
                                 s_logger.info("Skip downloading template " + tmplt.getUniqueName() + " since no url is specified.");
                                 continue;
                             }
@@ -458,9 +482,7 @@ public class TemplateServiceImpl implements TemplateService {
                     for (String uniqueName : templateInfos.keySet()) {
                         TemplateProp tInfo = templateInfos.get(uniqueName);
                         if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) {
-                            // we cannot directly call deleteTemplateSync here to
-                            // reuse delete logic since in this case, our db does not have
-                            // this template at all.
+                            // we cannot directly call deleteTemplateSync here to reuse delete logic since in this case db does not have this template at all.
                             TemplateObjectTO tmplTO = new TemplateObjectTO();
                             tmplTO.setDataStore(store.getTO());
                             tmplTO.setPath(tInfo.getInstallPath());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc399b98/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index 8c92cfc..814f44a 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -88,6 +88,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
         stateMachines = new StateMachine2<State, Event, DataObjectInStore>();
         stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, State.Creating);
         stateMachines.addTransition(State.Allocated, Event.DestroyRequested, State.Destroying);
+        stateMachines.addTransition(State.Allocated, Event.OperationFailed, State.Failed);
         stateMachines.addTransition(State.Creating, Event.OperationFailed, State.Allocated);
         stateMachines.addTransition(State.Creating, Event.OperationSuccessed, State.Ready);
         stateMachines.addTransition(State.Ready, Event.CopyingRequested, State.Copying);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc399b98/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index b0795ae..436c462 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -1390,7 +1390,7 @@ public class VolumeServiceImpl implements VolumeService {
                     for (VolumeDataStoreVO volumeStore : dbVolumes) {
                         VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId());
                         if (volume == null) {
-                            s_logger.warn("Volume_store_ref shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId +
+                            s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId +
                                     ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
                             volumeStore.setDestroyed(true);
                             _volumeStoreDao.update(volumeStore.getId(), volumeStore);
@@ -1406,20 +1406,23 @@ public class VolumeServiceImpl implements VolumeService {
                             }
                             if (volInfo.isCorrupted()) {
                                 volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
-                                String msg = "Volume " + volume.getUuid() + " is corrupted on image store ";
+                                String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
                                 volumeStore.setErrorString(msg);
-                                s_logger.info("msg");
-                                if (volumeStore.getDownloadUrl() == null) {
-                                    msg =
-                                            "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() +
-                                            "is corrupted, please check in image store: " + volumeStore.getDataStoreId();
+                                s_logger.info(msg);
+                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
+                                    s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as failed");
+                                    _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+                                    // mark volume as failed, so that storage GC will clean it up
+                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                                    volObj.processEvent(Event.OperationFailed);
+                                } else if (volumeStore.getDownloadUrl() == null) {
+                                    msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: " + volumeStore.getDataStoreId();
                                     s_logger.warn(msg);
                                 } else {
                                     s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
                                     _volumeStoreDao.remove(volumeStore.getId());
                                     toBeDownloaded.add(volumeStore);
                                 }
-
                             } else { // Put them in right status
                                 volumeStore.setDownloadPercent(100);
                                 volumeStore.setDownloadState(Status.DOWNLOADED);
@@ -1436,15 +1439,18 @@ public class VolumeServiceImpl implements VolumeService {
                                     _volumeDao.update(volumeStore.getVolumeId(), volume);
                                 }
 
+                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
+                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                                    volObj.processEvent(Event.OperationSuccessed);
+                                }
+
                                 if (volInfo.getSize() > 0) {
                                     try {
                                         _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
                                                 com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize());
                                     } catch (ResourceAllocationException e) {
                                         s_logger.warn(e.getMessage());
-                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(),
-                                                e.getMessage(),
-                                                e.getMessage());
+                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
                                     } finally {
                                         _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
                                                 com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
@@ -1452,11 +1458,21 @@ public class VolumeServiceImpl implements VolumeService {
                                 }
                             }
                             continue;
+                        } else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) { // failed uploads through SSVM
+                            s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
+                            toBeDownloaded.remove(volumeStore);
+                            volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                            String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
+                            volumeStore.setErrorString(msg);
+                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+                            // mark volume as failed, so that storage GC will clean it up
+                            VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                            volObj.processEvent(Event.OperationFailed);
+                            continue;
                         }
                         // Volume is not on secondary but we should download.
                         if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
-                            s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId +
-                                    ", will request download to start/resume shortly");
+                            s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
                             toBeDownloaded.add(volumeStore);
                         }
                     }
@@ -1464,7 +1480,7 @@ public class VolumeServiceImpl implements VolumeService {
                     // Download volumes which haven't been downloaded yet.
                     if (toBeDownloaded.size() > 0) {
                         for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
-                            if (volumeHost.getDownloadUrl() == null) { // If url is null we
+                            if (volumeHost.getDownloadUrl() == null) { // If url is null, skip downloading
                                 s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
                                 continue;
                             }
@@ -1472,8 +1488,7 @@ public class VolumeServiceImpl implements VolumeService {
                             // if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which
                             // means that this is a duplicate entry from migration of previous NFS to staging.
                             if (store.getScope().getScopeType() == ScopeType.REGION) {
-                                if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED
-                                        && volumeHost.getInstallPath() == null) {
+                                if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED && volumeHost.getInstallPath() == null) {
                                     s_logger.info("Skip sync volume for migration of previous NFS to object store");
                                     continue;
                                 }
@@ -1493,9 +1508,7 @@ public class VolumeServiceImpl implements VolumeService {
                         Long uniqueName = entry.getKey();
                         TemplateProp tInfo = entry.getValue();
 
-                        //we cannot directly call expungeVolumeAsync here to
-                        // reuse delete logic since in this case, our db does not have
-                        // this template at all.
+                        // we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
                         VolumeObjectTO tmplTO = new VolumeObjectTO();
                         tmplTO.setDataStore(store.getTO());
                         tmplTO.setPath(tInfo.getInstallPath());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc399b98/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 84b33d2..167f19f 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -303,6 +303,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             } else if (tmpVolume.getState() == Volume.State.UploadInProgress) { // check for timeout
                                 if (System.currentTimeMillis() - tmpVolumeDataStore.getCreated().getTime() > _uploadOperationTimeout) {
                                     tmpVolumeDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+                                    tmpVolumeDataStore.setState(State.Failed);
                                     stateMachine.transitTo(tmpVolume, Event.OperationFailed, null, _volumeDao);
                                     if (s_logger.isDebugEnabled()) {
                                         s_logger.debug("Volume " + tmpVolume.getUuid() + " failed to upload due to operation timed out");
@@ -377,6 +378,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                             } else if (tmpTemplate.getState() == VirtualMachineTemplate.State.UploadInProgress) { // check for timeout
                                 if (System.currentTimeMillis() - tmpTemplateDataStore.getCreated().getTime() > _uploadOperationTimeout) {
                                     tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+                                    tmpTemplateDataStore.setState(State.Failed);
                                     stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
                                     if (s_logger.isDebugEnabled()) {
                                         s_logger.debug("Template " + tmpTemplate.getUuid() + " failed to upload due to operation timed out");


[29/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
test data changes


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

Branch: refs/heads/master
Commit: 3c436775d3dd171608495718d6b179e51af1a63d
Parents: 98306c3
Author: sailajamada <sa...@citrix.com>
Authored: Thu Mar 26 10:18:47 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Thu Mar 26 10:18:47 2015 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/config/test_data.py | 336 ++++++++++++++++++---------
 1 file changed, 226 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c436775/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 6373ef5..c1156c4 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -41,6 +41,15 @@ test_data = {
             "name": "Project",
         "displaytext": "Test project"
     },
+    "publiciprange": {
+        "gateway": "",
+        "netmask": "",
+        "startip": "",
+        "endip": "",
+        "forvirtualnetwork": "true",
+        "vlan": "",
+        "zoneid": ""
+    },
     "private_gateway": {
        "ipaddress": "172.16.1.2",
        "gateway": "172.16.1.1",
@@ -62,14 +71,6 @@ test_data = {
         "username": "test-account2",
         "password": "password"
     },
-    "vmware_cluster" : {
-            "hypervisor": 'VMware',
-            "clustertype": 'ExternalManaged',
-            "username": 'administrator',
-            "password": 'password_123',
-            "url": 'http://10.147.60.15/42xescauto spaces/42xesc Clusters',
-            "clustername": 'VMWare Cluster with Space in DC name',
-        },
     "small": {
         "displayname": "testserver",
         "username": "root",
@@ -94,8 +95,8 @@ test_data = {
         "name": "Tiny Instance",
         "displaytext": "Tiny Instance",
         "cpunumber": 1,
-        "cpuspeed": 100,  # in MHz
-        "memory": 128,  # In MBs
+        "cpuspeed": 256,  # in MHz
+        "memory": 256,  # In MBs
     },
     "service_offerings": {
         "name": "Tiny Instance",
@@ -190,24 +191,23 @@ test_data = {
         },
     },
     "nw_off_isolated_netscaler": {
-        "name": "Network offering-ns services",
-        "displaytext": "Network offering-ns services",
-        "guestiptype": "Isolated",
-        "supportedservices":
-        "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat",
-        "traffictype": "GUEST",
-        "availability": "Optional'",
-        "serviceProviderList": {
-            "Dhcp": "VirtualRouter",
-            "Dns": "VirtualRouter",
-            "SourceNat": "VirtualRouter",
-            "PortForwarding": "VirtualRouter",
-            "Vpn": "VirtualRouter",
-            "Firewall": "VirtualRouter",
-            "Lb": "NetScaler",
-            "UserData": "VirtualRouter",
-            "StaticNat": "VirtualRouter"
-        }
+                "name": 'Netscaler',
+                "displaytext": 'Netscaler',
+                "guestiptype": 'Isolated',
+                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+                "traffictype": 'GUEST',
+                "availability": 'Optional',
+                "serviceProviderList": {
+                    "Dhcp": 'VirtualRouter',
+                    "Dns": 'VirtualRouter',
+                    "SourceNat": 'VirtualRouter',
+                    "PortForwarding": 'VirtualRouter',
+                    "Vpn": 'VirtualRouter',
+                    "Firewall": 'VirtualRouter',
+                    "Lb": 'Netscaler',
+                    "UserData": 'VirtualRouter',
+                    "StaticNat": 'VirtualRouter',
+                },
     },
     "nw_off_isolated_persistent": {
         "name": 'Test Nw off isolated persistent',
@@ -323,7 +323,21 @@ test_data = {
         "affinity": {
             "name": "webvms",
             "type": "host anti-affinity",
+        }
+    },
+    "virtual_machine_userdata": {
+        "displayname": "Test VM",
+        "username": "root",
+        "password": "password",
+        "ssh_port": 22,
+        "privateport": 22,
+        "publicport": 22,
+        "protocol": "TCP",
+        "affinity": {
+            "name": "webvms",
+            "type": "host anti-affinity",
         },
+        "userdata": "This is sample data"
     },
     "virtual_machine2": {
         "name": "testvm2",
@@ -772,6 +786,11 @@ test_data = {
         "mode": "HTTP_DOWNLOAD",
         "templatefilter": "self"
     },
+    "volume_from_snapshot": {
+        "diskname": 'Volume from snapshot',
+        "size": "1",
+        "zoneid": ""
+    },
     "templatefilter": 'self',
     "templates": {
         "displaytext": 'Template',
@@ -809,6 +828,13 @@ test_data = {
         "endport": "22",
         "cidrlist": "0.0.0.0/0"
     },
+    "ingress_rule_ICMP": {
+        "name": 'ICMP',
+        "protocol": 'ICMP',
+        "startport": -1,
+        "endport": -1,
+        "cidrlist": '0.0.0.0/0',
+    },
     "vpncustomergateway": {
             "ipsecpsk": "secreatKey",
             "ikepolicy": "aes128-sha1",
@@ -817,13 +843,20 @@ test_data = {
             "epslifetime": "3600",
             "dpd": "false"
     },
+    "vlan_ip_range": {
+                "startip": "",
+                "endip": "",
+                "netmask": "",
+                "gateway": "",
+                "forvirtualnetwork": "false",
+                "vlan": "untagged",
+    },
     "ostype": "CentOS 5.6 (64-bit)",
     "sleep": 90,
     "timeout": 10,
     "page": 1,
     "pagesize": 2,
     "listall": 'true',
-    "host_password": "password",
     "advanced_sg": {
         "zone": {
             "name": "",
@@ -848,66 +881,36 @@ test_data = {
         "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1",
         "name": "Primary iSCSI"
     },
-    "volume": {"diskname": "Test Volume"},
+    "volume": {"diskname": "Test Volume",
+               "size": 1
+    },
+    "volume_write_path": {
+        "diskname": "APP Data Volume",
+        "size": 1,   # in GBs
+        "xenserver": {"rootdiskdevice":"/dev/xvda",
+                     "datadiskdevice_1": '/dev/xvdb',
+                    "datadiskdevice_2": '/dev/xvdc',   # Data Disk
+                    },
+        "KVM":       {"rootdiskdevice": "/dev/vda",
+                    "datadiskdevice_1": "/dev/vdb",
+                    "datadiskdevice_2": "/dev/vdc"
+                    },
+        "vmware":    {"rootdiskdevice": "/dev/hda",
+                    "datadiskdevice_1": "/dev/hdb",
+                    "datadiskdevice_2": "/dev/hdc"
+                    }
+    },
+    "data_write_paths": {
+                "mount_dir": "/mnt/tmp",
+                "sub_dir": "test",
+                "sub_lvl_dir1": "test1",
+                "sub_lvl_dir2": "test2",
+                "random_data": "random.data",
+    },
     "custom_volume": {
         "customdisksize": 1,
         "diskname": "Custom disk",
     },
-    "upload_volume": {
-        "diskname": "UploadVol",
-        "format": "VHD",
-        "url":
-        "http://10.147.28.7/templates/393d3550-05ef-330f-9b8c-745b0e699759.vhd",
-        "checksum": "",
-    },
-    "browser_upload_volume":{
-          "VHD": {
-        "diskname": "XenUploadVol",
-        "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
-        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
-                },
-          "OVA": {
-        "diskname": "VMwareUploadVol",
-        "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
-        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
-                },
-          "QCOW2": {
-        "diskname": "KVMUploadVol",
-        "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
-        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
-                },
-    'browser_resized_disk_offering': {
-        "displaytext": "Resizeddisk",
-        "name": "Resizeddisk",
-        "disksize": 3,
-    }
-},
-    "browser_upload_template": {
-          "VHD": {
-        "templatename": "XenUploadtemplate",
-        "displaytext": "XenUploadtemplate",
-        "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
-        "hypervisor":"XenServer",
-        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
-        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
-                },
-          "OVA": {
-        "templatename": "VMwareUploadtemplate",
-        "displaytext": "VMwareUploadtemplate",
-        "url": "http://nfs1.lab.vmops.com/templates/vmware/CentOS5.3-x86_64.ova",
-        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
-        "hypervisor":"VMware",
-        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
-                },
-          "QCOW2": {
-        "templatename": "KVMUploadtemplate",
-        "displaytext": "VMwareUploadtemplate",
-        "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
-        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
-        "hypervisor":"KVM",
-        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
-                },
-                              },
     "recurring_snapshot": {
         "maxsnaps": 2,
         "timezone": "US/Arizona",
@@ -961,13 +964,6 @@ test_data = {
     "forvirtualnetwork": "true",
     "customdisksize": 1,
     "diskname": "Test Volume",
-    "portableIpRange": {
-        "gateway": "10.223.252.195",
-        "netmask": "255.255.255.192",
-        "startip": "10.223.252.196",
-        "endip": "10.223.252.197",
-        "vlan": "1001"
-    },
     "sparse": {
         "name": "Sparse Type Disk offering",
         "displaytext":
@@ -1419,24 +1415,6 @@ test_data = {
                 },
                 "ostype": 'CentOS 5.6 (64-bit)',
         },
-        "ldap_account": {
-            "email": "rmurphy@cloudstack.org",
-            "firstname": "Ryan",
-            "lastname": "Murphy",
-            "username": "rmurphy",
-            "password": "internalcloudstackpassword",
-            },
-        "ldapConfiguration_1": {
-            "basedn": "dc=cloudstack,dc=org",
-            "emailAttribute": "mail",
-            "userObject": "inetOrgPerson",
-            "usernameAttribute": "uid",
-            "hostname": "localhost",
-            "port": "10389",
-            "ldapUsername": "rmurphy",
-            "ldapPassword": "password"
-            },
-
       "test_34_DeployVM_in_SecondSGNetwork": {
           "zone": "advsg",
           "config": "D:\ACS-Repo\setup\dev\\advancedsg.cfg",#Absolute path to cfg file
@@ -1467,4 +1445,142 @@ test_data = {
               }
           ]
       },
+    "configurableData":
+    {
+        "portableIpRange": {
+            "gateway": "10.223.59.1",
+            "netmask": "255.255.255.0",
+            "startip": "10.223.59.200",
+            "endip": "10.223.59.240",
+            "vlan": "1000"
+        },
+        "netscaler": {
+            "ipaddress": "",
+            "username": "",
+            "password": "",
+            "networkdevicetype": "",
+            "publicinterface": "",
+            "privateinterface": "",
+            "numretries": "",
+            "lbdevicededicated": "False",
+            "lbdevicecapacity": 2,
+            "port": 22
+        },
+        "iscsi": {
+            "url": "",
+            "name": "Primary iSCSI"
+        },
+        "host": {
+                 "publicport": 22,
+                 "username": "root",
+                 "password": "password",
+        },
+       "ldap_account": {
+            "email": "",
+            "firstname": "",
+            "lastname": "",
+            "username": "",
+            "password": "",
+        },
+        "ldap_configuration": {
+            "basedn": "",
+            "emailAttribute": "",
+            "userObject": "",
+            "usernameAttribute": "",
+            "hostname": "",
+            "port": "",
+            "ldapUsername": "",
+            "ldapPassword": ""
+        },
+        "systemVmDelay": 120,
+	"setUsageConfigurationThroughTestCase": False,
+	"vmware_cluster" : {
+            "hypervisor": 'VMware',
+            "clustertype": 'ExternalManaged',
+            "username": '',
+            "password": '',
+            "url": '',
+            "clustername": 'VMWare Cluster with Space in DC name',
+        },
+        "upload_volume": {
+            "diskname": "UploadVol",
+            "format": "VHD",
+            "url":"http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2",
+            "checksum": "",
+        },
+    "browser_upload_volume":{
+          "VHD": {
+        "diskname": "XenUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
+        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
+                },
+          "OVA": {
+        "diskname": "VMwareUploadVol",
+        "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
+        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
+                },
+          "QCOW2": {
+        "diskname": "KVMUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
+        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
+                },
+    'browser_resized_disk_offering': {
+        "displaytext": "Resizeddisk",
+        "name": "Resizeddisk",
+        "disksize": 3,
+    }
+},
+    "browser_upload_template": {
+          "VHD": {
+        "templatename": "XenUploadtemplate",
+        "displaytext": "XenUploadtemplate",
+        "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
+        "hypervisor":"XenServer",
+        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
+        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
+                },
+          "OVA": {
+        "templatename": "VMwareUploadtemplate",
+        "displaytext": "VMwareUploadtemplate",
+        "url": "http://nfs1.lab.vmops.com/templates/vmware/CentOS5.3-x86_64.ova",
+        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
+        "hypervisor":"VMware",
+        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
+                },
+          "QCOW2": {
+        "templatename": "KVMUploadtemplate",
+        "displaytext": "VMwareUploadtemplate",
+        "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
+        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
+        "hypervisor":"KVM",
+        "ostypeid":"2e02e376-cdf3-11e4-beb3-8aa6272b57ef"
+                },
+                              },
+        "bootableIso":
+                {
+                    "displaytext": "Test Bootable ISO",
+                    "name": "testISO",
+                    "bootable": True,
+                    "ispublic": False,
+                    "url": "http://10.147.40.145/ISO/CentOS-6.3-x86_64-bin-DVD1.iso",
+                    "ostype": 'CentOS 6.3 (64-bit)',
+                    "mode": 'HTTP_DOWNLOAD'
+        },
+     "setHostConfigurationForIngressRule": False,
+     "vmxnet3template": {
+            "displaytext": "VMXNET3 Template",
+            "name": "VMXNET3 template",
+            "ostype": "CentOS 5.6 (64-bit)",
+            "isfeatured": True,
+            "ispublic": False,
+            "isextractable": True,
+            "mode": "HTTP_DOWNLOAD",
+            "templatefilter": "self",
+            "url": "http://10.147.28.7/templates/4.3.0.2/systemvm64template-2014-09-30-4.3-vmware.ova",
+            "hypervisor": "vmware",
+            "format": "OVA",
+            "nicadapter": "vmxnet3"
+        }
+    }
 }
+


[18/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
handling tcp close event in netty server

while the file is in uploading state and connection is reset by peer,
volume upload request posted again shows the upload is IN_Progress
state. marking them as errored


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

Branch: refs/heads/master
Commit: 6b8b4b92e6d5ec36d4b976e81083f72ae17245a3
Parents: 7d1ca8a
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Tue Mar 17 15:17:33 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Mar 17 15:21:25 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/storage/resource/HttpUploadServerHandler.java  | 7 +++++++
 .../storage/resource/NfsSecondaryStorageResource.java         | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b8b4b92/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
index 7a17ef1..0caee32 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
@@ -95,6 +95,13 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
     }
 
     @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        String message = "file receive failed or connection closed prematurely.";
+        logger.error(message);
+        storageResource.updateStateMapWithError(uuid, message);
+    }
+
+    @Override
     public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
         if (msg instanceof HttpRequest) {
             HttpRequest request = this.request = (HttpRequest) msg;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b8b4b92/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index d10242c..1bce4a0 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -2774,7 +2774,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         return _ssvmPSK;
     }
 
-    private void updateStateMapWithError(String uuid,String errorMessage) {
+    public void updateStateMapWithError(String uuid,String errorMessage) {
         UploadEntity uploadEntity=null;
         if (uploadEntityStateMap.get(uuid)!=null) {
             uploadEntity=uploadEntityStateMap.get(uuid);


[11/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Test Automation Scripts for Browser Bases Upload volumes and templates with testdata config changes


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

Branch: refs/heads/master
Commit: db7964fb11842ef008464e42e715838cbe46e72d
Parents: 24a8483
Author: sailajamada <sa...@citrix.com>
Authored: Tue Mar 10 21:39:55 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Tue Mar 10 21:39:55 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_templates.py          | 1324 ++++++++++++++++++
 .../component/test_browse_volumes.py            |  115 +-
 tools/marvin/marvin/config/test_data.py         |   22 +-
 3 files changed, 1449 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/db7964fb/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
new file mode 100644
index 0000000..9b1eda0
--- /dev/null
+++ b/test/integration/component/test_browse_templates.py
@@ -0,0 +1,1324 @@
+# 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.
+""" P1 tests for Browser Based Upload Volumes
+"""
+# Import Local Modules
+
+import marvin
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import cloudstackTestCase, unittest
+from marvin.cloudstackAPI import *
+from marvin.lib.utils import *
+from marvin.lib.base import *
+from marvin.lib.common import *
+from marvin.codes import PASS,FAILED,SUCCESS,XEN_SERVER
+
+from marvin.sshClient import SshClient
+
+import requests
+
+import wget
+
+import random
+
+import string
+
+import telnetlib
+import os
+import urllib
+import time
+import tempfile
+_multiprocess_shared_ = True
+
+class TestBrowseUploadVolume(cloudstackTestCase):
+
+    """
+    Testing Browse Upload Volume Feature
+    """
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestBrowseUploadVolume,cls).getClsTestClient()
+        #print cls.testClient.getParsedTestDataConfig()
+        cls.testdata = cls.testClient.getParsedTestDataConfig()
+        cls.apiclient = cls.testClient.getApiClient()
+        cls.hypervisor = cls.testClient.getHypervisorInfo()
+        cls._cleanup = []
+        cls.cleanup = []
+        cls.uploadtemplateformat="VHD"
+        cls.storagetype = 'shared'
+
+        hosts = list_hosts(
+            cls.apiclient,
+            type="Routing"
+        )
+
+        if hosts is None:
+            raise unittest.SkipTest(
+                "There are no hypervisor's available.Check listhosts response")
+        for hypervisorhost in hosts :
+                 if hypervisorhost.hypervisor == "XenServer":
+                     cls.uploadtemplateformat="VHD"
+                     break
+                 elif hypervisorhost.hypervisor== "VMware":
+                     cls.uploadtemplateformat="OVA"
+                     break
+                 elif hypervisorhost.hypervisor=="KVM":
+                     cls.uploadtemplateformat="QCOW2"
+                     break
+                 else:
+                     break
+
+        cls.uploadurl=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["url"]
+        cls.templatename=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["templatename"]
+        cls.md5sum=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["checksum"]
+        cls.templatedisplaytext=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["displaytext"]
+        cls.templatehypervisor=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["hypervisor"]
+        cls.templateostypeid=cls.testdata["browser_upload_template"][cls.uploadtemplateformat]["ostypeid"]
+        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
+        cls.domain = get_domain(cls.apiclient)
+        cls.pod = get_pod(cls.apiclient, cls.zone.id)
+
+        cls.account = Account.create(
+            cls.apiclient,
+            cls.testdata["account"],
+            domainid=cls.domain.id
+        )
+
+        cls.template = get_template(
+            cls.apiclient,
+            cls.zone.id)
+
+        if cls.template == FAILED:
+                raise unittest.SkipTest(
+                    "Check for default cent OS template readiness ")
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient, 
+            cls.testdata["service_offering"]
+        )
+        cls.disk_offering = DiskOffering.create(
+            cls.apiclient,
+            cls.testdata["browser_upload_volume"]["browser_resized_disk_offering"],
+            custom=True
+        )
+        cls._cleanup = [
+            cls.account,
+            cls.service_offering,
+            cls.disk_offering
+        ]
+
+
+
+    def __verify_values(self, expected_vals, actual_vals):
+
+        return_flag = True
+
+        if len(expected_vals) != len(actual_vals):
+            return False
+
+        keys = expected_vals.keys()
+        for i in range(0, len(expected_vals)):
+            exp_val = expected_vals[keys[i]]
+            act_val = actual_vals[keys[i]]
+            if exp_val == act_val:
+                return_flag = return_flag and True
+            else:
+                return_flag = return_flag and False
+                self.debug(
+                    "expected Value: %s, is not matching with actual value:\
+                    %s" %
+                    (exp_val, act_val))
+        return return_flag
+
+    def validate_uploaded_template(self,up_templateid,templatestate):
+
+        list_template_response = Template.list(
+                    self.apiclient,
+                    id=up_templateid
+                )
+        self.assertNotEqual(
+                    list_volume_response,
+                    None,
+                    "Check if template exists in ListTemplates"
+                )
+
+        self.assertEqual(
+                    list_template_response[0].state,
+                    templatestate,
+                    "Check template state in List templates"
+                )
+
+    def browse_upload_template(self):
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+        cmd.ostypeid=self.templateostypeid
+        #cmd.type="template"
+        getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        self.validate_uploaded_template(getuploadparamsresponce.id,'Uploaded')
+
+        return(getuploadparamsresponce)
+
+    def uploadtemplate(self):
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.zoneid = self.zone.id
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+        cmd.ostypeid=self.templateostypeid
+        #cmd.type="template"
+        getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+        time.sleep(60)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        return(getuploadparamsresponce)
+
+    def multiple_browse_upload_template(self):
+
+        templ1=self.uploadtemplate()
+        templ2=self.uploadtemplate()
+        templ3=self.uploadtemplate()
+        self.validate_uploaded_template(templ1.id,'Uploaded')
+        self.validate_uploaded_template(templ2.id,'Uploaded')
+        self.validate_uploaded_template(templ3.id,'Uploaded')
+        return
+
+    def validate_vm(self,vmdetails,vmstate):
+
+        time.sleep(120 )
+        vm_response = VirtualMachine.list(
+                self.apiclient,
+                id=vmdetails.id,
+            )
+        self.assertEqual(
+                isinstance(vm_response, list),
+                True,
+                "Check list VM response for valid list"
+            )
+
+            # Verify VM response to check whether VM deployment was successful
+        self.assertNotEqual(
+                len(vm_response),
+                0,
+                "Check VMs available in List VMs response"
+            )
+
+        deployedvm = vm_response[0]
+        self.assertEqual(
+                deployedvm.state,
+                vmstate,
+                "Check the state of VM"
+            )
+
+    def deploy_vm(self,template):
+            virtual_machine = VirtualMachine.create(
+                                                    self.apiclient,
+                                                    self.testdata["virtual_machine"],
+                                                    templateid=template.id,
+                                                    zoneid=self.zone.id,
+                                                    accountid=self.account.name,
+                                                    domainid=self.account.domainid,
+                                                    serviceofferingid=self.service_offering.id,
+                                                )
+            self.validate_vm(virtual_machine,'Running')
+            return(virtual_machine)
+
+    def attach_volume(self,vmlist,volid):
+
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=volid
+                )
+        print list_volume_response[0]
+        vmlist.attach_volume(
+                    self.apiclient,
+                    list_volume_response[0]
+                )
+        list_volume_response = Volume.list(
+                self.apiclient,
+                virtualmachineid=vmlist.id,
+                type='DATADISK',
+                listall=True
+            )
+        self.assertNotEqual(
+                list_volume_response,
+                None,
+                "Check if volume exists in ListVolumes")
+        self.assertEqual(
+                isinstance(list_volume_response, list),
+                True,
+                "Check list volumes response for valid list")
+        self.validate_uploaded_volume(volid,'Ready')
+
+
+    def reboot_vm(self,vmdetails):
+        vmdetails.reboot(self.apiclient)
+        self.validate_vm(vmdetails,'Running')
+
+    def stop_vm(self,vmdetails):
+        vmdetails.stop(self.apiclient)
+        self.validate_vm(vmdetails,'Stopped')
+
+    def start_vm(self,vmdetails):
+        vmdetails.start(self.apiclient)
+        self.validate_vm(vmdetails,'Running')
+
+    def vmoperations(self,vmdetails):
+        self.reboot_vm(vmdetails)
+
+        self.stop_vm(vmdetails)
+
+        self.start_vm(vmdetails)
+
+
+    def detach_volume(self,vmdetails,volid):
+        """Detach a Volume attached to a VM
+        """
+        list_volume_response = Volume.list(
+                    self.apiclient,
+                    id=volid
+                )
+        print list_volume_response[0]
+        vmdetails.detach_volume(self.apiclient,list_volume_response[0])
+
+        # Sleep to ensure the current state will reflected in other calls
+        time.sleep(self.testdata["sleep"])
+
+        list_volume_response = Volume.list(
+            self.apiclient,
+            id=volid
+        )
+        self.assertNotEqual(
+            list_volume_response,
+            None,
+            "Check if volume exists in ListVolumes"
+        )
+        self.assertEqual(
+            isinstance(list_volume_response, list),
+            True,
+            "Check list volumes response for valid list"
+        )
+        volume = list_volume_response[0]
+        self.assertEqual(
+            volume.virtualmachineid,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+
+        self.assertEqual(
+            volume.vmname,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+        return
+
+
+    def restore_vm(self,vmdetails):
+        #TODO: SIMENH: add another test the data on the restored VM.
+        """Test recover Virtual Machine
+        """
+
+        #cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
+        cmd = restoreVirtualMachine.restoreVirtualMachineCmd()
+        cmd.virtualmachineid = vmdetails.id
+        self.apiclient.recoverVirtualMachine(cmd)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Running",
+                            "Check virtual machine is in Running state"
+                        )
+
+        return
+
+    def deletevolume(self,volumeid):
+        """Delete a Volume attached to a VM
+        """
+
+        cmd = deleteVolume.deleteVolumeCmd()
+        cmd.id = volumeid
+
+        self.apiclient.deleteVolume(cmd)
+
+        list_volume_response = Volume.list(
+                                            self.apiclient,
+                                            id=volumeid,
+                                            type='DATADISK'
+                                            )
+        self.assertEqual(
+                        list_volume_response,
+                        None,
+                        "Check if volume exists in ListVolumes"
+                    )
+        return
+
+
+    def destroy_vm(self,vmdetails):
+
+        vmdetails.delete(self.apiclient, expunge=False)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Destroyed",
+                            "Check virtual machine is in destroyed state"
+                        )
+        return
+
+
+    def recover_destroyed_vm(self,vmdetails):
+
+        cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
+        cmd.id = vmdetails.id
+        self.apiclient.recoverVirtualMachine(cmd)
+
+        list_vm_response = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        self.assertEqual(
+                            isinstance(list_vm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_vm_response),
+                            0,
+                            "Check VM available in List Virtual Machines"
+                        )
+
+        self.assertEqual(
+                            list_vm_response[0].state,
+                            "Stopped",
+                            "Check virtual machine is in Stopped state"
+                        )
+
+        return
+
+    def expunge_vm(self,vmdetails):
+
+        self.debug("Expunge VM-ID: %s" % vmdetails.id)
+
+        cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
+        cmd.id = vmdetails.id
+        self.apiclient.destroyVirtualMachine(cmd)
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='expunge.delay'
+                                     )
+
+        expunge_delay = int(config[0].value)
+        time.sleep(expunge_delay * 2)
+
+        #VM should be destroyed unless expunge thread hasn't run
+        #Wait for two cycles of the expunge thread
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='expunge.interval'
+                                     )
+        expunge_cycle = int(config[0].value)
+        wait_time = expunge_cycle * 4
+        while wait_time >= 0:
+            list_vm_response = VirtualMachine.list(
+                                                self.apiclient,
+                                                id=vmdetails.id
+                                                )
+            if not list_vm_response:
+                break
+            self.debug("Waiting for VM to expunge")
+            time.sleep(expunge_cycle)
+            wait_time = wait_time - expunge_cycle
+
+        self.debug("listVirtualMachines response: %s" % list_vm_response)
+
+        self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response")
+        return
+
+
+    def waitForSystemVMAgent(self, vmname):
+        timeout = self.testdata["timeout"]
+
+        while True:
+            list_host_response = list_hosts(
+                                                 self.apiclient,
+                                                 name=vmname
+                                                )
+
+            if list_host_response and list_host_response[0].state == 'Up':
+                break
+
+            if timeout == 0:
+                raise Exception("Timed out waiting for SSVM agent to be Up")
+
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+
+    def ssvm_internals(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        self.debug("Running SSVM check script")
+
+        if self.hypervisor.lower() in ('vmware', 'hyperv'):
+            #SSH into SSVMs is done via management server for Vmware and Hyper-V
+            result = get_process_status(
+                                self.apiclient.connection.mgtSvr,
+                                22,
+                                self.apiclient.connection.user,
+                                self.apiclient.connection.passwd,
+                                ssvm.privateip,
+                                "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL",
+                                hypervisor=self.hypervisor
+                                )
+        else:
+            try:
+                host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
+                result = get_process_status(
+                                    host.ipaddress,
+                                    22,
+                                    host.user,
+                                    host.passwd,
+                                    ssvm.linklocalip,
+                                    "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL"
+                                )
+            except KeyError:
+                self.skipTest("Marvin configuration has no host credentials to check router services")
+        res = str(result)
+        self.debug("SSVM script output: %s" % res)
+
+        self.assertEqual(
+                            res.count("ERROR"),
+                            1,
+                            "Check for Errors in tests"
+                        )
+
+        self.assertEqual(
+                            res.count("WARNING"),
+                            1,
+                            "Check for warnings in tests"
+                        )
+
+        #Check status of cloud service
+        if self.hypervisor.lower() in ('vmware', 'hyperv'):
+            #SSH into SSVMs is done via management server for Vmware and Hyper-V
+            result = get_process_status(
+                                self.apiclient.connection.mgtSvr,
+                                22,
+                                self.apiclient.connection.user,
+                                self.apiclient.connection.passwd,
+                                ssvm.privateip,
+                                "service cloud status",
+                                hypervisor=self.hypervisor
+                                )
+        else:
+            try:
+                host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
+                result = get_process_status(
+                                    host.ipaddress,
+                                    22,
+                                    host.user,
+                                    host.passwd,
+                                    ssvm.linklocalip,
+                                    "service cloud status"
+                                    )
+            except KeyError:
+                self.skipTest("Marvin configuration has no host credentials to check router services")
+        res = str(result)
+        self.debug("Cloud Process status: %s" % res)
+        # cloud.com service (type=secstorage) is running: process id: 2346
+        self.assertEqual(
+                            res.count("is running"),
+                            1,
+                            "Check cloud service is running or not"
+                        )
+        return
+
+    def list_sec_storage_vm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        #Verify SSVM response
+        self.assertNotEqual(
+                            len(list_ssvm_response),
+                            0,
+                            "Check list System VMs response"
+                        )
+
+        list_zones_response = list_zones(self.apiclient)
+        
+        self.assertEqual(
+                            isinstance(list_zones_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+
+        self.debug("Number of zones: %s" % len(list_zones_response))
+        self.debug("Number of SSVMs: %s" % len(list_ssvm_response))
+        # Number of Sec storage VMs = No of Zones
+        self.assertEqual(
+                            len(list_ssvm_response),
+                            len(list_zones_response),
+                            "Check number of SSVMs with number of zones"
+                        )
+        #For each secondary storage VM check private IP,
+        #public IP, link local IP and DNS
+        for ssvm in list_ssvm_response:
+
+            self.debug("SSVM state: %s" % ssvm.state)
+            self.assertEqual(
+                            ssvm.state,
+                            'Running',
+                            "Check whether state of SSVM is running"
+                        )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'privateip'),
+                            True,
+                            "Check whether SSVM has private IP field"
+                            )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'linklocalip'),
+                            True,
+                            "Check whether SSVM has link local IP field"
+                            )
+
+            self.assertEqual(
+                            hasattr(ssvm, 'publicip'),
+                            True,
+                            "Check whether SSVM has public IP field"
+                            )
+
+            #Fetch corresponding ip ranges information from listVlanIpRanges
+            ipranges_response = list_vlan_ipranges(
+                                                   self.apiclient,
+                                                   zoneid=ssvm.zoneid
+                                                   )
+            self.assertEqual(
+                            isinstance(ipranges_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+            iprange = ipranges_response[0]
+            
+            #Fetch corresponding Physical Network of SSVM's Zone
+            listphyntwk = PhysicalNetwork.list(
+                            self.apiclient,
+                            zoneid=ssvm.zoneid
+                            )
+            
+            # Execute the following assertion in all zones except EIP-ELB Zones
+            if not (self.zone.networktype.lower() == 'basic' and isinstance(NetScaler.list(self.apiclient,physicalnetworkid=listphyntwk[0].id), list) is True):
+                self.assertEqual(
+                            ssvm.gateway,
+                            iprange.gateway,
+                            "Check gateway with that of corresponding ip range"
+                            )
+
+            #Fetch corresponding zone information from listZones
+            zone_response = list_zones(
+                                       self.apiclient,
+                                       id=ssvm.zoneid
+                                       )
+            self.assertEqual(
+                            isinstance(zone_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+            self.assertEqual(
+                            ssvm.dns1,
+                            zone_response[0].dns1,
+                            "Check DNS1 with that of corresponding zone"
+                            )
+
+            self.assertEqual(
+                            ssvm.dns2,
+                            zone_response[0].dns2,
+                            "Check DNS2 with that of corresponding zone"
+                            )
+        return
+
+    def stop_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        self.debug("Stopping SSVM: %s" % ssvm.id)
+        cmd = stopSystemVm.stopSystemVmCmd()
+        cmd.id = ssvm.id
+        self.apiclient.stopSystemVm(cmd)
+        
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        id=ssvm.id
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+        
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm_response = list_ssvm_response[0]
+        self.debug("SSVM state after debug: %s" % ssvm_response.state)
+        self.assertEqual(
+                        ssvm_response.state,
+                        'Running',
+                        "Check whether SSVM is running or not"
+                        )
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        # Call above tests to ensure SSVM is properly running
+        self.list_sec_storage_vm()
+
+
+    def reboot_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+    
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        
+        ssvm_response = list_ssvm_response[0]
+
+        hosts = list_hosts(
+                           self.apiclient,
+                           id=ssvm_response.hostid
+                           )
+        self.assertEqual(
+                            isinstance(hosts, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        host = hosts[0]
+
+        #Store the public & private IP values before reboot
+        old_public_ip = ssvm_response.publicip
+        old_private_ip = ssvm_response.privateip
+
+        self.debug("Rebooting SSVM: %s" % ssvm_response.id)
+        cmd = rebootSystemVm.rebootSystemVmCmd()
+        cmd.id = ssvm_response.id
+        self.apiclient.rebootSystemVm(cmd)
+
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        id=ssvm_response.id
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+        ssvm_response = list_ssvm_response[0]
+        self.debug("SSVM State: %s" % ssvm_response.state)
+        self.assertEqual(
+                        'Running',
+                        str(ssvm_response.state),
+                        "Check whether CPVM is running or not"
+                        )
+
+        self.assertEqual(
+                    ssvm_response.publicip,
+                    old_public_ip,
+                    "Check Public IP after reboot with that of before reboot"
+                    )
+
+        self.assertEqual(
+                    ssvm_response.privateip,
+                    old_private_ip,
+                    "Check Private IP after reboot with that of before reboot"
+                    )
+
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        return
+
+    def destroy_ssvm(self):
+
+        list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        systemvmtype='secondarystoragevm',
+                                        state='Running',
+                                        zoneid=self.zone.id
+                                        )
+        self.assertEqual(
+                            isinstance(list_ssvm_response, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+        ssvm_response = list_ssvm_response[0]
+
+        old_name = ssvm_response.name
+
+        self.debug("Destroying SSVM: %s" % ssvm_response.id)
+        cmd = destroySystemVm.destroySystemVmCmd()
+        cmd.id = ssvm_response.id
+        self.apiclient.destroySystemVm(cmd)
+
+        timeout = self.testdata["timeout"]
+        while True:
+            list_ssvm_response = list_ssvms(
+                                        self.apiclient,
+                                        zoneid=self.zone.id,
+                                        systemvmtype='secondarystoragevm'
+                                        )
+            if isinstance(list_ssvm_response, list):
+                if list_ssvm_response[0].state == 'Running':
+                    break
+            if timeout == 0:
+                raise Exception("List SSVM call failed!")
+            
+            time.sleep(self.testdata["sleep"])
+            timeout = timeout - 1
+
+        ssvm_response = list_ssvm_response[0]
+
+        # Verify Name, Public IP, Private IP and Link local IP
+        # for newly created SSVM
+        self.assertNotEqual(
+                        ssvm_response.name,
+                        old_name,
+                        "Check SSVM new name with name of destroyed SSVM"
+                        )
+        self.assertEqual(
+                        hasattr(ssvm_response, 'privateip'),
+                        True,
+                        "Check whether SSVM has private IP field"
+                        )
+
+        self.assertEqual(
+                        hasattr(ssvm_response, 'linklocalip'),
+                        True,
+                        "Check whether SSVM has link local IP field"
+                        )
+
+        self.assertEqual(
+                        hasattr(ssvm_response, 'publicip'),
+                        True,
+                        "Check whether SSVM has public IP field"
+                        )
+        
+        # Wait for the agent to be up
+        self.waitForSystemVMAgent(ssvm_response.name)
+
+        return
+
+    def create_data_volume(self):
+
+        diskoffering = DiskOffering.list(self.apiclient)
+        self.assertTrue(
+            isinstance(
+                diskoffering,
+                list),
+            msg="DiskOffering list is not a list?")
+        self.assertTrue(
+            len(diskoffering) > 0,
+            "no disk offerings in the deployment")
+
+        vol = Volume.create(
+            self.apiclient,
+            services=self.testdata["volume"],
+            zoneid=self.zone.id,
+            account=self.account.name,
+            domainid=self.domain.id,
+            diskofferingid=diskoffering[0].id
+        )
+        self.assertTrue(
+            vol is not None, "volume creation fails in domain %s as user %s" %
+            (self.domain.name, self.account.name))
+
+        listed_vol = Volume.list(self.apiclient, id=vol.id)
+        self.assertTrue(
+            listed_vol is not None and isinstance(
+                listed_vol,
+                list),
+            "invalid response from listVolumes for volume %s" %
+            vol.id)
+        self.assertTrue(
+            listed_vol[0].id == vol.id,
+            "Volume returned by list volumes %s not matching with queried\
+                    volume %s in domain %s" %
+            (listed_vol[0].id,
+                vol.id,
+                self.account.name))
+        return(listed_vol[0])
+
+    def attach_data_volume(self,volume,vmdetails):
+
+        list_volume_response = Volume.list(
+            self.apiclient,
+            id=volume.id
+        )
+        self.assertNotEqual(
+            list_volume_response,
+            None,
+            "Check if volume exists in ListVolumes"
+        )
+        self.assertEqual(
+            isinstance(list_volume_response, list),
+            True,
+            "Check list volumes response for valid list"
+        )
+        volume = list_volume_response[0]
+
+        self.assertEqual(
+            volume.type,
+            'DATADISK',
+            "Check volume type from list volume response"
+        )
+
+        self.assertEqual(
+            hasattr(volume, 'vmname'),
+            True,
+            "Check whether volume has vmname field"
+        )
+        self.assertEqual(
+            hasattr(volume, 'virtualmachineid'),
+            True,
+            "Check whether volume has virtualmachineid field"
+        )
+
+        # Attach volume to VM
+        self.debug("Attach volume: %s to VM: %s" % (
+            volume.id,
+            vmdetails.id
+        ))
+        vmdetails.attach_volume(self.apiclient, volume)
+
+        # Check all volumes attached to same VM
+        list_volume_response = Volume.list(
+            self.apiclient,
+            virtualmachineid=vmdetails.id,
+            type='DATADISK',
+            listall=True
+        )
+        self.assertNotEqual(
+            list_volume_response,
+            None,
+            "Check if volume exists in ListVolumes"
+        )
+        self.assertEqual(
+            isinstance(list_volume_response, list),
+            True,
+            "Check list volumes response for valid list"
+        )
+        volume = list_volume_response[0]
+        self.assertEqual(
+            volume.vmname,
+            vmdetails.name,
+            "Check virtual machine name in list volumes response"
+        )
+        self.assertEqual(
+            volume.virtualmachineid,
+            vmdetails.id,
+            "Check VM ID in list Volume response"
+        )
+        return
+
+
+    def delete_template(self,templatedetails):
+
+        list_template_response = Template.list(
+                                    self.apiclient,
+                                    templatefilter=\
+                                    self.testdata["template"]["templatefilter"],
+                                    id=templatedetails.id,
+                                    zoneid=self.zone.id)
+        self.assertEqual(
+                        isinstance(list_template_response, list),
+                        True,
+                        "Check for list template response return valid list"
+                        )
+
+        self.assertNotEqual(
+                            len(list_template_response),
+                            0,
+                            "Check template available in List Templates"
+                        )
+        template_response = list_template_response[0]
+
+        self.assertEqual(
+                            template_response.id,
+                            templatedetails.id,
+                            "Template id %s in the list is not matching with created template id %s" %
+                            (template_response.id, templatedetails.id)
+                        )
+
+        self.debug("Deleting template: %s" % self.template)
+        # Delete the template
+        templatedetails.delete(self.apiclient)
+        self.debug("Delete template: %s successful" % templatedetails)
+
+        list_template_response = Template.list(
+                                    self.apiclient,
+                                    templatefilter=\
+                                    self.services["template"]["templatefilter"],
+                                    id=templatedetails.id,
+                                    zoneid=self.zone.id
+                                    )
+        self.assertEqual(
+                            list_template_response,
+                            None,
+                            "Check template available in List Templates"
+                        )
+        return
+
+
+
+    def detach_data_volume(self,volume,vmdetails):
+
+        self.debug("Detach volume: %s to VM: %s" % (
+            volume.id,
+            vmdetails.id
+        ))
+        vmdetails.detach_volume(self.apiclient, volume)
+
+        # Sleep to ensure the current state will reflected in other calls
+        time.sleep(self.testdata["sleep"])
+
+        list_volume_response = Volume.list(
+            self.apiclient,
+            id=volume.id
+        )
+        self.assertNotEqual(
+            list_volume_response,
+            None,
+            "Check if volume exists in ListVolumes"
+        )
+        self.assertEqual(
+            isinstance(list_volume_response, list),
+            True,
+            "Check list volumes response for valid list"
+        )
+        volumelist = list_volume_response[0]
+        self.assertEqual(
+            volumelist.virtualmachineid,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+
+        self.assertEqual(
+            volumelist.vmname,
+            None,
+            "Check if volume state (detached) is reflected"
+        )
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_01_Browser_template_Life_cycle_tpath(self):
+        """
+        Test Browser_template_Life_cycle
+        """
+        try:
+
+            self.debug("========================= Test 1: Upload Browser based template and validate ========================= ")
+            browseup_template=self.browse_upload_template()
+
+            self.debug("========================= Test 2: Deploy a VM with uploaded template and validate VM Operations========================= ")
+
+            vm1details=self.deploy_vm(browseup_template)
+
+            #vm1details=self.deploy_vm(self.template)
+
+            self.vmoperations(vm1details)
+
+            self.debug("========================= Test 3: Attach DATA DISK to the VM ")
+
+            cvolume=self.create_data_volume()
+            self.attach_data_volume(cvolume, vm1details)
+            self.vmoperations(vm1details)
+
+
+
+            self.debug("========================= Test 4: Restore VM created with Uploaded template========================= ")
+
+            self.restore_vm(vm1details)
+
+            self.debug("========================= Test 5: Detach DATA DISK to the VM ")
+
+            self.detach_data_volume(cvolume,vm1details)
+            self.vmoperations(vm1details)
+
+            self.deletevolume(cvolume.id)
+
+
+            self.debug("========================= Test 6: Expunge VM created with Uploaded template========================= ")
+
+            self.expunge_vm(vm1details)
+
+            self.debug("========================= Test 7:  Destroy VM ========================= ")
+
+            #vm2details=self.deploy_vm(self.template)
+
+            vm2details=self.deploy_vm(browseup_template)
+            self.destroy_vm(vm2details)
+
+            self.debug("========================= Test 8:  Recover destroyed VM which has Uploaded volumes attached========================= ")
+
+            self.recover_destroyed_vm(vm2details)
+            self.expunge_vm(vm2details)
+
+            self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
+
+            self.delete_template(browseup_template)
+
+            self.debug("========================= Test 10:  Upload Multiple templates========================= ")
+
+            self.multiple_browse_upload_template()
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self):
+        """
+        Test SSVM_Life_Cycle_With_Browser_template_TPath 
+        """
+        try:
+            
+            self.debug("========================= Test 11: Stop and Start SSVM and Perform Browser based volume validations ========================= ")
+
+            self.stop_ssvm()
+            ssvm1browseup_template=self.browse_upload_template()
+
+            ssvm1vm1details=self.deploy_vm(ssvm1browseup_template)
+            #ssvm1vm1details=self.deploy_vm(self.template)
+
+            self.vmoperations(ssvm1vm1details)
+
+            self.expunge_vm(ssvm1vm1details)
+
+            self.debug("========================= Test 12: Reboot SSVM and Perform Browser based volume validations ========================= ")
+
+            self.reboot_ssvm()
+            ssvm2browseup_template=self.browse_upload_template()
+
+            ssvm2vm1details=self.deploy_vm(ssvm2browseup_template)
+
+            #ssvm2vm1details=self.deploy_vm(self.template)
+            self.vmoperations(ssvm2vm1details)
+
+            self.expunge_vm(ssvm2vm1details)
+
+            self.debug("========================= Test 13: Destroy SSVM and Perform Browser based volume validations ========================= ")
+
+            self.destroy_ssvm()
+            ssvm3browseup_template=self.browse_upload_template()
+
+            ssvm3vm1details=self.deploy_vm(ssvm3browseup_template)
+
+            #ssvm2vm1details=self.deploy_vm(self.template)
+            self.vmoperations(ssvm3vm1details)
+
+            self.expunge_vm(ssvm3vm1details)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+    @classmethod
+    def tearDownClass(self):
+        try:
+            self.apiclient = super(TestBrowseUploadVolume,self).getClsTestClient().getApiClient()
+            cleanup_resources(self.apiclient, self._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/db7964fb/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index 5f5c611..4018cc6 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -543,12 +543,43 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def destroy_vm(self,vmdetails):
 
+        success            = False
         vmdetails.delete(self.apiclient, expunge=False)
 
+        try:
+            list_vm_response1 = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        except Exception as ex:
+            if "Unable to find a virtual machine with specified vmId" in str(ex):
+                success = True
+
+        if success == "True": 
+            self.debug("VM is already expunged")
+            return
+
+        list_vm_response1 = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+
+        if list_vm_response1 is None:
+            self.debug("VM already expunged")
+            return
+
+        if list_vm_response1[0].state=="Expunging":
+            self.debug("VM already getting expunged")
+            return
+
         list_vm_response = VirtualMachine.list(
                                             self.apiclient,
                                             id=vmdetails.id
                                             )
+        if list_vm_response is None:
+            self.debug("VM already expunged")
+            return
+
         self.assertEqual(
                             isinstance(list_vm_response, list),
                             True,
@@ -571,10 +602,34 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def recover_destroyed_vm(self,vmdetails):
 
+        list_vm_response1 = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        if list_vm_response1 is None:
+            self.debug("VM already expunged")
+            return
+
         cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
         cmd.id = vmdetails.id
         self.apiclient.recoverVirtualMachine(cmd)
 
+        list_vm_response1 = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        if list_vm_response1 is None:
+            self.debug("VM already expunged")
+            return
+
+        list_vm_response1 = VirtualMachine.list(
+                                            self.apiclient,
+                                            id=vmdetails.id
+                                            )
+        if list_vm_response1[0].state=="Expunging":
+            self.debug("VM already getting expunged")
+            return
+
         list_vm_response = VirtualMachine.list(
                                             self.apiclient,
                                             id=vmdetails.id
@@ -599,6 +654,46 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
+    def expunge_vm(self,vmdetails):
+
+        self.debug("Expunge VM-ID: %s" % vmdetails.id)
+
+        cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
+        cmd.id = vmdetails.id
+        self.apiclient.destroyVirtualMachine(cmd)
+
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='expunge.delay'
+                                     )
+
+        expunge_delay = int(config[0].value)
+        time.sleep(expunge_delay * 2)
+
+        #VM should be destroyed unless expunge thread hasn't run
+        #Wait for two cycles of the expunge thread
+        config = Configurations.list(
+                                     self.apiclient,
+                                     name='expunge.interval'
+                                     )
+        expunge_cycle = int(config[0].value)
+        wait_time = expunge_cycle * 4
+        while wait_time >= 0:
+            list_vm_response = VirtualMachine.list(
+                                                self.apiclient,
+                                                id=vmdetails.id
+                                                )
+            if not list_vm_response:
+                break
+            self.debug("Waiting for VM to expunge")
+            time.sleep(expunge_cycle)
+            wait_time = wait_time - expunge_cycle
+
+        self.debug("listVirtualMachines response: %s" % list_vm_response)
+
+        self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response")
+        return
+
     def volume_snapshot(self,volumedetails):
         """
         @summary: Test to verify creation of snapshot from volume
@@ -1231,6 +1326,8 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.vmoperations(vm1details)
 
+            self.destroy_vm(vm1details)
+
             self.debug("========================= Test 5: Deploy New VM,Attach the detached Uploaded volume and validate VM operations after attach========================= ")
 
             vm2details=self.deploy_vm()
@@ -1250,6 +1347,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.attach_volume(vm2details,browseup_vol.id)
 
             self.vmoperations(vm2details)
+            self.detach_volume(vm2details,browseup_vol.id)
+
+            self.deletevolume(browseup_vol.id)
 
             self.debug("========================= Test 8: Try resizing uploaded state volume and validate the error scenario========================= ")
 
@@ -1281,8 +1381,12 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.debug("========================= Test 12:  Delete detached uploaded volume========================= ")
 
+
             self.deletevolume(browseup_vol3.id)
 
+            self.debug("========================= Deletion of UnUsed VM's after test is complete========================= ")
+
+            self.expunge_vm(vm2details)
 
             self.debug("========================= Test 13:  Delete Uploaded State volume========================= ")
 
@@ -1331,6 +1435,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.volume_snapshot_template(snapshotdetails)
 
             self.deletevolume(browseup_vol6.id)
+            self.expunge_vm(vm6details)
 
             self.debug("========================= Test 20: Upload Browser based volume with checksum and validate ========================= ")
             browseup_vol_withchecksum=self.browse_upload_volume_with_md5()
@@ -1348,7 +1453,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.vmoperations(vm7details)
 
-            self.destroy_vm(vm7details)
+            self.expunge_vm(vm7details)
 
 
         except Exception as e:
@@ -1357,7 +1462,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
     @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
-    def test_02_SSVM_Life_Cycle_With_Browser_Volume_TPath(self):
+    def xtest_02_SSVM_Life_Cycle_With_Browser_Volume_TPath(self):
         """
         Test SSVM_Life_Cycle_With_Browser_Volume_TPath - This includes SSVM life cycle followed by Browser volume upload operations
         """
@@ -1377,7 +1482,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.detach_volume(ssvm1vm1details,ssvm1browseup_vol.id)
 
             self.deletevolume(ssvm1browseup_vol.id)
-            self.destroy_vm(ssvm1vm1details)
+            self.expunge_vm(ssvm1vm1details)
 
             self.debug("========================= Test 24: Reboot SSVM and Perform Browser based volume validations ========================= ")
 
@@ -1394,7 +1499,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.deletevolume(ssvm2browseup_vol.id)
 
-            self.destroy_vm(ssvm2vm1details)
+            self.expunge_vm(ssvm2vm1details)
 
             self.debug("========================= Test 25: Reboot SSVM and Perform Browser based volume validations ========================= ")
 
@@ -1411,7 +1516,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             self.deletevolume(ssvm3browseup_vol.id)
 
-            self.destroy_vm(ssvm3vm1details)
+            self.expunge_vm(ssvm3vm1details)
 
         except Exception as e:
             self.fail("Exception occurred  : %s" % e)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/db7964fb/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 07be1d6..6373ef5 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -884,22 +884,30 @@ test_data = {
 },
     "browser_upload_template": {
           "VHD": {
-        "diskname": "XenUploadVol",
-        "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
+        "templatename": "XenUploadtemplate",
+        "displaytext": "XenUploadtemplate",
+        "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
+        "hypervisor":"XenServer",
         "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
+        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
                 },
           "OVA": {
-        "diskname": "VMwareUploadVol",
-        "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
+        "templatename": "VMwareUploadtemplate",
+        "displaytext": "VMwareUploadtemplate",
+        "url": "http://nfs1.lab.vmops.com/templates/vmware/CentOS5.3-x86_64.ova",
         "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
+        "hypervisor":"VMware",
+        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
                 },
           "QCOW2": {
-        "diskname": "KVMUploadVol",
-        "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
+        "templatename": "KVMUploadtemplate",
+        "displaytext": "VMwareUploadtemplate",
+        "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
         "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
+        "hypervisor":"KVM",
+        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
                 },
                               },
-                              },
     "recurring_snapshot": {
         "maxsnaps": 2,
         "timezone": "US/Arizona",


[36/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Browser bases Template additional scenarios


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

Branch: refs/heads/master
Commit: 0d06dbd077887ce89903fbb44e5eb14c3357d77c
Parents: 651f8c9
Author: sailajamada <sa...@citrix.com>
Authored: Mon Apr 6 23:57:39 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Apr 6 23:57:39 2015 +0530

----------------------------------------------------------------------
 .../component/test_browse_templates.py          | 154 +++++++++++++++----
 1 file changed, 123 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0d06dbd0/test/integration/component/test_browse_templates.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_templates.py b/test/integration/component/test_browse_templates.py
index d469446..594df5d 100644
--- a/test/integration/component/test_browse_templates.py
+++ b/test/integration/component/test_browse_templates.py
@@ -142,7 +142,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                     (exp_val, act_val))
         return return_flag
 
-    def validate_uploaded_template(self,up_templateid,templatestate):
+    def validate_uploaded_template(self,up_templateid,templatestate,zid):
 
         config = Configurations.list(
                                      self.apiclient,
@@ -156,7 +156,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                     self.apiclient,
                     id=up_templateid,
                     templatefilter="all",
-                    zoneid=self.zone.id)
+                    zoneid=zid)
 
         self.assertNotEqual(
                     list_template_response,
@@ -216,7 +216,59 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         if results.status_code !=200: 
             self.fail("Upload is not fine")
 
-        self.validate_uploaded_template(getuploadparamsresponce.id,'Download Complete')
+        self.validate_uploaded_template(getuploadparamsresponce.id,'Download Complete',self.zone.id)
+
+        return(getuploadparamsresponce)
+
+
+    def browse_upload_template_multiplezones(self,lzones):
+
+        cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd()
+        cmd.zoneid ="-1"
+        cmd.format = self.uploadtemplateformat
+        cmd.name=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.account=self.account.name
+        cmd.domainid=self.domain.id
+        cmd.displaytext=self.templatename+self.account.name+(random.choice(string.ascii_uppercase))
+        cmd.hypervisor=self.templatehypervisor
+        cmd.ostypeid=self.templateostypeid
+        #cmd.isdynamicallyscalable="false"
+        #cmd.type="template"
+        getuploadparamsresponce=self.apiclient.getUploadParamsForTemplate(cmd)
+
+        signt=getuploadparamsresponce.signature
+        posturl=getuploadparamsresponce.postURL
+        metadata=getuploadparamsresponce.metadata
+        expiredata=getuploadparamsresponce.expires
+        #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd'
+        url=self.uploadurl
+
+        uploadfile = url.split('/')[-1]
+        r = requests.get(url, stream=True)
+        with open(uploadfile, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=1024): 
+                if chunk: # filter out keep-alive new chunks
+                    f.write(chunk)
+                    f.flush()
+
+        #uploadfile='rajani-thin-volume.vhd'
+
+        #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')}
+
+        #headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')}
+
+        headers={'X-signature':signt,'X-metadata':metadata,'X-expires':expiredata}
+
+        results = requests.post(posturl,files=files,headers=headers,verify=False)
+
+        print results.status_code
+        if results.status_code !=200: 
+            self.fail("Upload is not fine")
+
+        for z1 in lzones:
+            self.validate_uploaded_template(getuploadparamsresponce.id,'Download Complete',z1.id)
 
         return(getuploadparamsresponce)
 
@@ -412,11 +464,8 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
 
     def restore_vm(self,vmdetails):
-        #TODO: SIMENH: add another test the data on the restored VM.
         """Test recover Virtual Machine
         """
-
-        #cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
         cmd = restoreVirtualMachine.restoreVirtualMachineCmd()
         cmd.virtualmachineid = vmdetails.id
         self.apiclient.recoverVirtualMachine(cmd)
@@ -445,6 +494,24 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
         return
 
+    def restore_vm_fail(self,vmdetails):
+
+        cmd = restoreVirtualMachine.restoreVirtualMachineCmd()
+        cmd.virtualmachineid = vmdetails.id
+        success= False
+        try:
+            self.apiclient.recoverVirtualMachine(cmd)
+        except Exception as ex:
+            if "isn't available in the zone" in str(ex):
+                success = True
+        self.assertEqual(
+                success,
+                True,
+                "Restore VM with Deleted Template - Verify Restore VM is handled when template with which VM created id deleted")
+
+        return
+
+
     def deletevolume(self,volumeid):
         """Delete a Volume attached to a VM
         """
@@ -1127,33 +1194,19 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
     def delete_template(self,templatedetails):
 
-        self.debug(templatedetails)
         list_template_response = Template.list(
                                     self.apiclient,
                                     templatefilter="all",
                                     id=templatedetails.id,
                                     zoneid=self.zone.id)
-        self.debug(list_template_response[0])
-
-        self.assertEqual(
-                        isinstance(list_template_response[0], list),
-                        True,
-                        "Check for list template response return valid list"
-                        )
 
+        if list_template_response is None:
+            self.debug("Template is not available")
+            return
 
-        template_response = list_template_response[0]
-
-        self.assertEqual(
-                            template_response.id,
-                            templatedetails.id,
-                            "Template id %s in the list is not matching with created template id %s" %
-                            (template_response.id, templatedetails.id)
-                        )
-
-                # Delete the template
-        templatedetails.delete(self.apiclient)
-        self.debug("Delete template: %s successful" % templatedetails)
+        cmd = deleteTemplate.deleteTemplateCmd()
+        cmd.id = templatedetails.id
+        self.apiclient.deleteTemplate(cmd)
 
         list_template_response = Template.list(
                                     self.apiclient,
@@ -1223,8 +1276,6 @@ class TestBrowseUploadVolume(cloudstackTestCase):
 
             vm1details=self.deploy_vm(browseup_template)
 
-            vm1details=self.deploy_vm(self.template)
-
             self.vmoperations(vm1details)
 
             self.debug("========================= Test 3: Attach DATA DISK to the VM ")
@@ -1261,9 +1312,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
             self.recover_destroyed_vm(vm2details)
             self.expunge_vm(vm2details)
 
-            #self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
-            #self.debug(browseup_template)
-            #self.delete_template(browseup_template)
+            self.debug("========================= Test 9:  Delete the Uploaded Template========================= ")
+            self.debug(browseup_template)
+            self.delete_template(browseup_template)
 
             self.debug("========================= Test 10:  Upload Multiple templates========================= ")
 
@@ -1322,6 +1373,47 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         return
 
 
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_03_Browser_template_upload_multiple_zones(self):
+        """
+        Test Browser_template_upload_multiple_zones
+        """
+
+        cmd = listZones.listZonesCmd()
+        zonelist=self.apiclient.listZones(cmd)
+        if len(zonelist) <2:
+            raise self.skipTest("Only one zone available hence skipping")
+        try:
+
+            self.debug("========================= Test 14: Upload Browser based template into multiple zones ========================= ")
+            browseup_template=self.browse_upload_template_multiplezones(zonelist)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
+
+
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_04_Browser_template_ResetVM_With_Deleted_Template(self):
+        """
+        Test Browser_template_upload_ResetVM_With_Deleted_Template
+        """
+        try:
+
+            self.debug("========================= Test 15: Test Browser_template_upload_ResetVM_With_Deleted_Template ========================= ")
+
+            browseup_template=self.browse_upload_template()
+
+            vm1details=self.deploy_vm(browseup_template)
+
+            self.delete_template(browseup_template)
+
+            self.restore_vm_fail(vm1details)
+
+        except Exception as e:
+            self.fail("Exception occurred  : %s" % e)
+        return
 
     @classmethod
     def tearDownClass(self):


[27/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: showing browser uploaded templates in UI.

Templates are not observed on UI after GetUploadParamsForTemplate API
call and Template upload requests initiated.


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

Branch: refs/heads/master
Commit: 5643d514eedf4d4fe40bde16915bb3c4afa3c007
Parents: c62ce3e
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Tue Mar 24 14:55:38 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Mar 24 15:11:14 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/api/query/QueryManagerImpl.java        | 2 +-
 server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5643d514/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 824bb9b..ac37c97 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -3202,7 +3202,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
         if (showRemovedTmpl) {
             uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
         } else {
-            sc.addAnd("templateState", SearchCriteria.Op.EQ, State.Active);
+            sc.addAnd("templateState", SearchCriteria.Op.IN, new State[]{State.Active, State.NotUploaded, State.UploadInProgress});
             uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter);
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5643d514/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index 4e33728..15cefa5 100644
--- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -74,7 +74,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
     protected TemplateJoinDaoImpl() {
 
         tmpltIdPairSearch = createSearchBuilder();
-        tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
+        tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.IN);
         tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN);
         tmpltIdPairSearch.done();
 
@@ -412,7 +412,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
             }
             SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
             if (!showRemoved) {
-                sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
+                sc.setParameters("templateState", VirtualMachineTemplate.State.Active, VirtualMachineTemplate.State.NotUploaded, VirtualMachineTemplate.State.UploadInProgress);
             }
             sc.setParameters("tempZonePairIN", labels);
             List<TemplateJoinVO> vms = searchIncludingRemoved(sc, searchFilter, null, false);


[43/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: fixed the error message incase of wrong image format


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

Branch: refs/heads/master
Commit: 4f35d3611a60c64a252f7ce2e233f228101774d0
Parents: d5bb2f1
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Apr 16 17:34:29 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Thu Apr 16 17:43:46 2015 +0530

----------------------------------------------------------------------
 server/src/com/cloud/storage/VolumeApiServiceImpl.java | 8 +++++---
 server/src/com/cloud/template/TemplateAdapterBase.java | 9 ++++++---
 2 files changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f35d361/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 533f6fa..2022dde 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -385,9 +385,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage);
         }
 
-        ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
-        if (imgfmt == null) {
-            throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+        try {
+            ImageFormat.valueOf(format.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
+            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
         }
 
         // Check that the the disk offering specified is valid

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f35d361/server/src/com/cloud/template/TemplateAdapterBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java
index 8bb93dd..c5d0c5b 100755
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/com/cloud/template/TemplateAdapterBase.java
@@ -198,9 +198,12 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
             featured = Boolean.FALSE;
         }
 
-        ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
-        if (imgfmt == null) {
-            throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+        ImageFormat imgfmt;
+        try {
+            imgfmt = ImageFormat.valueOf(format.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
+            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
         }
 
         // Check that the resource limit for templates/ISOs won't be exceeded


[10/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Modified test data


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

Branch: refs/heads/master
Commit: 24a8483b889b1186a87606de2ca2ccd78301cfc8
Parents: f22760a
Author: sailajamada <sa...@citrix.com>
Authored: Sun Mar 8 20:12:06 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Sun Mar 8 20:12:06 2015 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/config/test_data.py | 31 ++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/24a8483b/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index a9f1959..07be1d6 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -860,27 +860,46 @@ test_data = {
         "http://10.147.28.7/templates/393d3550-05ef-330f-9b8c-745b0e699759.vhd",
         "checksum": "",
     },
-    "browser_upload_volume": {
+    "browser_upload_volume":{
           "VHD": {
         "diskname": "XenUploadVol",
         "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
-        "checksum": "",
+        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
                 },
           "OVA": {
         "diskname": "VMwareUploadVol",
         "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
-        "checksum": "",
+        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
                 },
           "QCOW2": {
         "diskname": "KVMUploadVol",
         "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
-        "checksum": "",
+        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
                 },
     'browser_resized_disk_offering': {
         "displaytext": "Resizeddisk",
         "name": "Resizeddisk",
-        "disksize": 3
-    },
+        "disksize": 3,
+    }
+},
+    "browser_upload_template": {
+          "VHD": {
+        "diskname": "XenUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.vhd",
+        "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
+                },
+          "OVA": {
+        "diskname": "VMwareUploadVol",
+        "url": "http://10.147.28.7/templates/Autoscale_Template/CentOS5.5(64bit)-vmware-autoscale.ova",
+        "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
+                },
+          "QCOW2": {
+        "diskname": "KVMUploadVol",
+        "url": "http://10.147.28.7/templates/rajani-thin-volume.qcow2",
+        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
+                },
+                              },
+                              },
     "recurring_snapshot": {
         "maxsnaps": 2,
         "timezone": "US/Arizona",


[30/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Updated Test automation scripts


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

Branch: refs/heads/master
Commit: 5e7baa5a55d0942a630ad78c4ce11a467b40fb8f
Parents: 3c43677
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 30 09:50:30 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 30 09:50:30 2015 +0530

----------------------------------------------------------------------
 test/integration/component/test_browse_volumes.py | 8 ++++----
 tools/marvin/marvin/config/test_data.py           | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5e7baa5a/test/integration/component/test_browse_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py
index ddc8517..9067e2f 100644
--- a/test/integration/component/test_browse_volumes.py
+++ b/test/integration/component/test_browse_volumes.py
@@ -82,9 +82,9 @@ class TestBrowseUploadVolume(cloudstackTestCase):
                  else:
                      break
 
-        cls.uploadurl=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["url"]
-        cls.volname=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["diskname"]
-        cls.md5sum=cls.testdata["browser_upload_volume"][cls.uploadvolumeformat]["checksum"]
+        cls.uploadurl=cls.testdata["configurableData"]["browser_upload_volume"][cls.uploadvolumeformat]["url"]
+        cls.volname=cls.testdata["configurableData"]["browser_upload_volume"][cls.uploadvolumeformat]["diskname"]
+        cls.md5sum=cls.testdata["configurableData"]["browser_upload_volume"][cls.uploadvolumeformat]["checksum"]
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.domain = get_domain(cls.apiclient)
         cls.pod = get_pod(cls.apiclient, cls.zone.id)
@@ -108,7 +108,7 @@ class TestBrowseUploadVolume(cloudstackTestCase):
         )
         cls.disk_offering = DiskOffering.create(
             cls.apiclient,
-            cls.testdata["browser_upload_volume"]["browser_resized_disk_offering"],
+            cls.testdata["configurableData"]["browser_upload_volume"]["browser_resized_disk_offering"],
             custom=True
         )
         cls._cleanup = [

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5e7baa5a/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index c1156c4..9c12a0f 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -1537,7 +1537,7 @@ test_data = {
         "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
         "hypervisor":"XenServer",
         "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
-        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
+        "ostypeid":"fbe5230a-d490-11e4-a923-2611fa84f51d"
                 },
           "OVA": {
         "templatename": "VMwareUploadtemplate",
@@ -1551,9 +1551,9 @@ test_data = {
         "templatename": "KVMUploadtemplate",
         "displaytext": "VMwareUploadtemplate",
         "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
-        "checksum": "da997b697feaa2f1f6e0d4785b0cece2",
+        "checksum": "d06b5f6a-d44e-11e4-9d99-4af3a393b3ac",
         "hypervisor":"KVM",
-        "ostypeid":"2e02e376-cdf3-11e4-beb3-8aa6272b57ef"
+        "ostypeid":"d084e2c8-d44e-11e4-9d99-4af3a393b3ac"
                 },
                               },
         "bootableIso":


[31/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
Updated test data file with osid


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

Branch: refs/heads/master
Commit: eac8d4b15336d843147bcfe30acf44c141776985
Parents: 5e7baa5
Author: sailajamada <sa...@citrix.com>
Authored: Mon Mar 30 16:21:41 2015 +0530
Committer: sailajamada <sa...@citrix.com>
Committed: Mon Mar 30 16:21:41 2015 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/config/test_data.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eac8d4b1/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 9c12a0f..48053eb 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -1537,7 +1537,7 @@ test_data = {
         "url": "http://10.147.28.7/templates/builtin/centos56-x86_64.vhd.bz2",
         "hypervisor":"XenServer",
         "checksum": "09b08b6abb1b903fca7711d3ac8d6598",
-        "ostypeid":"fbe5230a-d490-11e4-a923-2611fa84f51d"
+        "ostypeid":"142"
                 },
           "OVA": {
         "templatename": "VMwareUploadtemplate",
@@ -1545,7 +1545,7 @@ test_data = {
         "url": "http://nfs1.lab.vmops.com/templates/vmware/CentOS5.3-x86_64.ova",
         "checksum": "02de0576dd3a61ab59c03fd795fc86ac",
         "hypervisor":"VMware",
-        "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4"
+        "ostypeid":"142"
                 },
           "QCOW2": {
         "templatename": "KVMUploadtemplate",
@@ -1553,7 +1553,7 @@ test_data = {
         "url": "http://10.147.28.7/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2",
         "checksum": "d06b5f6a-d44e-11e4-9d99-4af3a393b3ac",
         "hypervisor":"KVM",
-        "ostypeid":"d084e2c8-d44e-11e4-9d99-4af3a393b3ac"
+        "ostypeid":"142"
                 },
                               },
         "bootableIso":


[42/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: added state transition for a failed volume delete


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

Branch: refs/heads/master
Commit: d5bb2f16fc59876f1a2aa99bc049d322ee794ea8
Parents: 4338bea
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Thu Apr 16 17:32:33 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Thu Apr 16 17:42:18 2015 +0530

----------------------------------------------------------------------
 api/src/com/cloud/storage/Volume.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5bb2f16/api/src/com/cloud/storage/Volume.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java
index 106e4c2..b7a5eeb 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -98,6 +98,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Migrating, Event.OperationSucceeded, Ready, null));
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Migrating, Event.OperationFailed, Ready, null));
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Destroy, Event.OperationSucceeded, Destroy, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Destroy, Event.OperationFailed, Destroy, Arrays.asList(StateMachine2.Transition.Impact.USAGE)));
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadOp, Event.OperationSucceeded, Uploaded, null));
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadOp, Event.OperationFailed, Allocated, null));
             s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Uploaded, Event.DestroyRequested, Destroy, null));


[02/50] git commit: updated refs/heads/master to 0b83559

Posted by ra...@apache.org.
volume upload: cannot delete a volume in NotUploaded state Added exception handler in the upload status monitor thread.


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

Branch: refs/heads/master
Commit: 075c8410527df2fe58f5be0f4dcdfc358aeb6f82
Parents: d19ea52
Author: Koushik Das <ko...@apache.org>
Authored: Thu Feb 5 15:50:21 2015 +0530
Committer: Rajani Karuturi <ra...@gmail.com>
Committed: Tue Feb 17 12:31:41 2015 +0530

----------------------------------------------------------------------
 .../storage/ImageStoreUploadMonitorImpl.java    | 130 ++++++++++---------
 1 file changed, 72 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/075c8410/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index d87fe60..b2cc5d9 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -178,74 +178,88 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
             // 6. In listener check for the answer and update DB accordingly
             List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.NotUploaded, Volume.State.UploadInProgress);
             for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
-                DataStore dataStore = storeMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
-                EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
-                if (ep == null) {
-                    s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName());
-                    continue;
-                }
-                VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
-                if (volume == null) {
-                    s_logger.warn("Volume with id " + volumeDataStore.getVolumeId() + " not found");
-                    continue;
-                }
-                Host host = _hostDao.findById(ep.getId());
-                UploadStatusCommand cmd = new UploadStatusCommand(volume.getUuid(), EntityType.Volume);
-                if (host != null && host.getManagementServerId() != null) {
-                    if (_nodeId == host.getManagementServerId().longValue()) {
-                        Answer answer = null;
-                        try {
-                            answer = ep.sendMessage(cmd);
-                        } catch (CloudRuntimeException e) {
-                            s_logger.warn("Unable to get upload status for volume " + volume.getUuid() + ". Error details: " + e.getMessage());
-                            answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
-                        }
-                        if (answer == null || !(answer instanceof UploadStatusAnswer)) {
-                            s_logger.warn("No or invalid answer corresponding to UploadStatusCommand for volume " + volumeDataStore.getVolumeId());
-                            continue;
+                try {
+                    DataStore dataStore = storeMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
+                    EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
+                    if (ep == null) {
+                        s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName());
+                        continue;
+                    }
+                    VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
+                    if (volume == null) {
+                        s_logger.warn("Volume with id " + volumeDataStore.getVolumeId() + " not found");
+                        continue;
+                    }
+                    Host host = _hostDao.findById(ep.getId());
+                    UploadStatusCommand cmd = new UploadStatusCommand(volume.getUuid(), EntityType.Volume);
+                    if (host != null && host.getManagementServerId() != null) {
+                        if (_nodeId == host.getManagementServerId().longValue()) {
+                            Answer answer = null;
+                            try {
+                                answer = ep.sendMessage(cmd);
+                            } catch (CloudRuntimeException e) {
+                                s_logger.warn("Unable to get upload status for volume " + volume.getUuid() + ". Error details: " + e.getMessage());
+                                answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
+                            }
+                            if (answer == null || !(answer instanceof UploadStatusAnswer)) {
+                                s_logger.warn("No or invalid answer corresponding to UploadStatusCommand for volume " + volumeDataStore.getVolumeId());
+                                continue;
+                            }
+                            handleVolumeStatusResponse((UploadStatusAnswer)answer, volume, volumeDataStore);
                         }
-                        handleVolumeStatusResponse((UploadStatusAnswer)answer, volume, volumeDataStore);
+                    } else {
+                        String error = "Volume " + volume.getUuid() + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
+                        handleVolumeStatusResponse(new UploadStatusAnswer(cmd, UploadStatus.ERROR, error), volume, volumeDataStore);
+                    }
+                } catch (Throwable th) {
+                    s_logger.warn("Exception while checking status for uploaded volume " + volumeDataStore.getExtractUrl() + ". Error details: " + th.getMessage());
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Exception details: ", th);
                     }
-                } else {
-                    String error = "Volume " + volume.getUuid() + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
-                    handleVolumeStatusResponse(new UploadStatusAnswer(cmd, UploadStatus.ERROR, error), volume, volumeDataStore);
                 }
             }
 
             // Handle for template upload as well
             List<TemplateDataStoreVO> templateDataStores = _templateDataStoreDao.listByTemplateState(VirtualMachineTemplate.State.NotUploaded, VirtualMachineTemplate.State.UploadInProgress);
             for (TemplateDataStoreVO templateDataStore : templateDataStores) {
-                DataStore dataStore = storeMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
-                EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
-                if (ep == null) {
-                    s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName());
-                    continue;
-                }
-                VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
-                if (template == null) {
-                    s_logger.warn("Template with id " + templateDataStore.getTemplateId() + " not found");
-                    continue;
-                }
-                Host host = _hostDao.findById(ep.getId());
-                UploadStatusCommand cmd = new UploadStatusCommand(template.getUuid(), EntityType.Template);
-                if (host != null && host.getManagementServerId() != null) {
-                    if (_nodeId == host.getManagementServerId().longValue()) {
-                        Answer answer = null;
-                        try {
-                            answer = ep.sendMessage(cmd);
-                        } catch (CloudRuntimeException e) {
-                            s_logger.warn("Unable to get upload status for template " + template.getUuid() + ". Error details: " + e.getMessage());
-                            answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
-                        }
-                        if (answer == null || !(answer instanceof UploadStatusAnswer)) {
-                            s_logger.warn("No or invalid answer corresponding to UploadStatusCommand for template " + templateDataStore.getTemplateId());
-                            continue;
+                try {
+                    DataStore dataStore = storeMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
+                    EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
+                    if (ep == null) {
+                        s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName());
+                        continue;
+                    }
+                    VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
+                    if (template == null) {
+                        s_logger.warn("Template with id " + templateDataStore.getTemplateId() + " not found");
+                        continue;
+                    }
+                    Host host = _hostDao.findById(ep.getId());
+                    UploadStatusCommand cmd = new UploadStatusCommand(template.getUuid(), EntityType.Template);
+                    if (host != null && host.getManagementServerId() != null) {
+                        if (_nodeId == host.getManagementServerId().longValue()) {
+                            Answer answer = null;
+                            try {
+                                answer = ep.sendMessage(cmd);
+                            } catch (CloudRuntimeException e) {
+                                s_logger.warn("Unable to get upload status for template " + template.getUuid() + ". Error details: " + e.getMessage());
+                                answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
+                            }
+                            if (answer == null || !(answer instanceof UploadStatusAnswer)) {
+                                s_logger.warn("No or invalid answer corresponding to UploadStatusCommand for template " + templateDataStore.getTemplateId());
+                                continue;
+                            }
+                            handleTemplateStatusResponse((UploadStatusAnswer)answer, template, templateDataStore);
                         }
-                        handleTemplateStatusResponse((UploadStatusAnswer)answer, template, templateDataStore);
+                    } else {
+                        String error = "Template " + template.getUuid() + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
+                        handleTemplateStatusResponse(new UploadStatusAnswer(cmd, UploadStatus.ERROR, error), template, templateDataStore);
+                    }
+                } catch (Throwable th) {
+                    s_logger.warn("Exception while checking status for uploaded template " + templateDataStore.getExtractUrl() + ". Error details: " + th.getMessage());
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Exception details: ", th);
                     }
-                } else {
-                    String error = "Template " + template.getUuid() + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
-                    handleTemplateStatusResponse(new UploadStatusAnswer(cmd, UploadStatus.ERROR, error), template, templateDataStore);
                 }
             }
         }