Tomas Jelinek has uploaded a new change for review.

Change subject: core: enable migration to a different cluster
......................................................................

core: enable migration to a different cluster

Added a possibility to define the target cluster for the migration.

Change-Id: I9eb4fd7f10d3b0e63455a81f0b5c1389586a43f4
Bug-Url: https://bugzilla.redhat.com/1150191
Signed-off-by: Tomas Jelinek <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVMClusterCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVmClusterValidator.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmToServerCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmToServerParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
M 
frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
M 
frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
12 files changed, 265 insertions(+), 173 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/50/34650/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVMClusterCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVMClusterCommand.java
index 72ee6e1..84e0ed6 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVMClusterCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVMClusterCommand.java
@@ -1,34 +1,24 @@
 package org.ovirt.engine.core.bll;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.commons.lang.ObjectUtils;
 import org.ovirt.engine.core.bll.network.cluster.NetworkHelper;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
-import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
-import org.ovirt.engine.core.bll.validator.VmNicValidator;
 import org.ovirt.engine.core.common.AuditLogType;
-import org.ovirt.engine.core.common.FeatureSupported;
-import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.ChangeVMClusterParameters;
-import org.ovirt.engine.core.common.businessentities.ActionGroup;
-import org.ovirt.engine.core.common.businessentities.ArchitectureType;
-import org.ovirt.engine.core.common.businessentities.VDSGroup;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.network.Network;
 import org.ovirt.engine.core.common.businessentities.network.VmNic;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.common.scheduling.AffinityGroup;
-import org.ovirt.engine.core.compat.Version;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.utils.ObjectIdentityChecker;
 import org.ovirt.engine.core.utils.linq.LinqUtils;
 import org.ovirt.engine.core.utils.linq.Predicate;
 
+import java.util.List;
+
 public class ChangeVMClusterCommand<T extends ChangeVMClusterParameters> 
