You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/08/16 02:45:39 UTC
[5/7] refactor
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java b/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java
index 3ba8483..20e9aba 100644
--- a/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java
+++ b/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java
@@ -25,6 +25,7 @@ import com.cloud.cluster.CheckPointManager;
import com.cloud.cluster.CleanupMaid;
import com.cloud.server.ManagementServer;
import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.volume.Volume;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.NoTransitionException;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java
index 87cb065..f78ec26 100755
--- a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java
+++ b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java
@@ -36,24 +36,24 @@ import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.host.Host;
import com.cloud.server.StatsCollector;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.Type;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.pool.StoragePoolManager;
+import com.cloud.storage.pool.StoragePoolStatus;
+import com.cloud.storage.pool.Storage.StoragePoolType;
import com.cloud.storage.swift.SwiftManager;
+import com.cloud.storage.volume.Volume;
+import com.cloud.storage.volume.Volume.Type;
import com.cloud.template.TemplateManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.AdapterBase;
@@ -65,7 +65,7 @@ import com.cloud.vm.VirtualMachineProfile;
public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator {
private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class);
@Inject TemplateManager _tmpltMgr;
- @Inject StorageManager _storageMgr;
+ @Inject StoragePoolManager _storageMgr;
@Inject StoragePoolDao _storagePoolDao;
@Inject VMTemplateHostDao _templateHostDao;
@Inject VMTemplatePoolDao _templatePoolDao;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java
index 006931d..aa3f5bb 100644
--- a/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java
+++ b/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java
@@ -33,10 +33,10 @@ import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.server.StatsCollector;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.StoragePool;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.pool.Storage.StoragePoolType;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.user.Account;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java
index 2418583..1bd6231 100644
--- a/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java
+++ b/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java
@@ -27,8 +27,8 @@ import org.apache.log4j.Logger;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.pool.StoragePoolManager;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
@@ -40,7 +40,7 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl
StoragePoolAllocator _firstFitStoragePoolAllocator;
StoragePoolAllocator _localStoragePoolAllocator;
- StorageManager _storageMgr;
+ StoragePoolManager _storageMgr;
ConfigurationDao _configDao;
boolean _storagePoolCleanupEnabled;
@@ -92,9 +92,9 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl
_localStoragePoolAllocator = ComponentLocator.inject(LocalStoragePoolAllocator.class);
_localStoragePoolAllocator.configure("GCLocalStoragePoolAllocator", params);
- _storageMgr = locator.getManager(StorageManager.class);
+ _storageMgr = locator.getManager(StoragePoolManager.class);
if (_storageMgr == null) {
- throw new ConfigurationException("Unable to get " + StorageManager.class.getName());
+ throw new ConfigurationException("Unable to get " + StoragePoolManager.class.getName());
}
_configDao = locator.getDao(ConfigurationDao.class);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java
index 991baad..b565f6d 100644
--- a/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java
+++ b/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java
@@ -33,10 +33,10 @@ import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.pool.StoragePool;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.Inject;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java
index 13f44e7..93f99e2 100644
--- a/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java
+++ b/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java
@@ -22,7 +22,7 @@ import java.util.Set;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.host.Host;
-import com.cloud.storage.StoragePool;
+import com.cloud.storage.pool.StoragePool;
import com.cloud.utils.component.Adapter;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java b/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java
index 38e116a..ddc113f 100644
--- a/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java
+++ b/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java
@@ -27,8 +27,8 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.host.Host;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume.Type;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.volume.Volume.Type;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/backup/StorageBackupManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/backup/StorageBackupManager.java b/server/src/com/cloud/storage/backup/StorageBackupManager.java
new file mode 100644
index 0000000..2e2bcfd
--- /dev/null
+++ b/server/src/com/cloud/storage/backup/StorageBackupManager.java
@@ -0,0 +1,5 @@
+package com.cloud.storage.backup;
+
+public interface StorageBackupManager {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/backup/StorageBackupManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/backup/StorageBackupManagerImpl.java b/server/src/com/cloud/storage/backup/StorageBackupManagerImpl.java
new file mode 100644
index 0000000..8c19c20
--- /dev/null
+++ b/server/src/com/cloud/storage/backup/StorageBackupManagerImpl.java
@@ -0,0 +1,5 @@
+package com.cloud.storage.backup;
+
+public class StorageBackupManagerImpl implements StorageBackupManager {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java b/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
index 2ae394e..8a6975b 100644
--- a/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
@@ -28,8 +28,8 @@ import org.apache.log4j.Logger;
import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.pool.Storage.TemplateType;
import com.cloud.utils.DateUtil;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/SnapshotDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java
index 4bf54de..a9923e9 100644
--- a/server/src/com/cloud/storage/dao/SnapshotDao.java
+++ b/server/src/com/cloud/storage/dao/SnapshotDao.java
@@ -18,8 +18,8 @@ package com.cloud.storage.dao;
import java.util.List;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Type;
+import com.cloud.storage.snapshot.Snapshot;
+import com.cloud.storage.snapshot.Snapshot.Type;
import com.cloud.storage.SnapshotVO;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
index ac4bb6f..c4f065e 100644
--- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
@@ -25,10 +25,10 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.server.ResourceTag.TaggedResourceType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Type;
+import com.cloud.storage.snapshot.Snapshot;
+import com.cloud.storage.snapshot.Snapshot.Type;
+import com.cloud.storage.volume.Volume;
import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.utils.component.ComponentLocator;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
index c4e6a5a..fe3b925 100644
--- a/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
@@ -21,8 +21,8 @@ import java.util.List;
import javax.ejb.Local;
-import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotScheduleVO;
+import com.cloud.storage.snapshot.Snapshot;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/StoragePoolDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/StoragePoolDao.java b/server/src/com/cloud/storage/dao/StoragePoolDao.java
index ff8292e..acc69a4 100644
--- a/server/src/com/cloud/storage/dao/StoragePoolDao.java
+++ b/server/src/com/cloud/storage/dao/StoragePoolDao.java
@@ -20,8 +20,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StoragePoolVO;
+import com.cloud.storage.pool.StoragePoolStatus;
import com.cloud.utils.db.GenericDao;
/**
* Data Access Object for storage_pool table
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java
index 730610b..ab2689e 100644
--- a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java
@@ -28,9 +28,9 @@ import javax.ejb.Local;
import javax.naming.ConfigurationException;
import com.cloud.host.Status;
-import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.pool.StoragePoolStatus;
+import com.cloud.storage.pool.Storage.StoragePoolType;
import com.cloud.storage.StoragePoolDetailVO;
-import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StoragePoolVO;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.DB;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
index 2a0dfc8..5ae4afc 100755
--- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
@@ -43,10 +43,10 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.server.ResourceTag.TaggedResourceType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.pool.Storage;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.pool.Storage.TemplateType;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.tags.ResourceTagVO;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/VolumeDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/VolumeDao.java b/server/src/com/cloud/storage/dao/VolumeDao.java
index d7a2667..05130da 100755
--- a/server/src/com/cloud/storage/dao/VolumeDao.java
+++ b/server/src/com/cloud/storage/dao/VolumeDao.java
@@ -19,8 +19,8 @@ package com.cloud.storage.dao;
import java.util.List;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.volume.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/dao/VolumeDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java
index 638d209..f93c89e 100755
--- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java
@@ -29,11 +29,11 @@ import org.apache.log4j.Logger;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.server.ResourceTag.TaggedResourceType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.Event;
-import com.cloud.storage.Volume.State;
-import com.cloud.storage.Volume.Type;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.volume.Volume;
+import com.cloud.storage.volume.Volume.Event;
+import com.cloud.storage.volume.Volume.State;
+import com.cloud.storage.volume.Volume.Type;
import com.cloud.storage.VolumeVO;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.utils.Pair;
@@ -332,8 +332,8 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
}
@Override
- public boolean updateState(com.cloud.storage.Volume.State currentState,
- Event event, com.cloud.storage.Volume.State nextState, Volume vo,
+ public boolean updateState(com.cloud.storage.volume.Volume.State currentState,
+ Event event, com.cloud.storage.volume.Volume.State nextState, Volume vo,
Object data) {
Long oldUpdated = vo.getUpdatedCount();
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/download/DownloadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java
index 036d40a..7e86cbd 100755
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -43,19 +43,19 @@ import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConnectionException;
import com.cloud.host.HostVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.Volume.Event;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeHostDao;
import com.cloud.storage.download.DownloadState.DownloadEvent;
+import com.cloud.storage.pool.Storage;
+import com.cloud.storage.pool.StoragePoolManager;
+import com.cloud.storage.volume.Volume.Event;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
@@ -116,7 +116,7 @@ public class DownloadListener implements Listener {
private VolumeHostDao volumeHostDao;
private VolumeDao _volumeDao;
- private StorageManager _storageMgr;
+ private StoragePoolManager _storageMgr;
private VMTemplateHostDao vmTemplateHostDao;
private VMTemplateDao _vmTemplateDao;
@@ -154,7 +154,7 @@ public class DownloadListener implements Listener {
updateDatabase(Status.NOT_DOWNLOADED, "");
}
- public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr) {
+ public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StoragePoolManager storageMgr) {
this.ssAgent = ssAgent;
this.sserver = host;
this.volume = volume;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/download/DownloadMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java
index 30ec3b1..c33c9dc 100644
--- a/server/src/com/cloud/storage/download/DownloadMonitor.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitor.java
@@ -22,7 +22,7 @@ import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.HostVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
-import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.pool.Storage.ImageFormat;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.utils.component.Manager;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index 2736777..6f77dac 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -64,16 +64,12 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.resource.ResourceManager;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageManager;
import com.cloud.storage.SwiftVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.Volume;
import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.Volume.Event;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.dao.StoragePoolHostDao;
@@ -85,10 +81,14 @@ import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeHostDao;
+import com.cloud.storage.pool.StoragePoolManager;
+import com.cloud.storage.pool.Storage.ImageFormat;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.swift.SwiftManager;
import com.cloud.storage.template.TemplateConstants;
import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.volume.Volume;
+import com.cloud.storage.volume.Volume.Event;
import com.cloud.user.Account;
import com.cloud.user.ResourceLimitService;
import com.cloud.utils.component.Inject;
@@ -134,7 +134,7 @@ public class DownloadMonitorImpl implements DownloadMonitor {
@Inject
SecondaryStorageVmManager _ssvmMgr;
@Inject
- StorageManager _storageMgr ;
+ StoragePoolManager _storageMgr ;
@Inject
private final DataCenterDao _dcDao = null;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/image/ImageManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/image/ImageManager.java b/server/src/com/cloud/storage/image/ImageManager.java
new file mode 100644
index 0000000..2e44d7f
--- /dev/null
+++ b/server/src/com/cloud/storage/image/ImageManager.java
@@ -0,0 +1,12 @@
+package com.cloud.storage.image;
+
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.utils.Pair;
+
+public interface ImageManager {
+
+ VMTemplateVO getImageById(Long imageId);
+
+ Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/image/ImageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/image/ImageManagerImpl.java b/server/src/com/cloud/storage/image/ImageManagerImpl.java
new file mode 100644
index 0000000..1202799
--- /dev/null
+++ b/server/src/com/cloud/storage/image/ImageManagerImpl.java
@@ -0,0 +1,37 @@
+package com.cloud.storage.image;
+
+import java.util.List;
+
+import com.cloud.host.HostVO;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Inject;
+
+public class ImageManagerImpl implements ImageManager {
+ @Inject
+ VMTemplateDao _vmTemplDao;
+ @Override
+ public VMTemplateVO getImageById(Long imageId) {
+ return _vmTemplDao.findById(imageId);
+ }
+
+ @Override
+ public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId) {
+ String isoPath = null;
+
+ List<HostVO> storageHosts = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.SecondaryStorage, dataCenterId);
+ if (storageHosts != null) {
+ for (HostVO storageHost : storageHosts) {
+ VMTemplateHostVO templateHostVO = _vmTemplateHostDao.findByHostTemplate(storageHost.getId(), templateId);
+ if (templateHostVO != null) {
+ isoPath = storageHost.getStorageUrl() + "/" + templateHostVO.getInstallPath();
+ return new Pair<String, String>(isoPath, storageHost.getStorageUrl());
+ }
+ }
+ }
+ s_logger.warn("Unable to find secondary storage in zone id=" + dataCenterId);
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index 3bb002b..74fd524 100755
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -33,20 +33,20 @@ import com.cloud.host.Status;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.server.ManagementService;
import com.cloud.storage.OCFS2Manager;
-import com.cloud.storage.StorageManagerImpl;
import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.dao.StoragePoolDao;
+import com.cloud.storage.pool.StoragePoolManagerImpl;
+import com.cloud.storage.pool.Storage.StoragePoolType;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
public class StoragePoolMonitor implements Listener {
private static final Logger s_logger = Logger.getLogger(StoragePoolMonitor.class);
- private final StorageManagerImpl _storageManager;
+ private final StoragePoolManagerImpl _storageManager;
private final StoragePoolDao _poolDao;
OCFS2Manager _ocfs2Mgr;
- public StoragePoolMonitor(StorageManagerImpl mgr, StoragePoolDao poolDao) {
+ public StoragePoolMonitor(StoragePoolManagerImpl mgr, StoragePoolDao poolDao) {
this._storageManager = mgr;
this._poolDao = poolDao;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java b/server/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java
new file mode 100644
index 0000000..92b78af
--- /dev/null
+++ b/server/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java
@@ -0,0 +1,30 @@
+package com.cloud.storage.orchestra;
+
+import java.util.List;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientStorageCapacityException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.volume.Volume;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachineProfileImpl;
+
+public interface StorageOrchestraEngine {
+ void prepareForMigration(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest);
+ void prepare(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException,
+ InsufficientStorageCapacityException, ConcurrentOperationException;
+
+ void allocateVolume(Long vmId, Pair<? extends DiskOfferingVO, Long> rootDiskOffering,
+ List<Pair<DiskOfferingVO, Long>> dataDiskOfferings,
+ Long templateId, Account owner);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/orchestra/StorageOrchestraEngineImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/orchestra/StorageOrchestraEngineImpl.java b/server/src/com/cloud/storage/orchestra/StorageOrchestraEngineImpl.java
new file mode 100644
index 0000000..1321fa5
--- /dev/null
+++ b/server/src/com/cloud/storage/orchestra/StorageOrchestraEngineImpl.java
@@ -0,0 +1,1014 @@
+package com.cloud.storage.orchestra;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.api.commands.CreateVolumeCmd;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.Domain;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientStorageCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.StoragePoolVO;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeHostVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.pool.Storage;
+import com.cloud.storage.pool.StoragePool;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.pool.Storage.StoragePoolType;
+import com.cloud.storage.volume.InvalidParameterValueException;
+import com.cloud.storage.volume.PermissionDeniedException;
+import com.cloud.storage.volume.StorageFilerTO;
+import com.cloud.storage.volume.StorageMigrationCleanupMaid;
+import com.cloud.storage.volume.VMTemplateStoragePoolVO;
+import com.cloud.storage.volume.Volume;
+import com.cloud.storage.volume.Volume.Event;
+import com.cloud.storage.volume.Volume.Type;
+import com.cloud.storage.volume.VolumeManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class StorageOrchestraEngineImpl implements StorageOrchestraEngine, Manager {
+
+
+ @Inject
+ protected TemplateManager _templateMgr;
+ @Inject
+ protected VolumeManager _volumeMgr;
+ @Inject
+ protected VMInstanceDao _vmDao;
+ @DB
+ protected Pair<VolumeVO, String> createVolumeFromSnapshot(VolumeVO volume, SnapshotVO snapshot) {
+ VolumeVO createdVolume = null;
+ Long volumeId = volume.getId();
+
+ String volumeFolder = null;
+
+ try {
+ stateTransitTo(volume, Volume.Event.CreateRequested);
+ } catch (NoTransitionException e) {
+ s_logger.debug(e.toString());
+ return null;
+ }
+ // Create the Volume object and save it so that we can return it to the user
+ Account account = _accountDao.findById(volume.getAccountId());
+
+ final HashSet<StoragePool> poolsToAvoid = new HashSet<StoragePool>();
+ StoragePoolVO pool = null;
+ boolean success = false;
+ Set<Long> podsToAvoid = new HashSet<Long>();
+ Pair<HostPodVO, Long> pod = null;
+ String volumeUUID = null;
+ String details = null;
+
+ DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
+ DataCenterVO dc = _dcDao.findById(volume.getDataCenterId());
+ DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
+
+ int retry = 0;
+ // Determine what pod to store the volume in
+ while ((pod = _resourceMgr.findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
+ podsToAvoid.add(pod.first().getId());
+ // Determine what storage pool to store the volume in
+ while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, poolsToAvoid)) != null) {
+ poolsToAvoid.add(pool);
+ volumeFolder = pool.getPath();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Attempting to create volume from snapshotId: " + snapshot.getId() + " on storage pool " + pool.getName());
+ }
+
+ // Get the newly created VDI from the snapshot.
+ // This will return a null volumePath if it could not be created
+ Pair<String, String> volumeDetails = createVDIFromSnapshot(UserContext.current().getCallerUserId(), snapshot, pool);
+
+ volumeUUID = volumeDetails.first();
+ details = volumeDetails.second();
+
+ if (volumeUUID != null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Volume with UUID " + volumeUUID + " was created on storage pool " + pool.getName());
+ }
+ success = true;
+ break; // break out of the "find storage pool" loop
+ } else {
+ retry++;
+ if (retry >= 3) {
+ _volsDao.expunge(volumeId);
+ String msg = "Unable to create volume from snapshot " + snapshot.getId() + " after retrying 3 times, due to " + details;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+
+ }
+ }
+ s_logger.warn("Unable to create volume on pool " + pool.getName() + ", reason: " + details);
+ }
+
+ if (success) {
+ break; // break out of the "find pod" loop
+ }
+ }
+
+ if (!success) {
+ _volsDao.expunge(volumeId);
+ String msg = "Unable to create volume from snapshot " + snapshot.getId() + " due to " + details;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+
+ }
+
+ createdVolume = _volsDao.findById(volumeId);
+
+ try {
+ if (success) {
+ createdVolume.setPodId(pod.first().getId());
+ createdVolume.setPoolId(pool.getId());
+ createdVolume.setPoolType(pool.getPoolType());
+ createdVolume.setFolder(volumeFolder);
+ createdVolume.setPath(volumeUUID);
+ createdVolume.setDomainId(account.getDomainId());
+ stateTransitTo(createdVolume, Volume.Event.OperationSucceeded);
+ }
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to update volume state: " + e.toString());
+ return null;
+ }
+
+ return new Pair<VolumeVO, String>(createdVolume, details);
+ }
+
+ @Override
+ @DB
+ public VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering,
+ List<StoragePoolVO> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
+
+ final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
+ DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
+ dskCh.setHyperType(vm.getHypervisorType());
+ // Find a suitable storage to create volume on
+ StoragePoolVO destPool = findStoragePool(dskCh, dc, pod, clusterId, vm, avoidPools);
+
+ // Copy the volume from secondary storage to the destination storage pool
+ stateTransitTo(volume, Event.CopyRequested);
+ VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId());
+ HostVO secStorage = _hostDao.findById(volumeHostVO.getHostId());
+ String secondaryStorageURL = secStorage.getStorageUrl();
+ String[] volumePath = volumeHostVO.getInstallPath().split("/");
+ String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0];
+
+ CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volumeUUID, destPool, secondaryStorageURL, false, _copyvolumewait);
+ CopyVolumeAnswer cvAnswer;
+ try {
+ cvAnswer = (CopyVolumeAnswer) sendToPool(destPool, cvCmd);
+ } catch (StorageUnavailableException e1) {
+ stateTransitTo(volume, Event.CopyFailed);
+ throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ stateTransitTo(volume, Event.CopyFailed);
+ throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ volume.setPath(cvAnswer.getVolumePath());
+ volume.setFolder(destPool.getPath());
+ volume.setPodId(destPool.getPodId());
+ volume.setPoolId(destPool.getId());
+ volume.setPodId(destPool.getPodId());
+ stateTransitTo(volume, Event.CopySucceeded);
+ UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize());
+ _usageEventDao.persist(usageEvent);
+ _volumeHostDao.remove(volumeHostVO.getId());
+ txn.commit();
+ return volume;
+
+ }
+
+
+ protected Pair<String, String> createVDIFromSnapshot(long userId, SnapshotVO snapshot, StoragePoolVO pool) {
+ String vdiUUID = null;
+ Long snapshotId = snapshot.getId();
+ Long volumeId = snapshot.getVolumeId();
+ String primaryStoragePoolNameLabel = pool.getUuid(); // pool's uuid is actually the namelabel.
+ Long dcId = snapshot.getDataCenterId();
+ String secondaryStoragePoolUrl = _snapMgr.getSecondaryStorageURL(snapshot);
+ long accountId = snapshot.getAccountId();
+
+ String backedUpSnapshotUuid = snapshot.getBackupSnapshotId();
+ snapshot = _snapshotDao.findById(snapshotId);
+ if (snapshot.getVersion().trim().equals("2.1")) {
+ VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
+ if (volume == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
+ }
+ if (volume.getTemplateId() == null) {
+ _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
+ if (template == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
+ }
+ Long templateId = template.getId();
+ Long tmpltAccountId = template.getAccountId();
+ if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to this snapshot is being used, try it later ");
+ }
+ UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null, secondaryStoragePoolUrl, dcId, accountId, volumeId, templateId, tmpltAccountId, null, snapshot.getBackupSnapshotId(),
+ snapshot.getName(), "2.1");
+ Answer answer = null;
+ try {
+ answer = sendToPool(pool, cmd);
+ } catch (StorageUnavailableException e) {
+ } finally {
+ _snapshotDao.unlockFromLockTable(snapshotId.toString());
+ }
+ if ((answer != null) && answer.getResult()) {
+ _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ return new Pair<String, String>(null, "Unable to upgrade snapshot from 2.1 to 2.2 for " + snapshot.getId());
+ }
+ }
+ }
+ String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool;
+ try {
+ if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+ _snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+ }
+ CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId,
+ backedUpSnapshotUuid, snapshot.getName(), _createVolumeFromSnapshotWait);
+ CreateVolumeFromSnapshotAnswer answer;
+ if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException("failed to create volume from " + snapshotId + " due to this snapshot is being used, try it later ");
+ }
+ answer = (CreateVolumeFromSnapshotAnswer) sendToPool(pool, createVolumeFromSnapshotCommand);
+ if (answer != null && answer.getResult()) {
+ vdiUUID = answer.getVdi();
+ } else {
+ s_logger.error(basicErrMsg + " due to " + ((answer == null) ? "null" : answer.getDetails()));
+ throw new CloudRuntimeException(basicErrMsg);
+ }
+ } catch (StorageUnavailableException e) {
+ s_logger.error(basicErrMsg);
+ } finally {
+ if (snapshot.getSwiftId() != null) {
+ _snapshotMgr.deleteSnapshotsDirForVolume(secondaryStoragePoolUrl, dcId, accountId, volumeId);
+ }
+ _snapshotDao.unlockFromLockTable(snapshotId.toString());
+ }
+ return new Pair<String, String>(vdiUUID, basicErrMsg);
+ }
+
+ protected Pair<String, String> createVDIFromSnapshot(long userId, SnapshotVO snapshot, StoragePoolVO pool) {
+ String vdiUUID = null;
+ Long snapshotId = snapshot.getId();
+ Long volumeId = snapshot.getVolumeId();
+ String primaryStoragePoolNameLabel = pool.getUuid(); // pool's uuid is actually the namelabel.
+ Long dcId = snapshot.getDataCenterId();
+ String secondaryStoragePoolUrl = _snapMgr.getSecondaryStorageURL(snapshot);
+ long accountId = snapshot.getAccountId();
+
+ String backedUpSnapshotUuid = snapshot.getBackupSnapshotId();
+ snapshot = _snapshotDao.findById(snapshotId);
+ if (snapshot.getVersion().trim().equals("2.1")) {
+ VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
+ if (volume == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
+ }
+ if (volume.getTemplateId() == null) {
+ _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
+ if (template == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
+ }
+ Long templateId = template.getId();
+ Long tmpltAccountId = template.getAccountId();
+ if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to this snapshot is being used, try it later ");
+ }
+ UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null, secondaryStoragePoolUrl, dcId, accountId, volumeId, templateId, tmpltAccountId, null, snapshot.getBackupSnapshotId(),
+ snapshot.getName(), "2.1");
+ Answer answer = null;
+ try {
+ answer = sendToPool(pool, cmd);
+ } catch (StorageUnavailableException e) {
+ } finally {
+ _snapshotDao.unlockFromLockTable(snapshotId.toString());
+ }
+ if ((answer != null) && answer.getResult()) {
+ _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ return new Pair<String, String>(null, "Unable to upgrade snapshot from 2.1 to 2.2 for " + snapshot.getId());
+ }
+ }
+ }
+ String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool;
+ try {
+ if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+ _snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+ }
+ CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId,
+ backedUpSnapshotUuid, snapshot.getName(), _createVolumeFromSnapshotWait);
+ CreateVolumeFromSnapshotAnswer answer;
+ if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException("failed to create volume from " + snapshotId + " due to this snapshot is being used, try it later ");
+ }
+ answer = (CreateVolumeFromSnapshotAnswer) sendToPool(pool, createVolumeFromSnapshotCommand);
+ if (answer != null && answer.getResult()) {
+ vdiUUID = answer.getVdi();
+ } else {
+ s_logger.error(basicErrMsg + " due to " + ((answer == null) ? "null" : answer.getDetails()));
+ throw new CloudRuntimeException(basicErrMsg);
+ }
+ } catch (StorageUnavailableException e) {
+ s_logger.error(basicErrMsg);
+ } finally {
+ if (snapshot.getSwiftId() != null) {
+ _snapshotMgr.deleteSnapshotsDirForVolume(secondaryStoragePoolUrl, dcId, accountId, volumeId);
+ }
+ _snapshotDao.unlockFromLockTable(snapshotId.toString());
+ }
+ return new Pair<String, String>(vdiUUID, basicErrMsg);
+ }
+
+ @Override
+ public void prepareForMigration(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest) {
+ List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Preparing " + vols.size() + " volumes for " + vm);
+ }
+
+ for (VolumeVO vol : vols) {
+ StoragePool pool = _storagePoolDao.findById(vol.getPoolId());
+ vm.addDisk(new VolumeTO(vol, pool));
+ }
+
+ if (vm.getType() == VirtualMachine.Type.User) {
+ UserVmVO userVM = (UserVmVO) vm.getVirtualMachine();
+ if (userVM.getIsoId() != null) {
+ Pair<String, String> isoPathPair = getAbsoluteIsoPath(userVM.getIsoId(), userVM.getDataCenterIdToDeployIn());
+ if (isoPathPair != null) {
+ String isoPath = isoPathPair.first();
+ VolumeTO iso = new VolumeTO(vm.getId(), Volume.Type.ISO, StoragePoolType.ISO, null, null, null, isoPath, 0, null, null);
+ vm.addDisk(iso);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+
+ return false;
+ }
+
+ @Override
+ public boolean start() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean stop() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void prepare(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException, InsufficientStorageCapacityException {
+
+ if (dest == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("DeployDestination cannot be null, cannot prepare Volumes for the vm: " + vm);
+ }
+ throw new CloudRuntimeException("Unable to prepare Volume for vm because DeployDestination is null, vm:" + vm);
+ }
+ List<VolumeVO> vols = _volumeDao.findUsableVolumesForInstance(vm.getId());
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Checking if we need to prepare " + vols.size() + " volumes for " + vm);
+ }
+
+ List<VolumeVO> recreateVols = new ArrayList<VolumeVO>(vols.size());
+
+ for (VolumeVO vol : vols) {
+ StoragePool assignedPool = null;
+ if (dest.getStorageForDisks() != null) {
+ assignedPool = dest.getStorageForDisks().get(vol);
+ }
+ if (assignedPool == null && recreate) {
+ assignedPool = _storagePoolMgr.getStoragePool(vol.getPoolId());
+
+ }
+ if (assignedPool != null || recreate) {
+ Volume.State state = vol.getState();
+ if (state == Volume.State.Allocated || state == Volume.State.Creating) {
+ recreateVols.add(vol);
+ } else {
+ if (vol.isRecreatable()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
+ }
+ recreateVols.add(vol);
+ } else {
+ if (assignedPool.getId() != vol.getPoolId()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Mismatch in storage pool " + assignedPool + " assigned by deploymentPlanner and the one associated with volume " + vol);
+ }
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
+ if (diskOffering.getUseLocalStorage())
+ {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Local volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
+ }
+ recreateVols.add(vol);
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
+ }
+ try {
+ List<Volume> volumesToMigrate = new ArrayList<Volume>();
+ volumesToMigrate.add(vol);
+ migrateVolumes(volumesToMigrate, assignedPool);
+ vm.addDisk(new VolumeTO(vol, assignedPool));
+ } catch (ConcurrentOperationException e) {
+ throw new CloudRuntimeException("Migration of volume " + vol + " to storage pool " + assignedPool + " failed", e);
+ }
+ }
+ } else {
+ StoragePoolVO pool = (StoragePoolVO)_storagePoolMgr.getStoragePoolById(vol.getPoolId());
+ vm.addDisk(new VolumeTO(vol, pool));
+ }
+
+ }
+ }
+ } else {
+ if (vol.getPoolId() == null) {
+ throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol, Volume.class, vol.getId());
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
+ }
+ StoragePoolVO pool = (StoragePoolVO)_storagePoolMgr.getStoragePoolById(vol.getPoolId());
+ vm.addDisk(new VolumeTO(vol, pool));
+ }
+ }
+
+ for (VolumeVO vol : recreateVols) {
+ VolumeVO newVol;
+ StoragePool existingPool = null;
+ if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) {
+ existingPool = (StoragePoolVO)_storagePoolMgr.getStoragePoolById(vol.getPoolId());
+ s_logger.debug("existing pool: " + existingPool.getId());
+ }
+
+ if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
+ newVol = vol;
+ } else {
+ newVol = switchVolume(vol, vm);
+ // update the volume->storagePool map since volumeId has changed
+ if (dest.getStorageForDisks() != null && dest.getStorageForDisks().containsKey(vol)) {
+ StoragePool poolWithOldVol = dest.getStorageForDisks().get(vol);
+ dest.getStorageForDisks().put(newVol, poolWithOldVol);
+ dest.getStorageForDisks().remove(vol);
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
+ }
+ }
+
+ try {
+ stateTransitTo(newVol, Volume.Event.CreateRequested);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException("Unable to create " + e.toString());
+ }
+
+ Pair<VolumeTO, StoragePool> created = createVolume(newVol, _diskOfferingDao.findById(newVol.getDiskOfferingId()), vm, vols, dest, existingPool);
+
+ if (created == null) {
+ Long poolId = newVol.getPoolId();
+ newVol.setPoolId(null);
+ try {
+ stateTransitTo(newVol, Volume.Event.OperationFailed);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException("Unable to update the failure on a volume: " + newVol, e);
+ }
+ throw new StorageUnavailableException("Unable to create " + newVol, poolId == null ? -1L : poolId);
+ }
+ created.first().setDeviceId(newVol.getDeviceId().intValue());
+ newVol.setFolder(created.second().getPath());
+ newVol.setPath(created.first().getPath());
+ newVol.setSize(created.first().getSize());
+ newVol.setPoolType(created.second().getPoolType());
+ newVol.setPodId(created.second().getPodId());
+ try {
+ stateTransitTo(newVol, Volume.Event.OperationSucceeded);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException("Unable to update an CREATE operation succeeded on volume " + newVol, e);
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Volume " + newVol + " is created on " + created.second());
+ }
+
+ vm.addDisk(created.first());
+ }
+ }
+
+ /*
+ * Just allocate a volume in the database, don't send the createvolume cmd to hypervisor. The volume will be finally
+ * created
+ * only when it's attached to a VM.
+ */
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
+ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException {
+ // FIXME: some of the scheduled event stuff might be missing here...
+ Account caller = UserContext.current().getCaller();
+
+ long ownerId = cmd.getEntityOwnerId();
+
+ // permission check
+ _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId));
+
+ // Check that the resource limit for volumes won't be exceeded
+ _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume);
+
+ Long zoneId = cmd.getZoneId();
+ Long diskOfferingId = null;
+ Long size = null;
+
+ // validate input parameters before creating the volume
+ if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) || (cmd.getSnapshotId() != null && cmd.getDiskOfferingId() != null)) {
+ throw new InvalidParameterValueException("Either disk Offering Id or snapshot Id must be passed whilst creating volume");
+ }
+
+ if (cmd.getSnapshotId() == null) {// create a new volume
+
+ diskOfferingId = cmd.getDiskOfferingId();
+ size = cmd.getSize();
+ Long sizeInGB = size;
+ if (size != null) {
+ if (size > 0) {
+ size = size * 1024 * 1024 * 1024; // user specify size in GB
+ } else {
+ throw new InvalidParameterValueException("Disk size must be larger than 0");
+ }
+ }
+ if (diskOfferingId == null) {
+ throw new InvalidParameterValueException("Missing parameter(s),either a positive volume size or a valid disk offering id must be specified.");
+ }
+ // Check that the the disk offering is specified
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
+ if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
+ throw new InvalidParameterValueException("Please specify a valid disk offering.");
+ }
+
+ if (diskOffering.isCustomized()) {
+ if (size == null) {
+ throw new InvalidParameterValueException("This disk offering requires a custom size specified");
+ }
+ if ((sizeInGB < _customDiskOfferingMinSize) || (sizeInGB > _customDiskOfferingMaxSize)) {
+ throw new InvalidParameterValueException("Volume size: " + sizeInGB + "GB is out of allowed range. Max: " + _customDiskOfferingMaxSize + " Min:" + _customDiskOfferingMinSize);
+ }
+ }
+
+ if (!diskOffering.isCustomized() && size != null) {
+ throw new InvalidParameterValueException("This disk offering does not allow custom size");
+ }
+
+ if (diskOffering.getDomainId() == null) {
+ // do nothing as offering is public
+ } else {
+ _configMgr.checkDiskOfferingAccess(caller, diskOffering);
+ }
+
+ if (diskOffering.getDiskSize() > 0) {
+ size = diskOffering.getDiskSize();
+ }
+
+ if (!validateVolumeSizeRange(size)) {// convert size from mb to gb for validation
+ throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb);
+ }
+ } else { // create volume from snapshot
+ Long snapshotId = cmd.getSnapshotId();
+ SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
+ if (snapshotCheck == null) {
+ throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
+ }
+
+ if (snapshotCheck.getStatus() != Snapshot.Status.BackedUp) {
+ throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for volume creation");
+ }
+
+ diskOfferingId = (cmd.getDiskOfferingId() != null) ? cmd.getDiskOfferingId() : snapshotCheck.getDiskOfferingId();
+ zoneId = snapshotCheck.getDataCenterId();
+ size = snapshotCheck.getSize(); // ; disk offering is used for tags purposes
+
+ // check snapshot permissions
+ _accountMgr.checkAccess(caller, null, true, snapshotCheck);
+
+ /*
+ * // bug #11428. Operation not supported if vmware and snapshots parent volume = ROOT
+ * if(snapshotCheck.getHypervisorType() == HypervisorType.VMware
+ * && _volumeDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId()).getVolumeType() == Type.ROOT){
+ * throw new UnsupportedServiceException("operation not supported, snapshot with id " + snapshotId +
+ * " is created from ROOT volume");
+ * }
+ *
+ */
+ }
+
+ // Verify that zone exists
+ DataCenterVO zone = _dcDao.findById(zoneId);
+ if (zone == null) {
+ throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+ }
+
+ // Check if zone is disabled
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
+ throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+ }
+
+ // Check that there is a shared primary storage pool in the specified zone
+ List<StoragePoolVO> storagePools = _storagePoolDao.listByDataCenterId(zoneId);
+ boolean sharedPoolExists = false;
+ for (StoragePoolVO storagePool : storagePools) {
+ if (storagePool.isShared()) {
+ sharedPoolExists = true;
+ }
+ }
+
+ // Check that there is at least one host in the specified zone
+ List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.Routing, zoneId);
+ if (hosts.isEmpty()) {
+ throw new InvalidParameterValueException("There is no workable host in data center id " + zoneId + ", please check hosts' agent status and see if they are disabled");
+ }
+
+ if (!sharedPoolExists) {
+ throw new InvalidParameterValueException("Please specify a zone that has at least one shared primary storage pool.");
+ }
+
+ String userSpecifiedName = cmd.getVolumeName();
+ if (userSpecifiedName == null) {
+ userSpecifiedName = getRandomVolumeName();
+ }
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK);
+ volume.setPoolId(null);
+ volume.setDataCenterId(zoneId);
+ volume.setPodId(null);
+ volume.setAccountId(ownerId);
+ volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()));
+ volume.setDiskOfferingId(diskOfferingId);
+ volume.setSize(size);
+ volume.setInstanceId(null);
+ volume.setUpdated(new Date());
+ volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId());
+
+ volume = _volumeDao.persist(volume);
+ if(cmd.getSnapshotId() == null){
+ //for volume created from snapshot, create usage event after volume creation
+ UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size);
+ _usageEventDao.persist(usageEvent);
+ }
+
+ UserContext.current().setEventDetails("Volume Id: " + volume.getId());
+
+ // Increment resource count during allocation; if actual creation fails, decrement it
+ _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume);
+
+ txn.commit();
+
+ return volume;
+ }
+
+ public Pair<VolumeTO, StoragePool> createVolume(VolumeVO toBeCreated, DiskOfferingVO offering, VirtualMachineProfile<? extends VirtualMachine> vm, List<? extends Volume> alreadyCreated,
+ DeployDestination dest, StoragePool sPool) throws StorageUnavailableException {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Creating volume: " + toBeCreated);
+ }
+ DiskProfile diskProfile = new DiskProfile(toBeCreated, offering, vm.getHypervisorType());
+
+ VMTemplateVO template = null;
+ if (toBeCreated.getTemplateId() != null) {
+ template = _imageMgr.getImageById(toBeCreated.getTemplateId());
+ }
+
+ StoragePool pool = null;
+ if (sPool != null) {
+ pool = sPool;
+ } else {
+ pool = dest.getStorageForDisks().get(toBeCreated);
+ }
+
+ if (pool != null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Trying to create in " + pool);
+ }
+ toBeCreated.setPoolId(pool.getId());
+ try {
+ stateTransitTo(toBeCreated, Volume.Event.OperationRetry);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException("Unable to retry a create operation on volume " + toBeCreated);
+ }
+
+ CreateCommand cmd = null;
+ VMTemplateStoragePoolVO tmpltStoredOn = null;
+
+ for (int i = 0; i < 2; i++) {
+ if (template != null && template.getFormat() != Storage.ImageFormat.ISO) {
+ tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
+ if (tmpltStoredOn == null) {
+ s_logger.debug("Cannot use this pool " + pool + " because we can't propagate template " + template);
+ return null;
+ }
+ cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
+ } else {
+ if (template != null && Storage.ImageFormat.ISO == template.getFormat()) {
+ VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
+ if (tmpltHostOn == null) {
+ throw new CloudRuntimeException("Did not find ISO in secondry storage in zone " + pool.getDataCenterId());
+ }
+ }
+ cmd = new CreateCommand(diskProfile, new StorageFilerTO(pool));
+ }
+ long[] hostIdsToTryFirst = { dest.getHost().getId() };
+ Answer answer = _storagePoolMgr.sendToPool(pool, hostIdsToTryFirst, cmd);
+ if (answer.getResult()) {
+ CreateAnswer createAnswer = (CreateAnswer) answer;
+ return new Pair<VolumeTO, StoragePool>(createAnswer.getVolume(), pool);
+ } else {
+ if (tmpltStoredOn != null && (answer instanceof CreateAnswer) && ((CreateAnswer) answer).templateReloadRequested()) {
+ if (!_tmpltMgr.resetTemplateDownloadStateOnPool(tmpltStoredOn.getId())) {
+ break; // break out of template-redeploy retry loop
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unable to create volume " + toBeCreated);
+ }
+ return null;
+ }
+
+ @DB
+ public boolean migrateVolumes(List<Volume> volumes, StoragePool destPool) throws ConcurrentOperationException {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ boolean transitResult = false;
+ long checkPointTaskId = -1;
+ try {
+ List<Long> volIds = new ArrayList<Long>();
+ for (Volume volume : volumes) {
+ if (!_snapshotMgr.canOperateOnVolume((VolumeVO) volume)) {
+ throw new CloudRuntimeException("There are snapshots creating on this volume, can not move this volume");
+ }
+
+ try {
+ if (!stateTransitTo(volume, Volume.Event.MigrationRequested)) {
+ throw new ConcurrentOperationException("Failed to transit volume state");
+ }
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to set state into migrate: " + e.toString());
+ throw new CloudRuntimeException("Failed to set state into migrate: " + e.toString());
+ }
+ volIds.add(volume.getId());
+ }
+
+ checkPointTaskId = _checkPointMgr.pushCheckPoint(new StorageMigrationCleanupMaid(StorageMigrationCleanupMaid.StorageMigrationState.MIGRATING, volIds));
+ transitResult = true;
+ } finally {
+ if (!transitResult) {
+ txn.rollback();
+ } else {
+ txn.commit();
+ }
+ }
+
+ // At this stage, nobody can modify volumes. Send the copyvolume command
+ List<Pair<StoragePoolVO, DestroyCommand>> destroyCmds = new ArrayList<Pair<StoragePoolVO, DestroyCommand>>();
+ List<CopyVolumeAnswer> answers = new ArrayList<CopyVolumeAnswer>();
+ try {
+ for (Volume volume : volumes) {
+ String secondaryStorageURL = getSecondaryStorageURL(volume.getDataCenterId());
+ StoragePoolVO srcPool = _storagePoolDao.findById(volume.getPoolId());
+ CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, _copyvolumewait);
+ CopyVolumeAnswer cvAnswer;
+ try {
+ cvAnswer = (CopyVolumeAnswer) sendToPool(srcPool, cvCmd);
+ } catch (StorageUnavailableException e1) {
+ throw new CloudRuntimeException("Failed to copy the volume from the source primary storage pool to secondary storage.", e1);
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ throw new CloudRuntimeException("Failed to copy the volume from the source primary storage pool to secondary storage.");
+ }
+
+ String secondaryStorageVolumePath = cvAnswer.getVolumePath();
+
+ // Copy the volume from secondary storage to the destination storage
+ // pool
+ cvCmd = new CopyVolumeCommand(volume.getId(), secondaryStorageVolumePath, destPool, secondaryStorageURL, false, _copyvolumewait);
+ try {
+ cvAnswer = (CopyVolumeAnswer) sendToPool(destPool, cvCmd);
+ } catch (StorageUnavailableException e1) {
+ throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+
+ answers.add(cvAnswer);
+ destroyCmds.add(new Pair<StoragePoolVO, DestroyCommand>(srcPool, new DestroyCommand(srcPool, volume, null)));
+ }
+ } finally {
+ if (answers.size() != volumes.size()) {
+ // this means one of copying volume failed
+ for (Volume volume : volumes) {
+ try {
+ stateTransitTo(volume, Volume.Event.OperationFailed);
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to change volume state: " + e.toString());
+ }
+ }
+ _checkPointMgr.popCheckPoint(checkPointTaskId);
+ } else {
+ // Need a transaction, make sure all the volumes get migrated to new storage pool
+ txn = Transaction.currentTxn();
+ txn.start();
+
+ transitResult = false;
+ try {
+ for (int i = 0; i < volumes.size(); i++) {
+ CopyVolumeAnswer answer = answers.get(i);
+ VolumeVO volume = (VolumeVO) volumes.get(i);
+ Long oldPoolId = volume.getPoolId();
+ volume.setPath(answer.getVolumePath());
+ volume.setFolder(destPool.getPath());
+ volume.setPodId(destPool.getPodId());
+ volume.setPoolId(destPool.getId());
+ volume.setLastPoolId(oldPoolId);
+ volume.setPodId(destPool.getPodId());
+ try {
+ stateTransitTo(volume, Volume.Event.OperationSucceeded);
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to change volume state: " + e.toString());
+ throw new CloudRuntimeException("Failed to change volume state: " + e.toString());
+ }
+ }
+ transitResult = true;
+ try {
+ _checkPointMgr.popCheckPoint(checkPointTaskId);
+ } catch (Exception e) {
+
+ }
+ } finally {
+ if (!transitResult) {
+ txn.rollback();
+ } else {
+ txn.commit();
+ }
+ }
+
+ }
+ }
+
+ // all the volumes get migrated to new storage pool, need to delete the copy on old storage pool
+ for (Pair<StoragePoolVO, DestroyCommand> cmd : destroyCmds) {
+ try {
+ Answer cvAnswer = _storagePoolMgr.sendToPool(cmd.first(), cmd.second());
+ } catch (StorageUnavailableException e) {
+ s_logger.debug("Unable to delete the old copy on storage pool: " + e.toString());
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean StorageMigration(VirtualMachineProfile<? extends VirtualMachine> vm, StoragePool destPool) throws ConcurrentOperationException {
+ List<VolumeVO> vols = _volumeDao.findUsableVolumesForInstance(vm.getId());
+ List<Volume> volumesNeedToMigrate = new ArrayList<Volume>();
+
+ for (VolumeVO volume : vols) {
+ if (volume.getState() != Volume.State.Ready) {
+ s_logger.debug("volume: " + volume.getId() + " is in " + volume.getState() + " state");
+ throw new CloudRuntimeException("volume: " + volume.getId() + " is in " + volume.getState() + " state");
+ }
+
+ if (volume.getPoolId() == destPool.getId()) {
+ s_logger.debug("volume: " + volume.getId() + " is on the same storage pool: " + destPool.getId());
+ continue;
+ }
+
+ volumesNeedToMigrate.add(volume);
+ }
+
+ if (volumesNeedToMigrate.isEmpty()) {
+ s_logger.debug("No volume need to be migrated");
+ return true;
+ }
+
+ return migrateVolumes(volumesNeedToMigrate, destPool);
+ }
+
+
+ @DB
+ @Override
+ public Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException {
+ VolumeVO vol = _volumeDao.findById(volumeId);
+ if (vol == null) {
+ throw new InvalidParameterValueException("Failed to find the volume id: " + volumeId);
+ }
+
+ if (vol.getState() != Volume.State.Ready) {
+ throw new InvalidParameterValueException("Volume must be in ready state");
+ }
+
+ if (vol.getInstanceId() != null) {
+ throw new InvalidParameterValueException("Volume needs to be dettached from VM");
+ }
+
+ StoragePool destPool = _storagePoolMgr.getStoragePool(storagePoolId);
+ if (destPool == null) {
+ throw new InvalidParameterValueException("Faild to find the destination storage pool: " + storagePoolId);
+ }
+
+ List<Volume> vols = new ArrayList<Volume>();
+ vols.add(vol);
+
+ migrateVolumes(vols, destPool);
+ return vol;
+ }
+
+ @Override
+ public void allocateVolume(Long vmId,
+ Pair<? extends DiskOfferingVO, Long> rootDiskOffering,
+ List<Pair<DiskOfferingVO, Long>> dataDiskOfferings, Long templateId, Account owner) {
+
+ _volumeMgr.allocateVolume(vmId, rootDiskOffering, dataDiskOfferings, templateId, owner);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5ba4913f/server/src/com/cloud/storage/pool/StoragePoolManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/pool/StoragePoolManager.java b/server/src/com/cloud/storage/pool/StoragePoolManager.java
new file mode 100755
index 0000000..bd0b5c1
--- /dev/null
+++ b/server/src/com/cloud/storage/pool/StoragePoolManager.java
@@ -0,0 +1,151 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.pool;
+
+import java.util.List;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientStorageCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.StoragePoolVO;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.pool.Storage.ImageFormat;
+import com.cloud.storage.volume.Volume;
+import com.cloud.storage.volume.Volume.Event;
+import com.cloud.storage.volume.Volume.Type;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface StoragePoolManager extends StoragePoolService, Manager {
+ boolean canVmRestartOnAnotherServer(long vmId);
+
+ /**
+ * Returns the URL of the secondary storage host
+ * @param zoneId
+ * @return URL
+ */
+ public String getSecondaryStorageURL(long zoneId);
+
+ /**
+ * Returns a comma separated list of tags for the specified storage pool
+ * @param poolId
+ * @return comma separated list of tags
+ */
+ public String getStoragePoolTags(long poolId);
+
+ /**
+ * Returns the secondary storage host
+ * @param zoneId
+ * @return secondary storage host
+ */
+ public HostVO getSecondaryStorageHost(long zoneId);
+
+ /**
+ * Returns the secondary storage host
+ * @param zoneId
+ * @return secondary storage host
+ */
+ public VMTemplateHostVO findVmTemplateHost(long templateId, StoragePool pool);
+
+ /** Create capacity entries in the op capacity table
+ * @param storagePool
+ */
+ public void createCapacityEntry(StoragePoolVO storagePool);
+
+ Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException;
+ Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException;
+ Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException;
+ Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException;
+ Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException;
+ Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
+
+ /**
+ * Checks if a host has running VMs that are using its local storage pool.
+ * @return true if local storage is active on the host
+ */
+ boolean isLocalStorageActiveOnHost(Host host);
+
+ /**
+ * Cleans up storage pools by removing unused templates.
+ * @param recurring - true if this cleanup is part of a recurring garbage collection thread
+ */
+ void cleanupStorage(boolean recurring);
+
+ String getPrimaryStorageNameLabel(VolumeVO volume);
+
+ void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated);
+
+ void release(VirtualMachineProfile<? extends VMInstanceVO> profile);
+
+ Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException;
+
+ CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId);
+
+ CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId);
+
+ boolean createStoragePool(long hostId, StoragePoolVO pool);
+
+ boolean delPoolFromHost(long hostId);
+
+ HostVO getSecondaryStorageHost(long zoneId, long tmpltId);
+
+ List<HostVO> getSecondaryStorageHosts(long zoneId);
+
+ List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type);
+
+
+ List<VMInstanceVO> listByStoragePool(long storagePoolId);
+
+ StoragePoolVO findLocalStorageOnHost(long hostId);
+
+ VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, boolean readyOnly);
+
+ Host updateSecondaryStorage(long secStorageId, String newUrl);
+
+ List<Long> getUpHostsInPool(long poolId);
+
+ void cleanupSecondaryStorage(boolean recurring);
+
+ String getSupportedImageFormatForCluster(Long clusterId);
+
+ HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
+
+ boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
+
+ StoragePool getStoragePoolById(Long id);
+}