GutoVeronezi commented on a change in pull request #5030:
URL: https://github.com/apache/cloudstack/pull/5030#discussion_r637957284



##########
File path: server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
##########
@@ -6365,24 +6329,75 @@ public VirtualMachine 
migrateVirtualMachineWithVolume(Long vmId, Host destinatio
                 }
             }
         }
+        return volToPoolObjectMap;
+    }
 
-        // Check if all the volumes are in the correct state.
-        for (VolumeVO volume : vmVolumes) {
-            if (volume.getState() != Volume.State.Ready) {
-                throw new CloudRuntimeException("Volume " + volume + " of the 
VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = 
"migrating VM", async = true)
+    public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host 
destinationHost, Map<String, String> volumeToPool) throws 
ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, 
VirtualMachineMigrationException {
+        // Access check - only root administrator can migrate VM.
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied 
to migrate the VM");
             }
+            throw new PermissionDeniedException("No permission to migrate VM, 
Only Root Admin can migrate a VM!");
         }
 
-        // Check max guest vm limit for the destinationHost.
-        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
-        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
-            throw new VirtualMachineMigrationException("Host name: " + 
destinationHost.getName() + ", hostId: " + destinationHost.getId()
-            + " already has max running vms (count includes system VMs). 
Cannot" + " migrate to this host");
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by 
ID " + vmId);
         }
 
-        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+        // OfflineVmwareMigration: this would be it ;) if multiple paths 
exist: unify
+        if (vm.getState() != State.Running) {
+            // OfflineVmwareMigration: and not vmware
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " 
+ vm);
+            }
+            CloudRuntimeException ex = new 
CloudRuntimeException(String.format("Unable to migrate the VM %s (ID: %s) as it 
is not in Running state", vm.getInstanceName(), vm.getUuid()));
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), 
GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU 
enabled VM is not supported");
+        }
+
+        // OfflineVmwareMigration: this condition is to complicated. (already 
a method somewhere)
+        if (!Arrays.asList(new HypervisorType[]{
+                HypervisorType.XenServer,
+                HypervisorType.VMware,
+                HypervisorType.KVM,
+                HypervisorType.Simulator}).contains(vm.getHypervisorType())) {
+            throw new 
InvalidParameterValueException(String.format("Unsupported hypervisor: %s for VM 
migration, we support XenServer/VMware/KVM only", vm.getHypervisorType()));
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {

Review comment:
       We could assign the result of the method to a var and use 
`CollectionUtils` to validate it.

##########
File path: server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
##########
@@ -6365,24 +6329,75 @@ public VirtualMachine 
migrateVirtualMachineWithVolume(Long vmId, Host destinatio
                 }
             }
         }
+        return volToPoolObjectMap;
+    }
 
-        // Check if all the volumes are in the correct state.
-        for (VolumeVO volume : vmVolumes) {
-            if (volume.getState() != Volume.State.Ready) {
-                throw new CloudRuntimeException("Volume " + volume + " of the 
VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = 
"migrating VM", async = true)
+    public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host 
destinationHost, Map<String, String> volumeToPool) throws 
ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, 
VirtualMachineMigrationException {
+        // Access check - only root administrator can migrate VM.
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied 
to migrate the VM");
             }
+            throw new PermissionDeniedException("No permission to migrate VM, 
Only Root Admin can migrate a VM!");
         }
 
-        // Check max guest vm limit for the destinationHost.
-        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
-        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
-            throw new VirtualMachineMigrationException("Host name: " + 
destinationHost.getName() + ", hostId: " + destinationHost.getId()
-            + " already has max running vms (count includes system VMs). 
Cannot" + " migrate to this host");
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by 
ID " + vmId);
         }
 
-        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+        // OfflineVmwareMigration: this would be it ;) if multiple paths 
exist: unify
+        if (vm.getState() != State.Running) {
+            // OfflineVmwareMigration: and not vmware
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " 
+ vm);
+            }
+            CloudRuntimeException ex = new 
CloudRuntimeException(String.format("Unable to migrate the VM %s (ID: %s) as it 
is not in Running state", vm.getInstanceName(), vm.getUuid()));
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), 
GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU 
enabled VM is not supported");
+        }
+
+        // OfflineVmwareMigration: this condition is to complicated. (already 
a method somewhere)
+        if (!Arrays.asList(new HypervisorType[]{
+                HypervisorType.XenServer,
+                HypervisorType.VMware,
+                HypervisorType.KVM,
+                HypervisorType.Simulator}).contains(vm.getHypervisorType())) {
+            throw new 
InvalidParameterValueException(String.format("Unsupported hypervisor: %s for VM 
migration, we support XenServer/VMware/KVM only", vm.getHypervisorType()));
+        }
+
+        // Check that Vm does not have VM Snapshots

Review comment:
       As the code is clear and we have a explanation on the exception message, 
do still we need this comment?

##########
File path: server/src/main/java/com/cloud/storage/StorageManagerImpl.java
##########
@@ -2393,7 +2393,7 @@ public boolean 
storagePoolHasEnoughSpaceForResize(StoragePool pool, long current
     }
 
     @Override
-    public boolean isStoragePoolComplaintWithStoragePolicy(List<Volume> 
volumes, StoragePool pool) throws StorageUnavailableException {
+    public boolean isStoragePoolCompliantWithStoragePolicy(List<Volume> 
volumes, StoragePool pool) throws StorageUnavailableException {
         if (volumes == null || volumes.isEmpty()) {

Review comment:
       We can use `CollectionUtils` to do the validation.
   
   ```java
   ...
   if (CollectionUtils.isEmpty(volumes)) {
   ...
   ```

##########
File path: server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
##########
@@ -6365,24 +6329,75 @@ public VirtualMachine 
migrateVirtualMachineWithVolume(Long vmId, Host destinatio
                 }
             }
         }
+        return volToPoolObjectMap;
+    }
 
-        // Check if all the volumes are in the correct state.
-        for (VolumeVO volume : vmVolumes) {
-            if (volume.getState() != Volume.State.Ready) {
-                throw new CloudRuntimeException("Volume " + volume + " of the 
VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = 
"migrating VM", async = true)
+    public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host 
destinationHost, Map<String, String> volumeToPool) throws 
ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, 
VirtualMachineMigrationException {
+        // Access check - only root administrator can migrate VM.
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied 
to migrate the VM");
             }
+            throw new PermissionDeniedException("No permission to migrate VM, 
Only Root Admin can migrate a VM!");
         }
 
-        // Check max guest vm limit for the destinationHost.
-        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
-        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
-            throw new VirtualMachineMigrationException("Host name: " + 
destinationHost.getName() + ", hostId: " + destinationHost.getId()
-            + " already has max running vms (count includes system VMs). 
Cannot" + " migrate to this host");
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by 
ID " + vmId);
         }
 
-        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+        // OfflineVmwareMigration: this would be it ;) if multiple paths 
exist: unify
+        if (vm.getState() != State.Running) {
+            // OfflineVmwareMigration: and not vmware
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " 
+ vm);
+            }
+            CloudRuntimeException ex = new 
CloudRuntimeException(String.format("Unable to migrate the VM %s (ID: %s) as it 
is not in Running state", vm.getInstanceName(), vm.getUuid()));
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), 
GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU 
enabled VM is not supported");
+        }
+
+        // OfflineVmwareMigration: this condition is to complicated. (already 
a method somewhere)
+        if (!Arrays.asList(new HypervisorType[]{
+                HypervisorType.XenServer,
+                HypervisorType.VMware,
+                HypervisorType.KVM,
+                HypervisorType.Simulator}).contains(vm.getHypervisorType())) {

Review comment:
       This array will be created every time that this method is called, so we 
could extract this creation to a constant and use it here.

##########
File path: server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
##########
@@ -6299,38 +6261,40 @@ public VirtualMachine 
migrateVirtualMachineWithVolume(Long vmId, Host destinatio
             }
         }
 
-        if 
(!Boolean.TRUE.equals(_hypervisorCapabilitiesDao.isStorageMotionSupported(srcHost.getHypervisorType(),
 srcHostVersion))) {
-            throw new CloudRuntimeException("Migration with storage isn't 
supported for source host ID: " + srcHost.getUuid() + " on hypervisor " + 
srcHost.getHypervisorType() + " of version " + srcHost.getHypervisorVersion());
+        if 
(!_hypervisorCapabilitiesDao.isStorageMotionSupported(srcHost.getHypervisorType(),
 srcHostVersion)) {
+            throw new CloudRuntimeException(String.format("Migration with 
storage isn't supported for source host %s (ID: %s) on hypervisor %s with 
version %s", srcHost.getName(), srcHost.getUuid(), srcHost.getHypervisorType(), 
srcHost.getHypervisorVersion()));
         }
 
         if (srcHostVersion == null || !srcHostVersion.equals(destHostVersion)) 
{
-            if 
(!Boolean.TRUE.equals(_hypervisorCapabilitiesDao.isStorageMotionSupported(destinationHost.getHypervisorType(),
 destHostVersion))) {
-                throw new CloudRuntimeException("Migration with storage isn't 
supported for target host ID: " + srcHost.getUuid() + " on hypervisor " + 
srcHost.getHypervisorType() + " of version " + srcHost.getHypervisorVersion());
+            if 
(!_hypervisorCapabilitiesDao.isStorageMotionSupported(destinationHost.getHypervisorType(),
 destHostVersion)) {
+                throw new CloudRuntimeException(String.format("Migration with 
storage isn't supported for target host %s (ID: %s) on hypervisor %s with 
version %s", destinationHost.getName(), destinationHost.getUuid(), 
destinationHost.getHypervisorType(), destinationHost.getHypervisorVersion()));
             }
         }
 
         // Check if destination host is up.
         if (destinationHost.getState() != com.cloud.host.Status.Up || 
destinationHost.getResourceState() != ResourceState.Enabled) {
-            throw new CloudRuntimeException("Cannot migrate VM, destination 
host is not in correct state, has " + "status: " + destinationHost.getState() + 
", state: "
-                    + destinationHost.getResourceState());
+            throw new CloudRuntimeException(String.format("Cannot migrate VM, 
destination host %s (ID: %s) is not in correct state, has status: %s, state: 
%s",
+                    destinationHost.getName(), destinationHost.getUuid(), 
destinationHost.getState(), destinationHost.getResourceState()));
         }
 
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("VM with VM Snapshots 
cannot be migrated with storage, please remove all VM snapshots");
+        // Check max guest vm limit for the destinationHost.
+        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHost)) {
+            throw new VirtualMachineMigrationException(String.format("Cannot 
migrate VM as destination host %s (ID: %s) already has max running vms (count 
includes system VMs)",
+                    destinationHost.getName(), destinationHost.getUuid()));
         }
 
-        List<VolumeVO> vmVolumes = 
_volsDao.findUsableVolumesForInstance(vm.getId());
+        return new Pair<>(srcHost, destinationHost);
+    }
+
+    private Map<Long, Long> 
getVolumePoolMappingForMigrateVmWithStorage(VMInstanceVO vm, Map<String, 
String> volumeToPool) {
         Map<Long, Long> volToPoolObjectMap = new HashMap<Long, Long>();
-        if (!isVMUsingLocalStorage(vm) && MapUtils.isEmpty(volumeToPool)
-            && (destinationHost.getClusterId().equals(srcHost.getClusterId()) 
|| isVmVolumesOnZoneWideStore(vm))){
-            // If volumes do not have to be migrated
-            // call migrateVirtualMachine for non-user VMs else throw exception
-            if (!VirtualMachine.Type.User.equals(vm.getType())) {
-                return migrateVirtualMachine(vmId, destinationHost);
+
+        List<VolumeVO> vmVolumes = 
_volsDao.findUsableVolumesForInstance(vm.getId());
+        // Check if all the volumes are in the correct state.
+        for (VolumeVO volume : vmVolumes) {
+            if (volume.getState() != Volume.State.Ready) {
+                throw new CloudRuntimeException("Volume " + volume + " of the 
VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
             }
-            throw new InvalidParameterValueException("Migration of the vm " + 
vm + "from host " + srcHost + " to destination host " + destinationHost
-                    + " doesn't involve migrating the volumes.");
         }

Review comment:
       We could extract this code to a method with a properly name and remove 
the comment. Also, we could add unit tests to the method too.




-- 
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.

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


Reply via email to