From 5ba4913f632efd8bccec372c8e7f371456713f8e Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 15 Aug 2012 17:44:30 -0700 Subject: [PATCH] refactor --- .../agent/manager/MockStorageManagerImpl.java | 4 +- .../cloud/resource/AgentRoutingResource.java | 2 +- .../cloud/simulator/MockStoragePoolVO.java | 2 +- .../simulator/dao/MockStoragePoolDaoImpl.java | 2 +- .../cloud/agent/resource/DummyResource.java | 4 +- .../cloud/agent/api/AttachVolumeCommand.java | 2 +- .../agent/api/BackupSnapshotCommand.java | 2 +- .../agent/api/CreateStoragePoolCommand.java | 2 +- .../agent/api/DeleteStoragePoolCommand.java | 2 +- .../cloud/agent/api/GetFileStatsAnswer.java | 2 +- .../cloud/agent/api/GetFileStatsCommand.java | 2 +- .../agent/api/GetStorageStatsAnswer.java | 2 +- .../agent/api/GetStorageStatsCommand.java | 2 +- .../agent/api/ManageSnapshotCommand.java | 2 +- .../agent/api/ModifyStoragePoolCommand.java | 2 +- .../agent/api/StartupStorageCommand.java | 4 +- .../com/cloud/agent/api/StoragePoolInfo.java | 2 +- .../api/storage/AbstractDownloadCommand.java | 2 +- .../api/storage/AbstractUploadCommand.java | 2 +- .../agent/api/storage/CopyVolumeCommand.java | 2 +- .../agent/api/storage/CreateCommand.java | 2 +- .../storage/CreatePrivateTemplateAnswer.java | 2 +- .../agent/api/storage/DestroyCommand.java | 4 +- .../agent/api/storage/DownloadCommand.java | 4 +- .../PrimaryStorageDownloadCommand.java | 2 +- .../cloud/agent/api/to/StorageFilerTO.java | 4 +- .../com/cloud/agent/api/to/TemplateTO.java | 2 +- api/src/com/cloud/agent/api/to/VolumeTO.java | 6 +- api/src/com/cloud/api/BaseCmd.java | 6 +- api/src/com/cloud/api/ResponseGenerator.java | 6 +- .../cloud/api/commands/AttachVolumeCmd.java | 2 +- .../CancelPrimaryStorageMaintenanceCmd.java | 4 +- .../cloud/api/commands/CreateSnapshotCmd.java | 4 +- .../api/commands/CreateSnapshotPolicyCmd.java | 2 +- .../api/commands/CreateStoragePoolCmd.java | 2 +- .../cloud/api/commands/CreateTemplateCmd.java | 4 +- .../cloud/api/commands/CreateVolumeCmd.java | 2 +- .../com/cloud/api/commands/DeletePoolCmd.java | 4 +- .../cloud/api/commands/DeleteSnapshotCmd.java | 2 +- .../cloud/api/commands/DeleteVolumeCmd.java | 2 +- .../cloud/api/commands/DetachVolumeCmd.java | 2 +- .../cloud/api/commands/ExtractVolumeCmd.java | 2 +- .../commands/ListGuestOsCategoriesCmd.java | 2 +- .../cloud/api/commands/ListGuestOsCmd.java | 2 +- .../api/commands/ListIsoPermissionsCmd.java | 2 +- .../cloud/api/commands/ListSnapshotsCmd.java | 2 +- .../api/commands/ListStoragePoolsCmd.java | 2 +- .../commands/ListTemplatePermissionsCmd.java | 2 +- .../cloud/api/commands/ListVolumesCmd.java | 2 +- .../com/cloud/api/commands/MigrateVMCmd.java | 2 +- .../cloud/api/commands/MigrateVolumeCmd.java | 2 +- ...reparePrimaryStorageForMaintenanceCmd.java | 4 +- .../api/commands/UpdateStoragePoolCmd.java | 2 +- .../cloud/api/commands/UploadVolumeCmd.java | 4 +- .../cloud/api/response/SnapshotResponse.java | 2 +- .../api/response/StoragePoolResponse.java | 2 +- .../cloud/api/response/TemplateResponse.java | 2 +- .../com/cloud/deploy/DeployDestination.java | 4 +- .../com/cloud/deploy/DeploymentPlanner.java | 2 +- .../InsufficientStorageCapacityException.java | 2 +- .../StorageUnavailableException.java | 2 +- .../com/cloud/server/ManagementService.java | 6 +- .../orchestra/StorageOrchestraEngine.java | 10 + .../com/cloud/storage/{ => pool}/Storage.java | 2 +- .../cloud/storage/{ => pool}/StoragePool.java | 4 +- .../StoragePoolService.java} | 61 +- .../storage/{ => pool}/StoragePoolStatus.java | 2 +- .../storage/{ => pool}/StorageStats.java | 2 +- .../storage/{ => snapshot}/Snapshot.java | 2 +- .../storage/snapshot/SnapshotService.java | 1 - .../cloud/storage/{ => volume}/GuestOS.java | 2 +- .../storage/{ => volume}/GuestOsCategory.java | 2 +- .../storage/{ => volume}/StorageGuru.java | 2 +- .../cloud/storage/{ => volume}/Volume.java | 2 +- .../cloud/storage/volume/VolumeService.java | 59 + .../storage/{ => volume}/VolumeStats.java | 2 +- .../com/cloud/template/TemplateService.java | 5 + .../template/VirtualMachineTemplate.java | 4 +- api/src/com/cloud/vm/DiskProfile.java | 2 +- api/src/com/cloud/vm/UserVmService.java | 4 +- core/src/com/cloud/host/HostVO.java | 2 +- .../hyperv/resource/HypervResource.java | 2 +- .../com/cloud/storage/GuestOSCategoryVO.java | 1 + core/src/com/cloud/storage/GuestOSVO.java | 1 + .../cloud/storage/SecondaryStorageLayer.java | 2 +- core/src/com/cloud/storage/SnapshotVO.java | 1 + core/src/com/cloud/storage/StoragePoolVO.java | 4 +- core/src/com/cloud/storage/VMTemplateVO.java | 5 +- core/src/com/cloud/storage/VolumeHostVO.java | 3 +- core/src/com/cloud/storage/VolumeVO.java | 3 +- .../CifsSecondaryStorageResource.java | 4 +- .../LocalSecondaryStorageResource.java | 4 +- .../storage/template/DownloadManager.java | 2 +- .../storage/template/DownloadManagerImpl.java | 2 +- .../cloud/storage/template/IsoProcessor.java | 2 +- .../com/cloud/storage/template/Processor.java | 2 +- .../storage/template/QCOW2Processor.java | 2 +- .../storage/template/RawImageProcessor.java | 2 +- .../storage/template/TemplateLocation.java | 2 +- .../cloud/storage/template/UploadManager.java | 2 +- .../storage/template/UploadManagerImpl.java | 2 +- .../cloud/storage/template/VhdProcessor.java | 2 +- .../cloud/storage/template/VmdkProcessor.java | 2 +- core/src/com/cloud/vm/VirtualDisk.java | 2 +- .../cloud/agent/transport/RequestTest.java | 4 +- .../kvm/resource/FakeComputingResource.java | 8 +- .../resource/LibvirtComputingResource.java | 8 +- .../kvm/storage/KVMStoragePool.java | 2 +- .../kvm/storage/KVMStoragePoolManager.java | 2 +- .../kvm/storage/LibvirtStorageAdaptor.java | 2 +- .../kvm/storage/LibvirtStoragePool.java | 2 +- .../kvm/storage/StorageAdaptor.java | 2 +- .../cloud/ovm/hypervisor/OvmResourceBase.java | 6 +- .../vmware/VmwareServerDiscoverer.java | 4 +- .../manager/VmwareStorageManagerImpl.java | 2 +- .../vmware/resource/VmwareResource.java | 6 +- .../com/cloud/hypervisor/XenServerGuru.java | 2 +- .../xen/discoverer/XcpServerDiscoverer.java | 4 +- .../xen/resource/CitrixResourceBase.java | 8 +- .../xen/resource/XenServer56FP1Resource.java | 2 +- .../allocator/RandomStoragePoolAllocator.java | 2 +- .../cloud/agent/manager/AgentManagerImpl.java | 8 +- .../src/com/cloud/alert/AlertManagerImpl.java | 4 +- server/src/com/cloud/api/ApiDBUtils.java | 16 +- .../src/com/cloud/api/ApiResponseHelper.java | 18 +- .../cloud/async/AsyncJobExecutorContext.java | 4 +- .../async/AsyncJobExecutorContextImpl.java | 10 +- .../executor/ExtractJobResultObject.java | 2 +- .../baremetal/BareMetalVmManagerImpl.java | 6 +- .../cloud/capacity/CapacityManagerImpl.java | 4 +- .../capacity/StorageCapacityListener.java | 2 +- .../cloud/capacity/dao/CapacityDaoImpl.java | 2 +- .../src/com/cloud/configuration/Config.java | 14 +- .../DefaultComponentLibrary.java | 4 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 6 +- .../src/com/cloud/deploy/FirstFitPlanner.java | 8 +- .../cloud/ha/HighAvailabilityManagerImpl.java | 4 +- .../CloudZonesStartupProcessor.java | 2 +- .../VirtualNetworkApplianceManagerImpl.java | 2 +- .../cloud/resource/ResourceManagerImpl.java | 14 +- .../cloud/server/ManagementServerImpl.java | 12 +- .../src/com/cloud/server/StatsCollector.java | 10 +- .../storage/LocalStoragePoolListener.java | 4 +- .../src/com/cloud/storage/OCFS2Manager.java | 1 + .../com/cloud/storage/OCFS2ManagerImpl.java | 3 +- .../storage/StorageMigrationCleanupMaid.java | 1 + .../AbstractStoragePoolAllocator.java | 14 +- .../FirstFitStoragePoolAllocator.java | 4 +- ...GarbageCollectingStoragePoolAllocator.java | 10 +- .../allocator/LocalStoragePoolAllocator.java | 2 +- .../allocator/StoragePoolAllocator.java | 2 +- .../allocator/UseLocalForRootAllocator.java | 4 +- .../storage/backup/StorageBackupManager.java | 5 + .../backup/StorageBackupManagerImpl.java | 5 + .../storage/dao/LaunchPermissionDaoImpl.java | 4 +- .../com/cloud/storage/dao/SnapshotDao.java | 4 +- .../cloud/storage/dao/SnapshotDaoImpl.java | 6 +- .../storage/dao/SnapshotScheduleDaoImpl.java | 2 +- .../com/cloud/storage/dao/StoragePoolDao.java | 2 +- .../cloud/storage/dao/StoragePoolDaoImpl.java | 4 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 6 +- .../src/com/cloud/storage/dao/VolumeDao.java | 4 +- .../com/cloud/storage/dao/VolumeDaoImpl.java | 14 +- .../storage/download/DownloadListener.java | 10 +- .../storage/download/DownloadMonitor.java | 2 +- .../storage/download/DownloadMonitorImpl.java | 10 +- .../com/cloud/storage/image/ImageManager.java | 12 + .../cloud/storage/image/ImageManagerImpl.java | 37 + .../storage/listener/StoragePoolMonitor.java | 8 +- .../orchestra/StorageOrchestraEngine.java | 30 + .../orchestra/StorageOrchestraEngineImpl.java | 1014 +++++++++ .../StoragePoolManager.java} | 119 +- .../StoragePoolManagerImpl.java} | 1818 +---------------- .../DummySecondaryStorageResource.java | 4 +- .../secondary/SecondaryStorageListener.java | 2 +- .../SecondaryStorageManagerImpl.java | 2 +- .../storage/snapshot/SnapshotManagerImpl.java | 17 +- .../snapshot/SnapshotSchedulerImpl.java | 1 - .../cloud/storage/upload/UploadListener.java | 2 +- .../storage/upload/UploadMonitorImpl.java | 2 +- .../cloud/storage/volume/VolumeManager.java | 132 ++ .../storage/volume/VolumeManagerImpl.java | 1013 +++++++++ .../template/HyervisorTemplateAdapter.java | 4 +- .../cloud/template/TemplateAdapterBase.java | 6 +- .../com/cloud/template/TemplateManager.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 42 +- .../com/cloud/template/TemplateProfile.java | 2 +- .../com/cloud/user/AccountManagerImpl.java | 6 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 22 +- .../com/cloud/vm/VirtualMachineManager.java | 2 +- .../cloud/vm/VirtualMachineManagerImpl.java | 29 +- .../com/cloud/snapshot/SnapshotDaoTest.java | 2 +- .../cloud/storage/dao/StoragePoolDaoTest.java | 2 +- .../com/cloud/vm/MockUserVmManagerImpl.java | 4 +- .../vm/MockVirtualMachineManagerImpl.java | 2 +- 195 files changed, 2776 insertions(+), 2293 deletions(-) create mode 100644 api/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java rename api/src/com/cloud/storage/{ => pool}/Storage.java (99%) rename api/src/com/cloud/storage/{ => pool}/StoragePool.java (96%) rename api/src/com/cloud/storage/{StorageService.java => pool/StoragePoolService.java} (64%) rename api/src/com/cloud/storage/{ => pool}/StoragePoolStatus.java (96%) rename api/src/com/cloud/storage/{ => pool}/StorageStats.java (97%) rename api/src/com/cloud/storage/{ => snapshot}/Snapshot.java (98%) rename api/src/com/cloud/storage/{ => volume}/GuestOS.java (96%) rename api/src/com/cloud/storage/{ => volume}/GuestOsCategory.java (96%) rename api/src/com/cloud/storage/{ => volume}/StorageGuru.java (96%) rename api/src/com/cloud/storage/{ => volume}/Volume.java (99%) create mode 100644 api/src/com/cloud/storage/volume/VolumeService.java rename api/src/com/cloud/storage/{ => volume}/VolumeStats.java (96%) create mode 100644 server/src/com/cloud/storage/backup/StorageBackupManager.java create mode 100644 server/src/com/cloud/storage/backup/StorageBackupManagerImpl.java create mode 100644 server/src/com/cloud/storage/image/ImageManager.java create mode 100644 server/src/com/cloud/storage/image/ImageManagerImpl.java create mode 100644 server/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java create mode 100644 server/src/com/cloud/storage/orchestra/StorageOrchestraEngineImpl.java rename server/src/com/cloud/storage/{StorageManager.java => pool/StoragePoolManager.java} (54%) rename server/src/com/cloud/storage/{StorageManagerImpl.java => pool/StoragePoolManagerImpl.java} (55%) create mode 100644 server/src/com/cloud/storage/volume/VolumeManager.java create mode 100644 server/src/com/cloud/storage/volume/VolumeManagerImpl.java diff --git a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index 7b096fbd845..7c6532dac27 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -85,9 +85,9 @@ import com.cloud.simulator.dao.MockStoragePoolDao; import com.cloud.simulator.dao.MockVMDao; import com.cloud.simulator.dao.MockVolumeDao; import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.component.Inject; import com.cloud.vm.DiskProfile; diff --git a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java index f10713d126c..719898c833a 100644 --- a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -54,7 +54,7 @@ import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.simulator.MockVMVO; -import com.cloud.storage.Storage.StorageResourceType; +import com.cloud.storage.pool.Storage.StorageResourceType; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine.State; diff --git a/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java b/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java index 81f0432247d..851c77b49f7 100644 --- a/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java +++ b/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java @@ -25,7 +25,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; @Entity @Table(name="mockstoragepool") diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java b/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java index e35b5372946..3df026c7003 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java +++ b/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java @@ -19,7 +19,7 @@ package com.cloud.simulator.dao; import javax.ejb.Local; import com.cloud.simulator.MockStoragePoolVO; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; diff --git a/agent/src/com/cloud/agent/resource/DummyResource.java b/agent/src/com/cloud/agent/resource/DummyResource.java index 573f639b06d..58fe055c73f 100755 --- a/agent/src/com/cloud/agent/resource/DummyResource.java +++ b/agent/src/com/cloud/agent/resource/DummyResource.java @@ -40,8 +40,8 @@ import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.resource.ServerResource; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; @Local(value = { ServerResource.class }) public class DummyResource implements ServerResource { diff --git a/api/src/com/cloud/agent/api/AttachVolumeCommand.java b/api/src/com/cloud/agent/api/AttachVolumeCommand.java index 98bfb2e485e..84090116b74 100644 --- a/api/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/api/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public class AttachVolumeCommand extends Command { diff --git a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java index 9476d7d7065..6a0e9aa3df6 100644 --- a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java +++ b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java @@ -19,7 +19,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; /** * This currently assumes that both primary and secondary storage are mounted on the XenServer. diff --git a/api/src/com/cloud/agent/api/CreateStoragePoolCommand.java b/api/src/com/cloud/agent/api/CreateStoragePoolCommand.java index ecba6c232e2..1fc6c1ce4da 100644 --- a/api/src/com/cloud/agent/api/CreateStoragePoolCommand.java +++ b/api/src/com/cloud/agent/api/CreateStoragePoolCommand.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; public class CreateStoragePoolCommand extends ModifyStoragePoolCommand { diff --git a/api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java b/api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java index 7fa60adb0fe..4968308f926 100644 --- a/api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java +++ b/api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java @@ -20,7 +20,7 @@ import java.io.File; import java.util.UUID; import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; public class DeleteStoragePoolCommand extends Command { diff --git a/api/src/com/cloud/agent/api/GetFileStatsAnswer.java b/api/src/com/cloud/agent/api/GetFileStatsAnswer.java index f93070eae40..5f0a24b016e 100755 --- a/api/src/com/cloud/agent/api/GetFileStatsAnswer.java +++ b/api/src/com/cloud/agent/api/GetFileStatsAnswer.java @@ -17,7 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.storage.VolumeStats; +import com.cloud.storage.volume.VolumeStats; @LogLevel(Log4jLevel.Trace) public class GetFileStatsAnswer extends Answer implements VolumeStats { diff --git a/api/src/com/cloud/agent/api/GetFileStatsCommand.java b/api/src/com/cloud/agent/api/GetFileStatsCommand.java index c6dc213eff5..7372b7fa487 100755 --- a/api/src/com/cloud/agent/api/GetFileStatsCommand.java +++ b/api/src/com/cloud/agent/api/GetFileStatsCommand.java @@ -17,7 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; @LogLevel(Log4jLevel.Trace) public class GetFileStatsCommand extends Command { diff --git a/api/src/com/cloud/agent/api/GetStorageStatsAnswer.java b/api/src/com/cloud/agent/api/GetStorageStatsAnswer.java index 2443e8e0b9a..2e05f0f8f94 100755 --- a/api/src/com/cloud/agent/api/GetStorageStatsAnswer.java +++ b/api/src/com/cloud/agent/api/GetStorageStatsAnswer.java @@ -17,7 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.storage.StorageStats; +import com.cloud.storage.pool.StorageStats; @LogLevel(Log4jLevel.Trace) public class GetStorageStatsAnswer extends Answer implements StorageStats { diff --git a/api/src/com/cloud/agent/api/GetStorageStatsCommand.java b/api/src/com/cloud/agent/api/GetStorageStatsCommand.java index f7ebd51fb9f..4126ddacd97 100755 --- a/api/src/com/cloud/agent/api/GetStorageStatsCommand.java +++ b/api/src/com/cloud/agent/api/GetStorageStatsCommand.java @@ -17,7 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; @LogLevel(Log4jLevel.Trace) public class GetStorageStatsCommand extends Command { diff --git a/api/src/com/cloud/agent/api/ManageSnapshotCommand.java b/api/src/com/cloud/agent/api/ManageSnapshotCommand.java index 9a5f424167c..6056b64aec2 100644 --- a/api/src/com/cloud/agent/api/ManageSnapshotCommand.java +++ b/api/src/com/cloud/agent/api/ManageSnapshotCommand.java @@ -17,7 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; public class ManageSnapshotCommand extends Command { diff --git a/api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java b/api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java index 04f14e3de8f..46ad5fffa67 100644 --- a/api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java +++ b/api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java @@ -20,7 +20,7 @@ import java.io.File; import java.util.UUID; import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; public class ModifyStoragePoolCommand extends Command { diff --git a/api/src/com/cloud/agent/api/StartupStorageCommand.java b/api/src/com/cloud/agent/api/StartupStorageCommand.java index d1e67d48800..6781ac7a817 100755 --- a/api/src/com/cloud/agent/api/StartupStorageCommand.java +++ b/api/src/com/cloud/agent/api/StartupStorageCommand.java @@ -20,8 +20,8 @@ import java.util.HashMap; import java.util.Map; import com.cloud.host.Host; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; diff --git a/api/src/com/cloud/agent/api/StoragePoolInfo.java b/api/src/com/cloud/agent/api/StoragePoolInfo.java index 4ac6b296ba3..698d2c981b7 100644 --- a/api/src/com/cloud/agent/api/StoragePoolInfo.java +++ b/api/src/com/cloud/agent/api/StoragePoolInfo.java @@ -18,7 +18,7 @@ package com.cloud.agent.api; import java.util.Map; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public class StoragePoolInfo { String uuid; diff --git a/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java index 5737a05d98b..b772c574723 100644 --- a/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api.storage; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; public abstract class AbstractDownloadCommand extends ssCommand { diff --git a/api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java b/api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java index 1c55e8fafd6..2d6e0827f73 100644 --- a/api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java +++ b/api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api.storage; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; public class AbstractUploadCommand extends StorageCommand{ diff --git a/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 26bd1871138..f45d9a3f269 100644 --- a/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -18,7 +18,7 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.Command; import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; public class CopyVolumeCommand extends Command { diff --git a/api/src/com/cloud/agent/api/storage/CreateCommand.java b/api/src/com/cloud/agent/api/storage/CreateCommand.java index b8b2446216d..b607f3cb65a 100644 --- a/api/src/com/cloud/agent/api/storage/CreateCommand.java +++ b/api/src/com/cloud/agent/api/storage/CreateCommand.java @@ -18,7 +18,7 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.Command; import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.vm.DiskProfile; public class CreateCommand extends Command { diff --git a/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java b/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java index 2dfcf211c0f..5d3e972b3ee 100644 --- a/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java +++ b/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java @@ -18,7 +18,7 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; public class CreatePrivateTemplateAnswer extends Answer { private String _path; diff --git a/api/src/com/cloud/agent/api/storage/DestroyCommand.java b/api/src/com/cloud/agent/api/storage/DestroyCommand.java index 29c564c3bc3..c8fe396d440 100755 --- a/api/src/com/cloud/agent/api/storage/DestroyCommand.java +++ b/api/src/com/cloud/agent/api/storage/DestroyCommand.java @@ -17,9 +17,9 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.to.VolumeTO; -import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.volume.Volume; public class DestroyCommand extends StorageCommand { // in VMware, things are designed around VM instead of volume, we need it the volume VM context if the volume is attached diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/api/src/com/cloud/agent/api/storage/DownloadCommand.java index af9ff40b0f2..a5cfeeb692c 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadCommand.java @@ -18,8 +18,8 @@ package com.cloud.agent.api.storage; import java.net.URI; -import com.cloud.storage.Volume; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; diff --git a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java index b56317727e2..234d44cb250 100644 --- a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api.storage; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; /** diff --git a/api/src/com/cloud/agent/api/to/StorageFilerTO.java b/api/src/com/cloud/agent/api/to/StorageFilerTO.java index 26344daaeb6..cf6abd7ada3 100644 --- a/api/src/com/cloud/agent/api/to/StorageFilerTO.java +++ b/api/src/com/cloud/agent/api/to/StorageFilerTO.java @@ -16,8 +16,8 @@ // under the License. package com.cloud.agent.api.to; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.Storage.StoragePoolType; public class StorageFilerTO { long id; diff --git a/api/src/com/cloud/agent/api/to/TemplateTO.java b/api/src/com/cloud/agent/api/to/TemplateTO.java index e163340fbf0..39f30f058d5 100644 --- a/api/src/com/cloud/agent/api/to/TemplateTO.java +++ b/api/src/com/cloud/agent/api/to/TemplateTO.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.agent.api.to; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; public class TemplateTO { diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index ca0acb57876..3a6619d9516 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -16,9 +16,9 @@ // under the License. package com.cloud.agent.api.to; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.Storage.StoragePoolType; +import com.cloud.storage.volume.Volume; public class VolumeTO { protected VolumeTO() { diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index 91c2035665d..52cbbdd506b 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -55,7 +55,7 @@ import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceService; import com.cloud.server.ManagementService; import com.cloud.server.TaggedResourceService; -import com.cloud.storage.StorageService; +import com.cloud.storage.pool.StoragePoolService; import com.cloud.storage.snapshot.SnapshotService; import com.cloud.template.TemplateService; import com.cloud.user.Account; @@ -114,7 +114,7 @@ public abstract class BaseCmd { public static AccountService _accountService; public static UserVmService _userVmService; public static ManagementService _mgr; - public static StorageService _storageService; + public static StoragePoolService _storageService; public static ResourceService _resourceService; public static NetworkService _networkService; public static TemplateService _templateService; @@ -145,7 +145,7 @@ public abstract class BaseCmd { _accountService = locator.getManager(AccountService.class); _configService = locator.getManager(ConfigurationService.class); _userVmService = locator.getManager(UserVmService.class); - _storageService = locator.getManager(StorageService.class); + _storageService = locator.getManager(StoragePoolService.class); _resourceService = locator.getManager(ResourceService.class); _networkService = locator.getManager(NetworkService.class); _templateService = locator.getManager(TemplateService.class); diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 996a5fcfd4b..406f8a0bf97 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -131,11 +131,11 @@ import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.server.ResourceTag; -import com.cloud.storage.Snapshot; -import com.cloud.storage.StoragePool; import com.cloud.storage.Swift; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.User; diff --git a/api/src/com/cloud/api/commands/AttachVolumeCmd.java b/api/src/com/cloud/api/commands/AttachVolumeCmd.java index bfd1a84865e..2566014b70c 100755 --- a/api/src/com/cloud/api/commands/AttachVolumeCmd.java +++ b/api/src/com/cloud/api/commands/AttachVolumeCmd.java @@ -28,7 +28,7 @@ import com.cloud.api.ServerApiException; import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/CancelPrimaryStorageMaintenanceCmd.java b/api/src/com/cloud/api/commands/CancelPrimaryStorageMaintenanceCmd.java index c4d97aeb985..63c49ee071b 100644 --- a/api/src/com/cloud/api/commands/CancelPrimaryStorageMaintenanceCmd.java +++ b/api/src/com/cloud/api/commands/CancelPrimaryStorageMaintenanceCmd.java @@ -29,7 +29,7 @@ import com.cloud.api.response.StoragePoolResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -102,7 +102,7 @@ public class CancelPrimaryStorageMaintenanceCmd extends BaseAsyncCmd { @Override public void execute() throws ResourceUnavailableException{ - StoragePool result = _storageService.cancelPrimaryStorageForMaintenance(this); + StoragePool result = _storageService.cancelStorageForMaintenance(this); if (result != null) { StoragePoolResponse response = _responseGenerator.createStoragePoolResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java index d1b6d7ad41a..3fb4336bd32 100755 --- a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java @@ -32,8 +32,8 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.projects.Project; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Volume; +import com.cloud.storage.snapshot.Snapshot; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java index 6708bf9e8b2..a25951f3954 100644 --- a/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java @@ -28,8 +28,8 @@ import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.projects.Project; -import com.cloud.storage.Volume; import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; @Implementation(description="Creates a snapshot policy for the account.", responseObject=SnapshotPolicyResponse.class) diff --git a/api/src/com/cloud/api/commands/CreateStoragePoolCmd.java b/api/src/com/cloud/api/commands/CreateStoragePoolCmd.java index 69c1bb5f671..e9b28e6ef8b 100644 --- a/api/src/com/cloud/api/commands/CreateStoragePoolCmd.java +++ b/api/src/com/cloud/api/commands/CreateStoragePoolCmd.java @@ -30,7 +30,7 @@ import com.cloud.api.ServerApiException; import com.cloud.api.response.StoragePoolResponse; import com.cloud.exception.ResourceInUseException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; @SuppressWarnings("rawtypes") diff --git a/api/src/com/cloud/api/commands/CreateTemplateCmd.java b/api/src/com/cloud/api/commands/CreateTemplateCmd.java index 05f18fb9a49..9ee3bc5c29a 100755 --- a/api/src/com/cloud/api/commands/CreateTemplateCmd.java +++ b/api/src/com/cloud/api/commands/CreateTemplateCmd.java @@ -37,8 +37,8 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.projects.Project; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Volume; +import com.cloud.storage.snapshot.Snapshot; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/CreateVolumeCmd.java b/api/src/com/cloud/api/commands/CreateVolumeCmd.java index d0585fe1547..89f4a492661 100644 --- a/api/src/com/cloud/api/commands/CreateVolumeCmd.java +++ b/api/src/com/cloud/api/commands/CreateVolumeCmd.java @@ -29,7 +29,7 @@ import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.ResourceAllocationException; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.UserContext; @Implementation(responseObject=VolumeResponse.class, description="Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.") diff --git a/api/src/com/cloud/api/commands/DeletePoolCmd.java b/api/src/com/cloud/api/commands/DeletePoolCmd.java index ba2f73fdb24..c33e8a82776 100644 --- a/api/src/com/cloud/api/commands/DeletePoolCmd.java +++ b/api/src/com/cloud/api/commands/DeletePoolCmd.java @@ -25,8 +25,8 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolStatus; import com.cloud.user.Account; @Implementation(description = "Deletes a storage pool.", responseObject = SuccessResponse.class) diff --git a/api/src/com/cloud/api/commands/DeleteSnapshotCmd.java b/api/src/com/cloud/api/commands/DeleteSnapshotCmd.java index 97c25a50df0..8d46ecee353 100644 --- a/api/src/com/cloud/api/commands/DeleteSnapshotCmd.java +++ b/api/src/com/cloud/api/commands/DeleteSnapshotCmd.java @@ -28,7 +28,7 @@ import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; -import com.cloud.storage.Snapshot; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java index a998311321a..22f30ebdd0c 100644 --- a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java +++ b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java @@ -26,7 +26,7 @@ import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; import com.cloud.exception.ConcurrentOperationException; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/DetachVolumeCmd.java b/api/src/com/cloud/api/commands/DetachVolumeCmd.java index 3a3557da8e9..77a921b08b1 100755 --- a/api/src/com/cloud/api/commands/DetachVolumeCmd.java +++ b/api/src/com/cloud/api/commands/DetachVolumeCmd.java @@ -28,7 +28,7 @@ import com.cloud.api.ServerApiException; import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; diff --git a/api/src/com/cloud/api/commands/ExtractVolumeCmd.java b/api/src/com/cloud/api/commands/ExtractVolumeCmd.java index 2a9dbff9e70..beb6d3dc424 100755 --- a/api/src/com/cloud/api/commands/ExtractVolumeCmd.java +++ b/api/src/com/cloud/api/commands/ExtractVolumeCmd.java @@ -32,7 +32,7 @@ import com.cloud.async.AsyncJob; import com.cloud.dc.DataCenter; import com.cloud.event.EventTypes; import com.cloud.storage.Upload; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java b/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java index 9974aca8429..726cbe4af73 100644 --- a/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java +++ b/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java @@ -28,7 +28,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.response.GuestOSCategoryResponse; import com.cloud.api.response.ListResponse; -import com.cloud.storage.GuestOsCategory; +import com.cloud.storage.volume.GuestOsCategory; @Implementation(description="Lists all supported OS categories for this cloud.", responseObject=GuestOSCategoryResponse.class) public class ListGuestOsCategoriesCmd extends BaseListCmd { diff --git a/api/src/com/cloud/api/commands/ListGuestOsCmd.java b/api/src/com/cloud/api/commands/ListGuestOsCmd.java index 396c441f0af..e6ea319752c 100644 --- a/api/src/com/cloud/api/commands/ListGuestOsCmd.java +++ b/api/src/com/cloud/api/commands/ListGuestOsCmd.java @@ -28,7 +28,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.response.GuestOSResponse; import com.cloud.api.response.ListResponse; -import com.cloud.storage.GuestOS; +import com.cloud.storage.volume.GuestOS; @Implementation(description="Lists all supported OS types for this cloud.", responseObject=GuestOSResponse.class) public class ListGuestOsCmd extends BaseListCmd { diff --git a/api/src/com/cloud/api/commands/ListIsoPermissionsCmd.java b/api/src/com/cloud/api/commands/ListIsoPermissionsCmd.java index 0af58555ea6..d4df7b2a624 100644 --- a/api/src/com/cloud/api/commands/ListIsoPermissionsCmd.java +++ b/api/src/com/cloud/api/commands/ListIsoPermissionsCmd.java @@ -18,7 +18,7 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; public class ListIsoPermissionsCmd extends ListTemplateOrIsoPermissionsCmd { diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index d7b2c9e05f9..ce38d0e8b4a 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -29,7 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.SnapshotResponse; import com.cloud.async.AsyncJob; -import com.cloud.storage.Snapshot; +import com.cloud.storage.snapshot.Snapshot; @Implementation(description="Lists all available snapshots for the account.", responseObject=SnapshotResponse.class) diff --git a/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java b/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java index 6208dcd5691..66510112ea6 100644 --- a/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java +++ b/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java @@ -30,7 +30,7 @@ import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.async.AsyncJob; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; @Implementation(description="Lists storage pools.", responseObject=StoragePoolResponse.class) public class ListStoragePoolsCmd extends BaseListCmd { diff --git a/api/src/com/cloud/api/commands/ListTemplatePermissionsCmd.java b/api/src/com/cloud/api/commands/ListTemplatePermissionsCmd.java index af90df9282b..0be940ac6fd 100644 --- a/api/src/com/cloud/api/commands/ListTemplatePermissionsCmd.java +++ b/api/src/com/cloud/api/commands/ListTemplatePermissionsCmd.java @@ -18,7 +18,7 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; public class ListTemplatePermissionsCmd extends ListTemplateOrIsoPermissionsCmd { diff --git a/api/src/com/cloud/api/commands/ListVolumesCmd.java b/api/src/com/cloud/api/commands/ListVolumesCmd.java index e0393a9b76b..f5a6535d182 100755 --- a/api/src/com/cloud/api/commands/ListVolumesCmd.java +++ b/api/src/com/cloud/api/commands/ListVolumesCmd.java @@ -29,7 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; @Implementation(description="Lists all volumes.", responseObject=VolumeResponse.class) diff --git a/api/src/com/cloud/api/commands/MigrateVMCmd.java b/api/src/com/cloud/api/commands/MigrateVMCmd.java index c292a2e4e1b..e72e1721cfa 100644 --- a/api/src/com/cloud/api/commands/MigrateVMCmd.java +++ b/api/src/com/cloud/api/commands/MigrateVMCmd.java @@ -33,7 +33,7 @@ import com.cloud.exception.ManagementServerException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.host.Host; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; diff --git a/api/src/com/cloud/api/commands/MigrateVolumeCmd.java b/api/src/com/cloud/api/commands/MigrateVolumeCmd.java index 58f5d917ff2..a7d30ffe488 100644 --- a/api/src/com/cloud/api/commands/MigrateVolumeCmd.java +++ b/api/src/com/cloud/api/commands/MigrateVolumeCmd.java @@ -26,7 +26,7 @@ import com.cloud.api.ServerApiException; import com.cloud.api.response.VolumeResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.Account; diff --git a/api/src/com/cloud/api/commands/PreparePrimaryStorageForMaintenanceCmd.java b/api/src/com/cloud/api/commands/PreparePrimaryStorageForMaintenanceCmd.java index 31e181e56d7..2b31f4474aa 100644 --- a/api/src/com/cloud/api/commands/PreparePrimaryStorageForMaintenanceCmd.java +++ b/api/src/com/cloud/api/commands/PreparePrimaryStorageForMaintenanceCmd.java @@ -30,7 +30,7 @@ import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -100,7 +100,7 @@ public class PreparePrimaryStorageForMaintenanceCmd extends BaseAsyncCmd { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException{ - StoragePool result = _storageService.preparePrimaryStorageForMaintenance(getId()); + StoragePool result = _storageService.prepareStorageForMaintenance(getId()); if (result != null){ StoragePoolResponse response = _responseGenerator.createStoragePoolResponse(result); response.setResponseName("storagepool"); diff --git a/api/src/com/cloud/api/commands/UpdateStoragePoolCmd.java b/api/src/com/cloud/api/commands/UpdateStoragePoolCmd.java index 52b5a047dbf..b2ad5826f13 100644 --- a/api/src/com/cloud/api/commands/UpdateStoragePoolCmd.java +++ b/api/src/com/cloud/api/commands/UpdateStoragePoolCmd.java @@ -27,7 +27,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.StoragePoolResponse; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; @Implementation(description="Updates a storage pool.", responseObject=StoragePoolResponse.class, since="3.0.0") diff --git a/api/src/com/cloud/api/commands/UploadVolumeCmd.java b/api/src/com/cloud/api/commands/UploadVolumeCmd.java index 299b04df386..12e6f9d6b67 100755 --- a/api/src/com/cloud/api/commands/UploadVolumeCmd.java +++ b/api/src/com/cloud/api/commands/UploadVolumeCmd.java @@ -32,7 +32,7 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.user.UserContext; @Implementation(description="Uploads a data disk.", responseObject=VolumeResponse.class) @@ -109,7 +109,7 @@ public class UploadVolumeCmd extends BaseAsyncCmd { ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - Volume volume = _storageService.uploadVolume(this); + Volume volume = _templateService.uploadVolume(this); if (volume != null){ VolumeResponse response = _responseGenerator.createVolumeResponse(volume); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/response/SnapshotResponse.java b/api/src/com/cloud/api/response/SnapshotResponse.java index 71b1b14b8b5..b1d3b702121 100644 --- a/api/src/com/cloud/api/response/SnapshotResponse.java +++ b/api/src/com/cloud/api/response/SnapshotResponse.java @@ -21,7 +21,7 @@ import java.util.List; import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; -import com.cloud.storage.Snapshot; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; diff --git a/api/src/com/cloud/api/response/StoragePoolResponse.java b/api/src/com/cloud/api/response/StoragePoolResponse.java index 3b6a5792127..a888b5dbd1b 100755 --- a/api/src/com/cloud/api/response/StoragePoolResponse.java +++ b/api/src/com/cloud/api/response/StoragePoolResponse.java @@ -21,7 +21,7 @@ import java.util.Date; import com.cloud.api.ApiConstants; import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; -import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.pool.StoragePoolStatus; import com.google.gson.annotations.SerializedName; public class StoragePoolResponse extends BaseResponse { diff --git a/api/src/com/cloud/api/response/TemplateResponse.java b/api/src/com/cloud/api/response/TemplateResponse.java index 5c3d3399799..981303f0543 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -22,7 +22,7 @@ import java.util.Map; import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; diff --git a/api/src/com/cloud/deploy/DeployDestination.java b/api/src/com/cloud/deploy/DeployDestination.java index e00d3c6afd6..7e5434451aa 100644 --- a/api/src/com/cloud/deploy/DeployDestination.java +++ b/api/src/com/cloud/deploy/DeployDestination.java @@ -22,8 +22,8 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.host.Host; import com.cloud.org.Cluster; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.volume.Volume; import com.cloud.utils.NumbersUtil; public class DeployDestination { diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/com/cloud/deploy/DeploymentPlanner.java index e5dcff1be54..c8dc715428f 100644 --- a/api/src/com/cloud/deploy/DeploymentPlanner.java +++ b/api/src/com/cloud/deploy/DeploymentPlanner.java @@ -27,7 +27,7 @@ import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.org.Cluster; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.utils.component.Adapter; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; diff --git a/api/src/com/cloud/exception/InsufficientStorageCapacityException.java b/api/src/com/cloud/exception/InsufficientStorageCapacityException.java index f8ec10610ce..11c5efb7ac0 100755 --- a/api/src/com/cloud/exception/InsufficientStorageCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientStorageCapacityException.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.exception; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.utils.SerialVersionUID; /** diff --git a/api/src/com/cloud/exception/StorageUnavailableException.java b/api/src/com/cloud/exception/StorageUnavailableException.java index 7b443a91087..1afa3d0aa07 100644 --- a/api/src/com/cloud/exception/StorageUnavailableException.java +++ b/api/src/com/cloud/exception/StorageUnavailableException.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.exception; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; import com.cloud.utils.SerialVersionUID; /** diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 8dcc3983599..1b4708826cb 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -82,9 +82,9 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.offering.DiskOffering; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOsCategory; -import com.cloud.storage.StoragePool; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.volume.GuestOS; +import com.cloud.storage.volume.GuestOsCategory; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.SSHKeyPair; import com.cloud.utils.Pair; diff --git a/api/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java b/api/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java new file mode 100644 index 00000000000..ffcb1826eca --- /dev/null +++ b/api/src/com/cloud/storage/orchestra/StorageOrchestraEngine.java @@ -0,0 +1,10 @@ +package com.cloud.storage.orchestra; + +import com.cloud.storage.pool.StoragePoolService; +import com.cloud.storage.snapshot.SnapshotService; +import com.cloud.storage.volume.VolumeService; +import com.cloud.template.TemplateService; + +public interface StorageOrchestraEngine extends StoragePoolService, VolumeService, SnapshotService, TemplateService { + +} diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/pool/Storage.java similarity index 99% rename from api/src/com/cloud/storage/Storage.java rename to api/src/com/cloud/storage/pool/Storage.java index fba12b62d3d..3c2f476051d 100755 --- a/api/src/com/cloud/storage/Storage.java +++ b/api/src/com/cloud/storage/pool/Storage.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; import java.util.ArrayList; import java.util.List; diff --git a/api/src/com/cloud/storage/StoragePool.java b/api/src/com/cloud/storage/pool/StoragePool.java similarity index 96% rename from api/src/com/cloud/storage/StoragePool.java rename to api/src/com/cloud/storage/pool/StoragePool.java index 497523d7e38..76765ff905a 100644 --- a/api/src/com/cloud/storage/StoragePool.java +++ b/api/src/com/cloud/storage/pool/StoragePool.java @@ -14,11 +14,11 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; import java.util.Date; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public interface StoragePool { diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/pool/StoragePoolService.java similarity index 64% rename from api/src/com/cloud/storage/StorageService.java rename to api/src/com/cloud/storage/pool/StoragePoolService.java index 4fb3b55f057..c7bfc5b53ae 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/pool/StoragePoolService.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; import java.net.UnknownHostException; import java.util.List; @@ -32,8 +32,9 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceInUseException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.storage.volume.Volume; -public interface StorageService{ +public interface StoragePoolService { /** * Create StoragePool based on uri * @@ -45,34 +46,10 @@ public interface StorageService{ * @throws IllegalArgumentException * @throws UnknownHostException * @throws ResourceUnavailableException - * TODO */ StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; - - /** - * Creates the database object for a volume based on the given criteria - * - * @param cmd - * the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot, - * name) - * @return the volume object - * @throws PermissionDeniedException - */ - Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException; - - /** - * Creates the volume based on the given criteria - * - * @param cmd - * the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot, - * name) - * @return the volume object - */ - Volume createVolume(CreateVolumeCmd cmd); - - boolean deleteVolume(long volumeId) throws ConcurrentOperationException; - + /** * Delete the storage pool * @@ -81,21 +58,19 @@ public interface StorageService{ * @return success or failure */ boolean deletePool(DeletePoolCmd cmd); - + /** - * Enable maintenance for primary storage + * Enable maintenance for storage * * @param cmd * - the command specifying primaryStorageId * @return the primary storage pool * @throws ResourceUnavailableException - * TODO * @throws InsufficientCapacityException - * TODO */ - public StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, + public StoragePool prepareStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException; - + /** * Complete maintenance for primary storage * @@ -103,26 +78,14 @@ public interface StorageService{ * - the command specifying primaryStorageId * @return the primary storage pool * @throws ResourceUnavailableException - * TODO */ - public StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) + public StoragePool cancelStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException; + + + //TODO: Need to move around for this following APIs public StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException; public StoragePool getStoragePool(long id); - - Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException; - - List searchForVolumes(ListVolumesCmd cmd); - - /** - * Uploads the volume to secondary storage - * - * @param UploadVolumeCmd cmd - * - * @return Volume object - */ - Volume uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException; - } diff --git a/api/src/com/cloud/storage/StoragePoolStatus.java b/api/src/com/cloud/storage/pool/StoragePoolStatus.java similarity index 96% rename from api/src/com/cloud/storage/StoragePoolStatus.java rename to api/src/com/cloud/storage/pool/StoragePoolStatus.java index 0c949614412..b038b56aec6 100644 --- a/api/src/com/cloud/storage/StoragePoolStatus.java +++ b/api/src/com/cloud/storage/pool/StoragePoolStatus.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; public enum StoragePoolStatus { Up, diff --git a/api/src/com/cloud/storage/StorageStats.java b/api/src/com/cloud/storage/pool/StorageStats.java similarity index 97% rename from api/src/com/cloud/storage/StorageStats.java rename to api/src/com/cloud/storage/pool/StorageStats.java index fe21c44b702..6da18898ec4 100755 --- a/api/src/com/cloud/storage/StorageStats.java +++ b/api/src/com/cloud/storage/pool/StorageStats.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; public interface StorageStats { /** diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/snapshot/Snapshot.java similarity index 98% rename from api/src/com/cloud/storage/Snapshot.java rename to api/src/com/cloud/storage/snapshot/Snapshot.java index a37cc94241f..03aa77568da 100644 --- a/api/src/com/cloud/storage/Snapshot.java +++ b/api/src/com/cloud/storage/snapshot/Snapshot.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.snapshot; import java.util.Date; diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotService.java index 0500061670a..f0735c64324 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotService.java @@ -25,7 +25,6 @@ import com.cloud.api.commands.ListSnapshotPoliciesCmd; import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.storage.Snapshot; import com.cloud.user.Account; public interface SnapshotService { diff --git a/api/src/com/cloud/storage/GuestOS.java b/api/src/com/cloud/storage/volume/GuestOS.java similarity index 96% rename from api/src/com/cloud/storage/GuestOS.java rename to api/src/com/cloud/storage/volume/GuestOS.java index b9727db6612..e73b9a01731 100644 --- a/api/src/com/cloud/storage/GuestOS.java +++ b/api/src/com/cloud/storage/volume/GuestOS.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.volume; public interface GuestOS { diff --git a/api/src/com/cloud/storage/GuestOsCategory.java b/api/src/com/cloud/storage/volume/GuestOsCategory.java similarity index 96% rename from api/src/com/cloud/storage/GuestOsCategory.java rename to api/src/com/cloud/storage/volume/GuestOsCategory.java index 96123e47108..a1677a660d0 100644 --- a/api/src/com/cloud/storage/GuestOsCategory.java +++ b/api/src/com/cloud/storage/volume/GuestOsCategory.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.volume; public interface GuestOsCategory { long getId(); diff --git a/api/src/com/cloud/storage/StorageGuru.java b/api/src/com/cloud/storage/volume/StorageGuru.java similarity index 96% rename from api/src/com/cloud/storage/StorageGuru.java rename to api/src/com/cloud/storage/volume/StorageGuru.java index bbd89fbefe5..07c36a07acf 100644 --- a/api/src/com/cloud/storage/StorageGuru.java +++ b/api/src/com/cloud/storage/volume/StorageGuru.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.volume; import com.cloud.utils.component.Adapter; diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/volume/Volume.java similarity index 99% rename from api/src/com/cloud/storage/Volume.java rename to api/src/com/cloud/storage/volume/Volume.java index 6e8e48e48d8..87415a5d55e 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/volume/Volume.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.volume; import java.util.Date; diff --git a/api/src/com/cloud/storage/volume/VolumeService.java b/api/src/com/cloud/storage/volume/VolumeService.java new file mode 100644 index 00000000000..9c207f39a37 --- /dev/null +++ b/api/src/com/cloud/storage/volume/VolumeService.java @@ -0,0 +1,59 @@ +package com.cloud.storage.volume; + +import java.util.List; + +import com.cloud.api.commands.CreateVolumeCmd; +import com.cloud.api.commands.ListVolumesCmd; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceAllocationException; + +public interface VolumeService { + /** + * Creates the database object for a volume based on the given criteria + * + * @param cmd + * the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot, + * name) + * @return the volume object + * @throws PermissionDeniedException + */ + Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException; + + /** + * Creates the volume based on the given criteria + * + * @param cmd + * the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot, + * name) + * @return the volume object + */ + Volume createVolume(CreateVolumeCmd cmd); + + /** + * Delete volume + * @param volumeId + * @return + * @throws ConcurrentOperationException + */ + boolean deleteVolume(long volumeId) throws ConcurrentOperationException; + + /** + * Migrate volume to another storage pool + * @param volumeId + * @param storagePoolId + * @return + * @throws ConcurrentOperationException + */ + Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException; + + /** + * Copy volume another storage pool, a new volume will be created on destination storage pool + * @param volumeId + * @param destStoragePoolId + * @return + */ + Volume copyVolume(Long volumeId, Long destStoragePoolId); + + List searchForVolumes(ListVolumesCmd cmd); +} diff --git a/api/src/com/cloud/storage/VolumeStats.java b/api/src/com/cloud/storage/volume/VolumeStats.java similarity index 96% rename from api/src/com/cloud/storage/VolumeStats.java rename to api/src/com/cloud/storage/volume/VolumeStats.java index 70c0b17f84a..f9f7576875c 100644 --- a/api/src/com/cloud/storage/VolumeStats.java +++ b/api/src/com/cloud/storage/volume/VolumeStats.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.volume; public interface VolumeStats { /** diff --git a/api/src/com/cloud/template/TemplateService.java b/api/src/com/cloud/template/TemplateService.java index e45f43d5f9c..c66154cb3c4 100755 --- a/api/src/com/cloud/template/TemplateService.java +++ b/api/src/com/cloud/template/TemplateService.java @@ -28,9 +28,11 @@ import com.cloud.api.commands.ListTemplateOrIsoPermissionsCmd; import com.cloud.api.commands.RegisterIsoCmd; import com.cloud.api.commands.RegisterTemplateCmd; import com.cloud.api.commands.UpdateTemplateOrIsoPermissionsCmd; +import com.cloud.api.commands.UploadVolumeCmd; import com.cloud.exception.InternalErrorException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.storage.volume.Volume; public interface TemplateService { @@ -86,4 +88,7 @@ public interface TemplateService { List listTemplatePermissions(ListTemplateOrIsoPermissionsCmd cmd); boolean updateTemplateOrIsoPermissions(UpdateTemplateOrIsoPermissionsCmd cmd); + + Volume uploadVolume(UploadVolumeCmd cmd) + throws ResourceAllocationException; } diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java index 27f5871b750..03194281763 100755 --- a/api/src/com/cloud/template/VirtualMachineTemplate.java +++ b/api/src/com/cloud/template/VirtualMachineTemplate.java @@ -21,8 +21,8 @@ import java.util.Map; import com.cloud.acl.ControlledEntity; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; public interface VirtualMachineTemplate extends ControlledEntity { diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index bb74d848342..2869dfc5237 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -18,7 +18,7 @@ package com.cloud.vm; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.DiskOffering; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; /** * DiskProfile describes a disk and what functionality is required from it. diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 6635657042f..1b964005585 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -48,8 +48,8 @@ import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; diff --git a/core/src/com/cloud/host/HostVO.java b/core/src/com/cloud/host/HostVO.java index dab9768a943..d2fa1d057f3 100755 --- a/core/src/com/cloud/host/HostVO.java +++ b/core/src/com/cloud/host/HostVO.java @@ -40,7 +40,7 @@ import javax.persistence.Transient; import com.cloud.api.Identity; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceState; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDao; diff --git a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java index ede6301d9c3..131f495fd0a 100755 --- a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java +++ b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java @@ -104,8 +104,8 @@ import com.cloud.utils.ssh.SshHelper; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.serializer.GsonHelper; -import com.cloud.storage.Volume; import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.volume.Volume; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; diff --git a/core/src/com/cloud/storage/GuestOSCategoryVO.java b/core/src/com/cloud/storage/GuestOSCategoryVO.java index cbe242eef5d..9bb85f9c109 100644 --- a/core/src/com/cloud/storage/GuestOSCategoryVO.java +++ b/core/src/com/cloud/storage/GuestOSCategoryVO.java @@ -26,6 +26,7 @@ import javax.persistence.Id; import javax.persistence.Table; import com.cloud.api.Identity; +import com.cloud.storage.volume.GuestOsCategory; @Entity @Table(name="guest_os_category") diff --git a/core/src/com/cloud/storage/GuestOSVO.java b/core/src/com/cloud/storage/GuestOSVO.java index 85db94e29f6..8fe71c0be35 100644 --- a/core/src/com/cloud/storage/GuestOSVO.java +++ b/core/src/com/cloud/storage/GuestOSVO.java @@ -26,6 +26,7 @@ import javax.persistence.Id; import javax.persistence.Table; import com.cloud.api.Identity; +import com.cloud.storage.volume.GuestOS; @Entity @Table(name="guest_os") diff --git a/core/src/com/cloud/storage/SecondaryStorageLayer.java b/core/src/com/cloud/storage/SecondaryStorageLayer.java index 539733d3531..de5c08f0158 100644 --- a/core/src/com/cloud/storage/SecondaryStorageLayer.java +++ b/core/src/com/cloud/storage/SecondaryStorageLayer.java @@ -18,7 +18,7 @@ package com.cloud.storage; import java.net.URI; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.utils.component.Adapter; public interface SecondaryStorageLayer extends Adapter { diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index 08dfafa6bac..516580618f5 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -30,6 +30,7 @@ import javax.persistence.Table; import com.cloud.api.Identity; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.utils.db.GenericDao; import com.google.gson.annotations.Expose; diff --git a/core/src/com/cloud/storage/StoragePoolVO.java b/core/src/com/cloud/storage/StoragePoolVO.java index 5fecefb756d..bc442f6b308 100644 --- a/core/src/com/cloud/storage/StoragePoolVO.java +++ b/core/src/com/cloud/storage/StoragePoolVO.java @@ -31,7 +31,9 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; import com.cloud.api.Identity; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolStatus; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.utils.db.GenericDao; @Entity diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/core/src/com/cloud/storage/VMTemplateVO.java index cd17bc9bf5a..41bbcda5856 100755 --- a/core/src/com/cloud/storage/VMTemplateVO.java +++ b/core/src/com/cloud/storage/VMTemplateVO.java @@ -33,8 +33,9 @@ import javax.persistence.Transient; import com.cloud.api.Identity; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.template.VirtualMachineTemplate; import com.cloud.utils.db.GenericDao; diff --git a/core/src/com/cloud/storage/VolumeHostVO.java b/core/src/com/cloud/storage/VolumeHostVO.java index d3d88ae27a8..590e5707db7 100755 --- a/core/src/com/cloud/storage/VolumeHostVO.java +++ b/core/src/com/cloud/storage/VolumeHostVO.java @@ -30,8 +30,9 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; //import com.cloud.storage.VMVolumeStorageResourceAssoc.Status; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.utils.db.GenericDaoBase; /** diff --git a/core/src/com/cloud/storage/VolumeVO.java b/core/src/com/cloud/storage/VolumeVO.java index ef0fedaf651..55c508ad2d2 100755 --- a/core/src/com/cloud/storage/VolumeVO.java +++ b/core/src/com/cloud/storage/VolumeVO.java @@ -32,7 +32,8 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.api.Identity; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; +import com.cloud.storage.volume.Volume; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDao; diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java index c606fca1fbf..65f9ed3e3a4 100755 --- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java @@ -56,9 +56,9 @@ import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.TemplateInfo; diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java index d9c69f8b151..17b190fe4d9 100644 --- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java @@ -44,9 +44,9 @@ import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.resource.ServerResourceBase; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.TemplateInfo; diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java index f4f8a0f17fa..2db1752df1d 100644 --- a/core/src/com/cloud/storage/template/DownloadManager.java +++ b/core/src/com/cloud/storage/template/DownloadManager.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.resource.SecondaryStorageResource; import com.cloud.utils.component.Manager; diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index ab81bed7995..75c784099ab 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -51,10 +51,10 @@ import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.exception.InternalErrorException; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.resource.SecondaryStorageResource; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback; diff --git a/core/src/com/cloud/storage/template/IsoProcessor.java b/core/src/com/cloud/storage/template/IsoProcessor.java index 112002a641d..fb882bc43fc 100644 --- a/core/src/com/cloud/storage/template/IsoProcessor.java +++ b/core/src/com/cloud/storage/template/IsoProcessor.java @@ -25,7 +25,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.storage.StorageLayer; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; @Local(value=Processor.class) public class IsoProcessor implements Processor { diff --git a/core/src/com/cloud/storage/template/Processor.java b/core/src/com/cloud/storage/template/Processor.java index 2ec359318ff..c22f8a966b5 100644 --- a/core/src/com/cloud/storage/template/Processor.java +++ b/core/src/com/cloud/storage/template/Processor.java @@ -17,7 +17,7 @@ package com.cloud.storage.template; import com.cloud.exception.InternalErrorException; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.utils.component.Adapter; /** diff --git a/core/src/com/cloud/storage/template/QCOW2Processor.java b/core/src/com/cloud/storage/template/QCOW2Processor.java index 15af8490ea9..39e8db7b494 100644 --- a/core/src/com/cloud/storage/template/QCOW2Processor.java +++ b/core/src/com/cloud/storage/template/QCOW2Processor.java @@ -26,7 +26,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.utils.NumbersUtil; diff --git a/core/src/com/cloud/storage/template/RawImageProcessor.java b/core/src/com/cloud/storage/template/RawImageProcessor.java index 694c76a7074..3c7cd67bbde 100644 --- a/core/src/com/cloud/storage/template/RawImageProcessor.java +++ b/core/src/com/cloud/storage/template/RawImageProcessor.java @@ -26,7 +26,7 @@ import org.apache.log4j.Logger; import com.cloud.exception.InternalErrorException; import com.cloud.storage.StorageLayer; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.template.Processor.FormatInfo; @Local(value=Processor.class) diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index 58d023a4907..2c9aaf0df01 100644 --- a/core/src/com/cloud/storage/template/TemplateLocation.java +++ b/core/src/com/cloud/storage/template/TemplateLocation.java @@ -27,8 +27,8 @@ import java.util.Properties; import org.apache.log4j.Logger; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.utils.NumbersUtil; diff --git a/core/src/com/cloud/storage/template/UploadManager.java b/core/src/com/cloud/storage/template/UploadManager.java index fa40b8c9ac6..234f3de86e9 100755 --- a/core/src/com/cloud/storage/template/UploadManager.java +++ b/core/src/com/cloud/storage/template/UploadManager.java @@ -22,8 +22,8 @@ import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Upload.Status; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.resource.SecondaryStorageResource; import com.cloud.utils.component.Manager; diff --git a/core/src/com/cloud/storage/template/UploadManagerImpl.java b/core/src/com/cloud/storage/template/UploadManagerImpl.java index 2dd1751aeaa..d425b8304c8 100755 --- a/core/src/com/cloud/storage/template/UploadManagerImpl.java +++ b/core/src/com/cloud/storage/template/UploadManagerImpl.java @@ -38,10 +38,10 @@ import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadProgressCommand; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.storage.Upload; import com.cloud.storage.UploadVO; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.resource.SecondaryStorageResource; import com.cloud.storage.template.TemplateUploader.Status; import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback; diff --git a/core/src/com/cloud/storage/template/VhdProcessor.java b/core/src/com/cloud/storage/template/VhdProcessor.java index b65b1dc876d..698f402a2c7 100644 --- a/core/src/com/cloud/storage/template/VhdProcessor.java +++ b/core/src/com/cloud/storage/template/VhdProcessor.java @@ -28,7 +28,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.exception.InternalErrorException; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.utils.NumbersUtil; diff --git a/core/src/com/cloud/storage/template/VmdkProcessor.java b/core/src/com/cloud/storage/template/VmdkProcessor.java index ec7f014b4fd..0674e0846cf 100644 --- a/core/src/com/cloud/storage/template/VmdkProcessor.java +++ b/core/src/com/cloud/storage/template/VmdkProcessor.java @@ -30,7 +30,7 @@ import org.w3c.dom.NodeList; import org.apache.log4j.Logger; import com.cloud.exception.InternalErrorException; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.utils.script.Script; diff --git a/core/src/com/cloud/vm/VirtualDisk.java b/core/src/com/cloud/vm/VirtualDisk.java index ad7bb43d40b..16c33124e24 100644 --- a/core/src/com/cloud/vm/VirtualDisk.java +++ b/core/src/com/cloud/vm/VirtualDisk.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.vm; -import com.cloud.storage.Storage; +import com.cloud.storage.pool.Storage; /** * VirtualDisk describes the disks that are plugged into diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 64c1e0bddef..92f881c4f8c 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -34,9 +34,9 @@ import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.exception.UnsupportedVersionException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.serializer.GsonHelper; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; /** diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java index 83f69768495..8a8ecbe2572 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java @@ -94,10 +94,10 @@ import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.Networks.TrafficType; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.volume.Volume; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @@ -553,7 +553,7 @@ public class FakeComputingResource extends ServerResourceBase implements try { VolumeTO vol = new VolumeTO(cmd.getVolumeId(), Volume.Type.ROOT, - com.cloud.storage.Storage.StoragePoolType.LVM, cmd + com.cloud.storage.pool.Storage.StoragePoolType.LVM, cmd .getPool().getUuid(), "dummy", "/mountpoint", "dummyPath", 1000L, null); return new CreateAnswer(cmd, vol); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 8b876cf7d0c..007cd28c7f5 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -186,16 +186,16 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateLocation; +import com.cloud.storage.volume.Volume; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java index 5437e7c69b0..56dd037c73f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java @@ -19,7 +19,7 @@ package com.cloud.hypervisor.kvm.storage; import java.util.List; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public interface KVMStoragePool { public KVMPhysicalDisk createPhysicalDisk(String name, diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java index 751da837cf4..66bac525ff8 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java @@ -23,7 +23,7 @@ import com.cloud.hypervisor.kvm.resource.KVMHABase; import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType; import com.cloud.hypervisor.kvm.resource.KVMHAMonitor; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; public class KVMStoragePoolManager { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index 9f62ee8514d..ca948774339 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -45,7 +45,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef.volFormat; import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeXMLParser; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat; import com.cloud.exception.InternalErrorException; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java index 32f8ce99d9c..e7022ab59d7 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java @@ -21,7 +21,7 @@ import java.util.List; import org.libvirt.StoragePool; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public class LibvirtStoragePool implements KVMStoragePool { protected String uuid; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java index be6c5c0bda2..27d72ef05e9 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java @@ -19,7 +19,7 @@ package com.cloud.hypervisor.kvm.storage; import java.util.List; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat; -import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.StoragePoolType; public interface StorageAdaptor { diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index c5cb586e528..d4099dde6f7 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -111,10 +111,10 @@ import com.cloud.ovm.object.OvmVm; import com.cloud.ovm.object.OvmVolume; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index af53daded02..37afdb7abaa 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -54,10 +54,10 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.user.Account; import com.cloud.utils.UriUtils; import com.cloud.utils.component.ComponentLocator; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index b525e13654a..2f46ba8fb9a 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -45,8 +45,8 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.storage.JavaStorageLayer; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.template.VmdkProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 034a296cac6..8fabf1f3448 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -187,11 +187,11 @@ import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.resource.ServerResource; import com.cloud.serializer.GsonHelper; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.resource.StoragePoolResource; import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.volume.Volume; import com.cloud.utils.DateUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java index f9e1c8980e9..5d8fa6aeba3 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java @@ -17,8 +17,8 @@ import javax.ejb.Local; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.Storage; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.pool.Storage; import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.component.Inject; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 4fd202beedc..a13fc458ad3 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -73,11 +73,11 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.user.Account; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Inject; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 7abe28150d9..b11f55809ff 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -204,12 +204,12 @@ import com.cloud.network.ovs.OvsSetTagAndFlowCommand; import com.cloud.network.ovs.OvsSetupBridgeCommand; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java index d689393688b..198d988fc6e 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java @@ -30,7 +30,7 @@ import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.resource.ServerResource; -import com.cloud.storage.Volume; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; diff --git a/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java index 919270349a9..ee38cf88942 100644 --- a/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java +++ b/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java @@ -26,9 +26,9 @@ import org.apache.log4j.Logger; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.server.StatsCollector; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.pool.StoragePool; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 62e8acb0642..02786810e0b 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -94,11 +94,11 @@ import com.cloud.resource.Discoverer; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.resource.ServerResource; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StorageService; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StoragePoolService; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.user.AccountManager; @@ -194,8 +194,8 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { @Inject protected VirtualMachineManager _vmMgr = null; - @Inject StorageService _storageSvr = null; - @Inject StorageManager _storageMgr = null; + @Inject StoragePoolService _storageSvr = null; + @Inject StoragePoolManager _storageMgr = null; @Inject protected HypervisorGuruManager _hvGuruMgr; diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index 9c0cbb322fb..f4e3345769b 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -65,10 +65,10 @@ import com.cloud.host.dao.HostDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceManager; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; @@ -92,7 +92,7 @@ public class AlertManagerImpl implements AlertManager { private EmailAlert _emailAlert; @Inject private AlertDao _alertDao; @Inject private HostDao _hostDao; - @Inject protected StorageManager _storageMgr; + @Inject protected StoragePoolManager _storageMgr; @Inject protected CapacityManager _capacityMgr; @Inject private CapacityDao _capacityDao; @Inject private DataCenterDao _dcDao; diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index e1e88652ba3..ec0e4efdae4 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -94,19 +94,13 @@ import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; @@ -121,6 +115,12 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StorageStats; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.snapshot.Snapshot; +import com.cloud.storage.volume.GuestOS; +import com.cloud.storage.volume.Volume.Type; import com.cloud.user.Account; import com.cloud.user.AccountDetailsDao; import com.cloud.user.AccountVO; @@ -154,7 +154,7 @@ public class ApiDBUtils { private static ManagementServer _ms; public static AsyncJobManager _asyncMgr; private static SecurityGroupManager _securityGroupMgr; - private static StorageManager _storageMgr; + private static StoragePoolManager _storageMgr; private static UserVmManager _userVmMgr; private static NetworkManager _networkMgr; private static StatsCollector _statsCollector; @@ -212,7 +212,7 @@ public class ApiDBUtils { ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); _asyncMgr = locator.getManager(AsyncJobManager.class); _securityGroupMgr = locator.getManager(SecurityGroupManager.class); - _storageMgr = locator.getManager(StorageManager.class); + _storageMgr = locator.getManager(StoragePoolManager.class); _userVmMgr = locator.getManager(UserVmManager.class); _networkMgr = locator.getManager(NetworkManager.class); _configMgr = locator.getManager(ConfigurationService.class); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 0340a941b83..343709e27cb 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -176,25 +176,25 @@ import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; import com.cloud.storage.Swift; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StorageStats; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.TemplateType; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.storage.volume.GuestOS; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.test.PodZoneConfig; import com.cloud.user.Account; diff --git a/server/src/com/cloud/async/AsyncJobExecutorContext.java b/server/src/com/cloud/async/AsyncJobExecutorContext.java index 109fb5383f0..87f421bb06b 100644 --- a/server/src/com/cloud/async/AsyncJobExecutorContext.java +++ b/server/src/com/cloud/async/AsyncJobExecutorContext.java @@ -22,8 +22,8 @@ import com.cloud.event.dao.EventDao; import com.cloud.network.NetworkManager; import com.cloud.network.dao.IPAddressDao; import com.cloud.server.ManagementServer; -import com.cloud.storage.StorageManager; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDao; @@ -41,7 +41,7 @@ public interface AsyncJobExecutorContext extends Manager { public UserVmManager getVmMgr(); public SnapshotManager getSnapshotMgr(); public AccountManager getAccountMgr(); - public StorageManager getStorageMgr(); + public StoragePoolManager getStorageMgr(); public EventDao getEventDao(); public UserVmDao getVmDao(); public AccountDao getAccountDao(); diff --git a/server/src/com/cloud/async/AsyncJobExecutorContextImpl.java b/server/src/com/cloud/async/AsyncJobExecutorContextImpl.java index 5676b7c8aa2..c7158f60a6c 100644 --- a/server/src/com/cloud/async/AsyncJobExecutorContextImpl.java +++ b/server/src/com/cloud/async/AsyncJobExecutorContextImpl.java @@ -27,8 +27,8 @@ import com.cloud.event.dao.EventDao; import com.cloud.network.NetworkManager; import com.cloud.network.dao.IPAddressDao; import com.cloud.server.ManagementServer; -import com.cloud.storage.StorageManager; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDao; @@ -48,7 +48,7 @@ public class AsyncJobExecutorContextImpl implements AsyncJobExecutorContext { private UserVmManager _vmMgr; private SnapshotManager _snapMgr; private AccountManager _accountMgr; - private StorageManager _storageMgr; + private StoragePoolManager _storageMgr; private EventDao _eventDao; private UserVmDao _vmDao; private AccountDao _accountDao; @@ -82,7 +82,7 @@ public class AsyncJobExecutorContextImpl implements AsyncJobExecutorContext { } @Override - public StorageManager getStorageMgr() { + public StoragePoolManager getStorageMgr() { return _storageMgr; } @@ -179,9 +179,9 @@ public class AsyncJobExecutorContextImpl implements AsyncJobExecutorContext { throw new ConfigurationException("unable to get " + AccountManager.class.getName()); } - _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()); } _eventDao = locator.getDao(EventDao.class); diff --git a/server/src/com/cloud/async/executor/ExtractJobResultObject.java b/server/src/com/cloud/async/executor/ExtractJobResultObject.java index 772f0740e66..da01feca401 100644 --- a/server/src/com/cloud/async/executor/ExtractJobResultObject.java +++ b/server/src/com/cloud/async/executor/ExtractJobResultObject.java @@ -20,8 +20,8 @@ import java.util.Date; import com.cloud.async.AsyncInstanceCreateStatus; import com.cloud.serializer.Param; -import com.cloud.storage.Volume.Type; import com.cloud.storage.upload.UploadState; +import com.cloud.storage.volume.Volume.Type; public class ExtractJobResultObject { diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java index 3972728d5db..3271402ec75 100755 --- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java @@ -64,10 +64,10 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.org.Grouping; import com.cloud.resource.ResourceManager; import com.cloud.service.ServiceOfferingVO; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.TemplateType; +import com.cloud.storage.volume.Volume; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.template.TemplateAdapter; import com.cloud.template.TemplateAdapter.TemplateAdapterType; import com.cloud.template.TemplateProfile; diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index c410109b9ef..701bb9ef652 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -54,7 +54,6 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ServerResource; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStoragePoolVO; @@ -62,6 +61,7 @@ import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; @@ -101,7 +101,7 @@ public class CapacityManagerImpl implements CapacityManager, StateListener _storagePoolAllocators; diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 87743d5c469..9da5140e6ba 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -58,9 +58,9 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; -import com.cloud.storage.StorageManager; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.user.AccountManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Adapters; @@ -126,7 +126,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu @Inject AlertManager _alertMgr; @Inject - StorageManager _storageMgr; + StoragePoolManager _storageMgr; @Inject GuestOSDao _guestOSDao; @Inject diff --git a/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java b/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java index 5dd1694742d..0940fb7ee2d 100755 --- a/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java +++ b/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java @@ -47,7 +47,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage; +import com.cloud.storage.pool.Storage; import com.cloud.utils.component.Inject; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 82025116cd2..609516d7a17 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -179,11 +179,11 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.volume.Volume.Type; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 14b5df57a4b..54d0c404bed 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -107,12 +107,8 @@ import com.cloud.org.Grouping.AllocationState; import com.cloud.org.Managed; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageService; import com.cloud.storage.Swift; import com.cloud.storage.SwiftVO; import com.cloud.storage.VMTemplateVO; @@ -120,6 +116,10 @@ import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StoragePoolService; +import com.cloud.storage.pool.StoragePoolStatus; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.template.VirtualMachineTemplate; @@ -162,7 +162,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma @Inject AgentManager _agentMgr; @Inject - StorageManager _storageMgr; + StoragePoolManager _storageMgr; @Inject protected SecondaryStorageVmManager _secondaryStorageMgr; @@ -201,7 +201,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma @Inject protected HighAvailabilityManager _haMgr; @Inject - protected StorageService _storageSvr; + protected StoragePoolService _storageSvr; @Inject(adapter = Discoverer.class) protected Adapters _discoverers; @Inject @@ -1760,7 +1760,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma if (storagePool != null) { if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) { try { - storagePool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId()); + storagePool = _storageSvr.prepareStorageForMaintenance(storagePool.getId()); if (storagePool == null) { s_logger.debug("Failed to set primary storage into maintenance mode"); throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode"); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 32ed37d3e8a..4ea3ec46e8c 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -176,15 +176,11 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; @@ -193,10 +189,14 @@ import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.upload.UploadMonitor; +import com.cloud.storage.volume.Volume; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; @@ -291,7 +291,7 @@ public class ManagementServerImpl implements ManagementServer { private final StoragePoolDao _poolDao; private final NicDao _nicDao; private final NetworkDao _networkDao; - private final StorageManager _storageMgr; + private final StoragePoolManager _storageMgr; private final VirtualMachineManager _itMgr; private final HostPodDao _hostPodDao; private final VMInstanceDao _vmInstanceDao; @@ -355,7 +355,7 @@ public class ManagementServerImpl implements ManagementServer { _consoleProxyMgr = locator.getManager(ConsoleProxyManager.class); _secStorageVmMgr = locator.getManager(SecondaryStorageVmManager.class); _swiftMgr = locator.getManager(SwiftManager.class); - _storageMgr = locator.getManager(StorageManager.class); + _storageMgr = locator.getManager(StoragePoolManager.class); _publicIpAddressDao = locator.getDao(IPAddressDao.class); _consoleProxyDao = locator.getDao(ConsoleProxyDao.class); _secStorageVmDao = locator.getDao(SecondaryStorageVmDao.class); diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 08135fac55f..eada939748f 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -46,16 +46,16 @@ import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.resource.ResourceState; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StorageStats; import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.storage.volume.VolumeStats; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -81,7 +81,7 @@ public class StatsCollector { private final UserVmDao _userVmDao; private final VolumeDao _volsDao; private final StoragePoolDao _storagePoolDao; - private final StorageManager _storageManager; + private final StoragePoolManager _storageManager; private final StoragePoolHostDao _storagePoolHostDao; private final SecondaryStorageVmManager _ssvmMgr; private final ResourceManager _resourceMgr; @@ -118,7 +118,7 @@ public class StatsCollector { _userVmDao = locator.getDao(UserVmDao.class); _volsDao = locator.getDao(VolumeDao.class); _storagePoolDao = locator.getDao(StoragePoolDao.class); - _storageManager = locator.getManager(StorageManager.class); + _storageManager = locator.getManager(StoragePoolManager.class); _storagePoolHostDao = locator.getDao(StoragePoolHostDao.class); _resourceMgr = locator.getManager(ResourceManager.class); diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index 1be7a558aef..3242ecce1f3 100755 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -37,6 +37,8 @@ import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria; @@ -47,7 +49,7 @@ public class LocalStoragePoolListener implements Listener { @Inject StoragePoolDao _storagePoolDao; @Inject StoragePoolHostDao _storagePoolHostDao; @Inject CapacityDao _capacityDao; - @Inject StorageManager _storageMgr; + @Inject StoragePoolManager _storageMgr; @Override public int getTimeout() { diff --git a/server/src/com/cloud/storage/OCFS2Manager.java b/server/src/com/cloud/storage/OCFS2Manager.java index 3f0b7fbc6ca..673b38d63cd 100755 --- a/server/src/com/cloud/storage/OCFS2Manager.java +++ b/server/src/com/cloud/storage/OCFS2Manager.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import com.cloud.host.HostVO; +import com.cloud.storage.pool.StoragePool; import com.cloud.utils.component.Manager; public interface OCFS2Manager extends Manager { diff --git a/server/src/com/cloud/storage/OCFS2ManagerImpl.java b/server/src/com/cloud/storage/OCFS2ManagerImpl.java index a399b03dfad..66e6610bc34 100755 --- a/server/src/com/cloud/storage/OCFS2ManagerImpl.java +++ b/server/src/com/cloud/storage/OCFS2ManagerImpl.java @@ -39,9 +39,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; import com.cloud.resource.ServerResource; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.db.SearchCriteria.Op; diff --git a/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java b/server/src/com/cloud/storage/StorageMigrationCleanupMaid.java index 3ba8483d320..20e9aba49f3 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; diff --git a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java index 87cb065e285..f78ec260a47 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; diff --git a/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/FirstFitStoragePoolAllocator.java index 006931d4814..aa3f5bbf5d6 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; diff --git a/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java index 2418583419f..1bd6231c912 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); diff --git a/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/LocalStoragePoolAllocator.java index 991baadfc1f..b565f6d2034 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; diff --git a/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/StoragePoolAllocator.java index 13f44e7420d..93f99e25c65 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; diff --git a/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java b/server/src/com/cloud/storage/allocator/UseLocalForRootAllocator.java index 38e116ad947..ddc113f94ea 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; 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 00000000000..2e2bcfd89ba --- /dev/null +++ b/server/src/com/cloud/storage/backup/StorageBackupManager.java @@ -0,0 +1,5 @@ +package com.cloud.storage.backup; + +public interface StorageBackupManager { + +} 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 00000000000..8c19c202aae --- /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 { + +} diff --git a/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java b/server/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java index 2ae394e4a5c..8a6975b5e39 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; diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index 4bf54ded52d..a9923e906bb 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; diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index ac4bb6fc46d..c4f065e368d 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; diff --git a/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java index c4e6a5af89a..fe3b9250819 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; diff --git a/server/src/com/cloud/storage/dao/StoragePoolDao.java b/server/src/com/cloud/storage/dao/StoragePoolDao.java index ff8292e9705..acc69a46321 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 diff --git a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java index 730610b763b..ab2689e2f02 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; diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 2a0dfc85559..5ae4afc6247 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; diff --git a/server/src/com/cloud/storage/dao/VolumeDao.java b/server/src/com/cloud/storage/dao/VolumeDao.java index d7a2667edb9..05130da23b6 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; diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 638d209e5b1..f93c89e4bc5 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 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(); diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 036d40ad015..7e86cbd1289 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; diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index 30ec3b1623b..c33c9dc6d9a 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; diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 27367779650..6f77dacea48 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; 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 00000000000..2e44d7f287a --- /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 getAbsoluteIsoPath(long templateId, long dataCenterId); + +} 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 00000000000..12027991357 --- /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 getAbsoluteIsoPath(long templateId, long dataCenterId) { + String isoPath = null; + + List 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(isoPath, storageHost.getStorageUrl()); + } + } + } + s_logger.warn("Unable to find secondary storage in zone id=" + dataCenterId); + return null; + } +} diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index 3bb002bb70f..74fd5242db2 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; 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 00000000000..92b78afdef2 --- /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 vm, DeployDestination dest); + void prepare(VirtualMachineProfile vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException, + InsufficientStorageCapacityException, ConcurrentOperationException; + + void allocateVolume(Long vmId, Pair rootDiskOffering, + List> dataDiskOfferings, + Long templateId, Account owner); +} 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 00000000000..1321fa52d08 --- /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 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 poolsToAvoid = new HashSet(); + StoragePoolVO pool = null; + boolean success = false; + Set podsToAvoid = new HashSet(); + Pair 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 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(createdVolume, details); + } + + @Override + @DB + public VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, + List avoids, long size, HypervisorType hyperType) throws NoTransitionException { + + final HashSet avoidPools = new HashSet(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 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(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(vdiUUID, basicErrMsg); + } + + protected Pair 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(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(vdiUUID, basicErrMsg); + } + + @Override + public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) { + List 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 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 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 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 vols = _volumeDao.findUsableVolumesForInstance(vm.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking if we need to prepare " + vols.size() + " volumes for " + vm); + } + + List recreateVols = new ArrayList(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 volumesToMigrate = new ArrayList(); + 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 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 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 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 createVolume(VolumeVO toBeCreated, DiskOfferingVO offering, VirtualMachineProfile vm, List 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(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 volumes, StoragePool destPool) throws ConcurrentOperationException { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + boolean transitResult = false; + long checkPointTaskId = -1; + try { + List volIds = new ArrayList(); + 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> destroyCmds = new ArrayList>(); + List answers = new ArrayList(); + 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(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 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 vm, StoragePool destPool) throws ConcurrentOperationException { + List vols = _volumeDao.findUsableVolumesForInstance(vm.getId()); + List volumesNeedToMigrate = new ArrayList(); + + 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 vols = new ArrayList(); + vols.add(vol); + + migrateVolumes(vols, destPool); + return vol; + } + + @Override + public void allocateVolume(Long vmId, + Pair rootDiskOffering, + List> dataDiskOfferings, Long templateId, Account owner) { + + _volumeMgr.allocateVolume(vmId, rootDiskOffering, dataDiskOfferings, templateId, owner); + + } +} diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/pool/StoragePoolManager.java similarity index 54% rename from server/src/com/cloud/storage/StorageManager.java rename to server/src/com/cloud/storage/pool/StoragePoolManager.java index 59a02210d86..bd0b5c1a205 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/pool/StoragePoolManager.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; import java.util.List; @@ -27,14 +27,21 @@ 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.Storage.ImageFormat; -import com.cloud.storage.Volume.Event; -import com.cloud.storage.Volume.Type; +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; @@ -44,16 +51,9 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -public interface StorageManager extends StorageService, Manager { +public interface StoragePoolManager extends StoragePoolService, Manager { boolean canVmRestartOnAnotherServer(long vmId); - /** Returns the absolute path of the specified ISO - * @param templateId - the ID of the template that represents the ISO - * @param datacenterId - * @return absolute ISO path - */ - public Pair getAbsoluteIsoPath(long templateId, long dataCenterId); - /** * Returns the URL of the secondary storage host * @param zoneId @@ -82,54 +82,11 @@ public interface StorageManager extends StorageService, Manager { */ public VMTemplateHostVO findVmTemplateHost(long templateId, StoragePool pool); - /** - * Moves a volume from its current storage pool to a storage pool with enough capacity in the specified zone, pod, or cluster - * @param volume - * @param destPoolDcId - * @param destPoolPodId - * @param destPoolClusterId - * @return VolumeVO - * @throws ConcurrentOperationException - */ - VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException; - - /** - * Create a volume based on the given criteria - * @param volume - * @param vm - * @param template - * @param dc - * @param pod - * @param clusterId - * @param offering - * @param diskOffering - * @param avoids - * @param size - * @param hyperType - * @return volume VO if success, null otherwise - */ - VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, - ServiceOfferingVO offering, DiskOfferingVO diskOffering, List avoids, long size, HypervisorType hyperType); - - /** - * Marks the specified volume as destroyed in the management server database. The expunge thread will delete the volume from its storage pool. - * @param volume - * @return - */ - boolean destroyVolume(VolumeVO volume) throws ConcurrentOperationException; - /** Create capacity entries in the op capacity table * @param storagePool */ public void createCapacityEntry(StoragePoolVO storagePool); - /** - * Checks that the volume is stored on a shared storage pool - * @param volume - * @return true if the volume is on a shared storage pool, false otherwise - */ - boolean volumeOnSharedStoragePool(VolumeVO volume); - Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException; Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException; Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException; @@ -137,17 +94,6 @@ public interface StorageManager extends StorageService, Manager { Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Commands cmds) throws StorageUnavailableException; Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Command cmd) throws StorageUnavailableException; - /** - * Checks that one of the following is true: - * 1. The volume is not attached to any VM - * 2. The volume is attached to a VM that is running on a host with the KVM hypervisor, and the VM is stopped - * 3. The volume is attached to a VM that is running on a host with the XenServer hypervisor (the VM can be stopped or running) - * @return true if one of the above conditions is true - */ - boolean volumeInactive(VolumeVO volume); - - String getVmNameOnVolume(VolumeVO volume); - /** * Checks if a host has running VMs that are using its local storage pool. * @return true if local storage is active on the host @@ -162,32 +108,10 @@ public interface StorageManager extends StorageService, Manager { String getPrimaryStorageNameLabel(VolumeVO volume); - /** - * Allocates one volume. - * @param - * @param type - * @param offering - * @param name - * @param size - * @param template - * @param vm - * @param account - * @return VolumeVO a persisted volume. - */ - DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, T vm, Account owner); - DiskProfile allocateTemplatedVolume(Type type, String name, DiskOfferingVO offering, VMTemplateVO template, T vm, Account owner); - void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated); - - void prepare(VirtualMachineProfile vm, DeployDestination dest, boolean recreate) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException; - void release(VirtualMachineProfile profile); - void cleanupVolumes(long vmId) throws ConcurrentOperationException; - - void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest); - Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException; CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId); @@ -211,30 +135,17 @@ public interface StorageManager extends StorageService, Manager { VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, boolean readyOnly); - boolean StorageMigration( - VirtualMachineProfile vm, - StoragePool destPool) throws ConcurrentOperationException; - - boolean stateTransitTo(Volume vol, Event event) - throws NoTransitionException; - - VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId); - Host updateSecondaryStorage(long secStorageId, String newUrl); List getUpHostsInPool(long poolId); void cleanupSecondaryStorage(boolean recurring); - VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, - VMTemplateVO template, DataCenterVO dc, HostPodVO pod, - Long clusterId, ServiceOfferingVO offering, - DiskOfferingVO diskOffering, List avoids, long size, - HypervisorType hyperType) throws NoTransitionException; - String getSupportedImageFormatForCluster(Long clusterId); HypervisorType getHypervisorTypeFromFormat(ImageFormat format); - boolean storagePoolHasEnoughSpace(List volume, StoragePool pool); + boolean storagePoolHasEnoughSpace(List volume, StoragePool pool); + + StoragePool getStoragePoolById(Long id); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/pool/StoragePoolManagerImpl.java similarity index 55% rename from server/src/com/cloud/storage/StorageManagerImpl.java rename to server/src/com/cloud/storage/pool/StoragePoolManagerImpl.java index 20dde8bd0fe..e728ec87b1e 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/pool/StoragePoolManagerImpl.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package com.cloud.storage.pool; import java.math.BigDecimal; import java.net.Inet6Address; @@ -136,10 +136,20 @@ import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.StatsCollector; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume.Event; -import com.cloud.storage.Volume.Type; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.LocalStoragePoolListener; +import com.cloud.storage.OCFS2Manager; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.StoragePoolDiscoverer; +import com.cloud.storage.StoragePoolHostVO; +import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.StoragePoolWorkVO; +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeHostVO; +import com.cloud.storage.VolumeVO; import com.cloud.storage.allocator.StoragePoolAllocator; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; @@ -155,9 +165,15 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; +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.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; @@ -211,9 +227,9 @@ import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -@Local(value = { StorageManager.class, StorageService.class }) -public class StorageManagerImpl implements StorageManager, Manager, ClusterManagerListener { - private static final Logger s_logger = Logger.getLogger(StorageManagerImpl.class); +@Local(value = { StoragePoolManager.class, StoragePoolService.class }) +public class StoragePoolManagerImpl implements StoragePoolManager, Manager, ClusterManagerListener { + private static final Logger s_logger = Logger.getLogger(StoragePoolManagerImpl.class); protected String _name; @Inject @@ -326,6 +342,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag protected DownloadMonitor _downloadMonitor; @Inject protected ResourceTagDao _resourceTagDao; + @Inject + protected VolumeManager _volumeManager; @Inject(adapter = StoragePoolAllocator.class) protected Adapters _storagePoolAllocators; @@ -358,58 +376,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag private double _storageAllocatedThreshold = 1.0d; protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1); - public boolean share(VMInstanceVO vm, List vols, HostVO host, boolean cancelPreviousShare) throws StorageUnavailableException { - - // if pool is in maintenance and it is the ONLY pool available; reject - List rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), Type.ROOT); - if (rootVolForGivenVm != null && rootVolForGivenVm.size() > 0) { - boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId()); - if (!isPoolAvailable) { - throw new StorageUnavailableException("Can not share " + vm, rootVolForGivenVm.get(0).getPoolId()); - } - } - - // this check is done for maintenance mode for primary storage - // if any one of the volume is unusable, we return false - // if we return false, the allocator will try to switch to another PS if available - for (VolumeVO vol : vols) { - if (vol.getRemoved() != null) { - s_logger.warn("Volume id:" + vol.getId() + " is removed, cannot share on this instance"); - // not ok to share - return false; - } - } - - // ok to share - return true; - } - - @Override - public VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId) { - VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize()); - if (templateId != null) { - newVol.setTemplateId(templateId); - } else { - newVol.setTemplateId(oldVol.getTemplateId()); - } - newVol.setDeviceId(oldVol.getDeviceId()); - newVol.setInstanceId(oldVol.getInstanceId()); - newVol.setRecreatable(oldVol.isRecreatable()); - return _volsDao.persist(newVol); - } - - private boolean isPoolAvailable(Long poolId) { - // get list of all pools - List pools = _storagePoolDao.listAll(); - - // if no pools or 1 pool which is in maintenance - if (pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(StoragePoolStatus.Maintenance))) { - return false; - } else { - return true; - } - } - @Override public List ListByDataCenterHypervisor(long datacenterId, HypervisorType type) { List pools = _storagePoolDao.listByDataCenterId(datacenterId); @@ -504,27 +470,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return sendToPool(pool, cmds); } - protected DiskProfile createDiskCharacteristics(VolumeVO volume, VMTemplateVO template, DataCenterVO dc, DiskOfferingVO diskOffering) { - if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { - SearchCriteria sc = HostTemplateStatesSearch.create(); - sc.setParameters("id", template.getId()); - sc.setParameters("state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - sc.setJoinParameters("host", "dcId", dc.getId()); - - List sss = _vmTemplateHostDao.search(sc, null); - if (sss.size() == 0) { - throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId()); - } - VMTemplateHostVO ss = sss.get(0); - - return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(), diskOffering.getUseLocalStorage(), - diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null); - } else { - return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(), - diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null); - } - } - @Override public boolean canVmRestartOnAnotherServer(long vmId) { List vols = _volsDao.findCreatedByInstance(vmId); @@ -536,363 +481,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return true; } - @DB - protected Pair 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 poolsToAvoid = new HashSet(); - StoragePoolVO pool = null; - boolean success = false; - Set podsToAvoid = new HashSet(); - Pair 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 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(createdVolume, details); - } - - @Override - public boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException { - return _volStateMachine.transitTo(vol, event, null, _volsDao); - } - - protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId) { - - // By default, assume failure. - VolumeVO createdVolume = null; - SnapshotVO snapshot = _snapshotDao.findById(snapshotId); // Precondition: snapshot is not null and not removed. - - Pair volumeDetails = createVolumeFromSnapshot(volume, snapshot); - if (volumeDetails != null) { - createdVolume = volumeDetails.first(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(), - createdVolume.getDiskOfferingId(), null, createdVolume.getSize()); - _usageEventDao.persist(usageEvent); - } - return createdVolume; - } - - protected Pair 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(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(vdiUUID, basicErrMsg); - } - - - @Override - @DB - public VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, - List avoids, long size, HypervisorType hyperType) throws NoTransitionException { - - final HashSet avoidPools = new HashSet(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; - - } - - @Override - @DB - public VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, - List avoids, long size, HypervisorType hyperType) { - StoragePoolVO pool = null; - final HashSet avoidPools = new HashSet(avoids); - - try { - stateTransitTo(volume, Volume.Event.CreateRequested); - } catch (NoTransitionException e) { - s_logger.debug("Unable to update volume state: " + e.toString()); - return null; - } - - if (diskOffering != null && diskOffering.isCustomized()) { - diskOffering.setDiskSize(size); - } - DiskProfile dskCh = null; - if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { - dskCh = createDiskCharacteristics(volume, template, dc, offering); - } else { - dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); - } - - dskCh.setHyperType(hyperType); - - VolumeTO created = null; - int retry = _retry; - while (--retry >= 0) { - created = null; - - long podId = pod.getId(); - pod = _podDao.findById(podId); - if (pod == null) { - s_logger.warn("Unable to find pod " + podId + " when create volume " + volume.getName()); - break; - } - - pool = findStoragePool(dskCh, dc, pod, clusterId, vm, avoidPools); - if (pool == null) { - s_logger.warn("Unable to find storage poll when create volume " + volume.getName()); - break; - } - - avoidPools.add(pool); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to create " + volume + " on " + pool); - } - - CreateCommand cmd = null; - VMTemplateStoragePoolVO tmpltStoredOn = null; - - for (int i = 0; i < 2; i++) { - if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { - tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool); - if (tmpltStoredOn == null) { - continue; - } - cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool)); - } else { - if (volume.getVolumeType() == Type.ROOT && 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(dskCh, new StorageFilerTO(pool)); - } - - try { - Answer answer = sendToPool(pool, cmd); - if (answer != null && answer.getResult()) { - created = ((CreateAnswer) answer).getVolume(); - break; - } - - if (tmpltStoredOn != null && answer != null && (answer instanceof CreateAnswer) && ((CreateAnswer) answer).templateReloadRequested()) { - if (!_tmpltMgr.resetTemplateDownloadStateOnPool(tmpltStoredOn.getId())) { - break; // break out of template-redeploy retry loop - } - } else { - break; - } - } catch (StorageUnavailableException e) { - s_logger.debug("Storage unavailable for " + pool.getId()); - break; // break out of template-redeploy retry loop - } - } - - if (created != null) { - break; - } - - s_logger.debug("Retrying the create because it failed on pool " + pool); - } - - if (created == null) { - return null; - } else { - volume.setFolder(pool.getPath()); - volume.setPath(created.getPath()); - volume.setSize(created.getSize()); - volume.setPoolType(pool.getPoolType()); - volume.setPoolId(pool.getId()); - volume.setPodId(pod.getId()); - try { - stateTransitTo(volume, Volume.Event.OperationSucceeded); - } catch (NoTransitionException e) { - s_logger.debug("Unable to update volume state: " + e.toString()); - return null; - } - return volume; - } - } - public Long chooseHostForStoragePool(StoragePoolVO poolVO, List avoidHosts, boolean sendToVmResidesOn, Long vmId) { if (sendToVmResidesOn) { if (vmId != null) { @@ -997,16 +585,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag String _customDiskOfferingMaxSizeStr = configDao.getValue(Config.CustomDiskOfferingMaxSize.toString()); _customDiskOfferingMaxSize = NumbersUtil.parseInt(_customDiskOfferingMaxSizeStr, Integer.parseInt(Config.CustomDiskOfferingMaxSize.getDefaultValue())); - HostTemplateStatesSearch = _vmTemplateHostDao.createSearchBuilder(); - HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); - SearchBuilder HostSearch = _hostDao.createSearchBuilder(); - HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - - HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); - HostSearch.done(); - HostTemplateStatesSearch.done(); _serverId = ((ManagementServer) ComponentLocator.getComponent(ManagementServer.Name)).getId(); @@ -1036,74 +615,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return true; } - public String getRandomVolumeName() { - return UUID.randomUUID().toString(); - } - - @Override - public boolean volumeOnSharedStoragePool(VolumeVO volume) { - Long poolId = volume.getPoolId(); - if (poolId == null) { - return false; - } else { - StoragePoolVO pool = _storagePoolDao.findById(poolId); - - if (pool == null) { - return false; - } else { - return pool.isShared(); - } - } - } - - @Override - public boolean volumeInactive(VolumeVO volume) { - Long vmId = volume.getInstanceId(); - if (vmId != null) { - UserVm vm = _userVmDao.findById(vmId); - if (vm == null) { - return true; - } - State state = vm.getState(); - if (state.equals(State.Stopped) || state.equals(State.Destroyed)) { - return true; - } - } - return false; - } - - @Override - public String getVmNameOnVolume(VolumeVO volume) { - Long vmId = volume.getInstanceId(); - if (vmId != null) { - VMInstanceVO vm = _vmInstanceDao.findById(vmId); - - if (vm == null) { - return null; - } - return vm.getInstanceName(); - } - return null; - } - - @Override - public Pair getAbsoluteIsoPath(long templateId, long dataCenterId) { - String isoPath = null; - - List 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(isoPath, storageHost.getStorageUrl()); - } - } - } - s_logger.warn("Unable to find secondary storage in zone id=" + dataCenterId); - return null; - } - @Override public String getSecondaryStorageURL(long zoneId) { // Determine the secondary storage URL @@ -1217,10 +728,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return true; } - protected StorageManagerImpl() { - _volStateMachine = Volume.State.getStateMachine(); - } - @Override @SuppressWarnings("rawtypes") public StoragePoolVO createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException { @@ -1516,7 +1023,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag //force expunge non-destroyed volumes List vols = _volsDao.listVolumesToBeDestroyed(); for (VolumeVO vol : vols) { - expungeVolume(vol, true); + _volumeManager.expungeVolume(vol, true); } } } else { @@ -1696,421 +1203,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.info("Connection established between " + pool + " host + " + hostId); } - - @Override - public VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException { - - // Find a destination storage pool with the specified criteria - DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); - DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(), - diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null); - dskCh.setHyperType(dataDiskHyperType); - DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId); - HostPodVO destPoolPod = _podDao.findById(destPoolPodId); - StoragePoolVO destPool = findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, new HashSet()); - String secondaryStorageURL = getSecondaryStorageURL(volume.getDataCenterId()); - - if (destPool == null) { - throw new CloudRuntimeException("Failed to find a storage pool with enough capacity to move the volume to."); - } - if (secondaryStorageURL == null) { - throw new CloudRuntimeException("Failed to find secondary storage."); - } - - List vols = new ArrayList(); - vols.add(volume); - migrateVolumes(vols, destPool); - return _volsDao.findById(volume.getId()); - } - - /* - * Upload the volume to secondary storage. - * - */ - @Override - @DB - @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) - public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException{ - Account caller = UserContext.current().getCaller(); - long ownerId = cmd.getEntityOwnerId(); - Long zoneId = cmd.getZoneId(); - String volumeName = cmd.getVolumeName(); - String url = cmd.getUrl(); - String format = cmd.getFormat(); - - validateVolume(caller, ownerId, zoneId, volumeName, url, format); - VolumeVO volume = persistVolume(caller, ownerId, zoneId, volumeName, url, cmd.getFormat()); - _downloadMonitor.downloadVolumeToStorage(volume, zoneId, url, cmd.getChecksum(), ImageFormat.valueOf(format.toUpperCase())); - return volume; - } - - private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException{ - - // 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); - - - // 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); - } - - 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())); - } - - String userSpecifiedName = volumeName; - if (userSpecifiedName == null) { - userSpecifiedName = getRandomVolumeName(); - } - if((!url.toLowerCase().endsWith("vhd"))&&(!url.toLowerCase().endsWith("vhd.zip")) - &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz")) - &&(!url.toLowerCase().endsWith("qcow2"))&&(!url.toLowerCase().endsWith("qcow2.zip")) - &&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz")) - &&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip")) - &&(!url.toLowerCase().endsWith("ova.bz2"))&&(!url.toLowerCase().endsWith("ova.gz")) - &&(!url.toLowerCase().endsWith("img"))&&(!url.toLowerCase().endsWith("raw"))){ - throw new InvalidParameterValueException("Please specify a valid " + format.toLowerCase()); - } - - if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(".vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase().endsWith("vhd.gz") )) - || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz") )) - || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase().endsWith("ova.gz"))) - || (format.equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith(".img") && !url.toLowerCase().endsWith("raw")))) { - throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase()); - } - validateUrl(url); - - return false; - } - - private String validateUrl(String url){ - try { - URI uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") - && !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) { - throw new IllegalArgumentException("Unsupported scheme for url: " + url); - } - - int port = uri.getPort(); - if (!(port == 80 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); - } - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - - return uri.toString(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid URL " + url); - } - - } - - private VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - VolumeVO volume = new VolumeVO(volumeName, zoneId, -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())); - long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); - volume.setDiskOfferingId(diskOfferingId); - //volume.setSize(size); - volume.setInstanceId(null); - volume.setUpdated(new Date()); - volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()); - - volume = _volsDao.persist(volume); - try { - stateTransitTo(volume, Event.UploadRequested); - } catch (NoTransitionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - 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; - } - - - /* - * 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 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 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 = _volsDao.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; - } - - @Override - @DB - @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true) - public VolumeVO createVolume(CreateVolumeCmd cmd) { - VolumeVO volume = _volsDao.findById(cmd.getEntityId()); - boolean created = false; - - try { - if (cmd.getSnapshotId() != null) { - volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId()); - if (volume.getState() == Volume.State.Ready) { - created = true; - } - return volume; - } else { - _volsDao.update(volume.getId(), volume); - created = true; - } - - return _volsDao.findById(volume.getId()); - } finally { - if (!created) { - s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); - } - } - } - - @Override - @DB - public boolean destroyVolume(VolumeVO volume) throws ConcurrentOperationException { - try { - if (!stateTransitTo(volume, Volume.Event.DestroyRequested)) { - throw new ConcurrentOperationException("Failed to transit to destroyed state"); - } - } catch (NoTransitionException e) { - s_logger.debug("Unable to destoy the volume: " + e.toString()); - return false; - } - - long volumeId = volume.getId(); - - // Delete the recurring snapshot policies for this volume. - _snapshotMgr.deletePoliciesForVolume(volumeId); - - Long instanceId = volume.getInstanceId(); - VMInstanceVO vmInstance = null; - if (instanceId != null) { - vmInstance = _vmInstanceDao.findById(instanceId); - } - - if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { - // Decrement the resource count for volumes belonging user VM's only - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); - // Log usage event for volumes belonging user VM's only - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); - _usageEventDao.persist(usageEvent); - } - - try { - if (!stateTransitTo(volume, Volume.Event.OperationSucceeded)) { - throw new ConcurrentOperationException("Failed to transit state"); - - } - } catch (NoTransitionException e) { - s_logger.debug("Unable to change volume state: " + e.toString()); - return false; - } - - return true; - - } - @Override public void createCapacityEntry(StoragePoolVO storagePool) { createCapacityEntry(storagePool, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, 0); @@ -2255,7 +1348,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag List vols = _volsDao.listVolumesToBeDestroyed(); for (VolumeVO vol : vols) { try { - expungeVolume(vol, false); + _volumeManager.expungeVolume(vol, false); } catch (Exception e) { s_logger.warn("Unable to destroy " + vol.getId(), e); } @@ -2449,7 +1542,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @Override @DB - public StoragePoolVO preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException { + public StoragePoolVO prepareStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException { Long userId = UserContext.current().getCallerUserId(); User user = _userDao.findById(userId); Account account = UserContext.current().getCaller(); @@ -2678,7 +1771,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @Override @DB - public StoragePoolVO cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException { + public StoragePoolVO cancelStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException { Long primaryStorageId = cmd.getId(); Long userId = UserContext.current().getCallerUserId(); User user = _userDao.findById(userId); @@ -2825,744 +1918,17 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } } - private boolean sendToVmResidesOn(StoragePoolVO storagePool, Command cmd) { - ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); - if ((cluster.getHypervisorType() == HypervisorType.KVM || cluster.getHypervisorType() == HypervisorType.VMware) - && ((cmd instanceof ManageSnapshotCommand) || (cmd instanceof BackupSnapshotCommand))) { - return true; - } else { - return false; - } - } - - private boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); - } - - @Override - @DB - @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") - public boolean deleteVolume(long volumeId) throws ConcurrentOperationException { - Account caller = UserContext.current().getCaller(); - - // Check that the volume ID is valid - VolumeVO volume = _volsDao.findById(volumeId); - if (volume == null) { - throw new InvalidParameterValueException("Unable to aquire volume with ID: " + volumeId); - } - - if (!_snapshotMgr.canOperateOnVolume(volume)) { - throw new InvalidParameterValueException("There are snapshot creating on it, Unable to delete the volume"); - } - - // permission check - _accountMgr.checkAccess(caller, null, true, volume); - - // Check that the volume is not currently attached to any VM - if (volume.getInstanceId() != null) { - throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM."); - } - - // Check that volume is completely Uploaded - if (volume.getState() == Volume.State.UploadOp){ - VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(volume.getId()); - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ - throw new InvalidParameterValueException("Please specify a volume that is not uploading"); - } - } - - // Check that the volume is not already destroyed - if (volume.getState() != Volume.State.Destroy) { - if (!destroyVolume(volume)) { - return false; - } - } - - try { - expungeVolume(volume, false); - } catch (Exception e) { - s_logger.warn("Failed to expunge volume:", e); - return false; - } - - return true; - } - - private boolean validateVolumeSizeRange(long size) { - if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { - throw new InvalidParameterValueException("Please specify a size of at least 1 Gb."); - } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) { - throw new InvalidParameterValueException("volume size " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " Gb."); - } - - return true; - } - protected DiskProfile toDiskProfile(VolumeVO vol, DiskOfferingVO offering) { return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.isRecreatable(), vol.getTemplateId()); } - @Override - public DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, T vm, Account owner) { - if (size == null) { - size = offering.getDiskSize(); - } else { - size = (size * 1024 * 1024 * 1024); - } - VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), size); - if (vm != null) { - vol.setInstanceId(vm.getId()); - } - - if (type.equals(Type.ROOT)) { - vol.setDeviceId(0l); - } else { - vol.setDeviceId(1l); - } - - vol = _volsDao.persist(vol); - - // Save usage event and update resource count for user vm volumes - if (vm instanceof UserVm) { - - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size); - _usageEventDao.persist(usageEvent); - - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); - } - return toDiskProfile(vol, offering); - } - - @Override - public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOfferingVO offering, VMTemplateVO template, T vm, Account owner) { - assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really...."; - - SearchCriteria sc = HostTemplateStatesSearch.create(); - sc.setParameters("id", template.getId()); - sc.setParameters("state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - sc.setJoinParameters("host", "dcId", vm.getDataCenterIdToDeployIn()); - List tsvs = _vmTemplateSwiftDao.listByTemplateId(template.getId()); - Long size = null; - if (tsvs != null && tsvs.size() > 0) { - size = tsvs.get(0).getSize(); - } - if (size == null) { - List sss = _vmTemplateHostDao.search(sc, null); - if (sss == null || sss.size() == 0) { - throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + vm.getDataCenterIdToDeployIn()); - } - size = sss.get(0).getSize(); - } - - VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), size); - if (vm != null) { - vol.setInstanceId(vm.getId()); - } - vol.setTemplateId(template.getId()); - - if (type.equals(Type.ROOT)) { - vol.setDeviceId(0l); - if (!vm.getType().equals(VirtualMachine.Type.User)) { - vol.setRecreatable(true); - } - } else { - vol.setDeviceId(1l); - } - - vol = _volsDao.persist(vol); - - // Create event and update resource count for volumes if vm is a user vm - if (vm instanceof UserVm) { - - Long offeringId = null; - - if (offering.getType() == DiskOfferingVO.Type.Disk) { - offeringId = offering.getId(); - } - - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, template.getId(), - vol.getSize()); - _usageEventDao.persist(usageEvent); - - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); - } - return toDiskProfile(vol, offering); - } - - @Override - public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) { - List 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 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); - } - } - } - } - - @DB - @Override - public Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException { - VolumeVO vol = _volsDao.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 = _storagePoolDao.findById(storagePoolId); - if (destPool == null) { - throw new InvalidParameterValueException("Faild to find the destination storage pool: " + storagePoolId); - } - - List vols = new ArrayList(); - vols.add(vol); - - migrateVolumes(vols, destPool); - return vol; - } - - @DB - public boolean migrateVolumes(List volumes, StoragePool destPool) throws ConcurrentOperationException { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - boolean transitResult = false; - long checkPointTaskId = -1; - try { - List volIds = new ArrayList(); - 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> destroyCmds = new ArrayList>(); - List answers = new ArrayList(); - 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(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 cmd : destroyCmds) { - try { - Answer cvAnswer = 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 vm, StoragePool destPool) throws ConcurrentOperationException { - List vols = _volsDao.findUsableVolumesForInstance(vm.getId()); - List volumesNeedToMigrate = new ArrayList(); - - 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); - } - - @Override - public void prepare(VirtualMachineProfile 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 vols = _volsDao.findUsableVolumesForInstance(vm.getId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking if we need to prepare " + vols.size() + " volumes for " + vm); - } - - List recreateVols = new ArrayList(vols.size()); - - for (VolumeVO vol : vols) { - StoragePool assignedPool = null; - if (dest.getStorageForDisks() != null) { - assignedPool = dest.getStorageForDisks().get(vol); - } - if (assignedPool == null && recreate) { - assignedPool = _storagePoolDao.findById(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 volumesToMigrate = new ArrayList(); - 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 = _storagePoolDao.findById(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 = _storagePoolDao.findById(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 = _storagePoolDao.findById(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 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()); - } - } - - @DB - protected VolumeVO switchVolume(VolumeVO existingVolume, VirtualMachineProfile vm) throws StorageUnavailableException { - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - stateTransitTo(existingVolume, Volume.Event.DestroyRequested); - } catch (NoTransitionException e) { - s_logger.debug("Unable to destroy existing volume: " + e.toString()); - } - - Long templateIdToUse = null; - Long volTemplateId = existingVolume.getTemplateId(); - long vmTemplateId = vm.getTemplateId(); - if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId + ", updating templateId in the new Volume"); - } - templateIdToUse = vmTemplateId; - } - VolumeVO newVolume = allocateDuplicateVolume(existingVolume, templateIdToUse); - txn.commit(); - return newVolume; - - } - - public Pair createVolume(VolumeVO toBeCreated, DiskOfferingVO offering, VirtualMachineProfile vm, List 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 = _templateDao.findById(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 = sendToPool(pool, hostIdsToTryFirst, cmd); - if (answer.getResult()) { - CreateAnswer createAnswer = (CreateAnswer) answer; - return new Pair(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; - } @Override public void release(VirtualMachineProfile profile) { // add code here } - public void expungeVolume(VolumeVO vol, boolean force) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expunging " + vol); - } - - //Find out if the volume is present on secondary storage - VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(vol.getId()); - if(volumeHost != null){ - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED){ - HostVO ssHost = _hostDao.findById(volumeHost.getHostId()); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath()); - Answer answer = _agentMgr.sendToSecStorage(ssHost, dtCommand); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " + volumeHost + " due to " + ((answer == null) ? "answer is null" : answer.getDetails())); - return; - } - }else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ - s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); - } - _volumeHostDao.remove(volumeHost.getId()); - _volumeDao.remove(vol.getId()); - return; - } - - String vmName = null; - if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) { - VirtualMachine vm = _vmInstanceDao.findByIdIncludingRemoved(vol.getInstanceId()); - if (vm != null) { - vmName = vm.getInstanceName(); - } - } - - String volumePath = vol.getPath(); - Long poolId = vol.getPoolId(); - if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Marking volume that was never created as destroyed: " + vol); - } - _volsDao.remove(vol.getId()); - return; - } - - StoragePoolVO pool = _storagePoolDao.findById(poolId); - if (pool == null) { - s_logger.debug("Removing volume as storage pool is gone: " + poolId); - _volsDao.remove(vol.getId()); - return; - } - - DestroyCommand cmd = new DestroyCommand(pool, vol, vmName); - boolean removeVolume = false; - try { - Answer answer = sendToPool(pool, cmd); - if (answer != null && answer.getResult()) { - removeVolume = true; - } else { - s_logger.info("Will retry delete of " + vol + " from " + poolId); - } - } catch (StorageUnavailableException e) { - if (force) { - s_logger.info("Storage is unavailable currently, but marking volume id=" + vol.getId() + " as expunged anyway due to force=true"); - removeVolume = true; - } else { - s_logger.info("Storage is unavailable currently. Will retry delete of " + vol + " from " + poolId); - } - } catch (RuntimeException ex) { - if (force) { - s_logger.info("Failed to expunge volume, but marking volume id=" + vol.getId() + " as expunged anyway " + - "due to force=true. Volume failed to expunge due to ", ex); - removeVolume = true; - } else { - throw ex; - } - } finally { - if (removeVolume) { - _volsDao.remove(vol.getId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Volume successfully expunged from " + poolId); - } - } - } - - } - - @Override - @DB - public void cleanupVolumes(long vmId) throws ConcurrentOperationException { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cleaning storage for vm: " + vmId); - } - List volumesForVm = _volsDao.findByInstance(vmId); - List toBeExpunged = new ArrayList(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (VolumeVO vol : volumesForVm) { - if (vol.getVolumeType().equals(Type.ROOT)) { - // This check is for VM in Error state (volume is already destroyed) - if (!vol.getState().equals(Volume.State.Destroy)) { - destroyVolume(vol); - } - toBeExpunged.add(vol); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Detaching " + vol); - } - _volsDao.detachVolume(vol.getId()); - } - } - txn.commit(); - - for (VolumeVO expunge : toBeExpunged) { - expungeVolume(expunge, false); - } - } - protected class StorageGarbageCollector implements Runnable { public StorageGarbageCollector() { @@ -3788,124 +2154,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag _hostDao.update(secHost.getId(), secHost); return secHost; } - - @Override - public List searchForVolumes(ListVolumesCmd cmd) { - Account caller = UserContext.current().getCaller(); - List permittedAccounts = new ArrayList(); - - Long id = cmd.getId(); - Long vmInstanceId = cmd.getVirtualMachineId(); - String name = cmd.getVolumeName(); - String keyword = cmd.getKeyword(); - String type = cmd.getType(); - Map tags = cmd.getTags(); - - Long zoneId = cmd.getZoneId(); - Long podId = null; - // Object host = null; TODO - if (_accountMgr.isAdmin(caller.getType())) { - podId = cmd.getPodId(); - // host = cmd.getHostId(); TODO - } - - Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); - Long domainId = domainIdRecursiveListProject.first(); - Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - Filter searchFilter = new Filter(VolumeVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); - - // hack for now, this should be done better but due to needing a join I opted to - // do this quickly and worry about making it pretty later - SearchBuilder sb = _volumeDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE); - sb.and("instanceId", sb.entity().getInstanceId(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); - // Only return volumes that are not destroyed - sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); - - SearchBuilder diskOfferingSearch = _diskOfferingDao.createSearchBuilder(); - diskOfferingSearch.and("systemUse", diskOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.NEQ); - sb.join("diskOfferingSearch", diskOfferingSearch, sb.entity().getDiskOfferingId(), diskOfferingSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); - - // display UserVM volumes only - SearchBuilder vmSearch = _vmInstanceDao.createSearchBuilder(); - vmSearch.and("type", vmSearch.entity().getType(), SearchCriteria.Op.NIN); - vmSearch.or("nulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL); - sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); - - if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); - for (int count=0; count < tags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); - } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); - } - - // now set the SC criteria... - SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - if (keyword != null) { - SearchCriteria ssc = _volumeDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (name != null) { - sc.setParameters("name", "%" + name + "%"); - } - - sc.setJoinParameters("diskOfferingSearch", "systemUse", 1); - - if (tags != null && !tags.isEmpty()) { - int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.toString()); - for (String key : tags.keySet()) { - sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); - sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); - count++; - } - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (type != null) { - sc.setParameters("volumeType", "%" + type + "%"); - } - if (vmInstanceId != null) { - sc.setParameters("instanceId", vmInstanceId); - } - if (zoneId != null) { - sc.setParameters("dataCenterId", zoneId); - } - if (podId != null) { - sc.setParameters("podId", podId); - } - - // Don't return DomR and ConsoleProxy volumes - sc.setJoinParameters("vmSearch", "type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter); - - // Only return volumes that are not destroyed - sc.setParameters("state", Volume.State.Destroy); - - return _volumeDao.search(sc, searchFilter); - } - + @Override public String getSupportedImageFormatForCluster(Long clusterId) { ClusterVO cluster = ApiDBUtils.findClusterById(clusterId); @@ -4019,4 +2268,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return true; } + @Override + public StoragePool getStoragePoolById(Long id) { + StoragePool pool = _storagePoolDao.findById(id); + return pool; + } } diff --git a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java index 23f3def0c22..b784c9dfd50 100644 --- a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java +++ b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java @@ -44,10 +44,10 @@ import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.template.TemplateConstants; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.component.ComponentLocator; diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java index 6635b3cf317..9bad050d00f 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java @@ -29,7 +29,7 @@ import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.storage.Storage; +import com.cloud.storage.pool.Storage; public class SecondaryStorageListener implements Listener { private final static Logger s_logger = Logger.getLogger(SecondaryStorageListener.class); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 95eb7f65c5e..4c04a10b34b 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -92,7 +92,6 @@ import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; @@ -100,6 +99,7 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.pool.Storage; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 6e3f9c14116..6b2ac442ef2 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -72,19 +72,11 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Snapshot.Status; -import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; @@ -93,8 +85,15 @@ import com.cloud.storage.dao.SnapshotScheduleDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.Storage.StoragePoolType; import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.storage.snapshot.Snapshot.Status; +import com.cloud.storage.snapshot.Snapshot.Type; import com.cloud.storage.swift.SwiftManager; +import com.cloud.storage.volume.Volume; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -159,7 +158,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject protected DomainDao _domainDao; @Inject - protected StorageManager _storageMgr; + protected StoragePoolManager _storageMgr; @Inject protected AgentManager _agentMgr; @Inject diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index bfc636a3153..1b3ac80b279 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -38,7 +38,6 @@ import com.cloud.async.dao.AsyncJobDao; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; -import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index 5e8e3e0a8ab..ac7fd1d9b27 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -48,11 +48,11 @@ import com.cloud.async.executor.ExtractJobResultObject; import com.cloud.event.EventVO; import com.cloud.exception.AgentUnavailableException; import com.cloud.host.HostVO; -import com.cloud.storage.Storage; import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; import com.cloud.storage.UploadVO; import com.cloud.storage.dao.UploadDao; +import com.cloud.storage.pool.Storage; import com.cloud.storage.upload.UploadState.UploadEvent; import com.cloud.utils.exception.CloudRuntimeException; diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 7166504020f..b670f2c2046 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -49,7 +49,6 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.resource.ResourceManager; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Status; @@ -61,6 +60,7 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Inject; diff --git a/server/src/com/cloud/storage/volume/VolumeManager.java b/server/src/com/cloud/storage/volume/VolumeManager.java new file mode 100644 index 00000000000..657c491ffee --- /dev/null +++ b/server/src/com/cloud/storage/volume/VolumeManager.java @@ -0,0 +1,132 @@ +package com.cloud.storage.volume; + +import java.util.List; + +import com.cloud.api.commands.ListVolumesCmd; +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.hypervisor.Hypervisor.HypervisorType; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.pool.StoragePool; +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.fsm.NoTransitionException; +import com.cloud.vm.DiskProfile; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +public interface VolumeManager { + /** Returns the absolute path of the specified ISO + * @param templateId - the ID of the template that represents the ISO + * @param datacenterId + * @return absolute ISO path + */ + public Pair getAbsoluteIsoPath(long templateId, long dataCenterId); + + /** + * Moves a volume from its current storage pool to a storage pool with enough capacity in the specified zone, pod, or cluster + * @param volume + * @param destPoolDcId + * @param destPoolPodId + * @param destPoolClusterId + * @return VolumeVO + * @throws ConcurrentOperationException + */ + VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException; + + /** + * Create a volume based on the given criteria + * @param volume + * @param vm + * @param template + * @param dc + * @param pod + * @param clusterId + * @param offering + * @param diskOffering + * @param avoids + * @param size + * @param hyperType + * @return volume VO if success, null otherwise + */ + VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, + ServiceOfferingVO offering, DiskOfferingVO diskOffering, List avoids, long size, HypervisorType hyperType); + + /** + * Marks the specified volume as destroyed in the management server database. The expunge thread will delete the volume from its storage pool. + * @param volume + * @return + */ + boolean destroyVolume(VolumeVO volume) throws ConcurrentOperationException; + + /** + * Checks that one of the following is true: + * 1. The volume is not attached to any VM + * 2. The volume is attached to a VM that is running on a host with the KVM hypervisor, and the VM is stopped + * 3. The volume is attached to a VM that is running on a host with the XenServer hypervisor (the VM can be stopped or running) + * @return true if one of the above conditions is true + */ + boolean volumeInactive(VolumeVO volume); + + /** + * Allocates one volume. + * @param + * @param type + * @param offering + * @param name + * @param size + * @param template + * @param vm + * @param account + * @return VolumeVO a persisted volume. + */ + DiskProfile allocateVolume(Long vmId, + Pair rootDiskOffering, + List> dataDiskOfferings, Long templateId, Account owner); + + void cleanupVolumes(long vmId) throws ConcurrentOperationException; + boolean StorageMigration( + VirtualMachineProfile vm, + StoragePool destPool) throws ConcurrentOperationException; + + boolean stateTransitTo(Volume vol, Event event) + throws NoTransitionException; + + VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId); + boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException; + VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format); + + /** + * Checks that the volume is stored on a shared storage pool + * @param volume + * @return true if the volume is on a shared storage pool, false otherwise + */ + boolean volumeOnSharedStoragePool(VolumeVO volume); + + String getVmNameOnVolume(VolumeVO volume); + void expungeVolume(VolumeVO vol, boolean force); + + Volume migrateVolume(Long volumeId, Long storagePoolId) + throws ConcurrentOperationException; + + void prepare(VirtualMachineProfile vm, + DeployDestination dest, boolean recreate) + throws StorageUnavailableException, + InsufficientStorageCapacityException; + + Volume copyVolume(Long volumeId, Long destStoragePoolId); + + List searchForVolumes(ListVolumesCmd cmd); +} diff --git a/server/src/com/cloud/storage/volume/VolumeManagerImpl.java b/server/src/com/cloud/storage/volume/VolumeManagerImpl.java new file mode 100644 index 00000000000..58199d8313e --- /dev/null +++ b/server/src/com/cloud/storage/volume/VolumeManagerImpl.java @@ -0,0 +1,1013 @@ +package com.cloud.storage.volume; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.CreateAnswer; +import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DestroyCommand; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.api.commands.CreateVolumeCmd; +import com.cloud.api.commands.ListVolumesCmd; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.Domain; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientStorageCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.server.ResourceTag.TaggedResourceType; +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.VolumeHostVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.image.ImageManager; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.snapshot.SnapshotManager; +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.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +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.utils.fsm.StateMachine2; +import com.cloud.vm.DiskProfile; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.event.ActionEvent; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.template.TemplateManager; +import com.cloud.template.VirtualMachineTemplate; + +public class VolumeManagerImpl implements VolumeManager, Manager { + private static final Logger s_logger = Logger.getLogger(VolumeManagerImpl.class); + protected int _retry = 2; + private StateMachine2 _volStateMachine; + protected SearchBuilder HostTemplateStatesSearch; + @Inject + protected VolumeDao _volumeDao; + @Inject + protected VMTemplateHostDao _vmTemplateHostDao = null; + @Inject + protected HostDao _hostDao; + @Inject + protected DiskOfferingDao _diskOfferingDao; + @Inject + protected StoragePoolManager _storagePoolMgr; + @Inject + protected SnapshotManager _snapshotMgr; + @Inject + protected ImageManager _imageMgr; + @Inject + protected VolumeHostDao _volHostDao; + @Inject + protected AgentManager _agentMgr; + @Inject + protected VMInstanceDao _vmInstanceDao; + @Inject + protected ResourceTagDao _resourceTagDao; + @Inject + protected TemplateManager _templateMgr; + @Inject + protected VMInstanceDao _vmDao; + + @DB + @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true) + public VolumeVO createVolume(CreateVolumeCmd cmd) { + VolumeVO volume = _volumeDao.findById(cmd.getEntityId()); + boolean created = false; + + try { + if (cmd.getSnapshotId() != null) { + volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId()); + if (volume.getState() == Volume.State.Ready) { + created = true; + } + return volume; + } else { + _volumeDao.update(volume.getId(), volume); + created = true; + } + + return _volumeDao.findById(volume.getId()); + } finally { + if (!created) { + s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + } + } + } + + @Override + @DB + public boolean destroyVolume(VolumeVO volume) throws ConcurrentOperationException { + try { + if (!stateTransitTo(volume, Volume.Event.DestroyRequested)) { + throw new ConcurrentOperationException("Failed to transit to destroyed state"); + } + } catch (NoTransitionException e) { + s_logger.debug("Unable to destoy the volume: " + e.toString()); + return false; + } + + long volumeId = volume.getId(); + + // Delete the recurring snapshot policies for this volume. + _snapshotMgr.deletePoliciesForVolume(volumeId); + + Long instanceId = volume.getInstanceId(); + VMInstanceVO vmInstance = null; + if (instanceId != null) { + vmInstance = _vmInstanceDao.findById(instanceId); + } + + if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { + // Decrement the resource count for volumes belonging user VM's only + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + // Log usage event for volumes belonging user VM's only + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); + _usageEventDao.persist(usageEvent); + } + + try { + if (!stateTransitTo(volume, Volume.Event.OperationSucceeded)) { + throw new ConcurrentOperationException("Failed to transit state"); + + } + } catch (NoTransitionException e) { + s_logger.debug("Unable to change volume state: " + e.toString()); + return false; + } + + return true; + + } + + @Override + public VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId) { + VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize()); + if (templateId != null) { + newVol.setTemplateId(templateId); + } else { + newVol.setTemplateId(oldVol.getTemplateId()); + } + newVol.setDeviceId(oldVol.getDeviceId()); + newVol.setInstanceId(oldVol.getInstanceId()); + newVol.setRecreatable(oldVol.isRecreatable()); + return _volumeDao.persist(newVol); + } + + @Override + @DB + public VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, + List avoids, long size, HypervisorType hyperType) { + StoragePoolVO pool = null; + final HashSet avoidPools = new HashSet(avoids); + + try { + stateTransitTo(volume, Volume.Event.CreateRequested); + } catch (NoTransitionException e) { + s_logger.debug("Unable to update volume state: " + e.toString()); + return null; + } + + if (diskOffering != null && diskOffering.isCustomized()) { + diskOffering.setDiskSize(size); + } + DiskProfile dskCh = null; + if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { + dskCh = createDiskCharacteristics(volume, template, dc, offering); + } else { + dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); + } + + dskCh.setHyperType(hyperType); + + VolumeTO created = null; + int retry = _retry; + while (--retry >= 0) { + created = null; + + long podId = pod.getId(); + pod = _podDao.findById(podId); + if (pod == null) { + s_logger.warn("Unable to find pod " + podId + " when create volume " + volume.getName()); + break; + } + + pool = findStoragePool(dskCh, dc, pod, clusterId, vm, avoidPools); + if (pool == null) { + s_logger.warn("Unable to find storage poll when create volume " + volume.getName()); + break; + } + + avoidPools.add(pool); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Trying to create " + volume + " on " + pool); + } + + CreateCommand cmd = null; + VMTemplateStoragePoolVO tmpltStoredOn = null; + + for (int i = 0; i < 2; i++) { + if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { + tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool); + if (tmpltStoredOn == null) { + continue; + } + cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool)); + } else { + if (volume.getVolumeType() == Type.ROOT && 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(dskCh, new StorageFilerTO(pool)); + } + + try { + Answer answer = sendToPool(pool, cmd); + if (answer != null && answer.getResult()) { + created = ((CreateAnswer) answer).getVolume(); + break; + } + + if (tmpltStoredOn != null && answer != null && (answer instanceof CreateAnswer) && ((CreateAnswer) answer).templateReloadRequested()) { + if (!_tmpltMgr.resetTemplateDownloadStateOnPool(tmpltStoredOn.getId())) { + break; // break out of template-redeploy retry loop + } + } else { + break; + } + } catch (StorageUnavailableException e) { + s_logger.debug("Storage unavailable for " + pool.getId()); + break; // break out of template-redeploy retry loop + } + } + + if (created != null) { + break; + } + + s_logger.debug("Retrying the create because it failed on pool " + pool); + } + + if (created == null) { + return null; + } else { + volume.setFolder(pool.getPath()); + volume.setPath(created.getPath()); + volume.setSize(created.getSize()); + volume.setPoolType(pool.getPoolType()); + volume.setPoolId(pool.getId()); + volume.setPodId(pod.getId()); + try { + stateTransitTo(volume, Volume.Event.OperationSucceeded); + } catch (NoTransitionException e) { + s_logger.debug("Unable to update volume state: " + e.toString()); + return null; + } + return volume; + } + } + + @Override + public boolean volumeInactive(VolumeVO volume) { + Long vmId = volume.getInstanceId(); + if (vmId != null) { + UserVm vm = _userVmDao.findById(vmId); + if (vm == null) { + return true; + } + State state = vm.getState(); + if (state.equals(State.Stopped) || state.equals(State.Destroyed)) { + return true; + } + } + return false; + } + + @Override + public String getVmNameOnVolume(VolumeVO volume) { + Long vmId = volume.getInstanceId(); + if (vmId != null) { + VMInstanceVO vm = _vmInstanceDao.findById(vmId); + + if (vm == null) { + return null; + } + return vm.getInstanceName(); + } + return null; + } + + @Override + public boolean volumeOnSharedStoragePool(VolumeVO volume) { + Long poolId = volume.getPoolId(); + if (poolId == null) { + return false; + } else { + StoragePoolVO pool = _storagePoolDao.findById(poolId); + + if (pool == null) { + return false; + } else { + return pool.isShared(); + } + } + } + + public String getRandomVolumeName() { + return UUID.randomUUID().toString(); + } + + @Override + public VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException { + + // Find a destination storage pool with the specified criteria + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); + DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(), + diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null); + dskCh.setHyperType(dataDiskHyperType); + DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId); + HostPodVO destPoolPod = _podDao.findById(destPoolPodId); + StoragePoolVO destPool = findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, new HashSet()); + String secondaryStorageURL = getSecondaryStorageURL(volume.getDataCenterId()); + + if (destPool == null) { + throw new CloudRuntimeException("Failed to find a storage pool with enough capacity to move the volume to."); + } + if (secondaryStorageURL == null) { + throw new CloudRuntimeException("Failed to find secondary storage."); + } + + List vols = new ArrayList(); + vols.add(volume); + migrateVolumes(vols, destPool); + return _volumeDao.findById(volume.getId()); + } + + + public boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException{ + + // 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); + + + // 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); + } + + 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())); + } + + String userSpecifiedName = volumeName; + if (userSpecifiedName == null) { + userSpecifiedName = getRandomVolumeName(); + } + if((!url.toLowerCase().endsWith("vhd"))&&(!url.toLowerCase().endsWith("vhd.zip")) + &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz")) + &&(!url.toLowerCase().endsWith("qcow2"))&&(!url.toLowerCase().endsWith("qcow2.zip")) + &&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz")) + &&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip")) + &&(!url.toLowerCase().endsWith("ova.bz2"))&&(!url.toLowerCase().endsWith("ova.gz")) + &&(!url.toLowerCase().endsWith("img"))&&(!url.toLowerCase().endsWith("raw"))){ + throw new InvalidParameterValueException("Please specify a valid " + format.toLowerCase()); + } + + if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(".vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase().endsWith("vhd.gz") )) + || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz") )) + || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase().endsWith("ova.gz"))) + || (format.equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith(".img") && !url.toLowerCase().endsWith("raw")))) { + throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase()); + } + validateUrl(url); + + return false; + } + + private String validateUrl(String url){ + try { + URI uri = new URI(url); + if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") + && !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) { + throw new IllegalArgumentException("Unsupported scheme for url: " + url); + } + + int port = uri.getPort(); + if (!(port == 80 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + } + String host = uri.getHost(); + try { + InetAddress hostAddr = InetAddress.getByName(host); + if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { + throw new IllegalArgumentException("Illegal host specified in url"); + } + if (hostAddr instanceof Inet6Address) { + throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); + } + } catch (UnknownHostException uhe) { + throw new IllegalArgumentException("Unable to resolve " + host); + } + + return uri.toString(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid URL " + url); + } + + } + + + public VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) { + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + VolumeVO volume = new VolumeVO(volumeName, zoneId, -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())); + long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); + 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); + try { + stateTransitTo(volume, Event.UploadRequested); + } catch (NoTransitionException e) { + s_logger.debug("Can't create persist volume, due to " + e.toString()); + } + 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; + } + + + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") + public boolean deleteVolume(long volumeId) throws ConcurrentOperationException { + Account caller = UserContext.current().getCaller(); + + // Check that the volume ID is valid + VolumeVO volume = _volumeDao.findById(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("Unable to aquire volume with ID: " + volumeId); + } + + if (!_snapshotMgr.canOperateOnVolume(volume)) { + throw new InvalidParameterValueException("There are snapshot creating on it, Unable to delete the volume"); + } + + // permission check + _accountMgr.checkAccess(caller, null, true, volume); + + // Check that the volume is not currently attached to any VM + if (volume.getInstanceId() != null) { + throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM."); + } + + // Check that volume is completely Uploaded + if (volume.getState() == Volume.State.UploadOp){ + VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(volume.getId()); + if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ + throw new InvalidParameterValueException("Please specify a volume that is not uploading"); + } + } + + // Check that the volume is not already destroyed + if (volume.getState() != Volume.State.Destroy) { + if (!destroyVolume(volume)) { + return false; + } + } + + try { + expungeVolume(volume, false); + } catch (Exception e) { + s_logger.warn("Failed to expunge volume:", e); + return false; + } + + return true; + } + + private boolean validateVolumeSizeRange(long size) { + if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { + throw new InvalidParameterValueException("Please specify a size of at least 1 Gb."); + } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) { + throw new InvalidParameterValueException("volume size " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " Gb."); + } + + return true; + } + + @Override + public DiskProfile allocateVolume(Long vmId, + Pair rootDiskOffering, + List> dataDiskOfferings, Long templateId, Account owner) { + VirtualMachineTemplate template = _templateMgr.getTemplate(templateId); + VirtualMachine vm = _vmDao.findById(vmId); + DiskProfile diskProfile = null; + if (template.getFormat() == ImageFormat.ISO) { + diskProfile = allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner); + } else if (template.getFormat() == ImageFormat.BAREMETAL) { + // Do nothing + } else { + diskProfile = allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner); + } + + for (Pair offering : dataDiskOfferings) { + diskProfile = allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner); + } + return diskProfile; + } + + public DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, VirtualMachine vm, Account owner) { + if (size == null) { + size = offering.getDiskSize(); + } else { + size = (size * 1024 * 1024 * 1024); + } + VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), size); + if (vm != null) { + vol.setInstanceId(vm.getId()); + } + + if (type.equals(Type.ROOT)) { + vol.setDeviceId(0l); + } else { + vol.setDeviceId(1l); + } + + vol = _volumeDao.persist(vol); + + // Save usage event and update resource count for user vm volumes + if (vm instanceof UserVm) { + + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size); + _usageEventDao.persist(usageEvent); + + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); + } + return toDiskProfile(vol, offering); + } + + public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOfferingVO offering, VirtualMachineTemplate template, VirtualMachine vm, Account owner) { + assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really...."; + + SearchCriteria sc = HostTemplateStatesSearch.create(); + sc.setParameters("id", template.getId()); + sc.setParameters("state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + sc.setJoinParameters("host", "dcId", vm.getDataCenterIdToDeployIn()); + List tsvs = _vmTemplateSwiftDao.listByTemplateId(template.getId()); + Long size = null; + if (tsvs != null && tsvs.size() > 0) { + size = tsvs.get(0).getSize(); + } + if (size == null) { + List sss = _vmTemplateHostDao.search(sc, null); + if (sss == null || sss.size() == 0) { + throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + vm.getDataCenterIdToDeployIn()); + } + size = sss.get(0).getSize(); + } + + VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), size); + if (vm != null) { + vol.setInstanceId(vm.getId()); + } + vol.setTemplateId(template.getId()); + + if (type.equals(Type.ROOT)) { + vol.setDeviceId(0l); + if (!vm.getType().equals(VirtualMachine.Type.User)) { + vol.setRecreatable(true); + } + } else { + vol.setDeviceId(1l); + } + + vol = _volumeDao.persist(vol); + + // Create event and update resource count for volumes if vm is a user vm + if (vm instanceof UserVm) { + + Long offeringId = null; + + if (offering.getType() == DiskOfferingVO.Type.Disk) { + offeringId = offering.getId(); + } + + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, template.getId(), + vol.getSize()); + _usageEventDao.persist(usageEvent); + + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); + } + return toDiskProfile(vol, offering); + } + + @DB + protected VolumeVO switchVolume(VolumeVO existingVolume, VirtualMachineProfile vm) throws StorageUnavailableException { + Transaction txn = Transaction.currentTxn(); + txn.start(); + try { + stateTransitTo(existingVolume, Volume.Event.DestroyRequested); + } catch (NoTransitionException e) { + s_logger.debug("Unable to destroy existing volume: " + e.toString()); + } + + Long templateIdToUse = null; + Long volTemplateId = existingVolume.getTemplateId(); + long vmTemplateId = vm.getTemplateId(); + if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId + ", updating templateId in the new Volume"); + } + templateIdToUse = vmTemplateId; + } + VolumeVO newVolume = allocateDuplicateVolume(existingVolume, templateIdToUse); + txn.commit(); + return newVolume; + + } + + public void expungeVolume(VolumeVO vol, boolean force) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expunging " + vol); + } + + //Find out if the volume is present on secondary storage + VolumeHostVO volumeHost = _volHostDao.findByVolumeId(vol.getId()); + if(volumeHost != null){ + if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED){ + HostVO ssHost = _hostDao.findById(volumeHost.getHostId()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath()); + Answer answer = _agentMgr.sendToSecStorage(ssHost, dtCommand); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete " + volumeHost + " due to " + ((answer == null) ? "answer is null" : answer.getDetails())); + return; + } + }else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ + s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); + } + _volHostDao.remove(volumeHost.getId()); + _volumeDao.remove(vol.getId()); + return; + } + + String vmName = null; + if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) { + VirtualMachine vm = _vmInstanceDao.findByIdIncludingRemoved(vol.getInstanceId()); + if (vm != null) { + vmName = vm.getInstanceName(); + } + } + + String volumePath = vol.getPath(); + Long poolId = vol.getPoolId(); + if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Marking volume that was never created as destroyed: " + vol); + } + _volumeDao.remove(vol.getId()); + return; + } + + StoragePoolVO pool = (StoragePoolVO)_storagePoolMgr.getStoragePool(poolId); + if (pool == null) { + s_logger.debug("Removing volume as storage pool is gone: " + poolId); + _volumeDao.remove(vol.getId()); + return; + } + + DestroyCommand cmd = new DestroyCommand(pool, vol, vmName); + boolean removeVolume = false; + try { + Answer answer = _storagePoolMgr.sendToPool(pool, cmd); + if (answer != null && answer.getResult()) { + removeVolume = true; + } else { + s_logger.info("Will retry delete of " + vol + " from " + poolId); + } + } catch (StorageUnavailableException e) { + if (force) { + s_logger.info("Storage is unavailable currently, but marking volume id=" + vol.getId() + " as expunged anyway due to force=true"); + removeVolume = true; + } else { + s_logger.info("Storage is unavailable currently. Will retry delete of " + vol + " from " + poolId); + } + } catch (RuntimeException ex) { + if (force) { + s_logger.info("Failed to expunge volume, but marking volume id=" + vol.getId() + " as expunged anyway " + + "due to force=true. Volume failed to expunge due to ", ex); + removeVolume = true; + } else { + throw ex; + } + } finally { + if (removeVolume) { + _volumeDao.remove(vol.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Volume successfully expunged from " + poolId); + } + } + } + + } + + @Override + @DB + public void cleanupVolumes(long vmId) throws ConcurrentOperationException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cleaning storage for vm: " + vmId); + } + List volumesForVm = _volumeDao.findByInstance(vmId); + List toBeExpunged = new ArrayList(); + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (VolumeVO vol : volumesForVm) { + if (vol.getVolumeType().equals(Type.ROOT)) { + // This check is for VM in Error state (volume is already destroyed) + if (!vol.getState().equals(Volume.State.Destroy)) { + destroyVolume(vol); + } + toBeExpunged.add(vol); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Detaching " + vol); + } + _volumeDao.detachVolume(vol.getId()); + } + } + txn.commit(); + + for (VolumeVO expunge : toBeExpunged) { + expungeVolume(expunge, false); + } + } + + @Override + public List searchForVolumes(ListVolumesCmd cmd) { + //TODO: ACL code is removed + //Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Long id = cmd.getId(); + Long vmInstanceId = cmd.getVirtualMachineId(); + String name = cmd.getVolumeName(); + String keyword = cmd.getKeyword(); + String type = cmd.getType(); + Map tags = cmd.getTags(); + + Long zoneId = cmd.getZoneId(); + Long podId = null; + + /* + if (_accountMgr.isAdmin(caller.getType())) { + podId = cmd.getPodId(); + } + */ + + /*Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + */ + Filter searchFilter = new Filter(VolumeVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + + // hack for now, this should be done better but due to needing a join I opted to + // do this quickly and worry about making it pretty later + SearchBuilder sb = _volumeDao.createSearchBuilder(); + // _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE); + sb.and("instanceId", sb.entity().getInstanceId(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); + sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); + // Only return volumes that are not destroyed + sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); + + SearchBuilder diskOfferingSearch = _diskOfferingDao.createSearchBuilder(); + diskOfferingSearch.and("systemUse", diskOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.NEQ); + sb.join("diskOfferingSearch", diskOfferingSearch, sb.entity().getDiskOfferingId(), diskOfferingSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); + + // display UserVM volumes only + SearchBuilder vmSearch = _vmInstanceDao.createSearchBuilder(); + vmSearch.and("type", vmSearch.entity().getType(), SearchCriteria.Op.NIN); + vmSearch.or("nulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL); + sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + + // now set the SC criteria... + SearchCriteria sc = sb.create(); + //_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (keyword != null) { + SearchCriteria ssc = _volumeDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.setParameters("name", "%" + name + "%"); + } + + sc.setJoinParameters("diskOfferingSearch", "systemUse", 1); + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (type != null) { + sc.setParameters("volumeType", "%" + type + "%"); + } + if (vmInstanceId != null) { + sc.setParameters("instanceId", vmInstanceId); + } + if (zoneId != null) { + sc.setParameters("dataCenterId", zoneId); + } + if (podId != null) { + sc.setParameters("podId", podId); + } + + // Don't return DomR and ConsoleProxy volumes + sc.setJoinParameters("vmSearch", "type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter); + + // Only return volumes that are not destroyed + sc.setParameters("state", Volume.State.Destroy); + + return _volumeDao.search(sc, searchFilter); + } + + @Override + public Volume copyVolume(Long volumeId, Long destStoragePoolId) { + // TODO Auto-generated method stub + return null; + } + + + @Override + public boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException { + return _volStateMachine.transitTo(vol, event, null, _volumeDao); + } + + protected DiskProfile createDiskCharacteristics(VolumeVO volume, VMTemplateVO template, DataCenterVO dc, DiskOfferingVO diskOffering) { + if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { + SearchCriteria sc = HostTemplateStatesSearch.create(); + sc.setParameters("id", template.getId()); + sc.setParameters("state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + sc.setJoinParameters("host", "dcId", dc.getId()); + + List sss = _vmTemplateHostDao.search(sc, null); + if (sss.size() == 0) { + throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId()); + } + VMTemplateHostVO ss = sss.get(0); + + return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(), diskOffering.getUseLocalStorage(), + diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null); + } else { + return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(), + diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null); + } + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + HostTemplateStatesSearch = _vmTemplateHostDao.createSearchBuilder(); + HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + + SearchBuilder HostSearch = _hostDao.createSearchBuilder(); + HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + + HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); + HostSearch.done(); + HostTemplateStatesSearch.done(); + return false; + } + + protected void VolumeManagerImple() { + _volStateMachine = Volume.State.getStateMachine(); + } + + @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; + } +} diff --git a/server/src/com/cloud/template/HyervisorTemplateAdapter.java b/server/src/com/cloud/template/HyervisorTemplateAdapter.java index bdb89f65f80..f75e02124fb 100755 --- a/server/src/com/cloud/template/HyervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HyervisorTemplateAdapter.java @@ -41,13 +41,13 @@ import com.cloud.event.UsageEventVO; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.user.Account; import com.cloud.utils.component.Inject; diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 4a379b1e808..9d12a84c920 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -41,13 +41,13 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Grouping; -import com.cloud.storage.GuestOS; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; +import com.cloud.storage.volume.GuestOS; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index ad145a911bf..2e9f7342ff0 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -23,11 +23,11 @@ import com.cloud.exception.InternalErrorException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.pool.StoragePool; /** * TemplateManager manages the templates stored on secondary storage. It is responsible for creating private/public templates. diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 1e87de2fecb..aa8aac31f29 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -58,6 +59,7 @@ import com.cloud.api.commands.RegisterTemplateCmd; import com.cloud.api.commands.UpdateIsoPermissionsCmd; import com.cloud.api.commands.UpdateTemplateOrIsoPermissionsCmd; import com.cloud.api.commands.UpdateTemplatePermissionsCmd; +import com.cloud.api.commands.UploadVolumeCmd; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; import com.cloud.configuration.Config; @@ -67,6 +69,7 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -82,17 +85,12 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; +import com.cloud.org.Grouping; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Type; @@ -117,9 +115,17 @@ import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StoragePoolStatus; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.TemplateType; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.upload.UploadMonitor; +import com.cloud.storage.volume.Volume; +import com.cloud.storage.volume.Volume.Event; import com.cloud.template.TemplateAdapter.TemplateAdapterType; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -131,6 +137,7 @@ import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; +import com.cloud.utils.EnumUtils; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; @@ -144,6 +151,7 @@ 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.UserVmManager; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; @@ -187,7 +195,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe @Inject DomainDao _domainDao; @Inject UploadDao _uploadDao; long _routerTemplateId = -1; - @Inject StorageManager _storageMgr; + @Inject StoragePoolManager _storageMgr; @Inject AsyncJobManager _asyncMgr; @Inject UserVmManager _vmMgr; @Inject UsageEventDao _usageEventDao; @@ -1446,4 +1454,24 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe return true; } + /* + * Upload the volume to secondary storage. + * + */ + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) + public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException{ + Account caller = UserContext.current().getCaller(); + long ownerId = cmd.getEntityOwnerId(); + Long zoneId = cmd.getZoneId(); + String volumeName = cmd.getVolumeName(); + String url = cmd.getUrl(); + String format = cmd.getFormat(); + + _storageMgr.validateVolume(caller, ownerId, zoneId, volumeName, url, format); + VolumeVO volume = _storageMgr.persistVolume(caller, ownerId, zoneId, volumeName, url, cmd.getFormat()); + _downloadMonitor.downloadVolumeToStorage(volume, zoneId, url, cmd.getChecksum(), ImageFormat.valueOf(format.toUpperCase())); + return volume; + } } diff --git a/server/src/com/cloud/template/TemplateProfile.java b/server/src/com/cloud/template/TemplateProfile.java index b050f40accb..0484e203964 100755 --- a/server/src/com/cloud/template/TemplateProfile.java +++ b/server/src/com/cloud/template/TemplateProfile.java @@ -19,7 +19,7 @@ package com.cloud.template; import java.util.Map; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.ImageFormat; import com.cloud.storage.VMTemplateVO; public class TemplateProfile { diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 38153f30618..965475f0b94 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -98,14 +98,14 @@ import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.server.auth.UserAuthenticator; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.pool.StoragePoolManager; import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.storage.volume.Volume; import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account.State; @@ -184,7 +184,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Inject private UserVmManager _vmMgr; @Inject - private StorageManager _storageMgr; + private StoragePoolManager _storageMgr; @Inject private TemplateManager _tmpltMgr; @Inject diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 6f6a754021c..e0be8868589 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -156,22 +156,12 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.Volume; -import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; @@ -184,7 +174,17 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.pool.Storage; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.StoragePoolStatus; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.pool.Storage.StoragePoolType; +import com.cloud.storage.pool.Storage.TemplateType; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.storage.volume.Volume; +import com.cloud.storage.volume.Volume.Type; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate; @@ -271,7 +271,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Inject protected NetworkManager _networkMgr = null; @Inject - protected StorageManager _storageMgr = null; + protected StoragePoolManager _storageMgr = null; @Inject protected SnapshotManager _snapshotMgr = null; @Inject diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 4f04617baba..18e63fbdb09 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -38,8 +38,8 @@ import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair; diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 64210150aa2..6beaf87a26a 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -117,19 +117,20 @@ import com.cloud.resource.ResourceManager; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.orchestra.StorageOrchestraEngine; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.pool.StoragePoolManager; +import com.cloud.storage.pool.Storage.ImageFormat; +import com.cloud.storage.volume.Volume; +import com.cloud.storage.volume.Volume.Type; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; @@ -166,7 +167,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene String _name; @Inject - protected StorageManager _storageMgr; + protected StoragePoolManager _storageMgr; @Inject protected NetworkManager _networkMgr; @Inject @@ -236,6 +237,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Inject protected ResourceManager _resourceMgr; + + @Inject + protected StorageOrchestraEngine _storageOrchestraEngine; Map> _vmGurus = new HashMap>(); protected StateMachine2 _stateMachine; @@ -301,17 +305,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene s_logger.debug("Allocaing disks for " + vm); } - if (template.getFormat() == ImageFormat.ISO) { - _storageMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner); - } else if (template.getFormat() == ImageFormat.BAREMETAL) { - // Do nothing - } else { - _storageMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner); - } - - for (Pair offering : dataDiskOfferings) { - _storageMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner); - } + _storageOrchestraEngine.allocateVolume(vm.getId(), rootDiskOffering, dataDiskOfferings, template.getId(), Account owner); + txn.commit(); if (s_logger.isDebugEnabled()) { diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTest.java b/server/test/com/cloud/snapshot/SnapshotDaoTest.java index c412f49b3d4..d7c9ac0c542 100644 --- a/server/test/com/cloud/snapshot/SnapshotDaoTest.java +++ b/server/test/com/cloud/snapshot/SnapshotDaoTest.java @@ -18,9 +18,9 @@ package com.cloud.snapshot; import java.util.List; -import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDaoImpl; +import com.cloud.storage.snapshot.Snapshot; import com.cloud.utils.component.ComponentLocator; import junit.framework.Assert; diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java b/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java index ed766f557f6..6a0305c1ef3 100644 --- a/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java +++ b/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java @@ -18,7 +18,7 @@ package com.cloud.storage.dao; import junit.framework.TestCase; -import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.pool.StoragePoolStatus; import com.cloud.utils.component.ComponentLocator; public class StoragePoolDaoTest extends TestCase { diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java index e890262a769..ec442fa5264 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -59,8 +59,8 @@ import com.cloud.network.Network; import com.cloud.offering.ServiceOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.Criteria; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; +import com.cloud.storage.pool.StoragePool; +import com.cloud.storage.volume.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 6723198b81a..462397e43f2 100755 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -41,8 +41,8 @@ import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.pool.StoragePool; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair;