shwstppr commented on code in PR #7889:
URL: https://github.com/apache/cloudstack/pull/7889#discussion_r1372986600


##########
server/src/main/java/com/cloud/api/ApiDBUtils.java:
##########
@@ -1278,7 +1278,8 @@ public static HypervisorType 
getHypervisorTypeFromFormat(long dcId, ImageFormat
                 if(pool.getPoolType() == StoragePoolType.RBD ||
                     pool.getPoolType() == StoragePoolType.PowerFlex ||
                     pool.getPoolType() == StoragePoolType.CLVM ||
-                    pool.getPoolType() == StoragePoolType.Linstor) {
+                    pool.getPoolType() == StoragePoolType.Linstor ||
+                    pool.getPoolType() == StoragePoolType.FiberChannel) {

Review Comment:
   Can be,
   ```
   if(List.of(StoragePoolType.RBD, StoragePoolType.PowerFlex, 
StoragePoolType.CLVM,
                           StoragePoolType.Linstor, 
StoragePoolType.FiberChannel).contains(pool.getPoolType())) {
   ```



##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -1238,7 +1238,8 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws 
ResourceAllocationExcep
             if (storagePoolId != null) {
                 StoragePoolVO storagePoolVO = 
_storagePoolDao.findById(storagePoolId);
 
-                if (storagePoolVO.isManaged() && 
!storagePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex)) {
+                if (storagePoolVO.isManaged() && 
!(storagePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex) ||

Review Comment:
   ```suggestion
                   if (storagePoolVO.isManaged() && 
!List.of(Storage.StoragePoolType.PowerFlex, 
                           
Storage.StoragePoolType.FiberChannel).contains(storagePoolVO.getPoolType())) {
   ```



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -512,20 +515,30 @@ else if (volumePath == null) {
         }
     }
 
+    private void 
handleVolumeMigrationFromManagedStorageToManagedStorage(VolumeInfo 
srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                
AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (!HypervisorType.KVM.equals(srcVolumeInfo.getHypervisorType())) {
+            String errMsg = "Currently migrating volumes between managed 
storage providers is only supported on KVM hypervisor";

Review Comment:
   ```suggestion
               String errMsg = String.format("Currently migrating volumes 
between managed storage providers is not supported on %s hypervisor", 
srcVolumeInfo.getHypervisorType().toString());
   ```



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -826,24 +840,73 @@ private void handleFailedVolumeMigration(VolumeInfo 
srcVolumeInfo, VolumeInfo de
         _volumeDao.update(srcVolumeInfo.getId(), volumeVO);
     }
 
-    private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, 
VolumeInfo destVolumeInfo) {
+    private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, 
VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) 
{
         VirtualMachine vm = srcVolumeInfo.getAttachedVM();
 
-        if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
-            throw new CloudRuntimeException("Currently, if a volume to migrate 
from non-managed storage to managed storage on KVM is attached to " +
-                    "a VM, the VM must be in the Stopped state.");
-        }
+        checkAvailableForMigration(vm);
 
-        
destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(),
 destVolumeInfo, null);
+        String errMsg = null;
+        try {
+            
destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(),
 destVolumeInfo, null);
+            VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            updatePathFromScsiName(volumeVO);
+            destVolumeInfo = 
_volumeDataFactory.getVolume(destVolumeInfo.getId(), 
destVolumeInfo.getDataStore());
+            HostVO hostVO = 
getHostOnWhichToExecuteMigrationCommand(srcVolumeInfo, destVolumeInfo);
 
-        VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            // migrate the volume via the hypervisor
+            String path = migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, 
hostVO, "Unable to migrate the volume from non-managed storage to managed 
storage");
 
-        volumeVO.setPath(volumeVO.get_iScsiName());
+            updateVolumePath(destVolumeInfo.getId(), path);
+            volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            // only set this if it was not set.  default to QCOW2 for KVM
+            if (volumeVO.getFormat() == null) {
+                volumeVO.setFormat(ImageFormat.QCOW2);
+                _volumeDao.update(volumeVO.getId(), volumeVO);
+            }
+        } catch (Exception ex) {
+            errMsg = "Primary storage migration failued due to an unexpected 
error: " +
+                    ex.getMessage();
+            if (ex instanceof CloudRuntimeException) {
+                throw ex;
+            } else {
+                throw new CloudRuntimeException(errMsg, ex);
+            }
+        } finally {
+            CopyCmdAnswer copyCmdAnswer;
+            if (errMsg != null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+            else {
+                destVolumeInfo = 
_volumeDataFactory.getVolume(destVolumeInfo.getId(), 
destVolumeInfo.getDataStore());
+                DataTO dataTO = destVolumeInfo.getTO();
+                copyCmdAnswer = new CopyCmdAnswer(dataTO);
+            }
 
-        _volumeDao.update(volumeVO.getId(), volumeVO);
+            CopyCommandResult result = new CopyCommandResult(null, 
copyCmdAnswer);
+            result.setResult(errMsg);
+            callback.complete(result);
+        }
+    }
 
-        destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), 
destVolumeInfo.getDataStore());
+    private void checkAvailableForMigration(VirtualMachine vm) {

Review Comment:
   Similar code exists at line 541, should this method be used there?



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -294,7 +294,8 @@ public Answer copyTemplateToPrimaryStorage(final 
CopyCommand cmd) {
                 newTemplate.setSize(primaryVol.getSize());
                 if (primaryPool.getType() == StoragePoolType.RBD ||
                     primaryPool.getType() == StoragePoolType.PowerFlex ||
-                    primaryPool.getType() == StoragePoolType.Linstor) {
+                    primaryPool.getType() == StoragePoolType.Linstor ||
+                    primaryPool.getType() == StoragePoolType.FiberChannel) {

Review Comment:
   Can be checked using List



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java:
##########
@@ -466,13 +466,17 @@ protected Answer migrateVolumeToPool(DataObject srcData, 
DataObject destData) {
             s_logger.error(errMsg);
             answer = new Answer(command, false, errMsg);
         } else {
+            s_logger.info("Sending MIGRATE_COPY request to node " + ep);

Review Comment:
   Do we need all logs here with INFO level, they seem like they should be 
TRACE or DEBUG



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -826,24 +840,73 @@ private void handleFailedVolumeMigration(VolumeInfo 
srcVolumeInfo, VolumeInfo de
         _volumeDao.update(srcVolumeInfo.getId(), volumeVO);
     }
 
-    private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, 
VolumeInfo destVolumeInfo) {
+    private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, 
VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) 
{
         VirtualMachine vm = srcVolumeInfo.getAttachedVM();
 
-        if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
-            throw new CloudRuntimeException("Currently, if a volume to migrate 
from non-managed storage to managed storage on KVM is attached to " +
-                    "a VM, the VM must be in the Stopped state.");
-        }
+        checkAvailableForMigration(vm);
 
-        
destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(),
 destVolumeInfo, null);
+        String errMsg = null;
+        try {
+            
destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(),
 destVolumeInfo, null);
+            VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            updatePathFromScsiName(volumeVO);
+            destVolumeInfo = 
_volumeDataFactory.getVolume(destVolumeInfo.getId(), 
destVolumeInfo.getDataStore());
+            HostVO hostVO = 
getHostOnWhichToExecuteMigrationCommand(srcVolumeInfo, destVolumeInfo);
 
-        VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            // migrate the volume via the hypervisor
+            String path = migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, 
hostVO, "Unable to migrate the volume from non-managed storage to managed 
storage");
 
-        volumeVO.setPath(volumeVO.get_iScsiName());
+            updateVolumePath(destVolumeInfo.getId(), path);
+            volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+            // only set this if it was not set.  default to QCOW2 for KVM
+            if (volumeVO.getFormat() == null) {
+                volumeVO.setFormat(ImageFormat.QCOW2);
+                _volumeDao.update(volumeVO.getId(), volumeVO);
+            }
+        } catch (Exception ex) {
+            errMsg = "Primary storage migration failued due to an unexpected 
error: " +

Review Comment:
   ```suggestion
               errMsg = "Primary storage migration failed due to an unexpected 
error: " +
   ```



##########
server/src/main/java/com/cloud/server/StatsCollector.java:
##########
@@ -1620,7 +1620,11 @@ protected void runInContext() {
                 for (StoragePoolVO pool : pools) {
                     List<VolumeVO> volumes = 
_volsDao.findByPoolId(pool.getId(), null);
                     for (VolumeVO volume : volumes) {
-                        if (volume.getFormat() != ImageFormat.QCOW2 && 
volume.getFormat() != ImageFormat.VHD && volume.getFormat() != ImageFormat.OVA 
&& (volume.getFormat() != ImageFormat.RAW || pool.getPoolType() != 
Storage.StoragePoolType.PowerFlex)) {
+                       if (volume.getFormat() != ImageFormat.QCOW2 &&
+                            volume.getFormat() != ImageFormat.VHD &&
+                            volume.getFormat() != ImageFormat.OVA &&
+                            pool.getPoolType() != 
Storage.StoragePoolType.PowerFlex &&
+                            pool.getPoolType() != 
Storage.StoragePoolType.FiberChannel) {

Review Comment:
   Can be simplified,
   ```
   if (!List.of(ImageFormat.QCOW2, ImageFormat.VHD, 
ImageFormat.OVA).contains(volume.getFormat()) &&
                               !List.of(Storage.StoragePoolType.PowerFlex, 
Storage.StoragePoolType.FiberChannel).contains(pool.getPoolType())) {
   ```



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -400,15 +403,15 @@ private void handleCopyAsyncForVolumes(VolumeInfo 
srcVolumeInfo, VolumeInfo dest
                 } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
                     
handleVolumeMigrationFromManagedStorageToNonManagedStorage(srcVolumeInfo, 
destVolumeInfo, callback);
                 } else {
-                    String errMsg = "The source volume to migrate and the 
destination volume are both on managed storage. " +
-                            "Migration in this case is not yet supported.";
-
-                    handleError(errMsg, callback);
+                    
handleVolumeMigrationFromManagedStorageToManagedStorage(srcVolumeInfo, 
destVolumeInfo, callback);
                 }
             } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
-                String errMsg = "The 'StorageSystemDataMotionStrategy' does 
not support this migration use case.";
-
-                handleError(errMsg, callback);
+                if 
(!HypervisorType.KVM.equals(srcVolumeInfo.getHypervisorType())) {
+                    String errMsg = "Currently migrating volumes between 
managed storage providers is only supported on KVM hypervisor";

Review Comment:
   ```suggestion
                       String errMsg = String.format("Currently migrating 
volumes between managed storage providers is not supported on %s hypervisor", 
srcVolumeInfo.getHypervisorType().toString());
   ```



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -512,20 +515,30 @@ else if (volumePath == null) {
         }
     }
 
+    private void 
handleVolumeMigrationFromManagedStorageToManagedStorage(VolumeInfo 
srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                
AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (!HypervisorType.KVM.equals(srcVolumeInfo.getHypervisorType())) {
+            String errMsg = "Currently migrating volumes between managed 
storage providers is only supported on KVM hypervisor";
+            handleError(errMsg, callback);
+        } else {
+            handleVolumeMigrationForKVM(srcVolumeInfo, destVolumeInfo, 
callback);
+        }
+    }
+
     private void 
handleVolumeMigrationFromManagedStorageToNonManagedStorage(VolumeInfo 
srcVolumeInfo, VolumeInfo destVolumeInfo,
                                                                             
AsyncCompletionCallback<CopyCommandResult> callback) {
         String errMsg = null;
 
         try {
-            if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
+            if (!HypervisorType.KVM.equals(srcVolumeInfo.getHypervisorType())) 
{
                 throw new CloudRuntimeException("Currently, only the KVM 
hypervisor type is supported for the migration of a volume " +
                         "from managed storage to non-managed storage.");
             }
 
             HypervisorType hypervisorType = HypervisorType.KVM;
             VirtualMachine vm = srcVolumeInfo.getAttachedVM();
 
-            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
+            if (vm != null && (vm.getState() != VirtualMachine.State.Stopped 
&& vm.getState() != VirtualMachine.State.Migrating)) {

Review Comment:
   Do we need this check? Shouldn't this be blocked at higher level itself?



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -579,9 +592,10 @@ private void 
handleVolumeMigrationFromManagedStorageToNonManagedStorage(VolumeIn
 
     private void verifyFormatWithPoolType(ImageFormat imageFormat, 
StoragePoolType poolType) {
         if (imageFormat != ImageFormat.VHD && imageFormat != ImageFormat.OVA 
&& imageFormat != ImageFormat.QCOW2 &&
-                !(imageFormat == ImageFormat.RAW && StoragePoolType.PowerFlex 
== poolType)) {
+                !(imageFormat == ImageFormat.RAW && (StoragePoolType.PowerFlex 
== poolType ||
+                StoragePoolType.FiberChannel == poolType))) {
             throw new CloudRuntimeException("Only the following image types 
are currently supported: " +
-                    ImageFormat.VHD.toString() + ", " + 
ImageFormat.OVA.toString() + ", " + ImageFormat.QCOW2.toString() + ", and " + 
ImageFormat.RAW.toString() + "(for PowerFlex)");
+                    ImageFormat.VHD.toString() + ", " + 
ImageFormat.OVA.toString() + ", " + ImageFormat.QCOW2.toString() + ", and " + 
ImageFormat.RAW.toString() + "(for PowerFlex and FiberChannel)");

Review Comment:
   Can be formatted with String.format



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -1701,13 +1797,32 @@ private void createVolumeFromSnapshot(SnapshotInfo 
snapshotInfo) {
      * invocation of createVolumeFromSnapshot(SnapshotInfo).
      */
     private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
-        SnapshotDetailsVO snapshotDetails = 
handleSnapshotDetails(snapshotInfo.getId(), "delete");
+        VolumeVO volumeVO = null;
+        // cleanup any temporary volume previously created for copy from a 
snapshot
+        if 
("true".equalsIgnoreCase(snapshotInfo.getDataStore().getDriver().getCapabilities().get("CAN_CREATE_TEMP_VOLUME_FROM_SNAPSHOT")))
 {
+            SnapshotDetailsVO tempUuid = null;
+            tempUuid = _snapshotDetailsDao.findDetail(snapshotInfo.getId(), 
"TemporaryVolumeCopyUUID");
+            if (tempUuid == null || tempUuid.getValue() == null) {
+                return;
+            }
 
-        try {
-            
snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(),
 snapshotInfo, null);
+            volumeVO = _volumeDao.findByUuid(tempUuid.getValue());
+            if (volumeVO != null) {
+                _volumeDao.remove(volumeVO.getId());
+            }
+            _snapshotDetailsDao.remove(tempUuid.getId());
+            _snapshotDetailsDao.removeDetail(snapshotInfo.getId(), 
"TemporaryVolumeCopyUUID");
         }
-        finally {
-            _snapshotDetailsDao.remove(snapshotDetails.getId());
+        // fallback to original behavior of sending magic command to a create 
function to delete :)

Review Comment:
   Same as above, return can be added instead of else for simpler read



##########
api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java:
##########
@@ -61,6 +63,20 @@ public class UpdateStoragePoolCmd extends BaseCmd {
             " enable it back.")
     private Boolean enabled;
 
+    @Parameter(name = ApiConstants.DETAILS,
+                            type = CommandType.MAP,

Review Comment:
   minor - indentation seems a bit off



##########
engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java:
##########
@@ -1685,13 +1777,17 @@ private CopyCmdAnswer copyImageToVolume(DataObject 
srcDataObject, VolumeInfo des
      * resign the SR and the VDI that should be inside of the snapshot before 
copying the VHD file to secondary storage.
      */
     private void createVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
-        SnapshotDetailsVO snapshotDetails = 
handleSnapshotDetails(snapshotInfo.getId(), "create");
-
-        try {
-            
snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(),
 snapshotInfo, null);
-        }
-        finally {
-            _snapshotDetailsDao.remove(snapshotDetails.getId());
+        if 
("true".equalsIgnoreCase(snapshotInfo.getDataStore().getDriver().getCapabilities().get("CAN_CREATE_TEMP_VOLUME_FROM_SNAPSHOT")))
 {
+            prepTempVolumeForCopyFromSnapshot(snapshotInfo);
+        // fallback to original behavior of sending magic ddata to the create 
function

Review Comment:
   can add return here without adding else statement



##########
plugins/acl/project-role-based/src/main/java/org/apache/cloudstack/acl/ProjectRoleBasedApiAccessChecker.java:
##########
@@ -119,7 +119,7 @@ public boolean checkAccess(User user, String 
apiCommandName) throws PermissionDe
 
         Account userAccount = accountService.getAccount(user.getAccountId());
         if (accountService.isRootAdmin(userAccount.getId()) || 
accountService.isDomainAdmin(userAccount.getAccountId())) {
-            LOGGER.info(String.format("Account [%s] is Root Admin or Domain 
Admin, all APIs are allowed.", userAccount.getAccountName()));
+            LOGGER.trace(String.format("Account [%s] is Root Admin or Domain 
Admin, all APIs are allowed.", userAccount.getAccountName()));

Review Comment:
   Is this needed?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to