Daniel Erez has uploaded a new change for review.

Change subject: core: move unplugged disks while VM is running
......................................................................

core: move unplugged disks while VM is running

Refactor/rewrite of MoveDisksCommand to support the following:
* Offline move of unplugged disks while the VM is running.
* Add error messages when trying to move/migrate a mixture
  of plugged and unplugged disks (on a running VM).

Change-Id: Ie0fbfd95c0086cfe0d792b3071a2d804ff32c18e
Bug-Url: https://bugzilla.redhat.com/987783
Bug-Url: https://bugzilla.redhat.com/957494
Bug-Url: https://bugzilla.redhat.com/957492
Signed-off-by: Daniel Erez <de...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveDisksCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommand.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveDisksCommandTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommandTest.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
9 files changed, 257 insertions(+), 111 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/05/19105/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveDisksCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveDisksCommand.java
index fb97e9f..903e27c 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveDisksCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveDisksCommand.java
@@ -2,10 +2,11 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
-import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
+import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
 import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.LiveMigrateDiskParameters;
@@ -27,9 +28,9 @@
 public class MoveDisksCommand<T extends MoveDisksParameters> extends 
CommandBase<T> {
 
     private List<VdcReturnValueBase> vdcReturnValues = new 
ArrayList<VdcReturnValueBase>();
-    private List<MoveDiskParameters> moveParametersList = new 
ArrayList<MoveDiskParameters>();
-    private Map<Guid, List<LiveMigrateDiskParameters>> 
vmsLiveMigrateParametersMap =
-            new HashMap<Guid, List<LiveMigrateDiskParameters>>();
+    private List<MoveDiskParameters> moveDiskParametersList = new 
ArrayList<>();
+    private List<LiveMigrateVmDisksParameters> 
liveMigrateVmDisksParametersList = new ArrayList<>();
+    private Map<Guid, DiskImage> diskMap = new HashMap<>();
 
     public MoveDisksCommand(Guid commandId) {
         super(commandId);
@@ -41,14 +42,16 @@
 
     @Override
     protected void executeCommand() {
-        if (!moveParametersList.isEmpty()) {
+        updateParameters();
+
+        if (!moveDiskParametersList.isEmpty()) {
             
vdcReturnValues.addAll(Backend.getInstance().RunMultipleActions(VdcActionType.MoveOrCopyDisk,
-                    getMoveDisksParametersList(), false));
+                    getParametersArrayList(moveDiskParametersList), false));
         }
 
-        if (!vmsLiveMigrateParametersMap.isEmpty()) {
+        if (!liveMigrateVmDisksParametersList.isEmpty()) {
             
vdcReturnValues.addAll(Backend.getInstance().RunMultipleActions(VdcActionType.LiveMigrateVmDisks,
-                    getLiveMigrateDisksParametersList(), false));
+                    getParametersArrayList(liveMigrateVmDisksParametersList), 
false));
         }
 
         handleChildReturnValue();
@@ -68,7 +71,7 @@
             return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_NO_DISKS_SPECIFIED);
         }
 
-        return updateParameters();
+        return true;
     }
 
     @Override
@@ -77,41 +80,88 @@
         addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM_DISK);
     }
 
+    private void addDisksDeactivatedMessage(List<MoveDiskParameters> 
moveDiskParamsList) {
+        setActionMessageParameters();
+        addCanDoActionMessage(String.format("$%1$s %2$s", "diskAliases",
+                StringUtils.join(getUnpluggedDisksAliases(moveDiskParamsList), 
", ")));
+        
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_DISKS_DEACTIVATED);
+        getReturnValue().setCanDoAction(false);
+    }
+
+    private void addInvalidVmStateMessage(VM vm){
+        setActionMessageParameters();
+        addCanDoActionMessage(String.format("$%1$s %2$s", "VmName", 
vm.getName()));
+        
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN_OR_UP);
+        getReturnValue().setCanDoAction(false);
+    }
+
     /**
      * For each specified MoveDiskParameters, decide whether it should be moved
-     * using 'regular' move or using live migrate command.
-     *
-     * @return false if the command should fail on canDoAction; otherwise, true
+     * using offline move or live migrate command.
      */