extends VmCommand<T> {
 
-    private VDSGroup targetCluster;
     private boolean dedicatedHostWasCleared;
 
     public ChangeVMClusterCommand(T params) {
@@ -37,151 +27,23 @@
 
     @Override
     protected boolean canDoAction() {
-        // Set parameters for messaging.
+        if (!canRunActionOnNonManagedVm()) {
+            return false;
+        }
+
+        if (!isInternalExecution() && 
!ObjectIdentityChecker.CanUpdateField(getVm(), "vdsGroupId", 
getVm().getStatus())) {
+            
addCanDoActionMessage(VdcBllMessages.VM_STATUS_NOT_VALID_FOR_UPDATE);
+            return false;
+        }
+
+        ChangeVmClusterValidator validator = new 
ChangeVmClusterValidator(this, getParameters().getClusterId());
+        return validator.validate();
+    }
+
+    @Override
+    protected void setActionMessageParameters() {
         addCanDoActionMessage(VdcBllMessages.VAR__ACTION__UPDATE);
         addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM__CLUSTER);
-
-        VM vm = getVm();
-        if (vm == null) {
-            
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_EXIST);
-            return false;
-        } else {
-
-            if (!canRunActionOnNonManagedVm()) {
-                return false;
-            }
-
-            if (ObjectIdentityChecker.CanUpdateField(vm, "vdsGroupId", 
vm.getStatus())) {
-                targetCluster = 
DbFacade.getInstance().getVdsGroupDao().get(getParameters().getClusterId());
-                if (targetCluster == null) {
-                    
addCanDoActionMessage(VdcBllMessages.VM_CLUSTER_IS_NOT_VALID);
-                    return false;
-                }
-
-                // Check that the target cluster is in the same data center.
-                if 
(!targetCluster.getStoragePoolId().equals(vm.getStoragePoolId())) {
-                    
addCanDoActionMessage(VdcBllMessages.VM_CANNOT_MOVE_TO_CLUSTER_IN_OTHER_STORAGE_POOL);
-                    return false;
-                }
-
-                List<VmNic> interfaces = 
getVmNicDao().getAllForVm(getParameters().getVmId());
-
-                Version clusterCompatibilityVersion = 
targetCluster.getcompatibility_version();
-                if (!validateDestinationClusterContainsNetworks(interfaces)
-                        || !validateNics(interfaces, 
clusterCompatibilityVersion)) {
-                    return false;
-                }
-
-                // Check if VM static parameters are compatible for new 
cluster.
-                boolean isCpuSocketsValid = AddVmCommand.checkCpuSockets(
-                        vm.getStaticData().getNumOfSockets(),
-                        vm.getStaticData().getCpuPerSocket(),
-                        clusterCompatibilityVersion.getValue(),
-                        getReturnValue().getCanDoActionMessages());
-                if (!isCpuSocketsValid) {
-                    return false;
-                }
-
-                // Check that the USB policy is legal
-                if (!VmHandler.isUsbPolicyLegal(vm.getUsbPolicy(), vm.getOs(), 
targetCluster, getReturnValue().getCanDoActionMessages())) {
-                    return false;
-                }
-
-                // Check if the display type is supported
-                if (!VmHandler.isDisplayTypeSupported(vm.getOs(),
-                        vm.getDefaultDisplayType(),
-                        getReturnValue().getCanDoActionMessages(),
-                        clusterCompatibilityVersion)) {
-                    return false;
-                }
-
-                if (VmDeviceUtils.isVirtioScsiControllerAttached(vm.getId())) {
-                    // Verify cluster compatibility
-                    if 
(!FeatureSupported.virtIoScsi(targetCluster.getcompatibility_version())) {
-                        return 
failCanDoAction(VdcBllMessages.VIRTIO_SCSI_INTERFACE_IS_NOT_AVAILABLE_FOR_CLUSTER_LEVEL);
-                    }
-
-                    // Verify OS compatibility
-                    if (!VmHandler.isOsTypeSupportedForVirtioScsi(vm.getOs(), 
targetCluster.getcompatibility_version(),
-                            getReturnValue().getCanDoActionMessages())) {
-                        return false;
-                    }
-                }
-
-                // A existing VM cannot be changed into a cluster without a 
defined architecture
-                if (targetCluster.getArchitecture() == 
ArchitectureType.undefined) {
-                    return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE);
-                } else if (targetCluster.getArchitecture() != 
vm.getClusterArch()) {
-                    return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES);
-                }
-            } else {
-                
addCanDoActionMessage(VdcBllMessages.VM_STATUS_NOT_VALID_FOR_UPDATE);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Checks that when unlinking/null network is not supported in the 
destination cluster and a NIC has unlinked/null
-     * network, it's not valid.
-     *
-     * @param interfaces
-     *            The NICs to check.
-     * @param clusterCompatibilityVersion
-     *            The destination cluster's compatibility version.
-     * @return Whether the NICs are linked correctly and network name is valid 
(with regards to the destination
-     *         cluster).
-     */
-    private boolean validateNics(List<VmNic> interfaces,
-            Version clusterCompatibilityVersion) {
-        for (VmNic iface : interfaces) {
-            VmNicValidator nicValidator = new VmNicValidator(iface, 
clusterCompatibilityVersion);
-            if (!validate(nicValidator.emptyNetworkValid()) || 
!validate(nicValidator.linkedCorrectly())) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Checks that the destination cluster has all the networks that the given 
NICs require.<br>
-     * No network on a NIC is allowed (it's checked when running VM).
-     *
-     * @param interfaces
-     *            The NICs to check networks on.
-     * @return Whether the destination cluster has all networks configured or 
not.
-     */
-    private boolean validateDestinationClusterContainsNetworks(List<VmNic> 
interfaces) {
-        List<Network> networks =
-                
DbFacade.getInstance().getNetworkDao().getAllForCluster(getParameters().getClusterId());
-        StringBuilder missingNets = new StringBuilder();
-        for (VmNic iface : interfaces) {
-            Network network = 
NetworkHelper.getNetworkByVnicProfileId(iface.getVnicProfileId());
-            if (network != null) {
-                boolean exists = false;
-                for (Network net : networks) {
-                    if (net.getName().equals(network.getName())) {
-                        exists = true;
-                        break;
-                    }
-                }
-                if (!exists) {
-                    if (missingNets.length() > 0) {
-                        missingNets.append(", ");
-                    }
-                    missingNets.append(network.getName());
-                }
-            }
-        }
-        if (missingNets.length() > 0) {
-            
addCanDoActionMessage(VdcBllMessages.MOVE_VM_CLUSTER_MISSING_NETWORK);
-            addCanDoActionMessageVariable("networks", missingNets.toString());
-            return false;
-        }
-
-        return true;
     }
 
     @Override
@@ -253,10 +115,6 @@
 
     @Override
     public List<PermissionSubject> getPermissionCheckSubjects() {
-        List<PermissionSubject> permissionList = new 
ArrayList<PermissionSubject>();
-        // In addition to having EDIT_VM_PROPERTIES on the VM, you must have 
CREATE_VM on the cluster
-        permissionList.add(new PermissionSubject(getParameters().getVmId(), 
VdcObjectType.VM, getActionType().getActionGroup()));
-        permissionList.add(new 
PermissionSubject(getParameters().getClusterId(), VdcObjectType.VdsGroups, 
ActionGroup.CREATE_VM));
-        return permissionList;
+        return 
VmHandler.getPermissionsNeededToChangeCluster(getParameters().getVmId(), 
getParameters().getClusterId());
     }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVmClusterValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVmClusterValidator.java
new file mode 100644
index 0000000..085c74d
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ChangeVmClusterValidator.java
@@ -0,0 +1,162 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.bll.network.cluster.NetworkHelper;
+import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
+import org.ovirt.engine.core.bll.validator.VmNicValidator;
+import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.common.businessentities.ArchitectureType;
+import org.ovirt.engine.core.common.businessentities.VDSGroup;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.network.Network;
+import org.ovirt.engine.core.common.businessentities.network.VmNic;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.Version;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+
+import java.util.List;
+
+public class ChangeVmClusterValidator {
+
+    private final Guid targetClusterId;
+
+    private VmCommand parentCommand;
+
+    private VDSGroup targetCluster;
+
+    public ChangeVmClusterValidator(VmCommand parentCommand, Guid 
targetClusterId) {
+        this.parentCommand = parentCommand;
+        this.targetClusterId = targetClusterId;
+    }
+
+    protected boolean validate() {
+        VM vm = parentCommand.getVm();
+        if (vm == null) {
+            
parentCommand.addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_FOUND);
+            return false;
+        } else {
+            targetCluster = 
DbFacade.getInstance().getVdsGroupDao().get(targetClusterId);
+            if (targetCluster == null) {
+                
parentCommand.addCanDoActionMessage(VdcBllMessages.VM_CLUSTER_IS_NOT_VALID);
+                return false;
+            }
+
+            // Check that the target cluster is in the same data center.
+            if 
(!targetCluster.getStoragePoolId().equals(vm.getStoragePoolId())) {
+                
parentCommand.addCanDoActionMessage(VdcBllMessages.VM_CANNOT_MOVE_TO_CLUSTER_IN_OTHER_STORAGE_POOL);
+                return false;
+            }
+
+            List<VmNic> interfaces = 
DbFacade.getInstance().getVmNicDao().getAllForVm(vm.getId());
+
+            Version clusterCompatibilityVersion = 
targetCluster.getcompatibility_version();
+            if (!validateDestinationClusterContainsNetworks(interfaces)
+                    || !validateNics(interfaces, clusterCompatibilityVersion)) 
{
+                return false;
+            }
+
+            // Check if VM static parameters are compatible for new cluster.
+            boolean isCpuSocketsValid = AddVmCommand.checkCpuSockets(
+                    vm.getStaticData().getNumOfSockets(),
+                    vm.getStaticData().getCpuPerSocket(),
+                    clusterCompatibilityVersion.getValue(),
+                    parentCommand.getReturnValue().getCanDoActionMessages());
+            if (!isCpuSocketsValid) {
+                return false;
+            }
+
+            // Check that the USB policy is legal
+            if (!VmHandler.isUsbPolicyLegal(vm.getUsbPolicy(), vm.getOs(), 
targetCluster, parentCommand.getReturnValue().getCanDoActionMessages())) {
+                return false;
+            }
+
+            // Check if the display type is supported
+            if (!VmHandler.isDisplayTypeSupported(vm.getOs(),
+                    vm.getDefaultDisplayType(),
+                    parentCommand.getReturnValue().getCanDoActionMessages(),
+                    clusterCompatibilityVersion)) {
+                return false;
+            }
+
+            if (VmDeviceUtils.isVirtioScsiControllerAttached(vm.getId())) {
+                // Verify cluster compatibility
+                if 
(!FeatureSupported.virtIoScsi(targetCluster.getcompatibility_version())) {
+                    return 
parentCommand.failCanDoAction(VdcBllMessages.VIRTIO_SCSI_INTERFACE_IS_NOT_AVAILABLE_FOR_CLUSTER_LEVEL);
+                }
+
+                // Verify OS compatibility
+                if (!VmHandler.isOsTypeSupportedForVirtioScsi(vm.getOs(), 
targetCluster.getcompatibility_version(),
+                        
parentCommand.getReturnValue().getCanDoActionMessages())) {
+                    return false;
+                }
+            }
+
+            // A existing VM cannot be changed into a cluster without a 
defined architecture
+            if (targetCluster.getArchitecture() == ArchitectureType.undefined) 
{
+                return 
parentCommand.failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE);
+            } else if (targetCluster.getArchitecture() != vm.getClusterArch()) 
{
+                return 
parentCommand.failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Checks that the destination cluster has all the networks that the given 
NICs require.<br>
+     * No network on a NIC is allowed (it's checked when running VM).
+     *
+     * @param interfaces The NICs to check networks on.
+     * @return Whether the destination cluster has all networks configured or 
not.
+     */
+    private boolean validateDestinationClusterContainsNetworks(List<VmNic> 
interfaces) {
+        List<Network> networks =
+                
DbFacade.getInstance().getNetworkDao().getAllForCluster(targetClusterId);
+        StringBuilder missingNets = new StringBuilder();
+        for (VmNic iface : interfaces) {
+            Network network = 
NetworkHelper.getNetworkByVnicProfileId(iface.getVnicProfileId());
+            if (network != null) {
+                boolean exists = false;
+                for (Network net : networks) {
+                    if (net.getName().equals(network.getName())) {
+                        exists = true;
+                        break;
+                    }
+                }
+                if (!exists) {
+                    if (missingNets.length() > 0) {
+                        missingNets.append(", ");
+                    }
+                    missingNets.append(network.getName());
+                }
+            }
+        }
+        if (missingNets.length() > 0) {
+            
parentCommand.addCanDoActionMessage(VdcBllMessages.MOVE_VM_CLUSTER_MISSING_NETWORK);
+            parentCommand.addCanDoActionMessageVariable("networks", 
missingNets.toString());
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks that when unlinking/null network is not supported in the 
destination cluster and a NIC has unlinked/null
+     * network, it's not valid.
+     *
+     * @param interfaces                  The NICs to check.
+     * @param clusterCompatibilityVersion The destination cluster's 
compatibility version.
+     * @return Whether the NICs are linked correctly and network name is valid 
(with regards to the destination
+     * cluster).
+     */
+    private boolean validateNics(List<VmNic> interfaces,
+                                 Version clusterCompatibilityVersion) {
+        for (VmNic iface : interfaces) {
+            VmNicValidator nicValidator = new VmNicValidator(iface, 
clusterCompatibilityVersion);
+            if (!parentCommand.validate(nicValidator.emptyNetworkValid()) || 
!parentCommand.validate(nicValidator.linkedCorrectly())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java
index 3e7354b..bda20d7 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java
@@ -10,14 +10,17 @@
 import org.ovirt.engine.core.bll.scheduling.SchedulingManager;
 import org.ovirt.engine.core.bll.scheduling.VdsFreeMemoryChecker;
 import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
+import org.ovirt.engine.core.bll.utils.PermissionSubject;
 import org.ovirt.engine.core.bll.validator.DiskImagesValidator;
 import org.ovirt.engine.core.bll.validator.LocalizedVmStatus;
 import org.ovirt.engine.core.bll.validator.VmValidator;
 import org.ovirt.engine.core.common.AuditLogType;
 import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.common.action.ChangeVMClusterParameters;
 import org.ovirt.engine.core.common.action.LockProperties;
 import org.ovirt.engine.core.common.action.LockProperties.Scope;
 import org.ovirt.engine.core.common.action.MigrateVmParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.businessentities.MigrationMethod;
 import org.ovirt.engine.core.common.businessentities.MigrationSupport;
 import org.ovirt.engine.core.common.businessentities.VDS;
@@ -54,6 +57,12 @@
 
     public MigrateVmCommand(T migrateVmParameters, CommandContext cmdContext) {
         super(migrateVmParameters, cmdContext);
+
+        if (migrateVmParameters.getTargetVdsGroupId() != null) {
+            setVdsGroupId(migrateVmParameters.getTargetVdsGroupId());
+            // force reload
+            setVdsGroup(null);
+        }
     }
 
     @Override
@@ -173,10 +182,20 @@
     public void runningSucceded() {
         try {
             getVmDynamicDao().clearMigratingToVds(getVmId());
+            updateVmAfterMigrationToDifferentCluster();
         }
         finally {
             super.runningSucceded();
         }
+    }
+
+    private void updateVmAfterMigrationToDifferentCluster() {
+        if 
(getVm().getVdsGroupId().equals(getParameters().getTargetVdsGroupId())) {
+            return;
+        }
+
+        ChangeVMClusterParameters params = new 
ChangeVMClusterParameters(getParameters().getTargetVdsGroupId(), getVmId());
+        
setSucceeded(getBackend().runInternalAction(VdcActionType.ChangeVMCluster, 
params).getSucceeded());
     }
 
     private int getMaximumMigrationDowntime() {
@@ -357,6 +376,13 @@
             return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL);
         }
 
+        if (getParameters().getTargetVdsGroupId() != null) {
+            ChangeVmClusterValidator changeVmClusterValidator = new 
ChangeVmClusterValidator(this, getParameters().getTargetVdsGroupId());
+            if (!changeVmClusterValidator.validate()) {
+                return false;
+            }
+        }
+
         return validate(new 
SnapshotsValidator().vmNotDuringSnapshot(vm.getId()))
                 // This check was added to prevent migration of VM while its 
disks are being migrated
                 // TODO: replace it with a better solution
@@ -440,4 +466,15 @@
     protected List<Guid> getVdsWhiteList() {
         return getParameters().getInitialHosts();
     }
+
+    @Override
+    public List<PermissionSubject> getPermissionCheckSubjects() {
+        List<PermissionSubject> permissionList = 
super.getPermissionCheckSubjects();
+        if (getParameters().getTargetVdsGroupId() != null) {
+            // additional permissions needed since changing the cluster
+            
permissionList.addAll(VmHandler.getPermissionsNeededToChangeCluster(getParameters().getVmId(),
 getParameters().getTargetVdsGroupId()));
+        }
+
+        return permissionList;
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmToServerCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmToServerCommand.java
index e252ca7..00b74fd 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmToServerCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmToServerCommand.java
@@ -10,7 +10,6 @@
 import org.ovirt.engine.core.common.action.LockProperties.Scope;
 import org.ovirt.engine.core.common.action.MigrateVmToServerParameters;
 import org.ovirt.engine.core.common.businessentities.VDS;
-import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.compat.Guid;
 
@@ -42,13 +41,15 @@
             return false;
         }
 
-        VM vm = getVm();
+        if (getParameters().getTargetVdsGroupId() != null && 
!getParameters().getTargetVdsGroupId().equals(getDestinationVds().getVdsGroupId()))
 {
+            return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER);
+        }
 
-        if (vm.getRunOnVds() != null && 
vm.getRunOnVds().equals(destinationId)) {
+        if (getVm().getRunOnVds() != null && 
getVm().getRunOnVds().equals(getDestinationVdsId())) {
             return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST);
         }
 
-        if (!vm.getVdsGroupId().equals(getDestinationVds().getVdsGroupId())) {
+        if 
(!getVm().getVdsGroupId().equals(getDestinationVds().getVdsGroupId()) && 
getParameters().getTargetVdsGroupId() == null) {
             return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS);
         }
 
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
index 102539e..9f55a125 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
@@ -14,14 +14,17 @@
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.bll.context.CompensationContext;
 import org.ovirt.engine.core.bll.network.MacPoolManager;
+import org.ovirt.engine.core.bll.utils.PermissionSubject;
 import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
 import org.ovirt.engine.core.bll.validator.StorageDomainValidator;
 import org.ovirt.engine.core.bll.validator.VmValidationUtils;
 import org.ovirt.engine.core.common.AuditLogType;
 import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.action.VmManagementParametersBase;
 import org.ovirt.engine.core.common.backendinterfaces.BaseHandler;
+import org.ovirt.engine.core.common.businessentities.ActionGroup;
 import org.ovirt.engine.core.common.businessentities.ArchitectureType;
 import org.ovirt.engine.core.common.businessentities.Disk;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
@@ -897,4 +900,11 @@
 
         return new 
ValidationResult(VdcBllMessages.VM_NUMA_NODE_PREFERRED_NOT_PINNED_TO_SINGLE_NODE);
     }
+
+    public static List<PermissionSubject> 
getPermissionsNeededToChangeCluster(Guid vmId, Guid clusterId) {
+        List<PermissionSubject> permissionList = new ArrayList<>();
+        permissionList.add(new PermissionSubject(vmId, VdcObjectType.VM, 
ActionGroup.EDIT_VM_PROPERTIES));
+        permissionList.add(new PermissionSubject(clusterId, 
VdcObjectType.VdsGroups, ActionGroup.CREATE_VM));
+        return permissionList;
+    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmParameters.java
index 5cf0d01..2e2bd87 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmParameters.java
@@ -14,13 +14,19 @@
     protected boolean forceMigrationForNonMigratableVm;
     ArrayList<Guid> initialHosts;
     protected Date startTime;
+    private Guid targetVdsGroupId;
 
     public MigrateVmParameters() {
     }
 
     public MigrateVmParameters(boolean forceMigrationForNonMigratableVM, Guid 
vmId) {
+        this(forceMigrationForNonMigratableVM, vmId, null);
+    }
+
+    public MigrateVmParameters(boolean forceMigrationForNonMigratableVM, Guid 
vmId, Guid targetVdsGroupId) {
         super(vmId);
 
+        this.targetVdsGroupId = targetVdsGroupId;
         setForceMigrationForNonMigratableVm(forceMigrationForNonMigratableVM);
     }
 
@@ -56,4 +62,11 @@
         this.startTime = startTime;
     }
 
+    public Guid getTargetVdsGroupId() {
+        return targetVdsGroupId;
+    }
+
+    public void setTargetVdsGroupId(Guid targetVdsGroupId) {
+        this.targetVdsGroupId = targetVdsGroupId;
+    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmToServerParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmToServerParameters.java
index 7dd576c..b2a9382 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmToServerParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/MigrateVmToServerParameters.java
@@ -6,11 +6,15 @@
     private static final long serialVersionUID = 2378358850714143232L;
     private Guid vdsId;
 
-    public MigrateVmToServerParameters(boolean forceMigration, Guid vmId, Guid 
serverId) {
-        super(forceMigration, vmId);
+    public MigrateVmToServerParameters(boolean forceMigration, Guid vmId, Guid 
serverId, Guid targetVdsGroupId) {
+        super(forceMigration, vmId, targetVdsGroupId);
         vdsId = serverId;
     }
 
+    public MigrateVmToServerParameters(boolean forceMigration, Guid vmId, Guid 
serverId) {
+        this(forceMigration, vmId, serverId, null);
+    }
+
     public Guid getVdsId() {
         return vdsId;
     }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
index b889d61..718949c 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
@@ -210,6 +210,7 @@
     
ACTION_TYPE_FAILED_STORAGE_DOMAIN_TYPE_UNSUPPORTED(ErrorType.BAD_PARAMETERS),
     ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST(ErrorType.CONFLICT),
+    
ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER(ErrorType.CONFLICT),
     
ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE(ErrorType.BAD_PARAMETERS),
     ACTION_TYPE_FAILED_VDS_VM_CLUSTER(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_VDS_CLUSTER_DIFFERENT_ARCHITECTURES(ErrorType.CONFLICT),
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties 
b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
index f5b0f5b..7eab173 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
@@ -218,6 +218,7 @@
 ACTION_TYPE_FAILED_DISK_LUN_INVALID=Cannot ${action} ${type}. The provided LUN 
is not visible by the specified host, please check storage server connectivity.
 ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS=Cannot ${action} ${type}. VM 
migration is in progress
 ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST=Cannot ${action} ${type}. source and 
destination is the same.
+ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER=Cannot 
${action} ${type}. Destination host is not present in destination cluster.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_SYNTAX=Cannot ${action} 
${type} if custom properties are in invalid format. Please check the input.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_KEYS=Cannot ${action} 
${type} if some of the specified custom properties are not configured by the 
system. The keys are: ${MissingKeys}
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_VALUES=Cannot ${action} 
${type} if some of the specified custom properties have illegal values. The 
keys are: ${WrongValueKeys}
@@ -630,8 +631,8 @@
 ACTION_TYPE_FAILED_BOOKMARK_INVALID_ID=Cannot ${action} ${type}. Bookmark ID 
is not valid.
 ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL=Cannot ${action} ${type}. Operation can 
be performed only when Host status is ${hostStatus}.
 ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES=Cannot ${action} 
${type}. The VM and the destination cluster architectures do not match.
-ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. VM 
can be migrated only between Hosts in the same Cluster.\n\
-       -Please select target Host in the same Cluster to run the VM.
+ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. If 
target Cluster is not specified VM can be migrated only between Hosts in the 
same Cluster.\n\
+       -Please select target Host in the same Cluster to run the VM or specify 
a target Cluster.
 VDS_CANNOT_CHECK_VERSION_HOST_NON_RESPONSIVE=Cannot get Host version when Host 
is in Non Responsive status.
 STORAGE_DOMAIN_DOES_NOT_EXIST=Storage Domain doesn't exist.
 ACTION_TYPE_FAILED_VDS_INTERMITENT_CONNECTIVITY=Due to intermittent 
connectivity to this Host, fence operations are not allowed at this time. The 
system is trying to reconnect, please try again in 30 seconds.
diff --git 
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
 
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
index 4f03281..3457382 100644
--- 
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
+++ 
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
@@ -589,6 +589,9 @@
     @DefaultStringValue("Cannot ${action} ${type}. source and destination is 
the same.")
     String ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST();
 
+    @DefaultStringValue("Cannot ${action} ${type}. Destination host is not 
present in destination cluster.")
+    String ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER();
+
     @DefaultStringValue("Cannot ${action} ${type} if custom properties are in 
invalid format. Please check the input.")
     String ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_SYNTAX();
 
@@ -1732,7 +1735,7 @@
     @DefaultStringValue("Cannot ${action} ${type}. Operation can be performed 
only when Host status is ${hostStatus}.")
     String ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL();
 
-    @DefaultStringValue("Cannot ${action} ${type}. VM can be migrated only 
between Hosts in the same Cluster.\n-Please select target Host in the same 
Cluster to run the VM.")
+    @DefaultStringValue("Cannot ${action} ${type}. If target Cluster is not 
specified VM can be migrated only between Hosts in the same Cluster.\n-Please 
select target Host in the same Cluster to run the VM or specify a target 
Cluster.")
     String ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS();
 
     @DefaultStringValue("Cannot get Host version when Host is in Non 
Responsive status.")
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
index fdaae4b..7071a66 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
@@ -211,6 +211,7 @@
 ACTION_TYPE_FAILED_DISK_LUN_INVALID=Cannot ${action} ${type}. The provided LUN 
is not visible by the specified host, please check storage server connectivity.
 ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS=Cannot ${action} ${type}. VM 
migration is in progress
 ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST=Cannot ${action} ${type}. source and 
destination is the same.
+ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER=Cannot 
${action} ${type}. Destination host is not present in destination cluster.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_SYNTAX=Cannot ${action} 
${type} if custom properties are in invalid format. Please check the input.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_KEYS=Cannot ${action} 
${type} if some of the specified custom properties are not configured by the 
system. The keys are: ${MissingKeys}
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_VALUES=Cannot ${action} 
${type} if some of the specified custom properties have illegal values. The 
keys are: ${WrongValueKeys}
@@ -596,8 +597,8 @@
 ACTION_TYPE_FAILED_BOOKMARK_INVALID_ID=Cannot ${action} ${type}. Bookmark ID 
is not valid.
 ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL=Cannot ${action} ${type}. Operation can 
be performed only when Host status is ${hostStatus}.
 ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES=Cannot ${action} 
${type}. The VM and the destination cluster architectures do not match.
-ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. VM 
can be migrated only between Hosts in the same Cluster.\n\
-       -Please select target Host in the same Cluster to run the VM.
+ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. If 
target Cluster is not specified VM can be migrated only between Hosts in the 
same Cluster.\n\
+       -Please select target Host in the same Cluster to run the VM or specify 
a target Cluster.
 VDS_CANNOT_CHECK_VERSION_HOST_NON_RESPONSIVE=Cannot get Host version when Host 
is in Non Responsive status.
 STORAGE_DOMAIN_DOES_NOT_EXIST=Storage Domain doesn't exist.
 ACTION_TYPE_FAILED_VDS_INTERMITENT_CONNECTIVITY=Due to intermittent 
connectivity to this Host, fence operations are not allowed at this time. The 
system is trying to reconnect, please try again in 30 seconds.
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
index db32cd4..3d5e766 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
+++ 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
@@ -216,6 +216,7 @@
 ACTION_TYPE_FAILED_DISK_LUN_IS_ALREADY_IN_USE=Cannot ${action} ${type}. The 
provided lun is used by another disk.
 ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS=Cannot ${action} ${type}. VM 
migration is in progress
 ACTION_TYPE_FAILED_MIGRATION_TO_SAME_HOST=Cannot ${action} ${type}. source and 
destination is the same.
+ACTION_TYPE_FAILED_DESTINATION_HOST_NOT_IN_DESTINATION_CLUSTER=Cannot 
${action} ${type}. Destination host is not present in destination cluster.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_SYNTAX=Cannot ${action} 
${type} if custom properties are in invalid format. Please check the input.
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_KEYS=Cannot ${action} 
${type} if some of the specified custom properties are not configured by the 
system. The keys are: ${MissingKeys}
 ACTION_TYPE_FAILED_INVALID_CUSTOM_PROPERTIES_INVALID_VALUES=Cannot ${action} 
${type} if some of the specified custom properties have illegal values. The 
keys are: ${WrongValueKeys}
@@ -635,8 +636,8 @@
 ACTION_TYPE_FAILED_BOOKMARK_INVALID_ID=Cannot ${action} ${type}. Bookmark ID 
is not valid.
 ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL=Cannot ${action} ${type}. Operation can 
be performed only when Host status is ${hostStatus}.
 ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES=Cannot ${action} 
${type}. The VM and the destination cluster architectures do not match.
-ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. VM 
can be migrated only between Hosts in the same Cluster.\n\
-       -Please select target Host in the same Cluster to run the VM.
+ACTION_TYPE_FAILED_MIGRATE_BETWEEN_TWO_CLUSTERS=Cannot ${action} ${type}. If 
target Cluster is not specified VM can be migrated only between Hosts in the 
same Cluster.\n\
+       -Please select target Host in the same Cluster to run the VM or specify 
a target Cluster.
 STORAGE_DOMAIN_DOES_NOT_EXIST=Storage Domain doesn't exist.
 VDS_CANNOT_CHECK_VERSION_HOST_NON_RESPONSIVE=Cannot get Host version when Host 
is in Non Responsive status.
 ACTION_TYPE_FAILED_VDS_INTERMITENT_CONNECTIVITY=Due to intermittent 
connectivity to this Host, fence operations are not allowed at this time. The 
system is trying to reconnect, please try again in 30 seconds.


-- 
To view, visit http://gerrit.ovirt.org/34650
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9eb4fd7f10d3b0e63455a81f0b5c1389586a43f4
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5
Gerrit-Owner: Tomas Jelinek <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to