From 2e332a260dcda5517f476ea9e0ef62478031b8df Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 20 Mar 2024 13:45:22 +0100 Subject: [PATCH] Update 8808: part2 for local storage --- .../api/response/VolumeForImportResponse.java | 12 +++++ ...oudStackPrimaryDataStoreLifeCycleImpl.java | 2 +- .../VolumeImportUnmanagedManagerImpl.java | 50 +++++++++++++------ 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java index a3fc944451a3..803f154816a8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java @@ -66,6 +66,10 @@ public class VolumeForImportResponse extends BaseResponse { @Param(description = "name of the primary storage hosting the volume") private String storagePoolName; + @SerializedName(ApiConstants.STORAGE_TYPE) + @Param(description = "type of the primary storage hosting the volume") + private String storagePoolType; + @SerializedName(ApiConstants.DETAILS) @Param(description = "volume details in key/value pairs.") private Map details; @@ -146,6 +150,14 @@ public void setStoragePoolName(String storagePoolName) { this.storagePoolName = storagePoolName; } + public String getStoragePoolType() { + return storagePoolType; + } + + public void setStoragePoolType(String storagePoolType) { + this.storagePoolType = storagePoolType; + } + public Map getDetails() { return details; } diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index bbc61e765224..880213020ee5 100644 --- a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -148,7 +148,7 @@ public DataStore initialize(Map dsInfos) { String uri = String.format("%s://%s%s", scheme, storageHost, hostPath); Object localStorage = dsInfos.get("localStorage"); - if (localStorage != null) { + if (localStorage != null) { hostPath = hostPath.contains("//") ? hostPath.replaceFirst("/", "") : hostPath; hostPath = hostPath.replace("+", " "); } diff --git a/server/src/main/java/org/apache/cloudstack/storage/volume/VolumeImportUnmanagedManagerImpl.java b/server/src/main/java/org/apache/cloudstack/storage/volume/VolumeImportUnmanagedManagerImpl.java index cb45fb863b39..d0e3a550a6a4 100644 --- a/server/src/main/java/org/apache/cloudstack/storage/volume/VolumeImportUnmanagedManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/storage/volume/VolumeImportUnmanagedManagerImpl.java @@ -108,7 +108,9 @@ public class VolumeImportUnmanagedManagerImpl implements VolumeImportUnmanageSer private VMTemplatePoolDao templatePoolDao; private static final String DEFAULT_DISK_OFFERING_NAME = "Default Custom Offering for Volume Import"; - private static final String DEFAULT_DISK_OFFERING_UNIQUE_NAME = "Custom-Offering-Volume-Import"; + private static final String DEFAULT_DISK_OFFERING_UNIQUE_NAME = "Custom-Volume-Import"; + private static final String DEFAULT_DISK_OFFERING_NAME_LOCAL = DEFAULT_DISK_OFFERING_NAME + " - Local Storage"; + private static final String DEFAULT_DISK_OFFERING_UNIQUE_NAME_LOCAL = DEFAULT_DISK_OFFERING_UNIQUE_NAME + "-Local"; private void logFailureAndThrowException(String msg) { logger.error(msg); @@ -180,7 +182,7 @@ public VolumeResponse importVolume(ImportVolumeCmd cmd) { checkResourceLimitForImportVolume(owner, volume); // 6. get disk offering - DiskOfferingVO diskOffering = getOrCreateDiskOffering(owner, cmd.getDiskOfferingId(), pool.getDataCenterId()); + DiskOfferingVO diskOffering = getOrCreateDiskOffering(owner, cmd.getDiskOfferingId(), pool.getDataCenterId(), pool.isLocal()); // 7. create records VolumeVO volumeVO = createRecordsForVolumeImport(volume, diskOffering, owner, pool); @@ -284,6 +286,7 @@ private VolumeForImportResponse createVolumeForImportResponse(VolumeOnStorageTO response.setQemuEncryptFormat(volume.getQemuEncryptFormat()); response.setStoragePoolId(pool.getUuid()); response.setStoragePoolName(pool.getName()); + response.setStoragePoolType(String.valueOf(pool.getPoolType())); response.setDetails(volume.getDetails()); response.setObjectName("volumeforimport"); return response; @@ -297,7 +300,7 @@ private boolean checkIfVolumeForTemplate(StoragePoolVO pool, String volumePath) return templatePoolDao.findByPoolPath(pool.getId(), volumePath) != null; } - private DiskOfferingVO getOrCreateDiskOffering(Account owner, Long diskOfferingId, Long zoneId) { + private DiskOfferingVO getOrCreateDiskOffering(Account owner, Long diskOfferingId, Long zoneId, boolean isLocal) { if (diskOfferingId != null) { // check if disk offering exists and active DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(diskOfferingId); @@ -307,28 +310,43 @@ private DiskOfferingVO getOrCreateDiskOffering(Account owner, Long diskOfferingI if (!DiskOffering.State.Active.equals(diskOfferingVO.getState())) { logFailureAndThrowException(String.format("Disk offering with ID %s is not active", diskOfferingId)); } + if (diskOfferingVO.isUseLocalStorage() != isLocal) { + logFailureAndThrowException(String.format("Disk offering with ID %s should use %s storage", diskOfferingId, isLocal ? "local": "shared")); + } // check if disk offering is accessible by the account/owner try { configMgr.checkDiskOfferingAccess(owner, diskOfferingVO, dcDao.findById(zoneId)); return diskOfferingVO; - } catch (PermissionDeniedException ignored) { - logFailureAndThrowException(String.format("Disk offering with ID %s is not accessible by account %s", diskOfferingId, owner.getAccountName())); + } catch (PermissionDeniedException ex) { + logFailureAndThrowException(String.format("Disk offering with ID %s is not accessible by owner %s", diskOfferingId, owner)); } } - return getOrCreateDefaultDiskOfferingIdForVolumeImport(); + return getOrCreateDefaultDiskOfferingIdForVolumeImport(isLocal); } - - private DiskOfferingVO getOrCreateDefaultDiskOfferingIdForVolumeImport() { - DiskOfferingVO diskOffering = diskOfferingDao.findByUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME); - if (diskOffering != null) { - return diskOffering; + private DiskOfferingVO getOrCreateDefaultDiskOfferingIdForVolumeImport(boolean isLocalStorage) { + if (isLocalStorage) { + DiskOfferingVO diskOffering = diskOfferingDao.findByUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME_LOCAL); + if (diskOffering != null) { + return diskOffering; + } + DiskOfferingVO newDiskOffering = new DiskOfferingVO(DEFAULT_DISK_OFFERING_NAME_LOCAL, DEFAULT_DISK_OFFERING_NAME_LOCAL, + Storage.ProvisioningType.THIN, 0, null, true, null, null, null); + newDiskOffering.setUseLocalStorage(true); + newDiskOffering.setUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME_LOCAL); + newDiskOffering = diskOfferingDao.persistDefaultDiskOffering(newDiskOffering); + return newDiskOffering; + } else { + DiskOfferingVO diskOffering = diskOfferingDao.findByUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME); + if (diskOffering != null) { + return diskOffering; + } + DiskOfferingVO newDiskOffering = new DiskOfferingVO(DEFAULT_DISK_OFFERING_NAME, DEFAULT_DISK_OFFERING_NAME, + Storage.ProvisioningType.THIN, 0, null, true, null, null, null); + newDiskOffering.setUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME); + newDiskOffering = diskOfferingDao.persistDefaultDiskOffering(newDiskOffering); + return newDiskOffering; } - DiskOfferingVO newDiskOffering = new DiskOfferingVO(DEFAULT_DISK_OFFERING_NAME, DEFAULT_DISK_OFFERING_NAME, - Storage.ProvisioningType.THIN, 0, null, true, null, null, null); - newDiskOffering.setUniqueName(DEFAULT_DISK_OFFERING_UNIQUE_NAME); - newDiskOffering = diskOfferingDao.persistDefaultDiskOffering(newDiskOffering); - return newDiskOffering; } private VolumeVO createRecordsForVolumeImport(VolumeOnStorageTO volume, DiskOfferingVO diskOffering,