-    private boolean updateParameters() {
-        for (MoveDiskParameters moveDiskParameters : 
getParameters().getParametersList()) {
-            DiskImage diskImage = 
getDiskImageDao().get(moveDiskParameters.getImageId());
-            if (diskImage == null) {
-                return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_DISK_NOT_EXIST);
-            }
+    protected void updateParameters() {
+        Map<VM, List<MoveDiskParameters>> vmDiskParamsMap = 
createVmDiskParamsMap();
 
-            List<VM> allVms = getVmDAO().getVmsListForDisk(diskImage.getId());
-            VM vm = !allVms.isEmpty() ? allVms.get(0) : null;
+        for (Map.Entry<VM, List<MoveDiskParameters>> vmDiskParamsEntry : 
vmDiskParamsMap.entrySet()) {
+            VM vm = vmDiskParamsEntry.getKey();
+            List<MoveDiskParameters> moveDiskParamsList = 
vmDiskParamsEntry.getValue();
 
-            if (vm != null && 
!validate(createSnapshotsValidator().vmNotInPreview(vm.getId()))) {
-                return false;
-            }
-
-            if (vm == null || vm.isDown()) {
-                moveParametersList.add(moveDiskParameters);
+            if (vm == null || vm.isDown() || 
isAllDisksUnplugged(moveDiskParamsList)) {
+                // Adding parameters for offline move
+                moveDiskParametersList.addAll(moveDiskParamsList);
             }
             else if (vm.isRunningAndQualifyForDisksMigration()) {
-                MultiValueMapUtils.addToMap(vm.getId(),
-                        createLiveMigrateDiskParameters(moveDiskParameters, 
vm.getId()),
-                        vmsLiveMigrateParametersMap);
+                if (!isAllDisksPlugged(moveDiskParamsList)) {
+                    // Cannot live migrate and move disks concurrently
+                    addDisksDeactivatedMessage(moveDiskParamsList);
+                    continue;
+                }
+
+                // Adding parameters for live migrate
+                
liveMigrateVmDisksParametersList.add(createLiveMigrateVmDisksParameters(moveDiskParamsList,
 vm.getId()));
             }
             else {
-                addCanDoActionMessage(String.format("$%1$s %2$s", "VmName", 
vm.getName()));
-                return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN_OR_UP);
+                // Live migrate / move disk is not applicable according to VM 
status
+                addInvalidVmStateMessage(vm);
             }
         }
+    }
 
-        return true;
+    /**
+     * @return a map of VMs to relevant MoveDiskParameters list.
+     */
+    private Map<VM, List<MoveDiskParameters>> createVmDiskParamsMap() {
+        Map<VM, List<MoveDiskParameters>> vmDisksMap = new HashMap<>();
+        for (MoveDiskParameters moveDiskParameters : 
getParameters().getParametersList()) {
+            DiskImage diskImage = 
getDiskImageDao().get(moveDiskParameters.getImageId());
+
+            Map<Boolean, List<VM>> allVmsForDisk = 
getVmDAO().getForDisk(diskImage.getId());
+            List<VM> vmsForPluggedDisk = allVmsForDisk.get(Boolean.TRUE);
+            List<VM> vmsForUnpluggedDisk = allVmsForDisk.get(Boolean.FALSE);
+
+            VM vm = vmsForPluggedDisk != null ? vmsForPluggedDisk.get(0) :
+                    vmsForUnpluggedDisk != null ? vmsForUnpluggedDisk.get(0) : 
null;
+
+            addDiskToMap(diskImage, vmsForPluggedDisk, vmsForUnpluggedDisk);
+            MultiValueMapUtils.addToMap(vm, moveDiskParameters, vmDisksMap);
+        }
+
+        return vmDisksMap;
+    }
+
+    /**
+     * Add the specified diskImage to diskMap; with updated 'plugged' value.
+     * (diskMap contains all disks specified in the parameters).
+     */
+    private void addDiskToMap(DiskImage diskImage, List<VM> vmsForPluggedDisk, 
List<VM> vmsForUnpluggedDisk) {
+        if (vmsForPluggedDisk != null) {
+            diskImage.setPlugged(true);
+        }
+        else if (vmsForUnpluggedDisk != null) {
+            diskImage.setPlugged(false);
+        }
+
+        diskMap.put(diskImage.getImageId(), diskImage);
     }
 
     private LiveMigrateDiskParameters 
createLiveMigrateDiskParameters(MoveDiskParameters moveDiskParameters, Guid 
vmId) {
@@ -122,29 +172,63 @@
                 moveDiskParameters.getQuotaId());
     }
 
-    protected ArrayList<VdcActionParametersBase> getMoveDisksParametersList() {
-        for (MoveDiskParameters moveDiskParameters : moveParametersList) {
-            moveDiskParameters.setSessionId(getParameters().getSessionId());
+    private LiveMigrateVmDisksParameters 
createLiveMigrateVmDisksParameters(List<MoveDiskParameters> moveDiskParamsList, 
Guid vmId) {
+        // Create LiveMigrateDiskParameters list
+        List<LiveMigrateDiskParameters> liveMigrateDiskParametersList = new 
ArrayList<>();
+        for (MoveDiskParameters moveDiskParameters : moveDiskParamsList) {
+            
liveMigrateDiskParametersList.add(createLiveMigrateDiskParameters(moveDiskParameters,
 vmId));
         }
 
-        return new ArrayList<VdcActionParametersBase>(moveParametersList);
+        // Create LiveMigrateVmDisksParameters (multiple disks)
+        LiveMigrateVmDisksParameters liveMigrateDisksParameters =
+                new 
LiveMigrateVmDisksParameters(liveMigrateDiskParametersList, vmId);
+        liveMigrateDisksParameters.setParentCommand(VdcActionType.MoveDisks);
+
+        return liveMigrateDisksParameters;
     }
 
-    protected ArrayList<VdcActionParametersBase> 
getLiveMigrateDisksParametersList() {
-        ArrayList<LiveMigrateVmDisksParameters> liveMigrateDisksParametersList 
=
-                new ArrayList<LiveMigrateVmDisksParameters>();
-
-        for (Map.Entry<Guid, List<LiveMigrateDiskParameters>> entry : 
vmsLiveMigrateParametersMap.entrySet()) {
-            LiveMigrateVmDisksParameters liveMigrateDisksParameters =
-                    new LiveMigrateVmDisksParameters(entry.getValue(), 
entry.getKey());
-
-            
liveMigrateDisksParameters.setParentCommand(VdcActionType.MoveDisks);
-            
liveMigrateDisksParameters.setSessionId(getParameters().getSessionId());
-
-            liveMigrateDisksParametersList.add(liveMigrateDisksParameters);
+    private ArrayList<VdcActionParametersBase> getParametersArrayList(List<? 
extends VdcActionParametersBase> parametersList) {
+        for (VdcActionParametersBase parameters : parametersList) {
+            parameters.setSessionId(getParameters().getSessionId());
         }
 
-        return new 
ArrayList<VdcActionParametersBase>(liveMigrateDisksParametersList);
+        return new ArrayList<>(parametersList);
+    }
+
+    /**
+     * Return true if all specified disks are plugged; otherwise false.
+     */
+    private boolean isAllDisksPlugged(List<MoveDiskParameters> 
moveDiskParamsList) {
+        return isAllDisksPlugged(moveDiskParamsList, true);
+    }
+
+    /**
+     * Return false if all specified disks are unplugged; otherwise true.
+     */
+    private boolean isAllDisksUnplugged(List<MoveDiskParameters> 
moveDiskParamsList) {
+        return isAllDisksPlugged(moveDiskParamsList, false);
+    }
+
+    private boolean isAllDisksPlugged(List<MoveDiskParameters> 
moveDiskParamsList, boolean plugged) {
+        for (MoveDiskParameters moveDiskParameters : moveDiskParamsList) {
+            DiskImage diskImage = diskMap.get(moveDiskParameters.getImageId());
+            if (diskImage.getPlugged() != plugged) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private List<String> getUnpluggedDisksAliases(List<MoveDiskParameters> 
moveDiskParamsList) {
+        List<String> unpluggedDisks = new LinkedList<>();
+        for (MoveDiskParameters moveDiskParameters : moveDiskParamsList) {
+            DiskImage diskImage = diskMap.get(moveDiskParameters.getImageId());
+            if (!diskImage.getPlugged()) {
+                unpluggedDisks.add(diskImage.getDiskAlias());
+            }
+        }
+        return unpluggedDisks;
     }
 
     @Override
@@ -167,7 +251,11 @@
         return getDbFacade().getDiskImageDao();
     }
 
-    protected SnapshotsValidator createSnapshotsValidator() {
-        return new SnapshotsValidator();
+    protected List<MoveDiskParameters> getMoveDiskParametersList() {
+        return moveDiskParametersList;
+    }
+
+    protected List<LiveMigrateVmDisksParameters> 
getLiveMigrateVmDisksParametersList() {
+        return liveMigrateVmDisksParametersList;
     }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommand.java
index 20573c0..093e19d 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommand.java
@@ -16,6 +16,7 @@
 import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter;
 import org.ovirt.engine.core.bll.quota.QuotaStorageConsumptionParameter;
 import org.ovirt.engine.core.bll.quota.QuotaStorageDependent;
+import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
 import org.ovirt.engine.core.bll.tasks.SPMAsyncTaskHandler;
 import org.ovirt.engine.core.bll.tasks.TaskHandlerCommand;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
@@ -234,7 +235,7 @@
         setStoragePoolId(getVm().getStoragePoolId());
 
         if (!isValidParametersList() || !checkImagesStatus() || 
!isValidSpaceRequirements()
-                || !isVmNotRunningStateless()) {
+                || !isVmNotRunningStateless() || !isVmNotInPreview()) {
             return false;
         }
 
@@ -360,4 +361,12 @@
     protected VmValidator createVmValidator() {
         return new VmValidator(getVm());
     }
+
+    private boolean isVmNotInPreview() {
+        return validate(createSnapshotsValidator().vmNotInPreview(getVmId()));
+    }
+
+    protected SnapshotsValidator createSnapshotsValidator() {
+        return new SnapshotsValidator();
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveDisksCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveDisksCommandTest.java
index 11711bd..8ef0de0 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveDisksCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveDisksCommandTest.java
@@ -3,7 +3,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -18,17 +17,14 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
 import org.ovirt.engine.core.common.action.MoveDiskParameters;
 import org.ovirt.engine.core.common.action.MoveDisksParameters;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
-import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotStatus;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dao.DiskImageDAO;
-import org.ovirt.engine.core.dao.SnapshotDao;
 import org.ovirt.engine.core.dao.VmDAO;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -45,9 +41,6 @@
     @Mock
     private VmDAO vmDao;
 
-    @Mock
-    protected SnapshotDao snapshotDao;
-
     /**
      * The command under test
      */
@@ -57,7 +50,6 @@
     public void setupCommand() {
         initSpyCommand();
         mockDaos();
-        mockSnapshotValidator();
     }
 
     private void initSpyCommand() {
@@ -78,40 +70,16 @@
     }
 
     @Test
-    public void canDoActionImagesNotFound() {
-        command.getParameters().setParametersList(createMoveDisksParameters());
-
-        assertFalse(command.canDoAction());
-        assertTrue(command.getReturnValue()
-                .getCanDoActionMessages()
-                
.contains(VdcBllMessages.ACTION_TYPE_FAILED_DISK_NOT_EXIST.toString()));
-    }
-
-    @Test
     public void canDoActionInvalidVmStatus() {
         command.getParameters().setParametersList(createMoveDisksParameters());
 
         initDiskImage(diskImageId);
         initVm(VMStatus.Unknown, Guid.newGuid(), diskImageId);
 
-        assertFalse(command.canDoAction());
+        command.updateParameters();
         assertTrue(command.getReturnValue()
                 .getCanDoActionMessages()
                 
.contains(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN_OR_UP.toString()));
-    }
-
-    @Test
-    public void canDoActionVmInPreview() {
-        command.getParameters().setParametersList(createMoveDisksParameters());
-
-        initDiskImage(diskImageId);
-        initVm(VMStatus.Down, null, diskImageId);
-        setVmInPreview(true);
-
-        assertFalse(command.canDoAction());
-        assertTrue(command.getReturnValue()
-                .getCanDoActionMessages()
-                
.contains(VdcBllMessages.ACTION_TYPE_FAILED_VM_IN_PREVIEW.toString()));
     }
 
     @Test
@@ -121,8 +89,8 @@
         initDiskImage(diskImageId);
         initVm(VMStatus.Down, null, diskImageId);
 
-        assertTrue(command.canDoAction());
-        assertFalse(command.getMoveDisksParametersList().isEmpty());
+        command.updateParameters();
+        assertTrue(command.getMoveDiskParametersList().size() == 1);
     }
 
     @Test
@@ -131,8 +99,8 @@
 
         initDiskImage(diskImageId);
 
-        assertTrue(command.canDoAction());
-        assertFalse(command.getMoveDisksParametersList().isEmpty());
+        command.updateParameters();
+        assertTrue(command.getMoveDiskParametersList().size() == 1);
     }
 
     @Test
@@ -142,8 +110,8 @@
         initDiskImage(diskImageId);
         initVm(VMStatus.Up, Guid.newGuid(), diskImageId);
 
-        assertTrue(command.canDoAction());
-        assertFalse(command.getLiveMigrateDisksParametersList().isEmpty());
+        command.updateParameters();
+        assertTrue(command.getLiveMigrateVmDisksParametersList().size() == 1);
     }
 
     @Test
@@ -153,8 +121,30 @@
         initDiskImageBasedOnTemplate(diskImageId);
         initVm(VMStatus.Up, Guid.newGuid(), diskImageId);
 
-        assertTrue(command.canDoAction());
-        assertFalse(command.getLiveMigrateDisksParametersList().isEmpty());
+        command.updateParameters();
+        assertTrue(command.getLiveMigrateVmDisksParametersList().size() == 1);
+    }
+
+    @Test
+    public void moveUnpluggedDiskVmDown() {
+        command.getParameters().setParametersList(createMoveDisksParameters());
+
+        initDiskImage(diskImageId);
+        initVm(VMStatus.Down, Guid.newGuid(), diskImageId, false);
+
+        command.updateParameters();
+        assertTrue(command.getMoveDiskParametersList().size() == 1);
+    }
+
+    @Test
+    public void moveUnpluggedDiskVmUp() {
+        command.getParameters().setParametersList(createMoveDisksParameters());
+
+        initDiskImage(diskImageId);
+        initVm(VMStatus.Up, Guid.newGuid(), diskImageId, false);
+
+        command.updateParameters();
+        assertTrue(command.getMoveDiskParametersList().size() == 1);
     }
 
     @Test
@@ -171,24 +161,54 @@
         initVm(VMStatus.Up, Guid.newGuid(), diskImageId1);
         initVm(VMStatus.Down, Guid.newGuid(), diskImageId2);
 
-        assertTrue(command.canDoAction());
-        assertFalse(command.getMoveDisksParametersList().isEmpty());
-        assertFalse(command.getLiveMigrateDisksParametersList().isEmpty());
+        command.updateParameters();
+        assertTrue(command.getMoveDiskParametersList().size() == 1);
+        assertTrue(command.getLiveMigrateVmDisksParametersList().size() == 1);
+    }
+
+    @Test
+    public void movePluggedDiskAndUnpluggedDiskVmUp() {
+        Guid diskImageId1 = Guid.newGuid();
+        Guid diskImageId2 = Guid.newGuid();
+
+        MoveDiskParameters moveDiskParameters1 = new 
MoveDiskParameters(diskImageId1, srcStorageId, dstStorageId);
+        MoveDiskParameters moveDiskParameters2 = new 
MoveDiskParameters(diskImageId2, srcStorageId, dstStorageId);
+        
command.getParameters().setParametersList(Arrays.asList(moveDiskParameters1, 
moveDiskParameters2));
+
+        initDiskImage(diskImageId1);
+        initDiskImage(diskImageId2);
+        initVm(VMStatus.Up, Guid.newGuid(), diskImageId1, true, diskImageId2, 
false);
+
+        command.updateParameters();
+        assertTrue(command.getReturnValue()
+                .getCanDoActionMessages()
+                
.contains(VdcBllMessages.ACTION_TYPE_FAILED_DISKS_DEACTIVATED.toString()));
     }
 
     /** Initialize Entities */
 
     private void initVm(VMStatus vmStatus, Guid runOnVds, Guid diskImageId) {
+        initVm(vmStatus, runOnVds, diskImageId, true, null, false);
+    }
+
+    private void initVm(VMStatus vmStatus, Guid runOnVds, Guid diskImageId, 
boolean isPlugged) {
+        initVm(vmStatus, runOnVds, diskImageId, isPlugged, null, false);
+    }
+
+    private void initVm(VMStatus vmStatus, Guid runOnVds, Guid diskImageId1, 
boolean isPlugged1,
+            Guid diskImageId2, boolean isPlugged2) {
         VM vm = new VM();
         vm.setStatus(vmStatus);
         vm.setRunOnVds(runOnVds);
 
         when(vmDao.get(any(Guid.class))).thenReturn(vm);
-        
when(vmDao.getVmsListForDisk(diskImageId)).thenReturn(Collections.singletonList(vm));
-    }
+        when(vmDao.getForDisk(diskImageId1)).thenReturn(
+                Collections.singletonMap(isPlugged1, 
Collections.singletonList(vm)));
 
-    private void setVmInPreview(boolean isInPreview) {
-        when(snapshotDao.exists(any(Guid.class), 
eq(SnapshotStatus.IN_PREVIEW))).thenReturn(isInPreview);
+        if (diskImageId2 != null) {
+            when(vmDao.getForDisk(diskImageId2)).thenReturn(
+                    Collections.singletonMap(isPlugged2, 
Collections.singletonList(vm)));
+        }
     }
 
     private void initDiskImage(Guid diskImageId) {
@@ -205,19 +225,9 @@
     private DiskImage mockDiskImage(Guid diskImageId) {
         DiskImage diskImage = new DiskImage();
         diskImage.setId(diskImageId);
+        diskImage.setImageId(diskImageId);
 
         return diskImage;
-    }
-
-    private void mockSnapshotValidator() {
-        SnapshotsValidator validator = new SnapshotsValidator() {
-            @Override
-            protected SnapshotDao getSnapshotDao() {
-                return snapshotDao;
-            }
-
-        };
-        doReturn(validator).when(command).createSnapshotsValidator();
     }
 
     /** Mock DAOs */
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommandTest.java
index e1f3607..7e4734b 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/lsm/LiveMigrateVmDisksCommandTest.java
@@ -3,6 +3,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -18,10 +19,12 @@
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.ovirt.engine.core.bll.ValidationResult;
+import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
 import org.ovirt.engine.core.bll.validator.VmValidator;
 import org.ovirt.engine.core.common.action.LiveMigrateDiskParameters;
 import org.ovirt.engine.core.common.action.LiveMigrateVmDisksParameters;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
 import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
@@ -32,6 +35,7 @@
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.Version;
 import org.ovirt.engine.core.dao.DiskImageDAO;
+import org.ovirt.engine.core.dao.SnapshotDao;
 import org.ovirt.engine.core.dao.StorageDomainDAO;
 import org.ovirt.engine.core.dao.StoragePoolDAO;
 import org.ovirt.engine.core.dao.VmDAO;
@@ -60,7 +64,13 @@
     private VmDAO vmDao;
 
     @Mock
+    protected SnapshotDao snapshotDao;
+
+    @Mock
     private VmValidator vmValidator;
+
+    @Mock
+    private SnapshotsValidator snapshotsValidator;
 
     /**
      * The command under test
@@ -182,6 +192,22 @@
                 
.contains(VdcBllMessages.ACTION_TYPE_FAILED_VM_RUNNING_STATELESS.name()));
     }
 
+    @Test
+    public void canDoActionVmInPreview() {
+        createParameters();
+        initDiskImage(diskImageId);
+        initVm(VMStatus.Up, null, diskImageId);
+        setVmInPreview(true);
+
+        doReturn(new 
ValidationResult(VdcBllMessages.ACTION_TYPE_FAILED_VM_IN_PREVIEW)).when(snapshotsValidator)
+                .vmNotInPreview(any(Guid.class));
+
+        assertFalse(command.canDoAction());
+        assertTrue(command.getReturnValue()
+                .getCanDoActionMessages()
+                
.contains(VdcBllMessages.ACTION_TYPE_FAILED_VM_IN_PREVIEW.toString()));
+    }
+
     /** Initialize Entities */
 
     private void initVm(VMStatus vmStatus, Guid runOnVds, Guid diskImageId) {
@@ -226,6 +252,10 @@
         when(command.getStoragePoolId()).thenReturn(storagePoolId);
     }
 
+    private void setVmInPreview(boolean isInPreview) {
+        when(snapshotDao.exists(any(Guid.class), 
eq(Snapshot.SnapshotStatus.IN_PREVIEW))).thenReturn(isInPreview);
+    }
+
     /** Mock DAOs */
 
     private void mockDaos() {
@@ -254,6 +284,8 @@
 
     private void mockValidators() {
         doReturn(vmValidator).when(command).createVmValidator();
+        doReturn(snapshotsValidator).when(command).createSnapshotsValidator();
         
doReturn(ValidationResult.VALID).when(vmValidator).vmNotRunningStateless();
+        
doReturn(ValidationResult.VALID).when(snapshotsValidator).vmNotInPreview(any(Guid.class));
     }
 }
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 9d78564..2d182bc 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
@@ -105,6 +105,7 @@
     ACTION_TYPE_FAILED_VM_IN_PREVIEW(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_DISKS_LOCKED(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_DISKS_ILLEGAL(ErrorType.INTERNAL_ERROR),
+    ACTION_TYPE_FAILED_DISKS_DEACTIVATED(ErrorType.INTERNAL_ERROR),
     ACTION_TYPE_FAILED_IMPORT_DISKS_ALREADY_EXIST(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_VM_IS_LOCKED(ErrorType.CONFLICT),
     ACTION_TYPE_FAILED_VM_DURING_EXPORT(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 214e79a..41deb01 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
@@ -137,6 +137,7 @@
 ACTION_TYPE_FAILED_VM_IN_PREVIEW=Cannot ${action} ${type}. VM is previewing a 
Snapshot.
 ACTION_TYPE_FAILED_DISKS_LOCKED=Cannot ${action} ${type}: The following disks 
are locked: ${diskAliases}. Please try again in a few minutes.
 ACTION_TYPE_FAILED_DISKS_ILLEGAL=Cannot ${action} ${type}. The following 
attached disks are in ILLEGAL status: ${diskAliases} - please remove them and 
try again.
+ACTION_TYPE_FAILED_DISKS_DEACTIVATED=Cannot ${action} ${type}. The following 
disks are deactivated: ${diskAliases}. Please activate them and try again.
 ACTION_TYPE_FAILED_IMPORT_DISKS_ALREADY_EXIST=Cannot ${action} ${type}. The 
following disks already exist: ${diskAliases}. Please import as a clone.
 ACTION_TYPE_FAILED_VM_IS_LOCKED=Cannot ${action} ${type}: VM is locked. Please 
try again in a few minutes.
 ACTION_TYPE_FAILED_VM_DURING_EXPORT=Cannot ${action} ${type}: VM is being 
exported now. Please try again in a few minutes.
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 edb4b67..d0942cb 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
@@ -346,6 +346,9 @@
     @DefaultStringValue("Cannot ${action} ${type}. The following attached 
disks are in ILLEGAL status: ${diskAliases} - please remove them and try 
again.")
     String ACTION_TYPE_FAILED_DISKS_ILLEGAL();
 
+    @DefaultStringValue("Cannot ${action} ${type}. The following disks are 
deactivated: ${diskAliases}. Please activate them and try again.")
+    String ACTION_TYPE_FAILED_DISKS_DEACTIVATED();
+
     @DefaultStringValue("Cannot ${action} ${type}. The following disks already 
exist: ${diskAliases}. Please import as a clone.")
     String ACTION_TYPE_FAILED_IMPORT_DISKS_ALREADY_EXIST();
 
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 06cba89..92a2041 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
@@ -130,6 +130,7 @@
 ACTION_TYPE_FAILED_VM_IN_PREVIEW=Cannot ${action} ${type}. VM is previewing a 
Snapshot.
 ACTION_TYPE_FAILED_DISKS_LOCKED=Cannot ${action} ${type}: The following disks 
are locked: ${diskAliases}. Please try again in a few minutes.
 ACTION_TYPE_FAILED_DISKS_ILLEGAL=Cannot ${action} ${type}. The following 
attached disks are in ILLEGAL status: ${diskAliases} - please remove them and 
try again.
+ACTION_TYPE_FAILED_DISKS_DEACTIVATED=Cannot ${action} ${type}. The following 
disks are deactivated: ${diskAliases}. Please activate them and try again.
 ACTION_TYPE_FAILED_IMPORT_DISKS_ALREADY_EXIST=Cannot ${action} ${type}. The 
following disks already exist: ${diskAliases}. Please import as a clone.
 ACTION_TYPE_FAILED_VM_IS_LOCKED=Cannot ${action} ${type}: VM is locked. Please 
try again in a few minutes.
 ACTION_TYPE_FAILED_VM_DURING_EXPORT=Cannot ${action} ${type}: VM is being 
exported now. Please try again in a few minutes.
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 939800c..3f83c1b 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
@@ -134,6 +134,7 @@
 ACTION_TYPE_FAILED_VM_IN_PREVIEW=Cannot ${action} ${type}. VM is previewing a 
Snapshot.
 ACTION_TYPE_FAILED_DISKS_LOCKED=Cannot ${action} ${type}: The following disks 
are locked: ${diskAliases}. Please try again in a few minutes.
 ACTION_TYPE_FAILED_DISKS_ILLEGAL=Cannot ${action} ${type}. The following 
attached disks are in ILLEGAL status: ${diskAliases} - please remove them and 
try again.
+ACTION_TYPE_FAILED_DISKS_DEACTIVATED=Cannot ${action} ${type}. The following 
disks are deactivated: ${diskAliases}. Please activate them and try again.
 ACTION_TYPE_FAILED_IMPORT_DISKS_ALREADY_EXIST=Cannot ${action} ${type}. The 
following disks already exist: ${diskAliases}. Please import as a clone.
 ACTION_TYPE_FAILED_VM_IS_LOCKED=Cannot ${action} ${type}: VM is locked. Please 
try again in a few minutes.
 ACTION_TYPE_FAILED_VM_DURING_EXPORT=Cannot ${action} ${type}: VM is being 
exported now. Please try again in a few minutes.


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie0fbfd95c0086cfe0d792b3071a2d804ff32c18e
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Daniel Erez <de...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to